配置没写的滤波键等于"关",不再回落到会滤波的默认值 - What: DEFAULT_FORCE_MEDIAN_WINDOW 3 -> 1、DEFAULT_FLOW_EMA_ALPHA 0.5 -> 1.0(DEFAULT_FORCE_LOWPASS_HZ 本就是 0.0),并把注释改成"配置文件没写的键就是关,而不是我们觉得合理的那一档"——原因写在注释里:否则设备会去滤一个没人要求滤的测量,而文件里没有任何线索;实测的延迟/降噪数据保留在注释中,作为 balanced/low_noise 预设的依据。docs/filters.md 第 2 节增加"缺省 = 关"这一条并说明没有 filters 段的配置什么都不滤,预设表里 balanced 的用途由"默认建议"改为"建议起步档"(它不再是默认值)。examples/filters/README.md 补一句"整段删掉等价于 off"。tests/test_filter_presets.py 新增 test_a_config_with_no_filters_block_filters_nothing:把 box bundle 的 filters 段整段删掉后构造真实 Sensor,断言 filters_state() 报 ema 1.0 / median 1 / cutoff 0.0 且 any_stage_applied 为 False。 - Why: 上一版只把"非法值"改成回落到关,但"键根本不写"仍会走 DEFAULT_* 从而把 EMA 0.5 + 中值 3 打开——这与"配置自描述、文件说什么就跑什么、出厂默认全关"矛盾,且现实里存在大量没有 filters 段的手写配置(例如 _perf/cfg_res_280x300.json),它们会在无人察觉的情况下继续滤波。缺省开是这条链上最后一个隐藏默认值。 - Verification: 删掉 filters 段后实测 filters_state() = (1.0, 1, 0.0) 且 any_stage_applied=False,出厂 box/mini/finger 三份同样为全关;pytest tests/test_filter_presets.py + tests/test_calibration.py → 33 passed;SDK 全量 336 passed / 15 skipped(唯一失败仍是需要 1200 帧而样例只有 577 帧的 longrun 测试);app 侧 studio 85 项与 shared 142 项测试、ui_check 554 项检查在升级后的 0.5.2 下全绿。 - Not in this change: 出厂 bundle 的三个显式值未动(本来就全关);_perf 的两个校验脚本不在仓库内,已就地补上显式 filters 段(balanced)以保持"开 vs 关"对照仍有意义;app 侧 wrapper/齿轮/CSV 17 列未动。

This commit is contained in:
ykcheungab
2026-09-14 10:53:33 +08:00
parent ae5bf0c208
commit 11962cdc34
4 changed files with 50 additions and 10 deletions
+27
View File
@@ -10,6 +10,7 @@ when a copy stops matching them.
from __future__ import annotations
import json
import shutil
from pathlib import Path
import pytest
@@ -88,3 +89,29 @@ def test_shipped_bundles_report_all_off(bundle: str):
assert fp["measurement"] == {"flow_ema_alpha": 1.0}
assert fp["readout"]["force_median_window"] == 1
assert fp["readout"]["force_lowpass_cutoff_hz"] == 0.0
def test_a_config_with_no_filters_block_filters_nothing(tmp_path: Path):
"""Absence is off, not "the values we thought were sensible".
A key that is missing has to mean the stage is not running: otherwise a
device filters a measurement nobody asked for, and nothing in the file says
so. Callers with a hand-written config (an old customer file, a bench
script) rely on this.
"""
copy = tmp_path / "box"
shutil.copytree(REPO_ROOT / "sensors" / "box", copy)
path = copy / "sensor.json"
cfg = json.loads(path.read_text(encoding="utf-8"))
cfg.pop("filters", None)
path.write_text(json.dumps(cfg, indent=2), encoding="utf-8")
sensor = Sensor("external", config_name=str(path), verbose=False, backend="cpu")
try:
state = sensor.filters_state()
finally:
sensor.disconnect()
assert state["measurement"]["flow_ema_alpha"] == 1.0
assert state["readout"]["force_median_window"] == 1
assert state["readout"]["force_lowpass_cutoff_hz"] == 0.0
assert state["any_stage_applied"] is False