Two sensors can measure how far a board is tilted, and each fails in its own way. Watch them below against the dashed truth: one’s dots scatter about it, while the other’s smooth line drifts further off.
Noisy but right, smooth but drifting
Synthetic tilt, 30 s at 100 Hz: an accelerometer with 3° noise (seed 3220), a gyroscope with a 0.5 °/s bias and noise (seed 322).
The true tilt: still, up to 30°, down to −20°, back to level.
Describe this picture
A synthetic tilt, 30 s at 100 Hz, measured by an accelerometer with 3° noise (seed 3220) and a gyroscope with a 0.5 °/s bias and noise (seed 322). One panel, tilt from −40° to 45° against time from 0 to 30 s. The true tilt is a dashed line, the accelerometer’s readings are small dots, and the integrated gyroscope is a solid line. The readouts are the time in seconds, the accelerometer’s error RMS since 5 s, over the readings drawn so far, and the gyroscope’s error now, in degrees. There is no control. The 13 s clip opens on the true tilt alone: still, up to 30°, down to −20°, back to level. From 2.5 s both sensors draw. The drawing pauses at 15 s: the accelerometer scatters about the truth, 2.94° RMS, and the gyroscope follows each turn but has begun to drift, 7.6° off. Then it goes on to 30 s, where the accelerometer’s error is 3.00° RMS over 5–30 s, centred on 0, and the gyroscope is 15.2° off.
Noisy but right, smooth but drifting
A sensor never hands you the quantity itself. It hands you the quantity plus its own habits. The good news is that those habits come in a few kinds, and each kind has its own fix.
Four ways a sensor lies
An offset shifts every reading by the same amount. A scale that reads 0.2 kg with nothing on it has an offset. The fix is calibration: measure the offset at a moment when you know the truth, then subtract it from every reading.
A drift is an offset that changes slowly, with temperature or age. One calibration does not cure it, because the offset you measured stops being true. You have to measure it again, or check against a second sensor.
Noise scatters each reading around the truth. Smoothing reduces it, at the price of delay, as in “Choosing a” of Simple smoothing filters (18.2).
An outlier is a single wild reading, from a bad contact or a knock. A median ignores it, as in “A median ignores spikes” of the same lesson.
| Fault | What you see | The fix |
|---|---|---|
| offset | every reading shifted the same | calibrate: subtract a measured offset |
| drift | the shift changes slowly | calibrate again, or check against another sensor |
| noise | readings scatter about the truth | smooth, and accept some delay |
| outliers | single readings far off | take a median |
All of this is signal conditioning: turning raw readings into numbers you can trust. This page works through one classic case, where two sensors with opposite faults rescue each other.
Two ways to measure a tilt
Picture a board that tilts about one axis, like a phone tipped toward you. I want its tilt , the angle from level. On this page angles are in degrees: 30° is 0.52 rad.
An accelerometer measures the push it feels along each of its axes. At rest it feels only gravity, straight down. When the board tilts, gravity’s pull shifts from one of the sensor’s axes toward another, and the shares give the angle. I call that reading .
It is right on average, because gravity always points the same way. But each reading is noisy. A real one is also thrown off whenever the board speeds up or is shaken, since those pushes add to gravity. On this page its only fault is noise.
A gyroscope measures how fast the board turns, in degrees per second. I call that reading . It knows nothing about the angle itself, only how quickly it is changing.
To get an angle from it, add up the turns. Each sample the board turns by about , so the running total is the recursion of “Each answer comes from the last one” in Difference equations (6.1):
with the delay box starting at 0, since the board starts level. A gyroscope’s readings are smooth, so this angle is smooth too.
Its weakness is a small constant error in the rate, called its bias : the offset of a rate sensor. Added up sample after sample, a bias of degrees per second puts the angle degrees further off every second. A constant offset in the rate turns into a growing drift in the angle.
The two sensors often sit on one chip, called an inertial measurement unit, or IMU.
The test tilt
Every signal on this page is synthetic: a stated tilt, noise from the site’s seeded generator, and a stated gyroscope bias. Nothing is recorded, so every error can be measured against a known truth. I measure every RMS error from 5 s, where the first turn starts, to 30 s.
The true tilt lasts 30 s, sampled at 100 Hz, so s and there are 3000 samples. It is level until 5 s. It turns to 30° between 5 and 7 s, to −20° between 15 and 18 s, and back to 0° between 24 and 26 s.
Each turn follows half a cosine, so it starts and ends gently. Its rate is highest in the middle. The fastest is the 50° turn over 3 s, at 26.2 degrees per second.
The accelerometer reads the true tilt plus white noise of standard deviation 3°, from seed 3220. These 3000 draws measure 3.007°.
The gyroscope reads the true rate, plus a bias of 0.5 degrees per second, plus white noise of 0.3 degrees per second from seed 322. Those draws measure 0.301.
Think of a compass that jitters against a ship’s log of speed and heading. The compass is right on average. The log is smooth, but every small error in it carries forward, so the ship’s reckoned position slowly goes astray.
The picture at the top of the page draws both sensors against this tilt.
Notice the two kinds of error. The accelerometer’s dots stay centred on the truth, scattered by 3° at every moment. The gyroscope’s line is smooth and follows every turn, yet by the end it is 15.2° off.
Where the 15.2° comes from
Most of it is the bias. Half a degree per second for 30 s is 15°. The remaining 0.22° comes from adding up the gyroscope’s noise.
That noise does not average away when you add it up. Each sample adds an independent step of standard deviation °. In “White noise forgets, coloured noise remembers” of Random processes (24.2), variances of independent parts add.
So after samples the variance is times a step’s, and the spread is degrees. At 30 s that is 0.16°, and it keeps growing with the square root of time. This is 24.2’s AR(1) loop with : it never forgets, and its value wanders without limit.
So the gyroscope is good over short times and bad over long ones. The accelerometer is the opposite: no single reading is good, but on average it never strays.
Low-pass one, high-pass the other
That suggests the fix. Take the slow part of the tilt from the accelerometer, which is right on average, and the fast part from the gyroscope, which is smooth. It is like trusting a friend’s directions for the next turn and the map for the way home.
One line of code
Each sample, start from the last estimate and add the gyroscope’s turn. Then pull the result a small fraction of the way toward the accelerometer’s reading:
The hat marks an estimate, as in Random variables for signals (24.1). I start at the accelerometer’s first reading, , since I do not know the truth.
This is the complementary filter. Its two weights, and , add to 1. With a number in seconds, I set
Why is a time constant
Drop the gyroscope term and the line is the EMA of 18.2, . In “A 9-point average and its one-multiply twin”, its mean delay is samples.
With this , that is samples, which is exactly seconds. So is the filter’s time constant.
In “Choosing a”, 18.2 set instead. When is many samples long the two agree. At s, they give 0.990099 and 0.990050, both 0.9901.
The truth passes untouched
Suppose both sensors were perfect. The gyroscope’s turn would equal the true change, , and the accelerometer would read .
If the estimate is right at sample , the bracket becomes . Then , right again. Starting right, the estimate stays right at every sample, however fast the tilt moves.
So the filter adds no delay and no blur of its own. Only the sensors’ faults get through, and each through its own path.
What each path does
The accelerometer’s noise enters through the EMA, a low-pass. By 18.2’s noise rule, it keeps a share of the noise’s RMS. With this , that share is , so a longer leaves less noise.
The gyroscope’s bias goes the other way. Hold the board still and ignore the noise. The estimate settles at a steady error where one more step changes nothing:
For this the steady error is exactly , the bias times the time constant. With 18.2’s it would be a little less, about .
The error does not appear at once. From a correct start it grows as , getting most of the way there within a few .
So the time constant sets the trade. A short trusts the accelerometer and keeps its noise. A long one trusts the gyroscope and lets the bias push the estimate off, by up to .
The handover
In frequency, the accelerometer’s path has the EMA’s gain, as 18.2 worked out. It is 1 for a steady tilt and small for fast changes. The gyroscope’s path acts on the added-up angle and passes only its changes: nothing of a steady angle, nearly all of a fast one. A bias makes a ramp that never stops changing, which is why gets through.
The two gains are equal where . The distance from 1 to on the unit circle is , so with this the condition becomes . For the small angles here, , which in hertz is
I call this the handover frequency; it is also called the crossover. Slower changes come mostly from the accelerometer, faster ones mostly from the gyroscope.
Low-pass one, high-pass the other
The same sensors, fused with a complementary filter (gyro not calibrated).
τ = 0.05 s: mostly accelerometer; the noise comes through, 0.91° RMS.
Describe this picture
The same sensors, fused with a complementary filter, the gyroscope not calibrated. Two stacked panels share the time axis. The first, the tilt, has the axes of the first picture: the fused estimate is a solid line over the true tilt, dashed. The second draws the error, the estimate minus the truth, as a solid line from −10° to 10°. The readouts are in seconds, with four decimals, the error RMS over 5–30 s in degrees, and the handover frequency in hertz. The 13 s clip opens at τ = 0.05 s, = 0.8333: mostly accelerometer, so the noise comes through, 0.91° RMS, with the handover at 3.183 Hz. From 3.5 s the time constant grows to 20 s, = 0.9995: mostly gyroscope, smooth, but the bias pushes it off, 5.43° RMS, handover 0.008 Hz. From 8 s it moves to 0.5 s, = 0.9804: the handover where neither fault dominates, 0.42° RMS, at 0.318 Hz. When the clip ends, a full-width slider, “Time constant τ”, has 15 positions, 1, 2, 3 and 5 in each decade from 0.01 to 30 s, starting at 0.5 s. The arrow keys move one position, and the caption gives the error and the handover. The setting is kept in the link, as fusion.tau.
Watch the error panel as changes. At 0.05 s the accelerometer’s noise comes through; at 20 s the bias pushes the estimate off; at 0.5 s neither fault dominates.
Notice the error panel at 0.5 s, the best of the slider’s positions. The error is 0.42° RMS, about a seventh of the accelerometer’s 3.00°, and it does not grow with time like the gyroscope’s.
Checking the bias rule
Set s and look at the hold at 30°, from 10 to 15 s. The rule predicts a steady error of °. The run measures 0.45° on average there: the accelerometer’s noise, averaged over those 5 s, comes to −0.06°.
At s the rule predicts 10.0°, but only after a few time constants, a minute or more. Over the same hold the error averages 4.05° and is still growing.
Calibrate first
The bias is an offset in the rate, so it has the offset’s fix. The first 5 s are still, so the true rate there is 0. Whatever the gyroscope reports then is its bias plus noise.
The average of those 500 readings is degrees per second. Its own noise is about , so the true 0.5 is well within reach. Subtract from every gyroscope reading and fuse again.
Now the best of the slider’s positions moves to s, and the error falls to 0.14° RMS.
What stops a longer now is not the bias, which is down to 0.004 degrees per second. It is mostly the start: the filter began at the accelerometer’s first reading, 1.11° off, and a long takes long to forget it.
So why fuse at all, once calibrated? Over these 30 s the calibrated gyroscope alone stays within 0.12°. But a leftover of 0.004 degrees per second is 14.6° after an hour, and its added-up noise spreads by about 1.8°.
Real biases also change with temperature, so a calibration does not stay true. The accelerometer keeps the long run honest.
A Kalman filter with a fixed gain
Look again at the filter’s two steps. In “Predict, then correct” of RLS and the Kalman filter (26.4), a Kalman filter predicts with a model, then moves toward the measurement by a gain .
Here the prediction is the last estimate plus the gyroscope’s turn, and the measurement is . The correction gives times the prediction plus . That is the complementary filter, with .
The Kalman filter computes its gain from the noise sizes. The gyroscope’s noise adds a variance of per step to the prediction. The accelerometer’s variance is .
Started at the accelerometer’s first reading, with that reading’s variance, its gain begins at 0.5 and settles to 0.0010 within the 30 s. Then , and is about 10 s. That is the accelerometer’s noise over the gyroscope’s, 3 over 0.3.
Once its gain stops changing, a Kalman filter is a complementary filter. But this one’s model has no bias. On the uncalibrated gyroscope, the slider’s 10 s gives 3.82° RMS. Real attitude filters add the bias to the state, as 26.4 added the velocity.
The maths behind it · summing to the identity
The two paths add to the identity. The accelerometer’s path is , and the gyroscope’s, acting on , is . Their sum is 1 at every frequency, so a tilt both sensors measure correctly passes through undistorted.
The maths behind it · the bias–variance trade
The best balances two kinds of error. The accelerometer’s noise left is a random scatter, a variance, and it falls as grows. The gyroscope’s bias leaves a systematic error, , that grows with it. Their mean squares add, so this is a bias–variance trade, the central compromise of statistics.
Worked example
1. The coefficient. Take s and s. Then , and the mean delay is samples, 1 s.
2. Bias against τ. A gyroscope bias of degrees per second leaves a steady error °. This is exact for , once the start is forgotten and the tilt holds still.
3. The best τ, by hand. For much longer than , model the error as the accelerometer’s noise left, , plus the bias error . Their mean squares add: . Setting its slope to zero gives , so s.
The slider’s nearest position is 0.5 s. There the model gives a noise left of ° and a bias error of 0.25°, together °. The run measures 0.42°. The difference is the start, the turns, the gyroscope’s noise and this particular noise record.
4. The handover. At s, Hz. The exact equal-gain point, from , is also 0.318 Hz. At s the shortcut gives 3.183 Hz and the exact point 3.188 Hz.
5. Calibration. The gyroscope’s 500 still readings average 0.504 degrees per second. Subtracted, they leave 0.004, which at s is a steady error of °.
Where you’ll meet this
A phone fuses its accelerometer and gyroscope many times a second to know how it is held, for games and maps. Virtual reality headsets fuse the same two sensors to follow your head with little delay.
Drone flight controllers need their attitude, the tilt in every direction, hundreds of times a second to stay level. Many use a complementary filter of this kind, or its three-axis form by Mahony and colleagues. Self-balancing robots and scooters, and the stabilisers that keep a handheld camera level, do the same.
I left out the full three-dimensional problem, where the tilt is a rotation, often stored as a quaternion. I also left out magnetometers, which give a heading the way the accelerometer gives the tilt, and temperature compensation of the bias.
For more, see W. T. Higgins, “A comparison of complementary and Kalman filtering” (IEEE Trans. Aerospace and Electronic Systems, 1975), and R. Mahony, T. Hamel and J.-M. Pflimlin, “Nonlinear complementary filters on the special orthogonal group” (IEEE Trans. Automatic Control, 2008). Next, Radar signal processing (33.1) measures distance and speed from echoes.
Reference card
| Quantity | Formula | Notes |
|---|---|---|
| Gyroscope angle | a bias drifts by per second | |
| Calibration | = mean of while still; subtract it | removes the bias |
| Complementary filter | ||
| Mean delay | samples | exactly seconds |
| Accelerometer noise left | share of its RMS | falls as grows |
| Bias error | steady state; exact for this | |
| Handover | slow: accelerometer, fast: gyroscope | |
| Kalman link | once the gain settles |