Pick a scenario: it sets the gains and commands a step.
Anti-windup decides what the integrator does while the motor is saturated.
Red lines mark the motor limit. When the demanded torque (red dashed) exceeds it, the applied torque (blue) is clipped and the loop is no longer linear.
The science
Plant. A rigid arm with a joint motor: J θ″ + b θ′ + m g l sin θ = τ, θ measured from hanging straight down. Here J = 0.12 kg·m² + payload·0.45² (+ rotor inertia), m g l = 9.81 (1.2·0.30 + payload·0.45) N·m. The equation is integrated with RK4 at 2 ms with the controller output held constant per step (zero-order hold, like a 500 Hz digital loop).
Controller. τ = Kp e + ∫Ki e dt − Kd dθ̄/dt with the derivative taken on the (filtered) measurement so a set-point step causes no derivative kick. The motor saturates at ±τmax. Anti-windup: clamp stops integrating while saturated and the error pushes further into saturation; back-calculation bleeds the integrator by (τsat − τdemand)/Tt with Tt = 0.15 s.
Linear theory. For small angles the PD loop is J s² + (b+Kd) s + (Kp + m g l): ωn = √((Kp+mgl)/J), ζ = (b+Kd)/(2√(J(Kp+mgl))), overshoot = exp(−πζ/√(1−ζ²)), settling ≈ 4/(ζωn). Gravity acts as an extra spring, so a P/PD loop ends at Kp·r/(Kp+mgl) of the target; an integrator (or gravity feed-forward m g l sin r) removes the offset. The step metrics shown are measured on the full nonlinear model (large steps differ from the small-angle formulas).
Checks. (1) free small-angle period vs 2π√(J/mgl); (2) PD overshoot vs the closed form; (3) PD steady-state vs Kp·r/(Kp+mgl); (4) integral action reaching the target; (5) RK4 energy drift over a 60° undamped swing. Simplifications: no motor electrical dynamics or gearbox backlash, no Coulomb friction, ideal encoder except the optional white noise, and the arm is a single rigid link. Gains are in SI units but are not those of a specific commercial robot.
The backboard, motor, arm, dial and payload are low-poly models made in Blender; the control loop runs in the page.