Blog · 2026-07-05 · PID
Tuning by randomly poking three numbers is how people decide PID "doesn't work." Here is the systematic version: one gain at a time, in the right order, with a known symptom to watch for at each step.
This article assumes you know what the three terms do — if not, ten minutes with PID Control Explained Simply first will make everything below land harder. Tuning is where that theory meets your specific robot: the gains that balance one machine send another into violent oscillation, because gains encode the plant's mass, friction, motor strength and sensor scaling. There is no universal answer, but there absolutely is a universal procedure.
More "impossible to tune" systems are broken than mistuned. Verify four things first. Sign: a positive error must produce a correction in the direction that reduces it — flipped motor wiring or sensor sign makes the loop push the wrong way, and no gain fixes backwards. Loop rate: run the controller at a fixed, consistent interval (100 Hz is ample for hobby robots); an irregular dt corrupts both I and D. Sensor quality: plot the measurement at rest — if it's jumping around, filter it now, because D will amplify every jump later. Actuator authority: confirm the motor, sized properly (the Motor Sizing Calculator exists for this), can physically produce the correction; a controller commanding torque that isn't there just winds up its integral.
Set Ki = Kd = 0. Start Kp small — small enough that the response is obviously sluggish — and command a step change in setpoint. Double Kp and repeat. The response sharpens with each doubling until, at some value, the system overshoots and oscillates continuously around the target. That gain is your critical gain — write it down (call it Ku) along with the oscillation period (Tu, seconds per cycle); both feed the shortcut method below. Then retreat: set Kp ≈ 0.5 × Ku. You now have a brisk response that probably overshoots a little and — if any constant disturbance exists — settles slightly off target.
Raise Kd from zero in small steps, repeating the step test. Watch the overshoot shrink and the response snap crisply to target. Stop when overshoot is acceptable (10–15% is fine for most robots; some jobs want zero). Two warnings: too much Kd makes the response sluggish again — D is a brake, and you can drag it — and if the output starts buzzing or chattering, D has found your sensor noise: filter the derivative or reduce Kd. On clean systems it's common to end near Kd ≈ Kp × Tu ÷ 8.
If the response settles offset from the target, raise Ki from zero until the offset drains away over a second or so after each step. More Ki removes it faster but reintroduces overshoot and, past a point, a slow wallowing oscillation — the integral fighting itself. Use the minimum Ki that kills the offset in acceptable time, and always clamp the integral term (more below). If there's no steady-state error to fix — common in line followers — leave Ki at zero and enjoy a simpler controller.
A tune that looks perfect on one gentle step can fall apart elsewhere. Test big steps and small ones, disturbances (tap the arm, put the robot on carpet), and battery states — a LiPo at 12.6 V gives the motors more authority than at 10.5 V, which effectively changes your gains mid-match. Tune at mid-charge, verify at both ends.
The classic 1942 recipe converts the critical gain and period you recorded into a full gain set:
| Controller | Kp | Ki | Kd |
|---|---|---|---|
| P | 0.50 × Ku | — | — |
| PI | 0.45 × Ku | 0.54 × Ku ÷ Tu | — |
| PID | 0.60 × Ku | 1.2 × Ku ÷ Tu | 0.075 × Ku × Tu |
Treat the output as a starting point, not gospel — Z-N deliberately tunes aggressive (about quarter-amplitude decay), and most robots feel better with the resulting Kp and Ki backed off 20–30%. Its real value is skipping the wilderness: it lands you in the right order of magnitude in one experiment.
Your robot is blocked, error persists, and the integral term quietly accumulates a mountain of correction; when the blockage clears, the controller dumps the mountain — a huge, slow overshoot that looks like madness. Three standard defenses, best used together: clamp the integral to a sane range (the one-liner from the previous article); freeze integration when the output is saturated — if the motor is already at 100%, accumulating more demand is pure fiction; and reset the integral on large setpoint changes or mode switches. You can reproduce windup safely in the PID Tuning Visualizer — the "Windup" preset shows the signature fat overshoot, and sliding Ki down shows the cure.
| You see | It means | Do this |
|---|---|---|
| Fast, constant oscillation | Kp too high (or Kd noise feedback) | Reduce Kp 30–50% |
| Slow wallowing oscillation | Ki too high / windup | Reduce Ki, add clamp + saturation freeze |
| Overshoots then settles | Damping short for this Kp | Raise Kd (or trim Kp) |
| Sluggish, never arrives | Gains too low / too much Kd | Raise Kp; trim Kd |
| Settles off target | No integral vs constant disturbance | Add small Ki |
| Output chatter / motor buzz | D amplifying sensor noise | Filter measurement, reduce Kd |
| Perfect on bench, wild on floor | Plant changed (load, friction, voltage) | Retune under real conditions |
Derivative-on-measurement: compute D from the sensor value instead of the error and setpoint changes stop producing derivative "kick" — a free upgrade in most firmware. Output limits: always clamp the final output to your actuator's real range, and remember mechanical dead zones (a motor that doesn't move below 15% PWM) look like steady-state error and tempt you into excess Ki; feed-forward or a minimum-output offset is the honest fix. Backlash in cheap gearboxes creates a dead zone the loop hunts across — sometimes the correct tuning fix is a better gearbox, a trade covered in Gear Ratios Explained. Change one thing at a time and keep a log; tuning amnesia ("was 4.0 better than 6.0?") wastes more sessions than any technical mistake.
With this procedure and a repeatable step test: 20–60 minutes for a typical hobby loop. Days of frustration usually indicate a pre-flight failure (sign, noise, loop rate), not difficult dynamics.
Relay auto-tuners (the method in 3D printer firmware's M303) automate exactly the Ku/Tu experiment above and work well on well-behaved plants. Knowing the manual method is what lets you judge — and fix — their output.
The gains, no — they encode this machine. The procedure, the symptom table and your trained eye transfer completely, and that's the durable asset. Sharpen the eye for free in the PID Tuning Visualizer before your next build.
Balance bots, drones and position-controlled drives use nested PIDs — a fast inner loop (motor speed, or tilt rate) commanded by a slower outer loop (position, or tilt angle). The tuning rule is absolute: tune the inner loop first, alone, to be fast and well-damped; only then close the outer loop around it, treating the tuned inner loop as part of the plant. An outer loop wrapped around a sloppy inner loop produces coupled oscillations that no amount of outer-gain fiddling untangles, and the debugging experience is miserable because two loops' symptoms superimpose. Keep the loops separated in bandwidth too — the inner loop should be several times faster than the outer — or they fight over the same frequencies. When a cascaded system misbehaves after tuning, open the outer loop (command the inner loop directly) and re-verify the inner response before touching anything else; nine times out of ten the fault localizes immediately.
Gains carry hidden units: Kp converts error units into output units, so a controller reading degrees and writing PWM counts has gains meaningless to a controller reading radians and writing volts. This is why copied gains from a forum never work and why normalizing helps portability: scale error and output into −1…+1 ranges and gains become dimensionless, comparable across robots, and typically land in humane ranges (Kp of 0.5–5 rather than 47,000). It also makes the Visualizer's intuition transfer more directly — its plant is normalized the same way.