How the error grows
Noise walks, bias marches, scale stretches, and a heading error rotates everything after it.
Do this lesson in the simulatorPrint it: worksheet (PDF) · answers (PDF) · as a web page
Guide: Gyroscope vs accelerometer
Dead reckoning is exact arithmetic on inexact numbers. What matters is not that there is error but how it accumulates, and the different kinds accumulate differently.
Noise: a random walk
Zero-mean noise on each reading adds up as a random walk. After n steps the expected error is proportional to the square root of n, not to n, because the errors partly cancel.
Practically: noise is annoying and survivable. Doubling the run length multiplies the noise error by about 1.4. Averaging more readings, or running the loop faster, both help.
Bias: a march
A constant offset does not cancel. A gyro reading 0.4 deg/s too high, integrated for a minute, is 24 degrees of heading error, in the same direction, every run. The error grows linearly with time, and linear beats square root very quickly.
from bugbot import *
connect()
rates = []
for i in range(60):
rates.append(imu()[1])
wait(0.1)
mean = sum(rates) / len(rates)
spread = (sum((r - mean) ** 2 for r in rates) / len(rates)) ** 0.5
print("bias:", round(mean, 2), "deg/s")
print("noise:", round(spread, 2), "deg/s one sigma")
print("after 60 s that bias alone is", round(mean * 60, 1), "degrees")
Standing perfectly still, the gyro insists the robot is turning. That is the single most expensive number in this module, and it is measurable in six seconds.
Scale: a stretch
The flow sensor reads a few percent high or low, fixed for this robot on this mat. Every centimetre is consistently long or short, so the error is proportional to distance travelled: 4 percent is 4 cm in a metre, 40 cm in ten.
Heading error: the multiplier
The expensive one. A heading error e does not just make the heading wrong, it rotates every step taken afterwards. Drive d centimetres with a heading error of e radians and you end up roughly d * e to one side.
Ten metres at 3 degrees off is 52 cm sideways. The same 3 degrees costs you nothing at all if you do not move.
from bugbot import *
import math
connect()
for deg in (1, 3, 10):
print(deg, "degrees over 200 cm puts you", round(200 * math.radians(deg), 1), "cm to one side")
The ranking
For a ground robot with this sort of hardware, over a run of a minute or two:
- Heading bias, by a distance.
- Scale error on the translation.
- Wheel or flow slip, which is unmodelled and unpredictable.
- Noise, which mostly averages away.
That ranking tells you what to do, and it is the plan for the next two lessons: calibrate the bias, calibrate the scale, and get a fix from outside before the rest matters.
Task: measure the gyro bias
Without moving the robot at all, print this gyro's bias as bias: 0.31, in degrees per second.
from bugbot import *
connect()
rates = []
Challenges
- Measure the bias five times. Is it the same number each time? Is the noise?
- Run
set_noise(3)and measure again. Which changes, the bias or the spread? - Work out how long the robot can dead reckon before the bias alone costs it 10 cm, at 20 cm/s.