|
| 1 | +# Complementary Filter |
| 2 | + |
| 3 | +## Overview & Motivation |
| 4 | + |
| 5 | +Real-time attitude and heading estimation requires fusing two fundamentally different sensor |
| 6 | +modalities: a **gyroscope** that integrates angular rate to produce a short-term angle estimate |
| 7 | +(fast response, low noise, but subject to drift) and an **accelerometer or magnetometer** that |
| 8 | +reads the angle directly (accurate at rest, noisy during motion, slow dynamics). Neither sensor |
| 9 | +alone is sufficient. The complementary filter solves the fusion problem with two multiplies |
| 10 | +and two adds per sample, making it the default tilt estimator on virtually every IMU-based |
| 11 | +embedded project where a full Kalman filter is unaffordable. |
| 12 | + |
| 13 | +## Mathematical Theory |
| 14 | + |
| 15 | +### Frequency-Domain Complement |
| 16 | + |
| 17 | +The two sensor paths are complementary in the transfer-function sense: the gyro path acts as a |
| 18 | +**first-order high-pass filter** and the direct-angle path acts as a **first-order low-pass filter** |
| 19 | +sharing the same crossover frequency $\omega_c = 1/\tau$. Their sum is identically unity for all |
| 20 | +frequencies: |
| 21 | + |
| 22 | +$$H_{HP}(s) + H_{LP}(s) = 1$$ |
| 23 | + |
| 24 | +This ensures that no frequency content is amplified or attenuated by the fusion itself. |
| 25 | + |
| 26 | +### Discrete-Time Update Equation |
| 27 | + |
| 28 | +Given the fused angle $\theta_k$, gyro rate $\omega_k$, accelerometer angle $\theta_{acc,k}$, |
| 29 | +sample period $T_s$, and blend weight $\alpha \in [0,1]$: |
| 30 | + |
| 31 | +$$\theta_{k+1} = \alpha\,(\theta_k + \omega_k\,T_s) + (1-\alpha)\,\theta_{acc,k}$$ |
| 32 | + |
| 33 | +The term $\theta_k + \omega_k T_s$ is the **high-pass path** (integration of the fast sensor), |
| 34 | +and $\theta_{acc,k}$ is the **low-pass path** (direct measurement from the slow sensor). |
| 35 | + |
| 36 | +### Design Parameter |
| 37 | + |
| 38 | +The single tuning knob is the crossover time constant $\tau$, which maps to $\alpha$ via: |
| 39 | + |
| 40 | +$$\alpha = \frac{\tau}{\tau + T_s}$$ |
| 41 | + |
| 42 | +Below $1/\tau$ the filter trusts the accelerometer; above it, the gyroscope. Typical embedded |
| 43 | +values are $\tau = 0.5$–$2$ s, corresponding to $\alpha \approx 0.98$ at $T_s = 10$ ms. |
| 44 | + |
| 45 | +### Heading Wrap (Shortest-Arc Blend) |
| 46 | + |
| 47 | +When the state is a heading angle in $(-\pi, \pi]$, a naive linear blend can jump by $2\pi$ near |
| 48 | +the seam. Instead the blend is performed along the shortest arc: |
| 49 | + |
| 50 | +$$\delta = \mathrm{WrapToPi}(\theta_{acc} - \hat{\theta})$$ |
| 51 | +$$\theta_{k+1} = \mathrm{WrapToPi}\!\left(\hat{\theta} + (1-\alpha)\,\delta\right)$$ |
| 52 | + |
| 53 | +where $\mathrm{WrapToPi}(x) = \bigl((x + \pi) \bmod 2\pi\bigr) - \pi$. |
| 54 | + |
| 55 | +## Complexity Analysis |
| 56 | + |
| 57 | +| Operation | Time | Space | Notes | |
| 58 | +|-----------|--------|--------|--------------------------------------------| |
| 59 | +| Update | $O(1)$ | $O(1)$ | 2 multiplies, 2 adds; 1 fmod when wrapping | |
| 60 | +| Reset | $O(1)$ | $O(1)$ | Single state write | |
| 61 | + |
| 62 | +Total storage: one angle word plus two constant coefficients. |
| 63 | + |
| 64 | +## Step-by-Step Walkthrough |
| 65 | + |
| 66 | +**Setup:** $\alpha = 0.98$, $T_s = 10$ ms, initial angle $= 0$. |
| 67 | + |
| 68 | +**Sample 1:** gyro rate $\omega = 10$ deg/s $= 0.1745$ rad/s, accel reads $\theta_{acc} = 0.01$ rad. |
| 69 | + |
| 70 | +$$\hat{\theta} = 0 + 0.1745 \times 0.01 = 0.001745 \text{ rad} \quad (\text{gyro path})$$ |
| 71 | +$$\theta_1 = 0.98 \times 0.001745 + 0.02 \times 0.01 = 0.001710 + 0.000200 = 0.001910 \text{ rad}$$ |
| 72 | + |
| 73 | +**After many samples with zero rate and accel $= 0.2$ rad:** the low-pass term accumulates |
| 74 | +and $\theta \to 0.2$ rad as $(1-\alpha)^n \to 0$. |
| 75 | + |
| 76 | +## Pitfalls & Edge Cases |
| 77 | + |
| 78 | +- **Alpha at 1:** the gyro path integrates without bound; any constant bias drifts the angle |
| 79 | + indefinitely. This is intentional (gyro-only mode) but must be avoided in production. |
| 80 | +- **Alpha at 0:** the output equals the accelerometer reading at every step; the gyro is ignored. |
| 81 | +- **Heading wrap:** linear blending without shortest-arc correction produces a $2\pi$ jump when |
| 82 | + the heading crosses $\pm\pi$. Always enable the wrap mode for heading estimation. |
| 83 | +- **Gyro bias:** the filter has no bias estimator. A constant gyro bias produces a bounded |
| 84 | + steady-state error of approximately $\text{bias} \cdot T_s \cdot \alpha / (1-\alpha)$. |
| 85 | + Pre-subtract a calibrated bias before calling Update. |
| 86 | +- **Accelerometer noise during dynamics:** the accel path is unreliable when linear acceleration |
| 87 | + is present (non-gravitational). Reduce $(1-\alpha)$ or temporarily freeze the accel correction. |
| 88 | + |
| 89 | +## Variants & Generalizations |
| 90 | + |
| 91 | +| Variant | Key Difference | |
| 92 | +|----------------------------|-----------------------------------------------------------------------| |
| 93 | +| **Mahony filter** | 3-D quaternion formulation with integral gyro-bias estimator | |
| 94 | +| **Madgwick filter** | Gradient-descent quaternion fusion; no linearisation | |
| 95 | +| **Alpha-Beta filter** | Fixed-gain tracking without a slow sensor; pure high-pass integration | |
| 96 | +| **Kalman filter** | Optimal (minimum-variance) fusion; requires noise covariance tuning | |
| 97 | +| **Two-step complementary** | Separate pitch/roll from heading; common on 6-DOF IMUs | |
| 98 | + |
| 99 | +## Applications |
| 100 | + |
| 101 | +- **IMU tilt estimation** — Roll and pitch from a 6-axis MEMS sensor at low computational cost. |
| 102 | +- **Heading fusion** — Combining gyro yaw rate with magnetometer heading. |
| 103 | +- **Servo/motor feedback** — Fusing encoder velocity with potentiometer position. |
| 104 | +- **Altitude hold** — Mixing barometer (low-pass) with accelerometer integration (high-pass). |
| 105 | + |
| 106 | +## Connections to Other Algorithms |
| 107 | + |
| 108 | +| Algorithm | Relationship | |
| 109 | +|----------------------------------------------------------------------|--------------------------------------------------------------------------| |
| 110 | +| [Exponential Moving Average](../passive/ExponentialMovingAverage.md) | The low-pass path in isolation; $\alpha_{EMA} = 1-\alpha_{CF}$ | |
| 111 | +| [Alpha-Beta Filter](AlphaBetaFilter.md) | Complementary filter without a slow-sensor reference; fixed-gain tracker | |
| 112 | +| [AHRS Madgwick/Mahony](AhrsMadgwickMahony.md) | 3-D quaternion generalization with gyro-bias estimation | |
| 113 | +| [Kalman Filter](KalmanFilter.md) | Statistically optimal generalization requiring $Q$ and $R$ tuning | |
| 114 | + |
| 115 | +## References & Further Reading |
| 116 | + |
| 117 | +- W. T. Higgins, "A Comparison of Complementary and Kalman Filtering," *IEEE Transactions on |
| 118 | + Aerospace and Electronic Systems*, 11(3), pp. 321–325, 1975. |
| 119 | +- S. Madgwick, "An Efficient Orientation Filter for Inertial and Inertial/Magnetic Sensor Arrays," |
| 120 | + Technical Report, University of Bristol, 2010. |
| 121 | +- R. Mahony, T. Hamel, and J.-M. Pflimlin, "Nonlinear Complementary Filters on the Special |
| 122 | + Orthogonal Group," *IEEE Transactions on Automatic Control*, 53(5), pp. 1203–1218, 2008. |
0 commit comments