← Back to blog

A Fast Orientation Estimation Filter: Madgwick

I'm building a custom quadrotor flight controller, and one of the challenges is fast state estimation with limited onboard compute. The flight controller is a Teensy 4.0 (600 MHz ARM Cortex M7 with hardware FPU), and I need a fast orientation estimator that I can later fuse with other sensors (barometer, magnetometer, GPS) for state estimation, which will be used by an MPC or RL based controller (more on that in a future post) and for trajectory following. The IMU is an MPU6050, providing a 3-axis gyroscope and a 3-axis accelerometer.

Breadboard setup with a Teensy 4.0 and MPU6050

This post covers the Madgwick filter, which I used for orientation estimation. It's a short read focused on the algorithm and the math behind it.

Madgwick represents orientation throughout as a unit quaternion .

Problem

Integrating gyro readings alone drifts over time due to bias and noise accumulation every sample, and orientation error grows unbounded even when the drone is at rest.

The accelerometer measures gravity, which can be used as an absolute reference for roll and pitch with no drift. The reading is noisy sample to sample, though, and gets corrupted the moment there is sudden acceleration such as thrust changes or motor vibration.

Madgwick's filter fuses the two. The gyro gives a fast, drift prone estimate, and the accelerometer continuously corrects it with a slow, absolute, but noisy reference.

IMU data flows through the Madgwick filter to a quaternion, then to attitude and linear acceleration

1. Gyroscope prediction

The angular velocity , measured in rad/s, integrates into a quaternion rate using the standard quaternion kinematic equation.

This relates the time derivative of a rotation quaternion to the angular velocity. Expanded into scalar form, it can be expressed as the following four terms.

2. Accelerometer correction

The orientation is found by aligning the reference gravity direction in the inertial frame, rotated into the sensor frame, with the measured and normalized accelerometer reading . This alignment is expressed as an error function , which is zero when the current orientation guess exactly matches what the accelerometer sees.

This error function is minimized using gradient descent. Since has three components and has four, the sensitivity of each error component to each quaternion component is captured by the Jacobian of with respect to , shown below.

The gradient is , and it points in the direction that increases error the fastest. Expanding this product algebraically gives the four terms actually used in the update.

The vector is this gradient normalized to unit length, so it represents a pure correction direction rather than a magnitude tied to how large the current error happens to be.

Predicted gravity from the current quaternion versus measured accelerometer down; the difference is the error that drives the correction

3. Fusion

Since the gradient points toward increasing error, subtracting it moves the estimate toward decreasing error. is the only tuning parameter in the filter. It sets how much the accelerometer correction is trusted relative to the gyro prediction.

4. Integration and normalization

Normalization runs every step because adding does not preserve on its own. This predict, correct, fuse, integrate, and normalize sequence runs once for every IMU sample.

Roll, pitch, yaw

Clamp the argument to , since floating point rounding can occasionally push it slightly outside that range. Yaw has no absolute reference without a magnetometer, so it drifts slowly over time. Roll and pitch stay anchored by gravity and do not drift.

Linear acceleration

The gravity direction in the sensor frame, computed from , is given by the following three components.

The linear acceleration is then , where is the gravity constant, and is treated as a unit vector pointing in the direction gravity currently occupies in the sensor frame.

Choosing

A low gives smooth output, but roll and pitch visibly drift over tens of seconds. A high corrects drift quickly, but motor vibration and prop wash inject noise directly into the attitude estimate.