Files
orisys-sdk/docs/force-workflow.zh.md
T
ykcheungab ee830d8505 新增统一力读数会话 ForceSession
把同帧测量、空载归零、模型推断与共用后处理收进一个 SDK 会话,Studio 显示与记录使用同一样本;旧 Sensor 读数接口保持兼容。以 force session 与受影响 SDK 套件、lint 与文档门禁验证,硬件与真实载荷精度未验证。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpCfJF6SvonMKmPZhzKZHb
2026-10-20 07:07:22 +00:00

5.9 KiB
Raw Blame History

力读数工作流(ForceSession)

用途:SDK 显式力读数会话(studio-force/1)的公共接口参考。状态:已实现并接入 Studio,2026-10-20; 硬件、真实相机与真实载荷精度未验证。需求与验收矩阵见 流程规格,实施状态见 重写计划。

测量、标定模型、空载基线与输出后处理全部由本会话拥有;调用方只提供源帧与帧身份, 发送归零/换模型请求,并分发返回的 ForceOutput。这样同一帧只测量、推断、后处理各一次, 显示与记录拿到同一个不可变输出。

入口与版本

from orisys import ForceSession, WORKFLOW_VERSION

WORKFLOW_VERSION = "studio-force/1" 是处理顺序与语义的稳定身份,随每个输出返回, 记录、缓存键与诊断引用它;改变顺序或语义时必须提升该版本。

构造显式启用测量源(Sensor 或 FingerRuntime)的会话接缝:

session = ForceSession(
    source=runtime,              # 已打开、由调用方负责 close
    sensor_family="finger",      # box | mini | finger | finger-mems
    device_id="FINGER-001",      # 可选,用于标定身份校验
    context=context,             # schema 3 模型需要的实际管线身份
    calibration=model,           # Calibration(schema 1/2)、ModelCalibration(schema 3)或 None
    settings=output_settings,    # 可选;默认 OutputSettings(sample_rate_hz=30.0)
)

构造失败不会留下“半切换”的会话;旧 Sensor.read_info / ForceReadout.apply 路径在 未构造 ForceSession 时保持原语义,本模块不与旧路径并行运行。

主要方法与属性

成员 说明
process_frame(source_frame, stamp) -> ForceOutput 唯一逐帧入口:测量 → 归零状态 → 标定 → 后处理。同一 (session_id, frame_id) 重复调用返回同一缓存对象且不推进状态;乱序帧显式失败并清除完成标志
read_sdk_frame(source_frame, stamp) -> SdkReading 只做同帧测量(图像准备、光流/HHD、可选接触/场),不推断、不读数滤波
request_zero(*, reference_id, declared_unloaded, replay_window=None) -> ZeroProgress 启动唯一空载归零操作;declared_unloaded 必须为空载确认;拒绝带载相对置零
update_zero(reading) -> ZeroProgress 推进归零状态机并执行本帧一次模型推断;迟到代次的结果被忽略
invalidate(*, reason) -> ZeroProgress 断流、取消、换模型或测量配置变化时作废基线/完成状态与滤波历史
apply_calibration(reading, zero) -> CalibratedReading 不复用旧结果、不重复推断,给出未做读数滤波的 raw/N 与逐轴状态
apply_filter(measurement) -> ForceOutput 唯一后处理:raw 与 N 各自独立地 median → low-pass → 可关闭逐轴阈值
set_calibration(calibration, *, context=None) 帧边界原子换模型;校验失败保留原模型、基线与完成状态
zero、calibration_fingerprint、output_settings、last_output 只读状态/身份;output_settings 是实际生效参数

帧身份

FrameStamp(session_id, frame_id, source_frame_id, signal_time_s, time_basis);后处理低通的 采样率来自信号时间,不取离线处理耗时。实时与顺序录像只替换源适配器,其余流程相同。

归零(空载基线)

  1. request_zero(declared_unloaded=True, reference_id=...) 只登记请求并递增参考代次;
  2. 处理线程在下一个帧边界重置 tracker,然后才测量该帧;
  3. 采集重置后连续 30 个有效处理帧,按模型类型得到基线:标量模型取 raw 中位数, 场模型委托 ModelCalibration 用同一增益图加权后的 30 帧中位数;
  4. 第 30 帧仍为基线帧;第 31 帧起 phase="ready"、completed=True 并输出 N, effective_from_frame_id 指向该帧。

基线未完成、无效帧、窗口不足或已取消时 N 为 NaN、状态显式;窗口不足不越界补帧。 录像重算用 replay_window=(start, end) 在声明区间执行同一操作。

后处理与有效设置

OutputSettings(sample_rate_hz, median_window=1, lowpass_hz=0.0, lowpass_order=2, raw_threshold=0.0, newton_threshold=0.0)。每阶段由自身值关闭(median=1、lowpass=0、 threshold=0),全关时对有效值严格直通(NaN 保留);无效轴不进入滤波历史。 ForceOutput.settings 返回实际生效的参数(例如截止频率达到 Nyquist 时解析为 off)。

离线重滤波

from orisys.force_readout import process_output_sequence

raw_out, newton_out, effective = process_output_sequence(
    settings, raw_samples, newton_samples,
    raw_valid=None, newton_valid=None, signal_times_s=times,
)

该函数只重放输出级(带完整 warm-up),用于从已存未滤波序列生成新参数下的最终输出; 不重新测量、不打开模型链。

状态与诊断

逐轴状态:ok、out_of_range、zero_unavailable、no_contact、coordinate_unmapped、 outside_coverage、invalid_input、uncalibrated、measurement_failed、frame_order、 signal_time_order。仅 ok/out_of_range 携带可用牛顿值;模型不输出的轴(例如 FN-only 模型的 FX/FY)恒为 NaN + uncalibrated。缺失值与有效零分开。

CalibratedReading.diagnostics 提供 reference_id、baseline_N、baseline_raw_fn/fx/fy、 model_fingerprint、mapping、extrapolated_fraction、coverage_fraction、area_scale、 pending_reference_frames 等;调用方存储或展示,不据此改写逐轴有效性。

场模型质量(外推、覆盖)与 downsample 差异属于诊断,不替代有效性判断; hhd_downsample 不同是唯一允许的管线身份差异,其余差异仍拒绝并报告。