Commit Graph
90 Commits
Author SHA1 Message Date
jensandClaude Sonnet 4.6 241a796ffa Make grain_mass/water_mass per-step and re-derive plant params on change
grain_mass and water_mass now live on each step (defaulted from
default.step) instead of being fixed for the whole brew, since both
change over a mash (malt going in, water boiling off).
Sud.derive_plant_params() takes them as arguments so it can be
recomputed per step; the demo re-applies the resulting M/C to both the
real plant and the controller's Smith-predictor model on every step
change via the new Pot.set_thermal_params()/
TempController.set_model_params().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgR9tPaSzFkAwRAUyeaaCD
2026-06-20 07:45:42 +02:00
jensandClaude Sonnet 4.6 ca0a014ffb Remove leftover debug prints from StirrerSim and TempControllerBase
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgR9tPaSzFkAwRAUyeaaCD
2026-06-20 07:29:02 +02:00
jensandClaude Sonnet 4.6 2845051350 Refresh design-backlog docs after Pot's gain/theta cleanup
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>
2026-06-19 18:37:03 +02:00
jensandClaude Sonnet 4.6 1e89a58370 Replace Pid.scale()'s mutable gain factor with a stateless process() arg
Pid.scale(k) set self.k as persistent state, mutated from outside the
class and never reset in reset(), so a stale scale factor could survive
a state-transition reset. Replace it with a plain scale=1.0 argument on
Pid.process(), and have temp_controller.py/temp_controller_smith.py
compute the heat-rate-overshoot compensation factor themselves and pass
it through process_pid() each tick instead of mutating pid_hold's state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 17:37:55 +02:00
jensandClaude Sonnet 4.6 80da55da85 Make ambient temperature configurable and wire it everywhere it was hardcoded
brewpi.py passed a literal 20 as theta_amb to Pot, and
temp_controller_smith.py's two internal Pot models (and every demo's
Pot/TempController instantiation) silently relied on Pot's default of
20 instead. Add a top-level ambient_temperature key to
config.json(.templ/.sim), thread it through brewpi.py into both the
real plant and the Smith predictor's models via a new theta_amb param
on TempController, and make the demos pass it explicitly too.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 17:16:57 +02:00
jensandClaude Sonnet 4.6 40d57dc68a Refresh README and design-backlog docs against current code
Both TODO.md backlogs and the README's architecture section still
described the Kalman-filter/heat-diffusion design that's since been
replaced by the delay-line Pot model and Kalman-free Smith predictor.
Check off the items that rewrite already fixed (heat-loss units,
transport delay vs. single-pole lag, three-Kalman-tuning), note how
the kn/sensor-noise item was resolved differently than proposed, and
add newly-spotted issues: brewpi.py wiring set_model_power
unconditionally (breaks pid_type "Normal"), kalman.py being dead code
in production, stale Kalman/kn keys in the config templates, and
debug print()s left in Pot.process().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 17:02:04 +02:00
jensandClaude Sonnet 4.6 fef0f1e2a3 Consolidate States/DEFAULT_THRESHOLDS into temp_controller_base.py
tc_constants.py only held States and DEFAULT_THRESHOLDS, both used
exclusively by temp_controller_base.py and its subclasses; fold them
into temp_controller_base.py directly and drop the now-empty module.
Also drop heat_diffusion.py, unused since pot.py switched to the
delay-line model, and the matching dead import in pot.py.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 16:57:35 +02:00
jensandClaude Sonnet 4.6 ac8de9da55 Add sensor variance config and smooth heat-rate estimate
[Sensor] - replace TempSensorSim's hardcoded k_noise with configurable
temp_offset/variance, accept **kwargs on Max31865 too so both sensors
share a constructor signature usable from TempSensorFactory.create()
[Temp Controller] - low-pass filter the backward-difference heat-rate
estimate (alpha=0.1) in both temp_controller.py and
temp_controller_smith.py instead of using the raw, noisy derivative
[Pot] - drop kn from demo_pot.py's params, matching the unused-field
removal already made to pot.py itself

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 15:47:24 +02:00
jensandClaude Sonnet 4.6 95eacabe28 Rewrite Smith predictor controller and demo for the new Pot/no-Kalman design
temp_controller_smith.py still relied on Kalman filtering and Pot's old
get_temperature_intermediate(), both removed by the recent Pot/Kalman
simplification. Rebuild it using two Pot model copies (zero-delay and
delayed) and the same backward-difference heat rate as temp_controller.py,
combined into the classic Smith correction:
theta_ist = theta_model_fast + (theta_plant - theta_model_delay).

Also fix set_model_power() never being called, so the internal model
actually receives the controller's power output, and fill in
demo_temp_controller_smith.py to exercise it end-to-end with an extra
plot of plant vs. fast-model vs. delayed-model temperature.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 14:42:10 +02:00
jens 5c7cffa3a7 [Pot]
- remove HeatDiffusion
- use delay line for heat propagation modeling

[Temp Controller]
- remove Kalman
2026-06-19 14:21:23 +02:00
jensandClaude Sonnet 4.6 81e66dbcd1 Move PID matplotlib demo harnesses out of production modules
temp_controller.py, temp_controller_smith.py, and kalman.py imported
matplotlib at module level just to support eyeballed-plot __main__
blocks, coupling the live server's import graph to a GUI plotting lib
it never uses at runtime. Relocate those demos (and kalman_eval.py) to
scripts/demos/pid/ and strip the now-unused imports/__main__ blocks
from the production files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 08:21:47 +02:00
jensandClaude Sonnet 4.6 4256622e9d Make FSM hysteresis thresholds configurable
THRESH_HOLD_IDLE/HOLD_HEAT/IDLE_HEAT/IDLE_HOLD/HEAT_HOLD/HEAT_IDLE in
tc_constants.py were hardcoded module-level constants shared by every
controller instance, so tuning the IDLE/HOLD/HEAT hysteresis required
a code change.

Replace them with DEFAULT_THRESHOLDS plus an optional
TempCtrl.Thresholds config section, merged at construction time in
TempControllerBase.__init__ so configs that omit the section keep
behaving exactly as before. Documented the new section in
config.json.templ; left config.json.sim without it to exercise the
default-fallback path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 22:09:39 +02:00
jensandClaude Sonnet 4.6 b2a5652290 Add design-flaw backlog for components/pid
Tracks open issues from a review that weren't fixed as part of this
branch's Smith-predictor and dedup work: non-configurable FSM
thresholds, Pid.scale()'s gain-scheduling hack, shared Kalman tuning
across the Smith controller's 3 filters, matplotlib imported at
module level in production code, no automated tests, and unchecked
config access.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 21:31:23 +02:00
jensandClaude Sonnet 4.6 1bf3929b60 Drop model_params from base, enable Smith predictor delay correction
TempControllerBase no longer threads model_params through (only the
Smith subclass needs it, for its own Pot model and Kalman filters).

Enable the Smith predictor's actual delay-compensated error term
(theta_err now uses theta_ist_plant - theta_ist_model_delay +
theta_ist_model instead of the plain plant reading), which is the
correction this controller is named for.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 21:06:35 +02:00
jensandClaude Sonnet 4.6 78ee80f96d Deduplicate TempController/TempController_smith into a shared base
Both controllers had nearly identical process_fsm(), process_pid(),
and all getters/setters; only Kalman/model setup and process()
genuinely differed, and the duplication had already drifted (the
Smith variant resets model state on entering HEAT, the plain one
didn't).

Add TempControllerBase with the shared logic and three small hooks
(init_kalman, on_state_entered, post_pid) subclasses use to plug in
their own Kalman/model behavior. Each subclass now contains only what
makes it different.

Also fixes a latent crash: TempController's constructor only accepted
(dt, params), but PidFactory/brewpi.py always call it with a third
model_params arg, so pid_type "Normal" would have raised TypeError.
The shared base's model_params=None default fixes this. Also
initializes the Smith controller's trace attributes in __init__
instead of leaving them undefined until the first process() call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 20:50:01 +02:00
jens 879fa77ed3 - improved plot 2022-06-28 20:19:38 +02:00
jens b8ed02eb3a - put calculated power from heater into tc model 2021-10-18 21:32:37 +02:00
jens 7f66084082 - removed debug log 2021-10-18 17:58:36 +02:00
jens 54f2322c07 - added generic tracer class
- create tracer for TC
- tracer task runs TC-Tracer
2021-10-18 17:57:40 +02:00
jens 4a26e84c6e - TC export some vars
- cleaned up test
- added model vars to test
2021-10-13 18:29:33 +02:00
jens e8fa90e753 - PID/TC goes Idle state on first theat_ist measurement 2021-10-12 17:13:19 +02:00
jens bf7ec2beaf - PID: introduced INIT State
- refactored
2021-10-12 16:47:05 +02:00
jens 7eb9d16f4d - updatd constants 2021-10-12 16:19:21 +02:00
jens 3c010d7bfd - updatd constants 2021-10-12 13:24:19 +02:00
jens b4a6c70591 - init kalman_model_delay 2021-10-12 12:07:36 +02:00
jens 16cb3d3b3c - use heat diffusion for water model instead of delay line 2021-10-12 12:01:40 +02:00
jens 89ac2b8ea8 - updated tc params for test 2021-10-12 10:20:55 +02:00
jens 425567f3db - refactored
- increased Hold.Pid.kp
- decrease state change HEAT TO HOLD windows to 1°C
2021-10-12 09:11:07 +02:00
jens ff90c6d90c - added initial for filling Delay line
- added gain parameter for Pot sim
- from state change to heat init model temp with plant temp
- updated config template
2021-10-11 19:54:03 +02:00
jens 20b0363e26 - reset kalman on change to HEAT state 2021-10-11 19:04:32 +02:00
jens 9b20276012 - fixed setting model correct power in idle 2021-10-11 18:28:25 +02:00
jens 132081eeb1 - added debig 2021-10-11 16:54:58 +01:00
jens c5c39732cf - do data signal wiring at one central place
- fixed initializations
2021-10-11 13:05:18 +02:00
jens 80fa983c96 - fixed kalman test for different dt 2021-10-10 13:56:48 +02:00
jens dce3caa1eb - refactored 2021-10-09 12:27:36 +02:00
jens f6394e9e7a - refactored 2021-10-09 10:52:35 +02:00
jens b83ec71346 - refactored 2021-10-09 10:07:45 +02:00
jens 5923212055 - refactored 2021-10-09 09:46:52 +02:00
jens 529ae7ad2f - adjusted params for TC tests 2021-10-02 13:10:10 +02:00
jens 2e143ee03f - implemented APid
- choose Tempcontroller impl. from config
2021-10-02 12:24:42 +02:00
jens bf019733b2 - added abstarct PID APid
- added PidFactory
- use variable args for factory
2021-10-02 11:10:43 +02:00
jens 70426b9280 - start HOLD at diference of 2.0 °C 2021-08-10 15:39:54 +02:00
jens cc54887f9b - TC: HOLD controller doesn't use Smith Predictor 2020-12-22 13:32:14 +01:00
jens 58411e297c - use temp_controller_smith 2020-12-22 11:05:09 +01:00
jens b55bd5b366 - refactored 2020-12-22 11:02:37 +01:00
jens f2aff73f40 - refactored temp controllers 2020-12-22 10:51:38 +01:00
jens 4c93e85dd8 - improved temp controllers 2020-12-22 10:45:51 +01:00
jens 5762b7ab8f - added temp_controller with Smith Prediction 2020-12-22 10:27:21 +01:00
jens d777a955a4 - refactored dt 2020-12-22 10:26:56 +01:00
jens b5a0e6a7ac - removed dt from params 2020-12-21 16:06:17 +01:00