State estimation · University · about 30 min
Uncertainty in two dimensions has a shape, and the shape is the useful part.
[1 mark]A robot drives 200 cm straight with a 1 degree heading error. How large, in cm to one decimal place, is the across-track error?
[1 mark]In two dimensions, about what percentage of the probability lies inside the one sigma ellipse?
[1 mark]The ellipse axes of a covariance matrix [[5, 2], [2, 2]], from the 2 x 2 eigenvalue formula. What does it print?
a, b, d = 5.0, 2.0, 2.0 tr, det = a + d, a * d - b * b root = (tr * tr / 4 - det) ** 0.5 l1, l2 = tr / 2 + root, tr / 2 - root print(l1, l2) print(round(l1 ** 0.5, 2), round(l2 ** 0.5, 2))
6.0 1.0 2.45 1.0
The trace is 7 and the determinant 6, so the eigenvalues are 6 and 1. The one sigma axes are their square roots, 2.45 and 1: a tilted ellipse, because the off-diagonal is not zero.
[1 mark]A tag straight ahead of the robot gives a good range and a poor bearing. Which part of the uncertainty ellipse does a fix mainly shrink?
[1 mark]What does the off-diagonal term cov(x, y) of P tell you?
[1 mark]The uncertainty ellipse has grown long across the direction of travel. What kind of landmark would help most?
Drive at least 60 cm, growing an along-track and an across-track uncertainty as you go. Plot both, and print along: and across: at the end.
from bugbot import * import math connect() DT = 0.1 along = across = 0.0 head_sigma = 0.5
The hint students can ask for: Grow two numbers as the robot drives: the along-track uncertainty by the scale error times the distance travelled each tick, and the across-track by the distance times the heading uncertainty in radians. Plot both and watch the ellipse stretch.
from bugbot import *
import math
connect()
DT = 0.1
SCALE_ERR = 0.04 # the flow sensor's scale, a few percent
HEAD_ERR = 0.03 # radians of heading uncertainty, growing slowly
along = across = 0.0
head_sigma = 0.5
forward(70)
for i in range(60):
stepped = abs(flow()[1]) * DT
head_sigma += HEAD_ERR * DT * 10
along += SCALE_ERR * stepped
across += stepped * math.radians(head_sigma)
plot("along", along)
plot("across", across)
wait(DT)
stop()
print("along:", round(along, 2))
print("across:", round(across, 2))
Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.