An infant incubator warms its air from the room's 24 °C to a setpoint (about 36 °C). Overheating is dangerous, so the response must never overshoot: the air may never go above setpoint + 0.05 °C. Among the safe tunings the engineer wants the one that settles fastest. You are given a grid of candidate gains and must find it.
The heater's command p is a fraction of full power, limited to 0..1. The heating element lags: the heat it delivers, Q, follows the command with a time constant of 2 minutes. The air leaks heat to the room with a time constant of 20 minutes. The controller is a PI controller with clamping anti-windup, as in the oven problem. Everything starts cold: T = 24, Q = 0, I = 0. Take round(minutes / 0.1) steps of dt = 0.1 minutes, recording T[0] = 24, T[1], .... Each step, in this order:
e = setpoint - T
I_try = I + e * 0.1
if 0 <= Kp * e + Ki * I_try <= 1: I = I_try (otherwise I keeps its old value)
p = Kp * e + Ki * I, then limited to 0..1
Q = Q + 0.1 * (p - Q) / 2
T = T + 0.1 * ((24 - T) / 20 + Q)
A pair of gains is safe if no recorded temperature is above setpoint + 0.05. Its settling time is i * 0.1 minutes for the smallest index i such that T[i] and every later temperature satisfy abs(T[j] - setpoint) <= 0.02 * (setpoint - 24); a pair whose last temperature is outside that band has not settled and does not count.
Write best_tuning(setpoint, Kp_grid, Ki_grid, minutes) that tries every pair (Kp, Ki) with Kp from Kp_grid and Ki from Ki_grid, and returns a tuple (Kp, Ki, settling) for the safe, settled pair with the smallest settling time. If several pairs tie, return the one that comes first when looping over Kp_grid in the outer loop and Ki_grid in the inner loop. Return None if no pair is both safe and settled. Plot a few of the responses: small gains crawl, large integral gains overshoot, and the best pair sits just at the edge.
Examples
Input: setpoint = 36, Kp_grid = [0.1, 0.2, 0.4], Ki_grid = [0.005, 0.01, 0.02], minutes = 120
Output: (0.2, 0.02, 27.4)
Explanation: (0.1, 0.02), for instance, overshoots by 1.3 °C; (0.4, 0.02) is safe but
takes 51.4 minutes; (0.2, 0.02) rises without overshoot and stays within ±0.24 °C from 27.4 min.
Input: setpoint = 36, Kp_grid = [0.05, 0.1], Ki_grid = [0, 0.02], minutes = 120
Output: None
Explanation: without integral action the incubator settles short of 36 °C; with Ki = 0.02
these small proportional gains overshoot.
Constraints
Kp_gridandKi_gridhave at most 12 values each- answers are compared with a tolerance of
1e-6
Goals
- Simulate a PI loop with a lagging heater, a saturated command and clamping anti-windup
- Search a grid of gains for the fastest response that satisfies a hard limit
- Break ties in a stated order so the answer is unique