Step 2
Fusing measurements
Two sensors, one precise and one sloppy. Weigh each reading by how much you trust it: the Kalman update.
Builds on Combining two sensors, from the free Foundations.
Two sensors
The robot now has a real sensor, sensor, with two sources: a wide camera (σ = 2 cm) and a narrow one (σ = 5 mm). Both take a new reading 10 times per second. From here on, world.balls() is switched off: the sensor is your only way to see the ball.
m = sensor.next("red", "wide") # wait for the next reading
m.position, m.t # where it saw the ball, and when
m = sensor.read("red", "narrow") # the latest narrow reading (no waiting)
sensor.sigma("narrow") # 0.005
Averaging all readings equally would let the sloppy camera drag the answer around. You want to trust each reading in proportion to how precise it is.
Belief = estimate + uncertainty
Keep a belief: an estimate and a covariance (for one number, ). A measurement comes with its own covariance . The Kalman update blends them:
, the Kalman gain, is between 0 and 1 (a matrix in general). In one dimension:
- A vague belief (): , so jump to the measurement.
- A sloppy measurement (): , so barely move.
- Equal for every reading, starting vague: the updates add up to Step 1's plain average.
Precision (1/variance) adds up with every reading, so only ever shrinks. One narrow reading is worth wide ones.
Your task
- Implement
kf_update(x, P, z, R)and return(x, P).xandzare vectors,PandRare matrices; a 1D problem is a 1-vector with a 1×1 matrix. It must work in any dimension. - Start from a vague belief, fuse 20 readings from each source of the red ball, and store the result in a global
fused(a 3-vector). - Plot as the readings come in.