Drop the now-stale "config.json.templ/.sim still carry dead Model.kn/Plant.kn keys" note (they were deleted), note that Pot now always starts at theta_amb (no separate initial-temp param) and that dropping the gain (efficiency) factor entirely is a partial realism regression, not just a fix. Point the config-validation item at the gain key that's still dead in config.json.sim. Also update demo_sud.py to match the Pot params Pot.__init__ actually reads. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.4 KiB
components/plant design backlog
Findings from reviewing pot.py's water-bath model against real-plant
behavior (sim/real control mismatch reported by user), refreshed against
the current delay-line rewrite of Pot.
-
Heat-loss term has wrong units. Fixed by the
Potrewrite:process()now computesp_loss = self.L * self.M * (self.temp - self.theta_amb)in Watts and applies `self.temp += (self.delay.get()- p_loss) / (self.M * self.C) * self.dt
— the same/(M*C)normalization for both the gain and loss terms, instead of the old mismatchedleak = 1/self.M * self.L * (...)/ self.theta_amb`.
- p_loss) / (self.M * self.C) * self.dt
-
Thermal lag modeled as single-pole lag, not transport delay. Fixed:
Potno longer usesHeatDiffusion'salpha=dt/Tdexponential smoothing (that module was deleted). It now delays the input power throughplant/delay.py'sDelay(true dead time) before integrating it, matching what this item recommended. -
knis loaded but never applied. Resolved differently than originally proposed:knwas removed fromPotentirely rather than wired up as plant-side measurement noise. Sensor noise is now modeled one layer up, inTempSensorSim(temp_offset/variance, wired frombrewpi.py'sTempSensorFactory.create(..., temp_offset= -0.15, variance=0.01)), not in the plant model. The staleModel.kn/Plant.knkeys this item flagged have since been deleted fromconfig.json.templ/config.json.simtoo. -
theta_ambis hardcoded, not configured. Fixed: added a top-levelambient_temperaturekey toconfig.json(.templ/.sim);brewpi.pyreads it once and passes it to both the realPotand (via a newtheta_ambparam)temp_controller_smith.py's internal models, so the Smith predictor's model matches the real plant's assumed ambient instead of silently defaulting to 20.Potalso dropped its separateparams['theta']initial-temperature field — it now always starts attheta_amb(so the same config value governs both the assumed ambient and the pot's starting temperature; there's no longer a way to start a sim at a temperature other than ambient). Real ambient temperature still isn't modeled as a drifting disturbance (it's a static config value, not a live sensor reading, thoughPot.set_ambient_temperature()now exists as a hook for that), so robustness to ambient drift remains untested. -
No actuator/process realism. Partially improved (
process()clampsself.temptomin(100, ...), won't simulate past boiling) and partially regressed:Potalso dropped itsgain(heater efficiency) factor entirely —process()now applies 100% of commanded power with no loss, whereas beforeparams['gain']could model e.g. an 80% efficient transfer.Model.gain/Plant.gainare now dead keys inconfig.json.sim(already absent from.templ) — seecomponents/pid/TODO.md's config-validation item. Still no heater power saturation enforced insidePotitself (handled ad hoc in demo harnesses), no evaporation/lid heat loss, and no varying thermal massMas volume changes (e.g. boil-off, adding water/grain) —Mis a fixed constant for the whole simulation. -
Debug
print()s left inPot.process(). Fixed: the unconditionalp_loss/theta_amb/tempprints (leftover from the heat-loss-units fix) were removed.