Seed the forecast estimator's throwaway controller with start_theta
SudForecastEstimator.estimate() builds a fresh Pot/temperature controller per call and never set its initial theta_soll, leaving it at TempControllerBase's default of 0. For the upfront, full-schedule Forecast this was harmless - the first real step always carries its own 'temperature', overwriting it instantly. But the dynamic RemainingForecast is recomputed from wherever the live run currently is, and since ramping is no longer gated by a 'ramp' key, the remaining schedule's first step often has no 'temperature' of its own (e.g. resuming from a WAIT_USER pause into a hold-only step) - a fresh tc has no persisted target to inherit it from like the real run's tc does, so it span chasing 0 degrees, hit MAX_TICKS, and produced a ~200,000-point result instead of the expected ~10,000. That oversized payload (~6MB) is what was actually tripping websockets' default 1MB max_size and disconnecting clients with "1009 (message too big)" - not the GUI threading issue fixed separately. Verified live: the same remaining-schedule case that previously hit MAX_TICKS (200001 points) now resolves in 8348, and a full driven run (load, start, auto-confirm both WAIT_USER steps, completion) produces no oversized messages. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LhiQe64F74uHV8jzuoSa5K
This commit is contained in:
@@ -51,6 +51,17 @@ class SudForecastEstimator:
|
||||
tc = PidFactory.create(self.pid_type, self.dt, self.tempctrl_params, self.plant_params, theta_amb=self.theta_amb)
|
||||
tc.set_enabled(True)
|
||||
tc.set_theta_ist(pot.get_temperature())
|
||||
# Seed the target at start_theta - this tc is a fresh, throwaway
|
||||
# instance (unlike the real run's persistent one), so without this
|
||||
# its theta_soll_set defaults to 0 until a step pushes its own.
|
||||
# Steps without their own 'temperature' (common now that ramping
|
||||
# isn't gated by a 'ramp' key - see components/sud.py) rely on
|
||||
# inheriting whatever target was already running, which for a
|
||||
# schedule starting mid-brew (the dynamic remaining forecast) is
|
||||
# start_theta, not 0 - without this, such a schedule's first step
|
||||
# would have the simulated controller chase 0 degrees indefinitely,
|
||||
# hitting MAX_TICKS and producing a needlessly huge result.
|
||||
tc.set_theta_soll(start_theta)
|
||||
|
||||
def on_step_changed(step):
|
||||
if step is None:
|
||||
|
||||
Reference in New Issue
Block a user