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 04
Zero the drift
Kp and Kd drive it smoothly toward the target heading, but a steady side wind (or a wheel running a touch weak) keeps nudging it off course. Proportional control only pushes back in proportion to the error, so once the correction balances the wind it just settlesthere: a small, permanent offset. Derivative control can’t fix it either: it only reacts to change, and a steady error isn’t changing. Integral control adds a third term that accumulates error over time: steer = Kp·error + Ki·∫error + Kd·Δerror. As long as any offset remains, the integral keeps growing and pushing harder, until it’s gone.
Checkpoints
- Reach the target zone (waiting for Run)
- Hold the heading dead-on (2s steady) (waiting for Run)
Press Run ▸ to start checking your code.
Watch the heading gauge settle a few degrees short of zero: that’s the wind winning. Raise Ki until it lands dead on. Too much, and the correction overshoots and hunts back and forth before it settles.
Steps
- 1
Wire the correction to the wheels
The starter already computes
steer, then throws it away and drives dead straight. Feed it to the wheels. - 2
Ride it to the target zone
- 3
Hold the heading dead-on
▸API reference
- from mybot import PIDController
- Your lesson 03 piece. Haven't built it? The banner above offers the vetted reference.
- HeadingHold(kp, ki, kd)
- Built once when you press Run, with the three slider gains.
- step(heading_error, dt)
- Called every tick. heading_error is in RADIANS (sensor-delayed); convert with math.degrees, since the gain ranges are tuned for degrees. Return a (left, right) tuple.
- kp / ki / kd sliders (live)
- Moving a slider updates the gains on your RUNNING controller. The accumulated integral is kept, so you can watch Ki start to wind the error out mid-run. Run or Reset starts fresh.
space pause · r reset
Simulator
This lesson imports PIDController from your library. You haven’t built PIDController yet.