固定 HHD 下采样并标记三轴力单位

避免运行中改变 HHD 测量配置,并明确部分标定时各轴单位。已通过 SDK 与共享层测试。
This commit is contained in:
ykcheungab
2026-10-05 12:56:29 +08:00
parent 80f7da5a20
commit 38d3e67b00
4 changed files with 74 additions and 36 deletions
+32 -19
View File
@@ -1144,7 +1144,6 @@ class Sensor:
lowpass_enabled=None,
flow_ema_alpha=None,
force_median_window=None,
hhd_downsample=None,
):
"""Update runtime-safe settings without reconnecting the camera.
@@ -1167,9 +1166,18 @@ class Sensor:
force_median_window : int, optional
Causal sliding-median width applied to the raw force triple before
the low-pass. ``<= 1`` disables it; 3 is the default.
hhd_downsample : int, optional
Integer ``>= 1``. Rebuilds the HHD solver on the next frame.
"""
if flow_ema_alpha is not None:
alpha = float(flow_ema_alpha)
if not (0.0 < alpha <= 1.0):
raise ValueError("flow_ema_alpha must be in (0, 1]")
if self.calibration is not None:
mismatches, _ = cal_mod.filter_mismatches(
self.calibration.pipeline.get("filters"),
{"measurement": {"flow_ema_alpha": alpha}},
)
if mismatches:
raise cal_mod.CalibrationError("; ".join(mismatches))
filter_changed = False
if lowpass_cutoff_hz is not None:
self._lowpass_cutoff_hz = float(lowpass_cutoff_hz)
@@ -1209,9 +1217,6 @@ class Sensor:
filter_changed = True
if flow_ema_alpha is not None:
alpha = float(flow_ema_alpha)
if not (0.0 < alpha <= 1.0):
raise ValueError("flow_ema_alpha must be in (0, 1]")
self._flow_ema_alpha = alpha
self._ema_flow = None
@@ -1234,17 +1239,6 @@ class Sensor:
if self.compute_deformation_valid:
self._apply_force_filter()
if hhd_downsample is not None:
try:
k = max(1, int(hhd_downsample))
except (TypeError, ValueError) as exc:
raise ValueError("hhd_downsample must be an integer >= 1") from exc
if k != self._hhd_downsample:
self._hhd_downsample = k
self.__hhd = None
self._hhd_grid_shape = None
self._hhd_ref_shape = None
self._update_hhd_mask_cache()
return self
def _bundle_name_candidates(self) -> list[str]:
@@ -1381,7 +1375,11 @@ class Sensor:
"stitch_resolution": camera.get("resolution_stitch"),
"dis_mode": tracker.get("dis_mode"),
"hhd_downsample": tracker.get("hhd_downsample"),
"filters": cal_mod.filters_fingerprint(self._config.get("filters")),
"filters": cal_mod.filters_fingerprint(
self.filters_state()
if hasattr(self, "_flow_ema_alpha")
else self._config.get("filters")
),
}
@property
@@ -1393,6 +1391,22 @@ class Sensor:
def force_unit(self) -> str:
return "N" if self.force_calibrated else "raw"
@property
def calibrated_axes(self) -> tuple[str, ...]:
"""Axes with a loaded force-calibration curve."""
channels = self.calibration.channels if self.calibration is not None else {}
return tuple(axis for axis in cal_mod.CHANNEL_IDS if axis in channels)
@property
def force_units(self) -> tuple[str, str, str]:
"""Units of FN, FX and FY in that order."""
axes = self.calibrated_axes
return (
"N" if "fn" in axes else "raw",
"N" if "fx" in axes else "raw",
"N" if "fy" in axes else "raw",
)
def set_calibration(
self,
cal: "cal_mod.Calibration | str | Path | None",
@@ -1481,7 +1495,6 @@ class Sensor:
"measurement": {
"flow_ema_alpha": float(self._flow_ema_alpha),
"flow_ema_applied": bool(self._flow_ema_alpha < 1.0),
"hhd_downsample": int(getattr(self, "hhd_downsample", 0) or 0),
"dis_mode": tracker_cfg.get("dis_mode"),
},
"readout": {