A hot tub in a garden is kept warm by an electric heat pump (it can heat, and if asked for a negative power, cool). Its water temperature T (°C) changes each minute by
T = T + (15 - T) / 600 + 0.01 * p - d
The air is at 15 °C and the insulated tub has a time constant of 600 minutes; each kilowatt p adds 0.01 °C per minute; d is a disturbance: while the lid is on d = 0, and from minute t_lid on, with the lid off, evaporation takes away d = loss °C every minute.
Compare two controllers on the same day, each starting with the water at the air temperature, T = 15, and an empty integral, I = 0. Each minute t = 0, 1, ..., minutes - 1, in this order:
e = setpoint - T
I = I + e (one-minute steps, so e * dt is just e)
p = Kp * e + Ki * I (P controller: the same with Ki = 0)
d = loss if t >= t_lid else 0
T = T + (15 - T) / 600 + 0.01 * p - d
Write hot_tub(setpoint, Kp, Ki, loss, t_lid, minutes) that runs both controllers (the P one with Ki = 0, the PI one with the given Ki) and returns a tuple of four errors setpoint - T in °C:
- the P controller's error after
t_lidminutes (just before the lid comes off; after0minutes it is the starting error), - the P controller's error after
minutesminutes, - and 4. the same two for the PI controller.
Collect both temperature lists and plot them on one chart: when the lid comes off, the P controller sinks to a new, lower level and stays there; the PI controller dips and climbs back.
Examples
Input: setpoint = 38, Kp = 2, Ki = 0.02, loss = 0.01, t_lid = 600, minutes = 1200
Output: (1.76927237, 2.23076833, 0.04625161, -0.00112269)
Explanation: before the lid comes off the P controller sits 1.77 °C short; evaporation
pushes that to 2.23 °C. The PI controller is within 0.05 °C before and 0.002 °C after.
Input: setpoint = 38, Kp = 5, Ki = 0.05, loss = 0.02, t_lid = 400, minutes = 800
Output: (0.7419355, 1.12903226, -0.05770772, 0.00421324)
Constraints
0 <= t_lid <= minutes- answers are compared with a tolerance of
1e-6; do not round
Goals
- Simulate the same plant under a P and a PI controller
- Apply a constant disturbance part-way through a run
- See that a P controller's error grows with a disturbance while a PI controller's returns to zero