pid: replace IDLE-as-cooling with a real COOL state
IDLE conflated two unrelated things: "controller disabled" and "needs to cool, which this heat-only actuator fakes via zero output." Split them apart: - IDLE now means disabled only - the FSM forces it whenever enabled=False, regardless of the temperature gap, and process_pid() zeroes y for it same as before. - New COOL state (mirroring HEAT) takes over the negative-diff case, with its own pid_cool (separate "Cool" gains, alongside Hold/Heat) instead of reusing pid_rate. Its output can legitimately be negative - it's the actuator (tasks/heater.py's actor(), already max(0, ...)) that clamps it to 0 because *this* plant (Pot) can only heat. A plant with real cooling capability could one day honor it directly. - Thresholds renamed accordingly (HoldIdle->HoldCool, HeatIdle-> HeatCool, new CoolHold/CoolHeat); config.json/.sim/.templ and the hand-rolled ctrl_params in scripts/demos/pid/ and demo_sud.py updated with a "Cool" params section (mirrors "Heat" for now, since there's no real cooling actuator to tune against yet). Also fixes a regression in demo_sud.py/the other PID demos: none of them ever called set_enabled(True), so since enabled defaults to False they never drove the heater at all - only caught because this change's demo_sud.py re-run got stuck in RAMPING forever.
This commit is contained in:
@@ -33,7 +33,7 @@ class TempController(TempControllerBase):
|
||||
self.model_delay.set_ambient_temperature(theta_amb)
|
||||
|
||||
def on_state_entered(self, state):
|
||||
if state == States.HEAT:
|
||||
if state in (States.HEAT, States.COOL):
|
||||
self.model.initial(self.theta_ist)
|
||||
self.model_delay.initial(self.theta_ist)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user