The Hidden Magic of PID Controllers
An interactive dive into proportional, integral, derivative (PID) control systems.
Youâve probably benefited from multiple PID controllers today without realizing it. Theyâre in your carâs cruise control, your home thermostat, and the robotic arm that assembled your phone. PID controllers are everywhere because they provide an elegantly simple solution to a common problem: how do you get something to go where you want, and stay there?
In this post, weâre going to build an intuition for how PID controllers work. Weâll start with the simplest possible controller and gradually add complexity. By the end, youâll understand not just what each term does, but why itâs needed.
Pointer to Target
Letâs start with a concrete example. Imagine you have a motor attached to a pointer, like a speedometer needle. Your goal is to get the pointer to a target angle. Sounds simple enough: just power the motor until it arrives, right?
The catch is inertia. The pointer has mass, and mass resists changes in motion. If you cut the power the moment you reach the target, your momentum carries you right past it.
Try dragging the orange handle to set a new target angle and see how the system responds:
The motor has no idea it should slow down as it approaches the target! It provides full torque up to the target angle, then switches to full reverse torque. Without a way to slow down near the target, the pointer will oscillate right around it forever. We need a smarter control system.
Proportional Control
The first insight is simple: the further you are from the target, the harder you should push. If youâre 90° away, apply a lot of power. If youâre only 2° away, apply just a little. This is called proportional control because the output is proportional to the error.
The is the difference between the target and current position (or angle), and is the proportional gain that determines how aggressive the response is.
Hereâs how the control loop works:
The controller continuously compares setpoint vs measured position, calculates error, and outputs torque command
These steps are repeated 60 times per second:
- Measure the current position (feedback)
- Compute:
- Output: torque command proportional to the error
This creates a closed-loop system: the controller constantly adjusts based on what it observes. Now letâs see it in action:
Play with the slider and target angle. Notice that thereâs a tradeoff:
- Too low: Sluggish response, and any resistance will leave you stuck short of the target (steady-state error)
- Too high: Fast response, but overshoots and oscillatesâpotentially unstable
This is the fundamental tradeoff of proportional control. Higher gain gets you there faster but makes it more likely to overshoot and oscillate aggressively.
Derivative Control
The proportional term looks at where you are. But what if we could also look at how fast youâre approaching the target? If youâre racing toward the target at high speed, you should start braking early. If youâre crawling toward it, you donât need as much braking.
This is what the derivative term does: it responds to the rate of change of the error. This is the âDâ in PID.
If youâre approaching the target quickly, the derivative term applies a braking force. The purple arrow shows the contribution of the D term to the total output.
Like magic, the oscillation is almost entirely gone! The system now settles smoothly to the target instead of bouncing back and forth. Try setting to 0 to see the difference: the oscillation returns immediately.
Steady-State Error
Weâve solved the oscillation problem with PD control, but thereâs another issue lurking. Letâs add a mass to the end of the pointer. Watch what happens: the pointer canât reach the target:
This is steady-state error. Proportional control only pushes when thereâs error. To counteract the constant pull of gravity, some error must remain â otherwise thereâs nothing to push against. Higher shrinks the gap but canât close it.
Neither P nor D can fix this problem. We need something that remembers the past and builds up force over time.
Integral Control
Hereâs the key insight: if the error persists, we should keep adding force. Even a small error, given enough time, should result in a large correction. This is what the integral term does: it sums up all the past errors.
The integral term keeps track of persistent error. If an error has been there for a while, the integral builds up and eventually overwhelms the disturbance. Watch the term increase to counteract the constant pull of gravity:
The integral term eliminates steady-state error beautifully! Now the pointer reaches the target exactly, even with the mass pulling it down.
Temperature Control
Letâs see how the same principles apply to a completely different system: controlling the temperature of an oven. This is close to what youâd find in a real kitchen oven, a reflow soldering station, or an industrial furnace.
Notice something interesting: this controller only uses P and I - no derivative term at all! Why does that work here?
The key is that thermal systems have natural damping. Heat dissipates gradually, and the thermal mass of the oven acts like a built-in low-pass filter. Thereâs no âmomentumâ that would cause the temperature to overshoot wildly like our motor pointer. The system is inherently sluggish.
This sluggishness means:
- D isnât needed for dampingâthe physics provides it
- I is essentialâwe need to eliminate steady-state error from heat loss
- P provides the basic responsiveness
Try opening the door to see disturbance rejection! Watch how the integral term builds up to compensate for the increased heat loss.
Inverted Pendulum
For our final example, letâs look at one of the most dramatic demonstrations of PID control: balancing an inverted pendulum. This is the classic âbroom balancing on your palmâ problem, and itâs the same principle behind Segways and rocket landing.
Click the cart to poke it
The pendulum balances! But wait, watch what happens over time. Click the cart to poke it and observe: eventually the cart crashes into the edge of the track. The PD controller is doing its job of keeping the pendulum upright, but it has no concept of where the cart is on the track.
This is the classic problem of cascaded control. We have one controller for the angle, but we need another controller to manage position. The solution is to add a second PD loop:
Both loops use Σ to compute error. The position loop's bias shifts the nominal 0° to create a target θ.
Without the outer position loop, the inner angle loop always tries to keep the pendulum at 0° (vertical). The additional outer loop biases that target slightly off-vertical to push the cart back toward center:
// Outer loop: where should the pendulum lean?
positionError = targetPosition - cartPosition
targetAngle = Kp_pos * positionError + Kd_pos * cartVelocity
// Inner loop: achieve that lean angle
angleError = targetAngle - pendulumAngle // NOT just "0 - angle"!
motorForce = Kp_angle * angleError + Kd_angle * angularVelocity
If the cart drifts right, the position loop outputs a small negative target angle, telling the pendulum to lean slightly left. This creates a force that pushes the cart back. The inner angle loop doesnât care why itâs being told to lean; it just does its job of achieving that angle smoothly. Try moving around the target position and play with the coefficients to see the response:
Click cart to poke ¡ Drag handle to set target
Now we have two control loops working together:
- Angle Control (, ): Fast inner loop that keeps the pendulum at whatever angle itâs told
- Position Control (, ): Slower outer loop that adjusts that target angle to control cart position
The position controller adds a gentle bias to the angle controllerâs target, nudging the cart back toward center without destabilizing the balance. Try removing the derivative term from the angle controller and see how quickly the system becomes unstable.
This cascaded structure - an inner loop for fast dynamics (angle) and an outer loop for slower dynamics (position) - is extremely common in real control systems. Quadcopters use it (attitude inner loop, position outer loop), as do robotic arms and self-balancing robots.
The PID Controller
Now youâve seen all three terms in action:
| Term | Looks at | Effect | Fixes | Can cause |
|---|---|---|---|---|
| P | Present error | Push toward target | Slow response | Overshoot, oscillation |
| D | Future error (rate) | Brake before arrival | Overshoot, oscillation | Noise sensitivity |
| I | Past error (sum) | Eliminate steady-state error | Steady-state error | Windup, slow response |
Tuning Challenge
The art of PID control is choosing , , and to work in harmony. Each system is different: the mass of the pointer, the power of the motor, the amount of friction all affect what gains work best.
Can you tune a PID controller? Try to tune the controller for each challenge. Can you find values that work for all challenges?
Hold within 1° of the target for 0.5s to complete
Comparison Playground
Finally, hereâs a playground where you can compare P, PD, PI, and PID controllers side-by-side. All four controllers are trying to reach the same targetâwatch how they differ:
Compare P, PD, and PID responses
Click the Randomize Target button to see how each handles step changes. Increase the Mass to add a disturbance and observe:
- P (blue): Gets close but oscillates, and has steady-state error when mass is added
- PD (purple): Settles quickly with minimal overshoot, but still has steady-state error with mass
- PI (amber): Eliminates steady-state error but oscillates more than PDâno damping from D term
- PID (green): The best of both worldsâsmooth response AND no steady-state error
Notice how PI and PID both eliminate steady-state error (they reach the target exactly), but PID does it more smoothly because the D term provides damping. This is the power of combining all three terms: P provides responsiveness, D provides damping, and I eliminates persistent error.
What We Learned
Letâs recap the intuition weâve built:
Proportional (P): âPush toward the target, harder when far awayâ
- Good for: fast initial response
- Bad at: reaching the target exactly (steady-state error), not overshooting
Derivative (D): âIf weâre approaching fast, start brakingâ
- Good for: reducing overshoot, stabilizing oscillation
- Bad at: handling noisy measurements
Integral (I): âIf weâve been wrong for a while, try harderâ
- Good for: eliminating persistent error, overcoming disturbances
- Bad at: responding quickly (can cause windup and slow oscillation)
The magic of PID is that these three simple terms, combined properly, can control an enormous variety of systemsâfrom car engines to chemical plants to the autopilot in aircraft.
Going Further
PID is just the beginning. Once you understand these fundamentals, thereâs a whole world of control theory to explore:
- Feedforward control: Donât just react to errorâpredict what input youâll need
- Gain scheduling: Use different gains depending on operating conditions
- Model predictive control: Optimize over a future time horizon
- State-space control: Control multiple variables simultaneously
But PID remains the workhorse of industrial control for good reason: itâs simple, robust, and with proper tuning, good enough for the vast majority of applications.
This post was inspired by the interactive explanations at samwho.dev and ciechanow.ski.