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>
This commit is contained in:
2026-06-19 17:16:57 +02:00
co-authored by Claude Sonnet 4.6
parent 6711ab2200
commit 80da55da85
7 changed files with 15 additions and 9 deletions
+3 -2
View File
@@ -29,6 +29,7 @@ if __name__ == '__main__':
DT = config['Controller']['dt'] DT = config['Controller']['dt']
DT_TASK = 1.0 / config['Controller']['sim_warp_factor'] DT_TASK = 1.0 / config['Controller']['sim_warp_factor']
DT_TASK_TRACER = DT_TASK / DT DT_TASK_TRACER = DT_TASK / DT
theta_amb = config['ambient_temperature']
# Sensor # Sensor
sensor = TempSensorFactory.create(config['Controller']['sensor_name'], temp_offset=-0.15, variance=0.01) sensor = TempSensorFactory.create(config['Controller']['sensor_name'], temp_offset=-0.15, variance=0.01)
@@ -37,7 +38,7 @@ if __name__ == '__main__':
# Plant # Plant
pot_params = config['Plant'] pot_params = config['Plant']
pot = Pot(DT, pot_params, 20) pot = Pot(DT, pot_params, theta_amb)
taskmgr.add(PotTask(pot, DT_TASK, dispatcher.msgio_get("Pot"))) taskmgr.add(PotTask(pot, DT_TASK, dispatcher.msgio_get("Pot")))
# Heater # Heater
@@ -47,7 +48,7 @@ if __name__ == '__main__':
taskmgr.add(heater_task) taskmgr.add(heater_task)
# Temperature Controller # Temperature Controller
tc = PidFactory.create(config['Controller']['pid_type'], DT, config['TempCtrl'], config['Model']) tc = PidFactory.create(config['Controller']['pid_type'], DT, config['TempCtrl'], config['Model'], theta_amb=theta_amb)
tc_task = TcTask(tc, DT_TASK, dispatcher.msgio_get("TempCtrl")) tc_task = TcTask(tc, DT_TASK, dispatcher.msgio_get("TempCtrl"))
taskmgr.add(tc_task) taskmgr.add(tc_task)
+3 -3
View File
@@ -3,7 +3,7 @@ from components.pid.temp_controller_base import TempControllerBase, States
class TempController(TempControllerBase): class TempController(TempControllerBase):
def __init__(self, dt, params, model_params): def __init__(self, dt, params, model_params, theta_amb=20):
TempControllerBase.__init__(self, dt, params) TempControllerBase.__init__(self, dt, params)
self.dt = dt self.dt = dt
self.last_theta_ist = 20 self.last_theta_ist = 20
@@ -11,10 +11,10 @@ class TempController(TempControllerBase):
# Fast model: same plant model but with zero transport delay, used # Fast model: same plant model but with zero transport delay, used
# to predict the current temperature without the dead time. # to predict the current temperature without the dead time.
self.model = Pot(dt, {**model_params, 'Td': 0}) self.model = Pot(dt, {**model_params, 'Td': 0}, theta_amb)
# Delayed model: keeps the plant's assumed transport delay, so it # Delayed model: keeps the plant's assumed transport delay, so it
# can be compared like-for-like against the real (delayed) measurement. # can be compared like-for-like against the real (delayed) measurement.
self.model_delay = Pot(dt, model_params) self.model_delay = Pot(dt, model_params, theta_amb)
self.theta_ist_plant = 0 self.theta_ist_plant = 0
self.theta_ist_model = 0 self.theta_ist_model = 0
+1
View File
@@ -1,4 +1,5 @@
{ {
"ambient_temperature": 20,
"Controller" : { "Controller" : {
"dt": 0.1, "dt": 0.1,
"sim_warp_factor": 10.0, "sim_warp_factor": 10.0,
+1
View File
@@ -1,4 +1,5 @@
{ {
"ambient_temperature": 20,
"Controller" : { "Controller" : {
"dt": 1, "dt": 1,
"sim_warp_factor": 10.0, "sim_warp_factor": 10.0,
+2 -1
View File
@@ -31,13 +31,14 @@ if __name__ == '__main__':
} }
dt = 1.0 dt = 1.0
theta_amb = 20
k_noise = 0.001 k_noise = 0.001
temp_ist = 0 temp_ist = 0
temp_soll = 20 temp_soll = 20
heatrate_soll = 1.25 heatrate_soll = 1.25
ctrl = TempController(dt, ctrl_params) ctrl = TempController(dt, ctrl_params)
plant = Pot(dt, plant_params) plant = Pot(dt, plant_params, theta_amb)
_y = np.empty(0) _y = np.empty(0)
_fb = np.empty(0) _fb = np.empty(0)
_t = np.empty(0) _t = np.empty(0)
@@ -31,13 +31,14 @@ if __name__ == '__main__':
} }
dt = 1.0 dt = 1.0
theta_amb = 20
k_noise = 0.001 k_noise = 0.001
temp_ist = 0 temp_ist = 0
temp_soll = 20 temp_soll = 20
heatrate_soll = 1.25 heatrate_soll = 1.25
ctrl = TempController(dt, ctrl_params, plant_params) ctrl = TempController(dt, ctrl_params, plant_params, theta_amb)
plant = Pot(dt, plant_params) plant = Pot(dt, plant_params, theta_amb)
_y = np.empty(0) _y = np.empty(0)
_fb = np.empty(0) _fb = np.empty(0)
_t = np.empty(0) _t = np.empty(0)
+2 -1
View File
@@ -5,6 +5,7 @@ from components.plant.pot import Pot
if __name__ == '__main__': if __name__ == '__main__':
dt = 1.0 dt = 1.0
theta_amb = 20
power_on = 3500 power_on = 3500
steps_heat = 4000 steps_heat = 4000
steps_cool = 40000 steps_cool = 40000
@@ -18,7 +19,7 @@ if __name__ == '__main__':
"gain" : 1.0 "gain" : 1.0
} }
pot = Pot(dt, pot_params) pot = Pot(dt, pot_params, theta_amb)
_t = np.empty(0) _t = np.empty(0)
_temp = np.empty(0) _temp = np.empty(0)