Click & Whirr needs a wider screen
Open it on a laptop or desktop (1280px or wider recommended). The Learn · Code · Watch workspace needs the room to breathe.
Lesson 12
Two liars, one truth
Checkpoints · 0 of 2 (waiting for Run)
- Fuse them: peak error beats the raw noise (waiting for Run)
- Hold steady: stay locked on near the end (waiting for Run)
Two bad signals, one truth
Two of your robot’s signals lie, in opposite ways. Teach it to split the difference.
The heading you get by integrating the wheels is smooth: no jitter, tick to tick it barely moves. But it drifts. An unseen bias turns the robot a little more than the wheels report, and the error quietly piles up, the same way your L5 odometry peeled away from the truth. The absolute reading (think of a compass) has the opposite problem: it is honest, right on average, but it is noisy, twitching a few degrees every single tick. Neither one is trustworthy on its own.
The driving is not your job this time. Press Run and the sim steers a slow, fixed turn on its own, the same turn every run, so both lies stay visible. Your job is the ComplementaryFilter class in the editor: it takes both signals every tick and returns one number, its belief about the true heading. The fix is the classic complementary filter: mostly trust your smooth prediction, and let a small fraction of the honest absolute leak in so the drift can never accumulate. One blend knob, alpha, sets how much you trust yourself.
Predict from wheels, blend in the absolute
Hold steady, beat both
▸API reference
- ComplementaryFilter(alpha=0.999, theta=0.0)
- Built once on Run from your ctor default. alpha near 1 trusts your smooth-but-drifting integration; the small (1 - alpha) leak pulls you toward the noisy absolute reading so drift can't accumulate. Lower the default and Run again to leak more absolute in.
- update(absolute_heading, v_left, v_right, dt)
- Called every tick. absolute_heading is the noisy compass-style reading (radians); v_left/v_right are the commanded wheel speeds (the scripted turn's numbers, in wheel command units) for your short-term integration. Return your fused heading belief.
- robot.sensors.noisy_heading()
- The same raw absolute reading via the facade.
- how you're graded
- Your belief is compared against the true heading. Checkpoint 1 (fused) needs your peak error to beat the raw noise; checkpoint 2 (steady) needs your error to settle and stay settled. Pure noise fails the first, pure integration drifts and fails both. The blend beats both parents.
space pause · r reset · ctrl/cmd+enter run