mirror of
https://github.com/lynchaos/ashvale-station.git
synced 2026-09-12 12:47:49 +00:00
Take Kalman tuning from config, not from the saved state
q and r were written into station_state.json and restored over the configured values, so tuning was effectively immutable in the field. This was found the expensive way: the retune in the previous commit was deployed, the service restarted cleanly, and the filters carried on with q = 2e-6 because that is what the state file said. Measured median rate afterwards was 14.4 C/h against 12.4 before, which is to say nothing happened. Only the estimate is state. x, P and initialised are restored; q and r now come from config every time. P may be momentarily inconsistent with a changed q, which costs a few hundred samples of reconvergence and is far cheaper than a configuration change that appears to work and does not. load_dict also now skips filters this build no longer has, rather than resurrecting them from an older state file.
This commit is contained in:
@@ -333,3 +333,34 @@ def test_kalman_rate_is_physical_in_a_still_room():
|
||||
assert np.median(settled) < 3.0, (
|
||||
f"median |rate| {np.median(settled):.1f} C/h in a room drifting 0.4 C/h")
|
||||
assert np.percentile(settled, 95) < 10.0
|
||||
|
||||
|
||||
def test_retuning_q_survives_a_reload():
|
||||
"""Tuning lives in config, not in the state file.
|
||||
|
||||
q and r were persisted and restored, so a retune deployed to a running
|
||||
station did nothing: the service restarted and the filters carried on with
|
||||
whatever tuning was in force when the state was last written. The symptom
|
||||
is a config change that appears to work and does not, which is the worst
|
||||
kind.
|
||||
"""
|
||||
from ashvale.config import load_config
|
||||
from ashvale.estimation import SignalTracker
|
||||
|
||||
cfg = load_config()
|
||||
cfg.sensor.kalman_q_temp = 2.0e-6 # an old, badly tuned state file
|
||||
old = SignalTracker(cfg)
|
||||
for i in range(50):
|
||||
old.step(1.7554e9 + i * 2.0, 24.0, 50.0, 1013.0, 43.0)
|
||||
saved = old.to_dict()
|
||||
assert saved["filters"]["temperature"]["q"] == 2.0e-6
|
||||
|
||||
cfg.sensor.kalman_q_temp = 1.0e-9 # the retune
|
||||
fresh = SignalTracker(cfg)
|
||||
fresh.load_dict(saved)
|
||||
assert fresh.filters["temperature"].q == 1.0e-9, \
|
||||
"the state file overrode the configured tuning"
|
||||
# the estimate itself must still be carried across
|
||||
assert fresh.filters["temperature"].initialised
|
||||
assert fresh.filters["temperature"].x[0] == pytest.approx(
|
||||
old.filters["temperature"].x[0])
|
||||
|
||||
Reference in New Issue
Block a user