docs: note active-cooler architecture assessment in pid TODO
Captures the answer to "would the cascade/FSM design still hold up with a real active cooler instead of heat-only + passive loss": PID/plant model already generalize (symmetric y range, sign-agnostic plant math, existing COOL state/pid_inner_cool), but the actor-level max(0, y) clamp in tasks/heater.py is the one thing making today's tuning mismatches free - removing it exposes both Outer.y_hold_min and pid_inner_cool as live, untuned negative-power paths. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M2ierBoxW3v7nUbDw3M2pE
This commit is contained in:
@@ -118,6 +118,43 @@ git history for `temp_controller.py`/`temp_controller_smith.py`).
|
|||||||
`TestHoldOvershootRecoversToSetpoint` in
|
`TestHoldOvershootRecoversToSetpoint` in
|
||||||
`tests/components/pid/test_temp_controller_closed_loop.py`.
|
`tests/components/pid/test_temp_controller_closed_loop.py`.
|
||||||
|
|
||||||
|
- [ ] **Architecture isn't ready for a real active cooler yet, only a
|
||||||
|
heat-only actuator.** Asked (not yet built): would the cascade/FSM
|
||||||
|
design still hold up if an active cooler (compressor/chiller, some
|
||||||
|
finite cooling power) replaced "heater off + passive ambient loss"?
|
||||||
|
Mostly yes at the PID/plant-model level: `Pid.y_min`/`y_max` are
|
||||||
|
already symmetric `-1.0`/`1.0` (`pid.py:12-13`), `Pot.set_power()`/
|
||||||
|
`process()` are sign-agnostic so the simulator already models negative
|
||||||
|
power correctly, and the FSM already has a dedicated `COOL` state with
|
||||||
|
its own PID instance (`pid_inner_cool`, `temp_controller_fsm.py:35-39`)
|
||||||
|
whose comment explicitly anticipates this ("the actuator ... is
|
||||||
|
responsible for clamping the resulting negative power to whatever it's
|
||||||
|
actually capable of").
|
||||||
|
The gap is at the actuator boundary: today `y` only ever reaches one
|
||||||
|
consumer, `tasks/heater.py:59`'s `self.power_actor = max(0, ... * y)`,
|
||||||
|
which silently discards every negative command — that's what's made
|
||||||
|
tuning mismatches free so far. A real cooler needs (a) a second
|
||||||
|
actuator/device class consuming the negative half instead of that
|
||||||
|
`max(0, ...)` clamp — there's no `Cooler`/chiller abstraction anywhere
|
||||||
|
yet (`grep -rniE "cooler|chiller|compressor"` across all `.py` is
|
||||||
|
empty, fully greenfield), and `heater_hendi.py:80`'s `set_power` only
|
||||||
|
clamps to a max, not a min, so feeding it a negative value today would
|
||||||
|
call `setPowerWatts(negative)` on real hardware with undefined result;
|
||||||
|
and (b) its own power ceiling, since one normalized `y` scaled by one
|
||||||
|
`get_power_max()` breaks once heater and cooler have different max
|
||||||
|
power.
|
||||||
|
Biggest risk once that clamp is removed: two separate paths start
|
||||||
|
issuing real negative-power commands that were previously harmless -
|
||||||
|
HOLD's `Outer.y_hold_min` floor (via `Inner.Hold`, see the steady-state
|
||||||
|
overshoot item above) and the pre-existing `pid_inner_cool` (via
|
||||||
|
`Inner.Cool`) - and neither has been tuned against actual active-cooling
|
||||||
|
dynamics (compressor lag, min-on-time). `Inner.Cool` in the demo
|
||||||
|
configs is literally a copy of `Inner.Heat`'s gains, never validated
|
||||||
|
independently. So adding a real cooler is a wiring task (new actuator
|
||||||
|
class, per-actuator power scaling) plus a re-tuning task (`Inner.Cool`,
|
||||||
|
and re-checking the `HoldCool`/`CoolHold` thresholds in
|
||||||
|
`temp_controller_fsm.py:14-17`), not just wiring.
|
||||||
|
|
||||||
- [ ] **`kalman.py` is now dead code in production.** Neither
|
- [ ] **`kalman.py` is now dead code in production.** Neither
|
||||||
`temp_controller.py` nor `temp_controller_smith.py` uses `Kalman`
|
`temp_controller.py` nor `temp_controller_smith.py` uses `Kalman`
|
||||||
anymore; the only remaining references are
|
anymore; the only remaining references are
|
||||||
|
|||||||
Reference in New Issue
Block a user