将场加权标定模型接入回放分析
回放按声明的 30 帧加权空载窗口取基线并逐帧保存外推质量,field 模型单独进缓存键,实时入口拒绝。 新增测试覆盖窗口、质量与拒绝路径。全量门禁的 scene3d 两项失败与 studio 访问冲突为既有问题, 已归因并另立 studio-gate-hang。
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user