← Explorations
Closing the Loop
Why your robot overshoots, wobbles, and stops just short.
where it is where you told it to go motor push previous run
Overshoot
0%
Time to settle
0s
Left-over error
0m
Keep tuning

Measure, correct, repeat

A robot that cannot check its own work is guessing. Feedback control is the fix, and it is the same handful of lines whether you are driving a bot to a line, holding a drone at altitude, or keeping a 3D printer nozzle at 210 degrees.

1. Open loop is a guess

Flip the lab to Open loop and run it. The bot gets one instruction: full power for a fixed number of seconds, then coast. Tuned on a bench, it lands on the line. Beautiful.

Now add mass, or tick Drive uphill, and run it again. It lands somewhere else, and it has no idea. Nothing in that instruction ever looks at where the bot actually is. Open loop is a robot with its eyes shut, and the real world is never exactly the bench.

2. Error is the only number that matters

Close the loop and the bot gets a sensor. Now it can compute one number, over and over, hundreds of times a second:

error = target − where I actually am Positive means still short. Negative means gone too far. Zero means done.

Everything from here is just different ways of turning that one number into a motor command. That is the whole field.

3. P, I, and D are three different opinions

The classic controller runs three terms at once and adds them up. Each one is watching the error in a different tense.

P
the present

Far away, push hard. Close, push gently. The workhorse.

I
the past

Keeps a running total of every error so far. Notices a problem that never goes away.

D
the future

Watches how fast the error is shrinking and brakes before the bot arrives.

push = Kp·error + Ki·(sum of errors) + Kd·(rate of change) The three K values are the gains. Tuning a controller means picking these three numbers.

4. P on its own has two failure modes

Drag the P slider to 1.5 with I and D at zero. The bot creeps toward the line and the test ends before it gets there. Too little push.

Now drag P to 40. It arrives fast, blows straight past the line, comes back, overshoots the other way, and rings like a struck bell. The reason is momentum: at the exact moment the bot is on target the error is zero, so P is commanding nothing, but the bot is still doing three meters a second. Nothing has told it to slow down.

5. D is the brake

Leave P at 25 and raise D. The ringing damps out. D is looking at how fast the error is closing and pushing back against it, so the bot starts braking while it is still short of the line.

Here is a detail worth knowing. The target is not moving, so the rate of change of the error is just the bot's speed with a minus sign in front of it. The D term is literally reading the speedometer:

d(error)/dt = d(target − x)/dt = −velocity Which is why real controllers usually feed D from the speed sensor rather than from the error.

6. Why P can never finish the uphill job

Set P to 25, D to 14, and tick Drive uphill. Smooth as anything, and it stops about half a meter short. Forever. It is not still creeping. It has settled there.

P is proportional, so it needs error to produce push. Uphill, the bot needs a constant force just to hold station. The only way P can supply that force is to sit at exactly the error that generates it:

left-over error = force needed ÷ Kp Doubling P halves the gap. To close it completely you would need infinite P, which rings and saturates long before it gets there.

Now raise I. The running total of that small stubborn error keeps growing, so the I term keeps growing, and it quietly takes over supplying the hill force. When the bot finally reaches the line the error stops adding up and the total freezes at exactly the value that holds it there. That leftover total is the controller remembering the hill.

7. Three ways it bites you in real hardware

  • Saturation. The motor here stops at 40 N. Watch the purple trace flatten against the top on a hard run. Past that point, more P buys you nothing, because you are already asking for everything the motor has.
  • Integral windup. While the motor is pinned flat out, the error is not shrinking, so I keeps piling up into a number the machine could never act on. When the bot finally arrives, that stored-up push is still there and it sails past. Untick the windup guard in the lab and watch a clean 1% overshoot turn into 12%.
  • Noise. Push the sensor noise slider up with D high. The purple command line goes fuzzy and the bot judders. D reacts to change, and noise is nothing but change, so D amplifies it. This is why high D and cheap sensors do not mix.

8. The tuning recipe

Engineers have done this in the same order for about a century, and you can do it in the lab right now:

  • Start with I and D at zero. Raise P until the bot arrives quickly and just starts to ring.
  • Raise D until the ringing flattens out. If it starts to judder, back off.
  • If it settles near the target but not on it, raise I slowly until the gap closes. Too much I and the overshoot comes back.

Where this same loop is running right now

MachineTargetSensorMotor
Your thermostat21 degreesThermometerFurnace
Cruise control65 mphWheel speedThrottle
A drone hovering2 m altitudeBarometerFour rotors
3D printer hot end210 degreesThermistorHeater cartridge
A bot driving to a spotAn arena coordinatePositionDrive wheels
The thermostat is the honest ancestor. An old one is not even proportional: it slams the furnace fully on below the target and fully off above it. That is why the room swings a couple of degrees either side of what you asked for. Everything P, I, and D add is a way of being less blunt than that.

Check yourself

Six questions on the loop. Answers explain themselves as you go.