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
Checkpoints · 0 of 2 (waiting for Run)
- Reach the target zone (waiting for Run)
- Hold the heading dead-on (2s steady) (waiting for Run)
Why P and D settle short
A side wind keeps nudging your robot off course. Teach it to lean in and hold a heading dead on.
The wind is steady: about twenty degrees a second of induced yaw, a breeze on the chassis, or a wheel running a touch weak. Your Kp and Kd are the same two terms as lesson 3, tuned for this plant and set for you already, and they steer smoothly toward the target heading. But proportional control only pushes back in proportion to the error. Once its correction exactly balances the wind, the two cancel and nothing is left to close the last gap. The gauge settles a few degrees short: a small, permanent offset.
Derivative control cannot fix it either. D reacts to how fast the error is changing, and a steady offset is not changing, so D reads zero and stays quiet. What is missing is a term that cares about error that persists. Integral control accumulates the error over time: steer = Kp·error + Ki·∫error + Kd·Δerror. As long as any offset remains, the integral keeps growing and pushing harder, until the offset is gone.
The good news: the PIDController you built in lesson 3 already has the integral machinery inside it. This lesson feeds it a Ki and puts that third term to work.
Wire the correction to the wheels
Ride it to the target zone
Raise Ki until it lands 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=0.5, ki=6, kd=0.15)
- Built once when you press Run, from the defaults in your __init__ signature. It hands kd and ki straight to your PIDController.
- 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 defaults (tuned in code)
- Your gains live in the signature. Edit the ki default, press Run, and a fresh instance drives with the new value; the integral it accumulates is reset with it. Reset also rebuilds from your source.
space pause · r reset · ctrl/cmd+enter run
Simulator
This lesson imports PIDController from your library. You haven’t built PIDController yet.