A bakery's oven heats from the room's 20 °C to a setpoint with a PI controller. Its elements can deliver only 0 to p_max kW. Each minute the oven's temperature changes by
T = T + (20 - T) / 40 + 2 * p
(a time constant of 40 minutes, and 2 °C per minute for every kilowatt).
During the long warm-up the elements are flat out, but the error stays large for many minutes, and the integral keeps growing. By the time the oven reaches the setpoint the integral is so big that the controller still demands full power, and the oven sails far past the setpoint before the integral unwinds. That is integrator windup. The usual cure is clamping: do not integrate in a minute where integrating would ask for more than the elements can give.
Simulate two controllers, both starting at T = 20 with I = 0, for minutes minutes. Each minute, in this order:
e = setpoint - T
I_try = I + e
plain: I = I_try
clamped: if 0 <= Kp * e + Ki * I_try <= p_max: I = I_try (otherwise I keeps its old value)
p = Kp * e + Ki * I, then limited to 0..p_max
T = T + (20 - T) / 40 + 2 * p
Write oven_windup(setpoint, Kp, Ki, p_max, minutes) that returns a tuple of four numbers: the highest temperature of the plain controller, the highest temperature of the clamped one (both counting the starting 20 °C), then the number of minutes in which each ran at full power (p equal to p_max after limiting), plain first. Plot both temperature curves to see the difference.
Examples
Input: setpoint = 200, Kp = 0.1, Ki = 0.005, p_max = 3, minutes = 300
Output: (250.28884915, 199.99999208, 126, 39)
Explanation: the plain oven overshoots by 50 °C and runs at full power for 126 minutes,
long after it passed 200 °C. The clamped one creeps up to 200 °C without overshoot.
Input: setpoint = 150, Kp = 0.1, Ki = 0.005, p_max = 3, minutes = 5
Output: (48.53703359, 48.53703359, 5, 5)
Explanation: five minutes in, both are still flat out and nothing differs yet.
Constraints
- answers are compared with a tolerance of
1e-6; do not round
Goals
- Simulate a PI controller whose actuator saturates
- See the integral wind up while the actuator is at its limit and cause a large overshoot
- Implement anti-windup by not integrating while the command is out of range