A thermostat, a cruise control, and a robot elevator all run the same three-beat trick: measure what's happening, compare it to what you wanted, push against the difference. That's feedback — and PID is the classic recipe for how hard to push.
Here is the machine this whole page lives inside. The setpoint is what you want. The sensor reports what you have. Subtract them and you get the error — a single number saying how wrong you are, and in which direction. The controller's entire job is to turn that number into motor voltage:
The simplest possible filling is a reflex: bang-bang control — full power when you're below the target, nothing when you're above. No subtlety, just a light switch. Watch it fight a proportional controller (coming up next) for the job of parking an elevator carriage on a target line:
The fix for bang-bang's chatter is embarrassingly simple: push harder when you're far away, gently when you're close. Multiply the error by a constant and call the result voltage. That constant is the gain, written kP, and the whole controller is one line:
V — motor voltagee — the error, setpoint − measured height (meters here)kP — the proportional gain, in volts per meter of error: how aggressively distance is converted into push.kP is a personality dial. Small kP: patient, gentle, slow. Big kP: eager, fast — and, past a point, so eager it flies through the target and has to come back. You are about to meet all three personalities.
Think of it as tying the carriage to the target with a rubber band: the farther it strays, the harder it's pulled back. Tune the band's stiffness yourself:
So P alone has a flaw, and it's structural, not a tuning mistake. Gravity charges this elevator a standing bill of 1.5 V just to hold still. But V = kP·e can only produce voltage out of error — so to pay a permanent bill, it must hold a permanent error. The rubber band says it plainly: a spring holding up a weight must stay stretched.
ess — the steady-state error: the error left over once everything stops movingVhold — the constant voltage the load demands (gravity's 1.5 V here)kP — the proportional gain.Bigger kP shrinks the droop but never erases it — and cranking kP for that reason buys you the ringing from experiment 3. Erasing it takes a new idea, and the new idea is memory.
P only sees this instant. The integral term reads the history: it adds up the error over time — every second spent below the line grows the total — and pushes in proportion to that running sum. Persistently a little low? The sum quietly climbs, and the push climbs with it, until the error is actually zero. It is patience that turns into pressure:
VI — the integral term's share of the voltage∫ e dt — the integral of error: the running total of error × time, in meter-seconds; think of it as the area under the error curvekI — the integral gain, volts per meter-second of accumulated error.The key property: this sum only stops changing when e = 0. Any leftover droop keeps feeding it, so the push keeps growing until the droop is gone. It cannot rest until you're exactly on target.
Watch it erase the droop. The memory tank next to the elevator shows the integral filling up — and notice what it holds once everything settles:
Now for the opposite problem. Crank kP and the carriage doesn't just approach the target — it arrives at speed, blows through, and rings. P can't help: at the moment of crossing, the error is zero, so its push is zero, even though you're moving fast in the wrong direction. What's missing is a term that looks at how fast the error is changing — one that sees the line rushing toward you and starts braking early:
VD — the derivative term's share of the voltagede/dt — the derivative of error: its rate of change, in meters per second; negative while you're closing in on the targetkD — the derivative gain, volts per (meter per second).Closing fast on the setpoint makes de/dt negative, so V_D pushes against the motion — a braking force that grows with approach speed. It behaves exactly like a shock absorber, which is why engineers call its effect damping.
It's how you catch an egg: your hand gives way based on the egg's speed, not its position. Here's a deliberately over-eager P controller, plus the damper that civilizes it:
Stack the three terms and you have the full controller. It's worth saying out loud how neat this is: each term reads the same error signal on a different axis of time. P reads the present — how wrong am I now? I reads the past — how long have I been wrong? D reads the future — which way is the error heading? Their votes simply add:
V — total motor voltagee — the error, r − ykP, kI, kD — the three gains: the entire tuning of the controller lives in these three numbers.Any gain set to zero simply switches that term off — a "PD controller" or "PI controller" is just PID with a zero in it. Most FRC mechanisms run P or PD; I joins when a stubborn load refuses to let the error die.
Now earn it. The tuning bay below is the exercise this whole page was building to: a full PID controller, a spec to hit, and a disturbance to survive. Tuners in the real world usually work in this order — P for muscle, D for calm, I for the last centimeter:
In WPILib this controller is one object, and its gains have exactly the names you've been tuning:
PIDController — WPILib's implementation of everything on this page, run once per robot loop (every 20 ms)calculate(measurement, setpoint) — computes the error internally and returns the summed P + I + D outputkP, kI, kD — the same three gains, in volts per unit of your sensor.Concepts and the math live in Introduction to PID; the class itself in PID Control in WPILib.
1. Feedback is measure, compare, correct. Everything the controller does is powered by one number — the error — recomputed every loop.
2. P is a rubber band. Push proportional to the gap: simple and strong. But a spring holding a load must stay stretched — a constant demand like gravity leaves a permanent steady-state error.
3. I is memory. It accumulates unpaid error and ramps its push until the error is truly zero — then keeps holding the bill from memory. Overdo it and the memory sloshes.
4. D is a shock absorber. It reads the error's speed and brakes the approach, killing overshoot. Overdo it and everything turns to molasses.
5. Tuning has an order: P, then D, then I. Muscle first, then calm, then the last centimeter. Three numbers, tuned in the tuning bay the same way you'd tune them on a real robot.
One thing should still bother you: even perfectly tuned, this controller always reacts. It cannot lift a finger until the error already exists. The next lesson is about escaping exactly that — predicting the push instead of waiting to discover it. (And PID itself has real-world sharp edges — noisy sensors, motors that max out — which get their own lesson later.)
feedback — control powered by measuring the errorerror e — setpoint − measurement, recomputed every loopbang-bang — full power or nothing; arrives fast, chatters foreverkP — push per unit of error (the present)kI — push per unit of accumulated error (the past)kD — push against the error's rate of change (the future)steady-state error — the droop P alone can never eraseovershoot — how far past the target you fly, as % of the stepsettling time — time until you're inside the target band for good