将场加权标定模型接入回放分析

回放按声明的 30 帧加权空载窗口取基线并逐帧保存外推质量,field 模型单独进缓存键,实时入口拒绝。
新增测试覆盖窗口、质量与拒绝路径。全量门禁的 scene3d 两项失败与 studio 访问冲突为既有问题,
已归因并另立 studio-gate-hang。
This commit is contained in:
ykcheungab
2026-10-19 19:49:36 +08:00
parent 81063213f9
commit c1e6d21030
14 changed files with 1462 additions and 23 deletions
@@ -10,6 +10,8 @@ from __future__ import annotations
import math
import pytest
from orisys_app_shared.analysis.model import ALGORITHM_VERSION, ForceSample
from orisys_app_shared.analysis.service import AnalysisService
@@ -97,3 +99,45 @@ def test_results_stored_under_the_old_validity_rule_are_not_served():
# Version 1 marked every frame invalid when the model lacked a zero; the cache key
# carries this string, so those results must miss the cache and be recomputed.
assert ALGORITHM_VERSION != "flow-hhd-contact-1"
def test_extrapolated_fraction_is_quality_not_validity():
"""A field estimate's extrapolation is evidence about its support, not validity.
The SDK reports the field model's extrapolated/coverage fraction in
``calibration_diagnostics`` and keeps the per-axis status ``ok``; the app stores
the fractions as quality and must keep the newton value. Reading them as
invalidity would silently drop every experimental value.
"""
reading = _reading({"fn": "ok"}, normal=3.5)
reading["calibration_diagnostics"] = {
"extrapolated_fraction": 0.42,
"coverage_fraction": 0.9,
"baseline_N": 0.25,
"model_fingerprint": "f" * 64,
}
sample = ForceSample.from_reading(reading)
assert sample.normal == pytest.approx(3.5)
assert sample.valid
assert sample.diagnostics["extrapolated_fraction"] == pytest.approx(0.42)
assert sample.field_quality() == pytest.approx((0.42, 0.9))
# The force payload is unchanged by the new evidence: quality is stored in its
# own frame payload, so an older result and this one read the same force fields.
decoded = ForceSample.decode(sample.encode())
assert decoded.normal == pytest.approx(3.5)
assert decoded.diagnostics == {}
def test_a_baseline_wait_still_keeps_the_raw_measurement():
"""The first 30 declared frames are ``zero_unavailable``: raw, not newton."""
reading = _reading({"fn": "zero_unavailable"}, normal=float("nan"))
reading["calibration_diagnostics"] = {
"pending_reference_frames": 7,
"extrapolated_fraction": 0.35,
}
sample = ForceSample.from_reading(reading)
assert sample.valid
assert sample.raw() == (1234.0, -5.0, 7.0)
assert math.isnan(sample.normal)
assert sample.diagnostics["pending_reference_frames"] == 7