Keep the plant/controller model in sync as the Sud advances
SudTask.on_step_changed() set the controller's target temp/rate on every step, but never touched the real Pot's or the Smith predictor's internal model's thermal mass (M/C) - those stayed frozen at brewpi.py's startup DEFAULT_PLANT_PARAMS for the whole brew, even though grain_mass/water_mass change per step (malt going in, water boiling off) and demo_sud.py already recomputes them every step via derive_plant_params(). Production SudTask just never got the same treatment. Adds SudTask.apply_plant_params(), called alongside the existing theta_soll/heatrate_soll push, mirroring the demo. Needs the real Pot now, so SudTask takes a `pot` constructor arg; set_model_params() is only called if the configured controller actually defines one (the "Normal" pid_type doesn't).
This commit is contained in:
+1
-1
@@ -74,7 +74,7 @@ if __name__ == '__main__':
|
||||
sud_path = config.get('sud')
|
||||
if sud_path:
|
||||
sud = Sud(sud_path)
|
||||
taskmgr.add(SudTask(sud, tc, stirrer, DT_TASK, dispatcher.msgio_get("Sud")))
|
||||
taskmgr.add(SudTask(sud, tc, stirrer, pot, DT_TASK, dispatcher.msgio_get("Sud")))
|
||||
|
||||
# Tracer
|
||||
taskmgr.add(TracerTask(sensor, heater, tc, trace_tc, DT_TASK_TRACER, dispatcher.msgio_get("Tracer")))
|
||||
|
||||
+14
-1
@@ -3,6 +3,7 @@ from tasks import ATask
|
||||
from ws.message import MsgIo
|
||||
from utils.value import ChangedFloat
|
||||
from components import APid, AStirrer
|
||||
from components.plant import APlant
|
||||
from components.sud import Sud, SudState
|
||||
|
||||
# How close theta_ist needs to be to theta_soll_set to count as "reached".
|
||||
@@ -10,14 +11,25 @@ TEMP_REACHED_TOLERANCE = 0.2
|
||||
|
||||
|
||||
class SudTask(ATask):
|
||||
def __init__(self, sud: Sud, tc: APid, stirrer: AStirrer, interval, msg_handler: MsgIo):
|
||||
def __init__(self, sud: Sud, tc: APid, stirrer: AStirrer, pot: APlant, interval, msg_handler: MsgIo):
|
||||
ATask.__init__(self, interval)
|
||||
self.sud = sud
|
||||
self.tc = tc
|
||||
self.stirrer = stirrer
|
||||
self.pot = pot
|
||||
self.msg_handler = msg_handler
|
||||
msg_handler.set_recv_handler(self.recv)
|
||||
|
||||
def apply_plant_params(self, step):
|
||||
"""Keeps the real plant's and the controller's internal model's
|
||||
lumped (M, C) in sync with the step's grain_mass/water_mass, since
|
||||
those vary over the course of a brew (malt going in, water boiling
|
||||
off) - mirrors demo_sud.py's apply_plant_params()."""
|
||||
params = self.sud.derive_plant_params(step.get('grain_mass', 0), step.get('water_mass', 0))
|
||||
self.pot.set_thermal_params(params['M'], params['C'])
|
||||
if hasattr(self.tc, 'set_model_params'):
|
||||
self.tc.set_model_params(params['M'], params['C'])
|
||||
|
||||
def apply_stirrer(self, step):
|
||||
stirrer_cfg = step.get('ramp', step.get('hold', {})).get('stirrer', {})
|
||||
speed = stirrer_cfg.get('speed', 0)
|
||||
@@ -35,6 +47,7 @@ class SudTask(ATask):
|
||||
ramp = step.get('ramp') if step else None
|
||||
hold = step.get('hold') if step else None
|
||||
if step is not None:
|
||||
self.apply_plant_params(step)
|
||||
if ramp is not None:
|
||||
self.tc.set_theta_soll(ramp['temp'])
|
||||
self.tc.set_heatrate_soll(ramp['rate'])
|
||||
|
||||
Reference in New Issue
Block a user