Project: the long lap
Two metres of driving, one landmark, and an estimate that has to stay honest.
Do this lesson in the simulatorEverything in the module, in one program.
Drive a lap of at least two metres, come back to where you started, and keep your own estimate of the pose the whole way. At the end, print what you think and be marked against what is true, to within 10 cm after two metres of driving.
What it takes
- Calibrate the gyro first. Stand still, average, subtract for the rest of the run. Without this the rest does not matter.
- Run the odometry every tick, including while turning and while stopped. An update skipped is a piece of the path missing, and stopping is exactly when robots are most often nudged.
- Rotate by the midpoint heading, so the turns do not lean.
- Take a fix if you pass the tag. Tag 3 is on the far wall. It is optional, and it is the difference between a good estimate and a lucky one.
- Come home on the estimate. The lap has to end in the home zone, and the way back is to steer towards (0, 0) in your own estimated frame, with the inverse kinematics from U2. If the estimate is good you arrive. If it is not, you do not, and that is the test.
The shape of the program
from bugbot import *
import math
connect()
DT = 0.1
x = y = h = 0.0
bias = 0.0
def calibrate(seconds=4.0):
global bias
rates = []
for i in range(int(seconds / DT)):
rates.append(imu()[1])
wait(DT)
bias = sum(rates) / len(rates)
def step(n=1):
"""n odometry updates, one per tick, whatever the robot is doing."""
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
plot("x", x)
plot("y", y)
wait(DT)
calibrate()
forward(75)
step(20)
stop()
step(4)
print("after one leg:", (round(x, 1), round(y, 1)), "truth", position())
Task: the long lap
Two metres of driving, back into the home zone under your own navigation, with my x: and my y: printed at the end and within 10 cm of the truth.
from bugbot import *
import math
connect()
DT = 0.1
# calibrate, then drive the lap, updating every tick
Challenges
- Plot your estimate and the truth for both axes on one chart. Where does the gap open up?
- Do the lap in the other direction. Is the error the same size? If not, what does that say about the bias?
- Run the lap at
set_noise(0.5),1and2, and plot the final error against the noise level. Is it a straight line?
What comes next
U4 stops treating a sensor reading as a number and starts treating it as a number plus a distribution. That is where filtering comes from, and it is what lets U6 decide how much to trust a fix instead of guessing 0.8.