How the error grows
Noise walks, bias marches, scale stretches, and a heading error rotates everything after it.
Do this lesson in the simulatorDead 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.