Problem 596446 · medium · Level 05 Advanced Algorithms & Graphs

A Greenhouse That Reads the Weather

feedforward · measured disturbance · proportional control · saturation · simulation · RMS error

A greenhouse is heated to a target temperature r (°C). Each minute it loses heat to the outside air, whose temperature w a weather sensor measures. One minute of the greenhouse is

T[k+1] = a * T[k] + b * u[k] + (1 - a) * w[k]

with T the inside temperature, u the heater power in kW (between 0 and u_max), a (just below 1) the share of the inside temperature that is kept from one minute to the next, and b the warming per kW per minute.

A plain feedback controller, u = K * (r - T), only reacts once the cold has already cooled the greenhouse. But the outside temperature is measured, and the model says exactly how much power holds the greenhouse at r against a given w: setting T[k+1] = T[k] = r gives

u_ff = (1 - a) * (r - w[k]) / b        (the feedforward power)

Feedforward adds this to the feedback: u = u_ff + K * (r - T). If the model is right and the heater has the power, the outside temperature no longer moves the inside one at all.

Simulate both controllers. Start each run at T = T0 and, for every minute k (one per entry of outside), in this order:

u = K * (r - T)                     (feedback)
u = u + (1 - a) * (r - w[k]) / b    (only with feedforward)
u = min(max(u, 0), u_max)           (the heater's limits)
T = a * T + b * u + (1 - a) * w[k]

and add (r - T) ** 2 (with the new T) to a sum. The RMS error is sqrt(sum / len(outside)).

Write greenhouse(r, T0, a, b, K, u_max, outside) that returns (rms_feedback_only, rms_with_feedforward). With an empty outside both are 0.0. Press Run with plot on your two temperature lists to see the feedback-only greenhouse sag on a cold night.

Examples

Input:  r = 20, T0 = 20, a = 0.9, b = 0.5, K = 2, u_max = 30, outside = [5, 5, 0, 0, -5, -5, 0, 5]
Output: (1.8115517439527178, 0.0)
Explanation: feedback alone first lets the greenhouse cool to 18.5 °C (it heats only once there is
an error) and stays 1.3 to 2.3 °C low. With feedforward the heater supplies the loss before
it happens and the temperature never leaves 20 °C.

Input:  r = 20, T0 = 20, a = 0.9, b = 0.5, K = 2, u_max = 4, outside = [5, 5, 0, 0, -5, -5, 0, 5]
Output: (1.9644385467957008, 0.4944890355205057)
Explanation: at -5 °C holding 20 °C takes 5 kW, but the heater gives at most 4: even feedforward
cannot cancel what the heater cannot supply.

Constraints

  • 0 < a < 1, b > 0, K >= 0, u_max > 0
  • answers are compared with a tolerance of 1e-6; a list is accepted in place of the pair

Goals

  • Compute a feedforward term that cancels a measured disturbance using the plant model
  • Simulate the same loop with and without feedforward, step by step
  • See where feedforward stops helping: when the actuator saturates
Starting Python…