Learning roadmapIntermediate

PID Control for Robots: A Learning Roadmap

Turn a noisy measurement into a smooth error signal and tune a stable PID controller that tracks without oscillating.

A PID controller is the workhorse of robotics: it turns the gap between where a robot is and where it should be into a correction. But a controller is only as good as the signal it acts on, so this roadmap starts by cleaning up noisy sensor readings, then teaches you to tune the proportional, integral, and derivative terms so the robot tracks smoothly instead of oscillating.

The hands-on nodes are where the order matters. First tune a bare PID loop where a single setpoint and a single plant let you see overshoot, oscillation, and steady-state error in isolation. Only then take the same three gains to the line follower, where the plant fights back and the error arrives from a real sensor—which is where tuning stops being tidy.

The roadmap then ends somewhere the earlier nodes cannot take you. Every plant up to that point is stable: ignore it and it sits there, so tuning is about doing better than doing nothing. A self-balancing robot is not stable—leave it alone and it is on the floor within a second. That single change makes good tuning a requirement rather than an improvement, and it forces the structural idea this roadmap finishes on: when you cannot command the thing you actually care about, you nest two loops, and let the outer one move the inner one’s target.

Before you start

You should already be able to read a sensor and drive a motor at a commanded speed — the motor control path covers both. Bring a robot or a simulator where you can change one number and immediately see what it does.

What you will be able to do

  • Tune P, then I, then D in a deliberate order, rather than changing three numbers at once and hoping.
  • Read a response curve and name what is wrong from its shape: overshoot, sustained oscillation, or steady-state error that never closes.
  • Recognise integral windup when the actuator saturates, and fix it by clamping rather than by lowering the gain until the symptom hides.
  • Nest two loops so an outer controller moves an inner controller’s setpoint.

Where people get stuck

Tuning all three gains together. With three interacting knobs and one output, changing everything at once means you learn nothing from the result. Raise P until it oscillates and back off; only then add D; add I last and only if a steady offset remains.

Taking the derivative of the error. When the setpoint steps, the error steps with it, and its derivative is briefly enormous — the robot jerks for no physical reason. Take the derivative of the measurement instead. The maths is nearly identical and the kick disappears.

Feeding D a noisy signal. Differentiation amplifies noise. If your sensor is jittery, D turns that jitter into motor commands. Filter first — which is why this path starts with sensor noise rather than with the controller.

Assuming gains transfer. Gains are properties of a specific plant. Fresh batteries, a heavier chassis, or a different surface all change the plant, and the tune that was perfect yesterday will not be today.

An inconsistent loop rate. Both I and D depend on how much time passed. If your loop runs whenever it happens to finish, both terms are computed against a lie. Fix the interval, or measure it and pass real elapsed time into the maths.

What you need

What Why this path needs it Notes
A plant you can excite Something that responds to a command and settles — a motor, a heater, a robot The simulators substitute for all three if you have none
A way to plot Tuning by watching a robot is guesswork; tuning by reading a curve is not Serial plotter, or the labs on this path
A fixed loop interval Both I and D are computed against elapsed time. A loop that runs whenever it finishes computes both against a lie The millis() pattern
Patience for one knob at a time The whole method

You can complete every node of this path in the browser. The three labs are real controllers on real (simulated) plants, and the tuning procedure transfers directly to hardware — which is the point of doing it here first.

Why the path runs in this order

The order is chosen so that each stage adds exactly one new difficulty.

Filtering comes first because a controller is only as good as its input, and D is the term that punishes you for skipping this. Differentiation amplifies noise: a sensor with ±2 counts of jitter sampled every 10 ms produces a derivative estimate swinging by 200 counts per second, and D turns that straight into motor commands. Tuning a controller on an unfiltered signal teaches you the wrong lesson — that D is useless.

The bare loop comes before the robot because it isolates the controller. One setpoint, one plant, three gains, and no steering geometry, no sensor placement, no wheel slip. When the response overshoots here, the cause is the gains, and there is nothing else it could be.

The line follower comes next because it adds two things at once, and both are honest additions: the error now comes from a real sensor with a limited field of view, and the plant fights back — the robot’s own motion changes the error faster than the controller expects. This is where a tune that looked finished stops being finished.

The balance robot comes last, and it is the point of the whole path. Every plant before it is stable: ignore it and it sits there, so tuning is an optimisation. An inverted pendulum is not stable — leave it alone for one second and it is on the floor. That single change turns good tuning from an improvement into a requirement, and it forces the structural idea the path finishes on: when you cannot command the thing you care about, you nest two loops.

Checkpoints: how to know a stage landed

Stage The check What a pass looks like
Filtering Plot raw and filtered signal on the same axes while disturbing the sensor You can point to the lag your filter costs, in milliseconds, and say why it is worth paying
P only Raise P until steady oscillation, note the value, halve it You have a number for the critical gain, and the response now overshoots and settles
Add D Increase D until the overshoot is damped Overshoot drops without the response becoming sluggish; too much D and it goes jagged
Add I Only if a steady offset remains The offset closes, and you have clamped the accumulator before testing near saturation
Read a curve Look at three responses and name what is wrong with each You can distinguish overshoot, sustained oscillation, and steady-state error by shape alone
Windup Command a setpoint far beyond what the actuator can reach, then release The system does not sail past on release — if it does, your clamp is missing
Loop rate Print your actual interval over a minute It is fixed, or you are passing measured elapsed time into the maths
Cascade Command a position on a balancing plant The inner loop runs several times faster than the outer one, and you can say the ratio

Where this path stops

PID is the workhorse, not the whole field, and this path is honest about where it ends.

It stops at single-input, single-output control. Real robots often have several coupled loops that interfere with each other, and there is a whole discipline for that which PID does not address.

It does not cover feed-forward, which is the largest practical improvement most robot loops are missing. PID is reactive by construction — it cannot act until an error exists. If you already know the move you are commanding, you can compute most of the required output in advance and leave PID to correct only the difference. The motion profiles tutorial is the first half of that idea.

It does not cover model-based control — LQR, pole placement, or anything that starts by writing down the plant’s equations. Those give better results when you have an accurate model, and most small robots do not.

And it does not cover gain scheduling, the standard answer to the fact that gains do not transfer: keeping several tunes and switching between them based on speed, load or battery voltage.

Learning roadmap

The path

Follow the nodes in order—each unlocks the next once you have done it. Your progress saves on this device.

0 / 7 done

100%
Goal

Tune a stable controller

Skill unlocked

Common questions

Frequently asked questions

What order should I tune PID gains in?

P, then D, then I, and only ever one at a time. Raise the proportional gain until the response oscillates steadily, then back off to roughly half that value—this is the classic Ziegler–Nichols starting point and it gets you close fast. Add derivative next to damp the overshoot P leaves behind. Add integral last, and only if a steady offset remains that P alone will not close. Changing all three at once teaches you nothing, because with three interacting knobs and one output you cannot attribute the change you see to the knob you turned.

Why does my PID controller oscillate?

Usually proportional gain that is too high for the plant's delay. Every loop has lag—sensor filtering, motor inertia, the loop interval itself—and P acts on error that is already out of date. Past a certain gain the correction arrives late enough to make things worse, and the loop rings. Lower P and add D, which acts on the rate of change and so anticipates. If the oscillation is fast and jagged rather than smooth, suspect noise reaching D instead: differentiation amplifies noise, and a jittery sensor turns into jittery motor commands.

What is integral windup and how do I fix it?

When the actuator saturates—motors already at full power—the error stops shrinking, but the integral term keeps accumulating it. By the time the setpoint is reached the integral holds a large stored value that must be unwound, so the system sails past and takes a long time to come back. The fix is to clamp the integral accumulator to a sensible range, or to stop accumulating whenever the output is saturated. What you should not do is lower the integral gain until the symptom hides, which trades the overshoot for an offset that never closes.

Do my PID gains transfer to another robot?

No, and often not even to the same robot tomorrow. Gains are properties of the plant, not of the algorithm, and the plant includes the battery's charge state, the mass of the chassis, the surface, and the temperature of the gearbox. A tune that was perfect on fresh batteries will be sluggish on flat ones because the same duty cycle now produces less torque. This is why the path insists on tuning by procedure rather than by copying numbers—the procedure transfers even though the gains do not.

Why take the derivative of the measurement instead of the error?

Because when the setpoint steps, the error steps with it, and the derivative of a step is briefly enormous. The robot jerks hard for a reason that has nothing to do with physics—nothing actually moved, you just asked for something different. Differentiating the measurement instead gives you the same information about how fast the system is actually changing, with none of the setpoint kick. The change is one line of code and it is nearly always the right one.

What is cascaded PID and when do I need it?

Two nested loops, where the outer one's output is the inner one's setpoint. You need it whenever you cannot command the thing you actually care about. On a self-balancing robot you want to control position, but the motors control wheel torque, and the only way to move is to deliberately lean—so an inner loop holds tilt at whatever angle it is given, and an outer loop asks for a lean in order to travel. The inner loop must be several times faster than the outer one, or the outer loop is chasing a target the inner one has not reached yet.