This simulation models a PID (Proportional-Integral-Derivative) controller driving one of three real plants: a first-order thermal mass, a second-order cart-spring-damper, or a liquid tank with a valve. Each control tick the controller measures the error e = r − y between setpoint r and plant output y, then computes u = Kp·e + Ki·∫e·dt + Kd·de/dt, clamped to actuator limits with anti-wind-up so the integral term stops accumulating once the output saturates. The scope plots setpoint and response over the last 20 seconds while Step, Disturb and Ziegler–Nichols autotune let you probe the classic tuning tradeoff between rise time, overshoot, settling time and steady-state error.
A live feedback loop: the plant graphic (thermometer, cart-on-a-rail, or tank) shows the controlled variable y chasing the setpoint r, the two side bars show the instantaneous control signal u and error e, and the scope traces r (dashed) against y (solid) over a rolling 20-second window. Stats below report rise time, percentage overshoot, settling time and steady-state error, computed live from each Step test.
Pick a plant (Thermal mass, Cart-spring-damper, or Tank + valve), then drag the Kp, Ki and Kd sliders to change proportional, integral and derivative gains, and the Setpoint slider to move the target. Press Step to command a setpoint jump and measure rise/overshoot/settling, Disturb to inject a sudden external disturbance (heat loss, push, or leak depending on plant), and ZN autotune to auto-fill Kp/Ki/Kd from Ziegler–Nichols ultimate-gain rules. Toggle Measurement noise to see how derivative action amplifies sensor noise, and use Time scale to speed up or slow down the simulation.
The Ziegler–Nichols method, published in 1942, tunes a PID controller from just two numbers — the ultimate gain Ku and ultimate period Tu at which a P-only loop starts to oscillate — giving Kp = 0.6·Ku, Ki = 1.2·Ku/Tu, Kd = 0.075·Ku·Tu. PID loops are everywhere: cruise control, home thermostats, drone flight stabilisation and industrial process control all rely on the same three-term feedback law this simulation implements.
The proportional term Kp·e reacts to the current error and provides most of the immediate correction, but a P-only controller settles with a persistent steady-state error because it needs some residual error to keep producing output. The integral term Ki·∫e·dt accumulates past error over time and drives that steady-state error to zero, at the cost of extra overshoot and a slower response if the gain is too high. The derivative term Kd·de/dt reacts to how fast the error is changing, damping oscillation and speeding up settling, but it also amplifies measurement noise, which is why this simulation exposes a noise toggle.
Integrator wind-up happens when the actuator saturates (hits its uMin/uMax limit) while the error still has the same sign, causing the integral term to keep growing far beyond what the plant can actually use. When the error finally reverses, the controller then has to "unwind" that excess integral before it can respond, producing large overshoot. This simulation's anti-wind-up logic freezes the integral update whenever the tentative control signal would push further into saturation in the same direction as the existing error, so the integral only grows when it can still do useful work.
These four numbers, all measured automatically when you press Step, summarise a control loop's step response. Rise time is how long the output takes to go from 10% to 90% of the way to the new setpoint. Overshoot is how far the output peaks past the target, as a percentage of the step size. Settling time is how long it takes for the output to enter and stay within a 2% band around the target for at least one second. Steady-state error is the remaining gap between setpoint and output once the transient has died out — driven toward zero by the integral term.
The thermal plant is first-order (τ·dy/dt + (y − ambient) = gain·u), so it can only ever approach its target smoothly with no natural overshoot from the plant itself — any overshoot you see comes purely from the controller. The cart-spring-damper is second-order (m·a + c·v + k·x = u), so it has its own natural oscillation and can overshoot and ring even under a well-tuned controller. The tank plant is nonlinear because outflow depends on the square root of the liquid level (A·dh/dt = inflow − kOut·√h), so its response speed changes with fill level, which is a good test of how robust a fixed set of PID gains really is.
The classic Ziegler–Nichols method finds the ultimate gain Ku and ultimate oscillation period Tu — the point at which a proportional-only loop sits on the edge of sustained oscillation — then derives PID gains from simple ratios: Kp = 0.6·Ku, Ki = 1.2·Ku/Tu, Kd = 0.075·Ku·Tu. This simulation's ZN autotune button uses representative Ku/Tu values for each plant rather than running a live relay test, then applies those same classic formulas to fill in the Kp/Ki/Kd sliders instantly so you can compare hand-tuning against the textbook rule.