Review of pot.py found a likely root cause for sim-vs-real control mismatches: the heat-loss term carries the wrong units, masking ambient cooling in simulation. Also notes the dropped sensor-noise term, hardcoded ambient temp, and lag-vs-dead-time modeling gap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2.8 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). Not yet acted on.
-
Heat-loss term has wrong units.
pot.py:37:leak = 1/self.M * self.L * (self.theta_amb - self.temp)/self.theta_amb. The power term right above it ispower/(self.M * self.C)(W / (J/K) -> K/s).leakshould follow the same pattern —self.L * (self.theta_amb - self.temp) / (self.M * self.C)— but instead it's missing/Cand divides bytheta_amb(~20) instead, which isn't a physically meaningful normalization. WithC=4190this suppresses ambient heat loss by ~3-4 orders of magnitude versus what the power term implies, so the simulated pot barely cools at all. The Smith predictor's internal model is also aPotinstance with the identical bug, so this never showed up in sim-vs-sim testing — only against the real plant. Likely the primary cause of the sim/real control mismatch. -
knis loaded but never applied.pot.py:18readsparams['kn']but nothing inprocess()/get_temperature()uses it. Git history shows it used to add Gaussian sensor noise (self.kn * np.random.normal(...)) to the output, since commented out and then dropped during the heat-diffusion refactor. Sim is currently fully deterministic/noise-free, making the Kalman filter and PID derivative term look better-behaved in sim than they will against a real noisy sensor. Re-enable as measurement noise (and decide if process noise is also wanted). -
theta_ambis hardcoded, not configured.brewpi.py:40passes a literal20instead of reading it from config or a live ambient sensor. Real ambient temperature drifts and is never modeled as a disturbance, so the controller's robustness to it is untested. -
Thermal lag modeled as single-pole lag, not transport delay.
HeatDiffusion(heat_diffusion.py) implementsalpha=dt/Tdexponential smoothing, not true dead time. There's already aDelayclass (plant/delay.py) for pure transport delay, dropped in favor ofHeatDiffusionin commit16cb3d3. If the real pot's heater-to-sensor coupling behaves more like dead time (heat must propagate through the water before reaching the sensor) than a single lag,Tdwon't represent the same dynamic in sim vs. reality, and the Smith predictor's delay compensation (which assumesTdmatches the real plant) will be off. -
No actuator/process realism. No heater power saturation enforced inside
Potitself (handled ad hoc in test harnesses), no evaporation/lid heat loss, no varying thermal massMas volume changes (e.g. boil-off, adding water/grain) —Mis a fixed constant for the whole simulation.