TL;DR:
A gyroscope reports rotation rate. Integrating it gives angle, and any small bias is integrated too.
A bias of 0.1°/s adds 6° of error every minute.
A complementary filter blends the smooth gyroscope with the drift-free accelerometer.
Your self-balancing robot stands upright for a few seconds, then starts leaning, then falls. Nothing is broken. The gyroscope in it is working as designed, and a very small error in it has been growing every second. This is called drift, and almost every robot with a gyroscope has to deal with it.
From rate to angle
A gyroscope does not measure angle. It measures angular rate, how fast the sensor turns, for example in degrees per second. To get the angle you add up the rate over time:
angle(new) = angle(old) + rate × dt
This is integration. If the robot turns at 10°/s for 2 seconds, the angle changes by 10 × 2 = 20°. Do this update many times a second, and you track the orientation.
Bias: a small error that never goes away
No gyroscope reads exactly zero when it is still. It has a small offset called bias. Integration adds up everything, including the bias, so the error does not average out. It keeps piling up.
Worked example: a 0.1°/s bias integrated for one minute gives 6°
Say your gyroscope has a bias of 0.1°/s while sitting perfectly still. Each second, the code adds 0.1° to the angle.
After 1 second:
0.1 × 1 = 0.1°.After 10 seconds:
0.1 × 10 = 1°.After 1 minute:
0.1 × 60 = 6°.After 1 hour:
0.1 × 3600 = 360°, a whole turn that never happened.
The robot has not moved at all, but the code believes it has turned 6° in a minute. For a balancing robot, 6° is a serious lean. For a mapping robot, a 6° heading error sends the map off in the wrong direction. These numbers are illustrative: real bias values differ between sensors and change with temperature.
Fixing part of it: calibrate the bias
You can measure the bias at startup by averaging readings while the robot is still, and subtracting it from every later reading. This helps a lot. It cannot remove the problem entirely, because bias shifts with temperature and time, and the gyroscope also has random noise that adds its own slow wander.
Fusing with an accelerometer
The accelerometer gives tilt with no drift when the robot is still, but it is noisy and confused by motion (see the article on how an IMU finds down). The gyroscope is smooth and quick but drifts. Each sensor is strong where the other is weak, so combine them.
A simple recipe is the complementary filter: trust the gyroscope for short-term changes and the accelerometer for long-term truth.
angle = α × (angle + gyro × dt) + (1 − α) × accel_angle
Here α is close to 1, such as 0.98. Work through one update with dt = 0.01 s, a current angle of 10°, a gyroscope rate of 5°/s and an accelerometer angle of 10.4°:
Gyroscope prediction:
10 + 5 × 0.01 = 10.05°.Weighted:
0.98 × 10.05 = 9.849.Accelerometer pull:
0.02 × 10.4 = 0.208.New angle:
9.849 + 0.208 = 10.057°.
Each step the accelerometer nudges the answer by a small amount towards its own reading. Any drift in the gyroscope part is pulled back before it can build up, while quick motion still comes mostly from the gyroscope. The right value of α depends on your update rate and sensors, so tune it by testing.
Note: More advanced fusion methods, such as the Kalman filter, do the same job with a more careful treatment of the noise in each sensor. The complementary filter is a good place to start because you can understand and tune every part.
Why noise also makes the angle wander
Even after you remove the bias, each reading has random noise. When you integrate noise, the errors do not cancel perfectly. They behave like a random walk, so the angle wanders a little further from the truth the longer you run, although more slowly than a steady bias would. This is why even a well-calibrated gyroscope cannot be trusted for hours without a second sensor to check against.
You can see it for yourself by logging the integrated angle of a still sensor for several minutes: the line is not straight, because bias gives a trend and noise adds a jitter around it.
What fusion cannot fix
Yaw. Gravity gives no heading, so yaw drift needs a magnetometer or another sensor such as wheel encoders or a camera.
Long accelerations. If the robot accelerates for a long time, the accelerometer pull can bend the estimate.
Bad calibration. Fusion works best when each sensor is calibrated first.
Common mistakes
Using the raw gyroscope angle for long runs.
Forgetting to subtract the bias before integrating.
Updating at an irregular rate and using a fixed
dt.Making
αso close to 1 that the accelerometer correction is too slow to help.
Your plan for this week
Leave your gyroscope still on a table for one minute, integrate its output and note the angle it reports. Then subtract the average bias and repeat. The difference shows how much of the drift was bias. If you want to work through the filter step by step, DuckyHelper can walk through the update with you on a blackboard.
Frequently asked questions
Why not just use a better gyroscope?
Better ones drift less, but none has zero drift. Fusing with another sensor is how robots deal with the rest.
Do all robots need this?
Any robot that estimates orientation from a gyroscope does. The more demanding the task, the more careful the fusion needs to be.
