Odometry and drift · University · about 30 min
Measuring the gyro bias and the flow scale, and taking both out of the estimate.
[1 mark]A robot is driven exactly 100 cm, and its integrated flow says 96 cm. What scale factor should multiply future readings? Give three decimal places.
[1 mark]A gyro with a bias of 0.3 deg/s is integrated over five 0.1 s ticks, once raw and once with the bias subtracted. What does this print?
DT = 0.1
bias = 0.3
rates = [0.3, 0.3, 30.3, 30.3, 0.3]
raw = cal = 0.0
for r in rates:
raw += r * DT
cal += (r - bias) * DT
print(round(raw, 2), round(cal, 2))6.15 6.0
The robot really turned 30 deg/s for 0.2 s, which is 6 degrees. Raw integration adds 0.3 × 0.5 = 0.15 degrees of bias to give 6.15; the calibrated sum is exactly 6.0.
[1 mark]Why calibrate the gyro before the flow scale?
[1 mark]What is the name for recalibrating an inertial sensor at every moment the vehicle is known to be still, as a shoe-mounted pedestrian tracker does once per step?
[1 mark]Which of these can calibration not fix?
Tick every answer that is true.
[1 mark]Why can the flow scale not be calibrated using only the robot's own sensors?
Calibrate the gyro, then dead reckon at least 120 cm with turns in it. Print bias:, my x: and my y:. The position tolerance is tighter than the uncalibrated task, so the calibration has to be real.
from bugbot import * import math connect() DT = 0.1 # stand still first and learn the bias
The hint students can ask for: Stand still for a few seconds first and average the gyro. Subtract that bias from every turn rate afterwards. The tolerance here is tighter than the uncalibrated task, so the calibration has to be doing real work.
from bugbot import *
import math
connect()
DT = 0.1
# stand still and learn the gyro's bias
rates = []
for i in range(40):
rates.append(imu()[1])
wait(DT)
bias = sum(rates) / len(rates)
x = y = h = 0.0
def step(n=1):
global x, y, h
for i in range(n):
vx, vy = flow()
rate = imu()[1] - bias
a = math.radians(h + 0.5 * rate * DT)
x += (vx * math.cos(a) + vy * math.sin(a)) * DT
y += (-vx * math.sin(a) + vy * math.cos(a)) * DT
h += rate * DT
wait(DT)
forward(75)
step(45)
stop()
step(4)
drive(0, 0, 55)
while h < 88:
step()
stop()
step(4)
forward(75)
step(45)
stop()
step(4)
print("bias:", round(bias, 2))
print("my x:", round(x, 1))
print("my y:", round(y, 1))
print("truth", position())
Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.