A hands-on guide to PID control
Picture a robot on two wheels, trying to stay upright. It has a gyroscope to measure tilt and motors to spin the wheels. But how should it decide what to do? Push the motors forward? Backward? How hard?
That question turns out to be more interesting than it sounds. This article works through it step by step, starting with the simplest possible answer and improving it until we arrive at something called a PID controller — the same technique used in everything from cruise control in cars to quadcopter drones.
But we won't start with balancing. Balancing is tricky because everything happens fast and the robot falls over if anything is slightly wrong. Instead, let's learn with a simpler problem first, then apply what we know to balancing at the end.
Imagine a small robot on a track with a wall at one end. The robot has a distance sensor that measures how far it is from the wall. Its job: drive along the track and stop exactly 100mm from the wall.
The sensor gives the robot one number: the distance to the wall. The robot also knows the target distance — 100mm. The difference between those two is the error:
Drag the robot to see how the three key numbers change:
If the error is positive, the robot is too far from the wall and needs to drive forward. If it's negative, the robot is too close. If it's zero, the robot is exactly where it should be.
The robot controls one thing: the force applied to its wheels. Positive force drives it toward the wall, negative pushes it away. The question is: given the current error, how much force should the robot apply?
The simplest idea: if the robot is too far from the wall, drive toward it at full power. If it's too close, reverse at full power. This is sometimes called bang-bang control.
Press play and watch what happens.
The robot overshoots the 100mm mark, reverses at full power, overshoots again, and never settles down. It keeps slamming back and forth forever.
The problem is obvious: when the robot is just a millimetre past the target, it still uses full power. It's like parking a car by flooring the accelerator and only switching between drive and reverse. The robot has no concept of "almost there."
A better idea: make the force proportional to the error. When the robot is far from the target, push hard. When it's close, push gently.
Kp is a tunable number — the proportional gain. It controls how aggressively the robot reacts. Try dragging the slider to different values and watch how the behaviour changes.
Low Kp: the robot is sluggish and barely reaches the target. High Kp: the robot overshoots and oscillates, a lot like bang-bang. There's a sweet spot in the middle, but the robot still wobbles before settling.
Proportional control is a huge improvement. But notice that at any Kp value, the robot oscillates before it stops. Sometimes the oscillation takes a long time to die down. That's because of momentum: even when the robot reaches the 100mm mark and the error hits zero, it's still moving. The proportional controller doesn't know about speed — it only looks at distance.
Watch the robot approach the target with proportional control. At the exact moment it reaches 100mm, the error is zero, so the force is zero. But the robot is still moving! It flies right past.
What if the robot could sense that it's approaching the target quickly, and start braking before it arrives? It needs to react not just to the error, but to how fast the error is changing.
What does "how fast the error is changing" actually mean? Imagine checking the distance sensor twice, a fraction of a second apart. The first reading says 120mm; the next says 115mm. The error shrank by 5mm in that short time — so the error is changing quickly, in the negative direction (getting smaller). That rate of change is called the derivative.
A large negative derivative means the robot is closing in fast. A derivative near zero means the error is barely changing — the robot is moving slowly or has stopped. A positive derivative would mean the error is growing — the robot is moving the wrong way.
The key insight: the derivative predicts what's about to happen. If the error is small but shrinking fast, the robot is about to overshoot. If the error is large but shrinking slowly, there's no rush. Adding a derivative term lets the robot brake ahead of time:
The Kd term acts like a damper — it resists rapid changes, smoothing out the approach. Start the simulation with Kd at 0 to see the oscillation, then increase it and watch the wobble disappear.
With Kd at 0, the robot oscillates just like before. Increase Kd and the robot glides smoothly to the target and stops — no wobbling.
This is already pretty good. With the right Kp and Kd, the robot moves quickly to the target and stops cleanly. For many real-world problems, PD control is all you need.
But there's one more situation where it falls short.
In the real world, things aren't perfect. Maybe there's a slope on the track, or friction that's stronger on one side, or a constant wind pushing the robot. Let's simulate this by adding a small constant force pushing the robot away from the wall.
Watch what happens with just P and D control:
With Ki at 0, the robot settles at the wrong distance — too far from the wall. The wind pushes it back, and the P term alone isn't enough to close the gap. Now slowly increase Ki and watch it correct the offset.
The robot settles, but not at the target. It ends up a bit too far from the wall, stuck in a position where the proportional force exactly balances the wind. The error is small but not zero, and the P term isn't strong enough to close that gap without creating overshoot.
The fix is to keep a running total of the error over time. Imagine writing down the error every tenth of a second and adding all the numbers together. If the robot is 2mm too far for five seconds straight, that's fifty readings of +2mm — a running total of +100. Even though each individual error is tiny, the accumulated total grows and grows.
This running total is called the integral. It turns persistent small errors into a steadily increasing correction force:
Go back to the simulation above and increase Ki slowly. Watch the robot gradually correct its offset.
That's it. The full PID controller combines three terms:
P (proportional) reacts to where the robot is right now.
I (integral) remembers where the robot has been.
D (derivative) anticipates where the robot is going.
Each term handles a different aspect of the problem, and the three gain values — Kp, Ki, Kd — control their contributions. Here's a sandbox with all three. Try to get the robot to reach the target quickly, with no overshoot, and push it to test its recovery.
Click "Push!" to shove the robot while it's running. Well-tuned PID recovers quickly.
Everything above applies directly to a balancing robot. The only difference is what "error" and "force" mean:
For the driving problem, the error was distance from target. For balancing, the error is the tilt angle — how far the robot is leaning from upright. A gyroscope measures this.
For driving, the force moved the robot along the track. For balancing, the motor power drives the wheels forward or backward — into the lean — to catch the robot before it falls.
The formula is identical:
Below is a side view of a two-wheeled robot. It starts slightly off-balance. All three gains start at zero — the challenge is to find values that keep it upright. This is harder than the driving problem because the robot is unstable: do nothing and it falls over.
Hint: start with Ki = 0 and Kd = 0. Get Kp high enough that the robot doesn't fall immediately. Then increase Kd to stop the oscillation. Finally, add a little Ki.
A PID controller is three simple ideas combined:
P looks at the present — how big is the error right now?
I looks at the past — has there been a small error for a long time?
D looks at the future — is the error getting better or worse?
The exact same logic that drove our simulated robot to a target distance is what keeps a real balancing robot upright. The maths doesn't change — only the meaning of "error" and "output." That's what makes PID so useful: it works for almost any control problem, from oven thermostats to cruise control to self-balancing scooters.