明确 finger 阶段一手动标定与采集时间契约

将阶段一改为手动加载、记录和逐点灵敏度可视化的完整流程。文档门禁与示例 JSON 校验通过。
This commit is contained in:
ykcheungab
2026-10-11 11:55:14 +08:00
parent 0e34cbfcdb
commit 46c8c8cbf6
2 changed files with 60 additions and 138 deletions
+28 -38
View File
@@ -1,6 +1,6 @@
# Autocal 标定操作与数据格式草稿
状态:待评审,2026-10-11。用途:方案及操作指南。近期目标只针对 finger 传感器跑通多测点法向采集、保存和离线重算;下列操作是首版目标流程,尚非全部可执行的软件说明。
状态:待评审,2026-10-11。用途:方案及操作指南。阶段一只针对 finger,由操作员手动完成选点、设档、加载、记录和逐点灵敏度可视化;下列流程尚非全部可执行的软件说明。
## 范围与软件现状
@@ -12,17 +12,11 @@
| 参考 | 砝码或 50 N/2 N·m FT sensor,首版先接通一种 |
| 图像 | 一个完整测试事件一个连续视频,档位间不切段 |
| 调试输入 | 先用已有视频接通 finger 采集链;实时相机随后复用同一个 worker 和 `SdkPacket` 消费路径 |
| 交付 | 单个 session 能重新打开、追溯参考载荷并离线重算 |
| 交付 | 单个 session 能重新打开、追溯参考载荷,计算并显示不同测点的灵敏度 |
[LF606 规格书](references/lf606-d40-h18-4x-spec.pdf)量程表包含 50 N/2 N·m 档位,但图签为 200 N/8 N·m;实机以铭牌及标定证书核对。
| 功能 | 源码现状 | 首版需要补齐 |
|---|---|---|
| 设备设置、轴操作、测点姿态预览 | Autocal 已有对应模块 | 与采集事件关联 |
| `.oryseq` 导入导出 | 已有;见 [sequence-format.md](sequence-format.md) | 载荷循环由 trial 的 steps 表达,不假定旧序列已支持 |
| 自动执行、传感器及标定点页面 | 运行入口提示未实现,相关页面占位 | 最小事件控制和采集入口 |
| 图像、读数、事件记录 | Studio/shared 已有记录链 | 接入 Autocal,增加 trial/step、参考流及独立事件视频 |
| 新格式回放、拟合及导出 | 本文定义目标契约 | 关联校验与最小离线处理 |
现有模块与待接工作见[实施计划](implementation-plan.zh.md);旧 `.oryseq` 格式见 [sequence-format.md](sequence-format.md),其本身不包含下文的载荷循环。
## 操作员逐步流程
@@ -33,13 +27,13 @@
| 1. 建立会话 | 填写传感器 SN、gel ID、实验台、压头和参考设备;选保存位置 | 创建唯一 `session_id`;保存身份和配置快照 |
| 2. 检查设备 | 完成设备设置、回零及既定检查,核对相机和参考输入 | 状态可读;运动边界按既定流程确认 |
| 3. 确认测点 | 在有效 UV 区域选点,核对三维位置和姿态 | 分配 `site_id`,UV→3D 映射有效 |
| 4. 设置循环 | 选择载荷档位、保持时间及重复数;预览正反路径 | 保存 `load_levels_n`、`hold_s`、`repeats`;档位不超本次确认范围 |
| 4. 设置循环 | 定义加载范围、档位、保持时间和重复数,选择手动模式 | 保存计划;自动加载留到下一阶段 |
| 5. 建立基准 | 无接触时检查零载荷,保存参考图像和必要历史 | 保存归零/基准事件及 `baseline_id` |
| 6. 开始事件 | 到达确认的测点姿态后,在加载前启动记录 | 新建 `trial_id` 和视频;确认视频与参考记录正常后加载 |
| 7. 逐级加载 | 按路径到各目标档位并保持,标记实际到达时间 | 每档有 `step_id`、目标及实际参考力、分支和时间范围 |
| 7. 逐级加载 | 用现有手动控制或砝码到目标档位,确认实际到达并保持 | 每档有 `step_id`、目标及有效参考力、分支和时间范围 |
| 8. 逐级卸载 | 按相同档位下降到零,保留恢复过程 | 连续记录卸载分支;循环内不重新归零或重置图像基准 |
| 9. 结束/重复 | 检查恢复与记录状态,停止事件;重复或移到下一点 | 完成写入后标记状态;每次重复使用新 trial 和视频 |
| 10. 复核会话 | 重新打开文件,回放至少一个完整事件,检查档位对应关系 | 缺失、丢帧和中断可见;保留完整 trial 作独立验证 |
| 10. 计算与复核 | 重新打开会话,选择有效保持窗口,查看每点曲线及 UV 灵敏度图 | 显示加载/卸载差异、误差、无效原因;留完整 trial 独立验证 |
推荐路径为 `0 → F1 → F2 → Fmax → F2 → F1 → 0`,具体档位待定。逐级卸载提供与加载分支相同载荷的对照;各档采用相同保持规则。保持时间先支持 10–30 s 配置,人工选择分析窗口并记录原因;到时不自动等于稳定。异常时按既定流程停止,保留未完成记录,重测用新 trial。
@@ -62,31 +56,32 @@
| `session.json` | `format_version`、`session_id`、`sensor_type`、`input_source`、身份、配置快照、坐标定义、文件清单、sites、trials、状态 | 会话建立、事件完成及结束时 |
| `sequence.oryseq` | 实际使用的测点计划;遵循现有格式 | 开始采集前保存快照 |
| `video/<trial_id>.<ext>` | 算法入口图像、完整循环及恢复 | 每 trial 开始至结束 |
| `frames.csv` | `session_id`、`trial_id`、`frame_id`、`t_rel_s`、视频路径、段内帧号、丢帧标记 | 每帧 |
| `frames.csv` | `session_id`、`trial_id`、`frame_id`、`t_host_mono_ns`、`t_host_utc_ns`、`time_basis`、视频路径、帧号、丢帧标记 | 每帧,时间与帧身份同时绑定 |
| `baseline/` | 基准图像、初始状态或预录引用、`baseline_id` | 建立/重置基准时 |
| `reference.csv` | `trial_id`、`t_rel_s`、`clock_id`、实测力分量、有效性 | FT 自身采样频率;砝码方式可不生成此流 |
| `reference.csv` | `trial_id`、`sample_id`、`t_host_mono_ns`、`clock_id`、力、有效性、来源及延迟估计 | FT/ECAT 每个样本;砝码用事件和有效时段 |
| `motion.csv` | 时间、目标/反馈位姿、有效性 | 有实际反馈时保存;缺少反馈须注明 |
| `events.csv` | 时间、trial/step、事件类型、原因 | 到档、阶段切换、归零、异常及中断 |
| `derived/<processing_id>/` | 对齐样本、特征、拟合结果、验证指标和处理配置 | 离线处理;不覆盖原始文件 |
| `events.csv` | `t_host_mono_ns`、trial/step、事件类型、参考有效时段、原因 | 到档确认、阶段切换、归零、异常及中断 |
| `derived/<processing_id>/` | 逐点灵敏度表、加载/卸载曲线、误差、分析窗口和处理配置 | 分析时另存;不覆盖原始文件 |
| 参数归属 | 主要参数 | 单位/填写来源 |
|---|---|---|
| session 身份 | `sensor_sn`、`gel_id`、`bench_id`、`indenter_id`、`reference_source` | 操作员填写或设备读取 |
| session 采集 | 分辨率、像素格式、编码、版本、滤波与归零配置 | 软件快照;编码待实测确认 |
| 输入来源 | `input_source.kind` 为 `video` 或 `camera`;`value` 分别为视频路径或相机整数编号;视频另存文件哈希 | 传给同一 `FingerAcquisitionWorker.start`;来源文件与 trial 输出视频不可混淆 |
| session 时间 | 各流 `clock_id`、时间戳含义、偏移及同步误差 | 软件记录;不能按行号配对 |
| session 时间 | 同进程 `clock_id`、单调时钟原点、UTC 对照、时间来源、延迟及同步误差 | 电脑采集/接收时记录;不能按行号配对 |
| site | `site_id`、UV、三维位置、几何关联 | pixel/mm;软件映射 |
| trial | `trial_id`、`site_id`、重复编号、姿态、`baseline_id`、视频、起止时间、状态 | 软件分配并记录实际执行 |
| trial 计划 | `load_levels_n`、`hold_s`、`repeats` | N/s/次数;操作员设置 |
| step | `step_id`、`target_load_n`、`branch`、起止时间、`analysis_window_s` | N/会话相对秒;branch 为 load/unload/zero |
| step | `step_id`、`target_load_n`、`branch`、实际起止时刻、`analysis_window_s` | N/电脑单调时间;branch 为 load/unload/zero |
| step 砝码参考 | 质量、重力加速度、传力方向、有效时段及 `reference_load_n` | kg/m/s²/N;仅在传力条件成立时使用 m×g |
| 质量 | `valid`、`invalid_reason`、丢帧/中断状态 | 未知不补零;算法失败不等于图像不可用 |
| 逐点结果 | `site_id`、`gain_n_per_raw`、`sensitivity_raw_per_n`、有效档位数、误差及滞后 | 仅对有效独立参考与原始法向信号拟合;缺数据标无效 |
视频输入的现有 `SdkPacket.mono_t` 由帧号和配置帧率推算;相机输入使用采集期间的单调时钟。已检查的 DD02 示例视频约 20 fps,而配置为 30 fps;因此现有视频时间不能直接用于物理保持时长或 FT 对齐。P1 须读取来源视频的实际时间基准,核对配置帧率,并在不一致时拒绝时间对齐或明确标记失效。
实时采集以电脑收到**该帧**时的单调时间为主时间。采集线程需把 `t_host_mono_ns` 与帧序号、图像原子配对;记录器再保存 UTC 对照,处理结束时间不能代替采集时间。FT/ECAT 样本也在电脑收到时打同源时间戳,按时间关联,并记录可测得的延迟与失同步;低延迟不等于零延迟。砝码的人工到档时刻只定义有效区间,稳定窗口仍需检查。
两种输入都输出 `frame_id` 和 `raw_frame`,但不能把不同来源的时间戳当成同一物理时钟。离线视频若无同步的 FT/运动记录,只能验证图像链和文件关联。manifest 须保留来源路径、哈希、配置身份、配置/实际帧率及时间基准;正式会话还应保存现场取得的设备身份。
旧视频没有原始逐帧电脑时间时,重放取得的是本次解码时间,`time_basis=host_replay`;它可验证处理链,不能还原原实验与 FT 的同步。若视频附有原始帧时间则保留 `time_basis=original_recorded` 和原时钟身份。现有 finger worker 对视频按配置帧率推算 `mono_t`,且已检查的 DD02 视频约 20 fps、配置为 30 fps;实施时须停止把该推算值当采集时刻。manifest 保留来源路径、哈希、配置、媒体帧率及各时间基准。
P0 事件边界如下。`events.csv` 每行至少保存 `event_id`、`trial_id`、可为空的 `step_id`、`event_type`、`t_rel_s`、`clock_id` 和 `reason`。事件只记录已发生的事实,不以 UI 按钮时间冒充到档或写盘完成。P1/P2 用同一 `trial_id` 将视频帧、参考值和事件相连。
事件边界如下。`events.csv` 每行至少保存 `event_id`、`trial_id`、可为空的 `step_id`、`event_type`、`t_host_mono_ns`、`clock_id` 和 `reason`。操作员的确认时间和设备反馈时间分别标明来源;不得把按钮时刻冒充设备实际到档。所有流用 `trial_id` 与同源单调时间关联。
| 事件 | 触发与状态 |
|---|---|
@@ -98,7 +93,9 @@ P0 事件边界如下。`events.csv` 每行至少保存 `event_id`、`trial_id`
`session` 在所有 trial 完成并检查文件后才进入 `complete`;任何缺失必须保留 `incomplete` 与原因。每次重试使用新的 `trial_id`,不覆盖旧视频。
以下是目标 `session.json` 的最小示意,供 P1/P2 共用字段;`video/` 是本次 trial 的输出,不是 `input_source` 原文件。例子不代表写入器已经实现。
逐点灵敏度先用有效保持窗口中的 `normal_force_raw` 和独立参考力拟合 `F_ref = gain_n_per_raw × raw + offset_n`;`sensitivity_raw_per_n` 为非零斜率的倒数。每个测点单独保存拟合范围、有效档位数、误差和加载/卸载差异。原始通道缺失、参考无效或载荷档位不足时不生成看似有效的系数。界面显示各点散点/拟合曲线,并在 UV 测点图着色;阶段一不从稀疏点外推整面精度。
以下是目标 `session.json` 的最小示意,供记录与分析模块共用字段;`video/` 是本次 trial 的输出,不是 `input_source` 原文件。例子不代表写入器已经实现。
```json
{
@@ -109,7 +106,8 @@ P0 事件边界如下。`events.csv` 每行至少保存 `event_id`、`trial_id`
"kind": "video",
"value": "D:/samples/finger-input.mp4",
"sha256": "<待采集时计算>",
"clock_id": "video_frame_rate",
"clock_id": "host_replay",
"time_basis": "host_replay",
"configured_fps": 30.0,
"source_fps": 30.0
},
@@ -132,25 +130,16 @@ P0 事件边界如下。`events.csv` 每行至少保存 `event_id`、`trial_id`
## 软件数据流与责任
### 当前实际链路
| 链路 | 代码位置/输出 | 对 Autocal 的含义 |
|---|---|---|
| 运行请求 → 未实现提示 | [window.py](../src/orisys_autocal/ui/window.py) 的 `_on_run_requested` | 尚无自动采集循环 |
| 页面装配 → 占位页面 | [workspace.py](../src/orisys_autocal/ui/workspace.py) | 传感器、表面和标定点页尚未接通 |
| Studio 采集包 → 记录通道 | [recording.py](../../studio/src/orisys_studio/recording.py) 的 `RecordingChannel.on_packet` | 将采集包分发给会话存储、标定采样器及文件记录器 |
| 采集包 → 有界队列 → 写入线程 | [experiment.py](../../../shared/src/orisys_app_shared/record/experiment.py) | 当前写 session、forces、frames、events、分段 MP4 或 PNG;不能直接视为新格式已完成 |
### 首版待接通链路
### 阶段一待接通链路
| 顺序 | 输入 → 处理 → 输出 | 负责模块 |
|---|---|---|
| 1 | 操作员设置 + `.oryseq` → sites/载荷路径 → session 快照 | Autocal 会话与事件控制 |
| 1 | 操作员设测点/载荷路径,可选导入 `.oryseq` → session 快照 | Autocal 会话与事件控制 |
| 2 | UV + 固定映射 → mesh 位置 + 平台姿态 → site/trial | 几何及现有姿态计算能力 |
| 3 | 视频路径优先、相机编号随后 → 同一 `FingerAcquisitionWorker` → `SdkPacket` → trial 视频、帧索引 | 复用 shared 采集能力;Autocal 不导入 Studio 的 UI 或控制器 |
| 4 | FT/砝码 + 平台反馈 + 档位事件 → 带时间的数据流 | Autocal 参考输入及事件控制;与图像并行 |
| 3 | 视频路径先调试、相机随后 → 同一 finger 处理链;电脑采集时刻与帧绑定 → `SdkPacket`、trial 视频和索引 | SDK capture + shared worker;Autocal 不导入 Studio 的 UI 或控制器 |
| 4 | FT/ECAT 样本或砝码有效时段 + 手动控制反馈/确认 → 同源电脑时间流 | Autocal 参考输入及事件控制;与图像并行 |
| 5 | 事件结束 → 完成写入 + 完整性检查 → trial 状态 | 文件记录器及会话控制 |
| 6 | 视频解码 + 基准/配置 → SDK 特征重算;时间对齐参考 → 拟合/验证 | 离线处理,结果存 derived |
| 6 | 视频解码 + 基准/配置 → 原始信号;时间对齐参考 → 逐点拟合、误差和 UV 着色 | Autocal 分析与可视化;结果存 derived |
保留现有算法通道值时可沿用 `forces.csv`,但它不是独立参考力。业务层组织试验,SDK 负责图像算法,共享记录器负责文件写入;不让 SDK 依赖 Autocal UI。
@@ -162,5 +151,6 @@ P0 事件边界如下。`events.csv` 每行至少保存 `event_id`、`trial_id`
| 可回放 | 重新打开后能解码完整 trial,恢复处理状态并重算选定窗口 |
| 有效性 | 丢帧、参考缺失、中断及失败显式可见;原始记录不被重处理覆盖 |
| 最小验证 | 至少留出完整 trial,分别比较加载/卸载的法向误差;阈值待定 |
| 逐点呈现 | 多测点各有灵敏度、有效性、参考力—原始信号曲线;UV 图能定位差异 |
开跑前仍须确定载荷档位、轴方向及精确原点、参考采集与同步、视频编码和恢复窗口。先实测单 trial 的容量及丢帧,再估算整场存储。视频空档不承诺连续回放。空间模型、实时集成及长期可靠性验证后续再做;本流程不证明剪切或多接触精度。
开跑前仍须确定载荷档位、轴方向及精确原点、参考采集与同步、视频编码和恢复窗口。先实测单 trial 的容量及丢帧,再估算整场存储。视频空档不承诺连续回放。自动加载、空间模型及长期可靠性验证后续再做;本流程不证明剪切或多接触精度。
+32 -100
View File
@@ -1,116 +1,48 @@
# Autocal 最小标定流程实施计划
# Autocal finger 标定实施计划
状态:P0 契约和离线验证完成,2026-10-11;P1–P5 待实施。用途:方案。后续完整实施建议两个子代理;当前不启动代理或设备动作。需求以[操作与数据格式草稿](calibration-data-format.zh.md)为准。
状态:2026-10-11 修订。用途:方案。阶段一的交付改为操作员手动控制完成整条标定流程;现有 P0 只验证了视频进入 finger 采集链,尚未实现会话记录或灵敏度页面。操作与文件字段以[数据格式草稿](calibration-data-format.zh.md)为准。
## 首版边界
## 阶段一目标
| 交付 | 首版选择 |
操作员选择 finger 测点,设定法向加载范围和档位,在已有平台手动控制界面逐步移动或人工加砝码,标记实际到档时间。系统从加载前到卸载恢复持续记录图像、参考载荷、平台反馈和事件;结束后按测点计算灵敏度,展示曲线与空间分布,并能重新打开会话复核。阶段一不自动遍历测点或按载荷闭环运动。“自动执行”只作为以后可替换的动作来源,不改变记录和分析链。
| 边界 | 阶段一选择 |
|---|---|
| 采集对象 | 固定为 finger;先以视频文件输入验证,再用实时相机输入验证同一路径 |
| 测点 | 复用现有选择和姿态能力;UV pixel→3D mm,保存映射身份 |
| 参考输入 | 人工确认砝码档位,记录质量、传力条件及有效时段;FT 自动采集另估 |
| 载荷循环 | 操作员逐级加载卸载,软件记录到档、保持及恢复;暂不做闭环力控制 |
| 视频 | 输入视频用于无设备调试;每 trial 的输出视频独立连续,含必要预录/基准;编码必须通过本机回放验证 |
| 复核 | 重新打开 session,按 step 选择窗口,重算特征并对照参考载荷 |
| 验证 | 独立 trial 的法向拟合误差及加载卸载差异;不承诺未经验证的实时精度 |
| 传感器与坐标 | 仅 finger;UV pixel 与 mesh mm 同存,保存几何版本和测点姿态 |
| 加载 | 目标范围暂定 0–30 N;操作员确认档位并手动控制,加载与卸载保持同一 trial;不把范围当设备动作许可 |
| 参考 | 先用人工砝码/人工确认的有效时段跑通;ECAT 或 FT 有可用接口时接入同一时间与参考数据契约 |
| 视频 | 先用已有视频调试 `FingerAcquisitionWorker`;正式采集由相机进入同一 `SdkPacket`、记录和分析路径;每 trial 保存独立视频 |
| 结果 | 每个测点的参考力—原始法向信号曲线、拟合系数、有效点数、误差和加载/卸载差异;在 UV 测点图上着色,可切换测点看曲线 |
人工砝码方案依赖现有装夹能够实现有效法向传力;若实际只能用 FT,自动接口须提前纳入关键路径。0–30 N 是需求范围,不是已批准的设备动作上限。自动测点遍历、自动压入、复杂空间模型、实时部署及新安装包均不在首版。
## 时间与来源契约
## 现有基础及缺口
实时相机在电脑收到新帧时记录高精度单调时钟,时间戳须与**该帧身份**一起传递;`frames.csv` 记录采集时间,不用处理完成时间或配置帧率推算时间。另存 UTC 墙钟供外部追溯,时长和同进程流对齐用单调时钟。ECAT/FT 采样在电脑收到对应样本时使用相同时间基准,记录来源、采样序号、有效性及可测得的通信延迟。低延迟是待验证条件,不能省略时间戳或默认各流无偏移。
基线为 app `c98390ff4a09233d838be2c5698fa8b42e3c3eb6`。以下是源码审阅结论,尚未进行设备或吞吐测试。
`orisys-sdk` 的 `CaptureSource` 现在只在状态中保存 `last_frame_time`,不能保证后续读取时该值仍属于取到的帧;shared finger worker 的视频 `mono_t` 还按配置帧率推算。阶段一需在采集层把时间与帧序号原子配对,再传到 shared worker 和记录器,避免让 Autocal UI 修补时间。文件视频的电脑时间是**本次解码时间**,只用于调试运行过程;若输入没有原始逐帧采集时间,不能与原实验的 FT/运动流做物理同步。原视频的媒体时间与重放时间分别保存;重新录制的 trial 视频保留本次帧索引和时间。
| 位置 | 可复用 | 尚缺 |
|---|---|---|
| `apps/autocal/src/orisys_autocal/sequence_io.py` | `.oryseq` 校验与保存 | trial/step 载荷路径 |
| `sensor/export_bundle.py`、`sensor/uv_flat.py`、`motion/kinematics.py` | 几何、UV 与姿态能力;bundle 已有物理尺度处理 | 验证计算管线 UV 与预览映射、坐标尺度一致 |
| `shared/src/orisys_app_shared/acquisition/` | `FingerAcquisitionWorker.start` 接受视频路径或相机整数编号,两者经同一 finger 处理链输出 `SdkPacket` | Autocal 生命周期与最小预览接入;视频与相机分别验证时间基准 |
| `shared/.../record/experiment.py`、`video_writer.py` | 有界队列、后台写入、丢帧及错误处理 | 当前为滚动 MP4;事件视频、编码和新 manifest 不可直接视作已支持 |
| `apps/studio/src/orisys_studio/recording.py`、`replay_analysis.py` | 已有记录组织和回放经验 | Autocal 不应直接依赖 Studio 私有模块;需要时仅提取共同核心到 shared |
| Autocal `ui/window.py`、`ui/workspace.py` | 设备和页面装配 | 运行入口未实现,采集及标定点页占位 |
## 复用边界与实施顺序
原始 mesh 不应直接当作 mm;沿用 `SensorBundle.vertices_mm` 等经过验证的物理输出。SDK 只负责图像算法,Autocal 组织试验,shared 提供实际共用的采集/存储能力。
| 包 | 交付与验收 | 主要所有者 | 人时 |
|---|---|---|---:|
| M1 采集与时钟 | 视频/相机同一 finger worker;帧身份与电脑采集时间配对,来源和掉帧可见;针对两种输入测试 | SDK capture、shared acquisition | 8–12 |
| M2 会话记录 | `session/site/trial/step`、基准、每 trial 视频、帧/参考/事件索引;失败保留 incomplete,可重新打开 | Autocal 控制;shared record 仅提取真正共用的写入能力 | 12–18 |
| M3 手动操作 | 选点、设范围/档位、预览、开始、到档确认、卸载、结束/中止;沿用已有手动运动入口 | Autocal UI 与 motion | 10–14 |
| M4 灵敏度与图表 | 从有效保持窗口取原始法向信号和参考力,逐测点拟合;展示曲线、空间图、误差和滞后 | Autocal analysis/UI;优先复用 shared 的标定准备及拟合逻辑 | 8–12 |
| M5 集成验收 | 合成会话、旧消费者回归、视频重放、真实设备手动试验及操作指南核对 | 主代理集成 | 6–10 |
| 合计 | 可手动完成一次多点标定并复核结果 | 见下文 | 44–66 |
## 传感器控制复用与迁移
先实现 M1 的视频输入和带时间的数据包,再以同一包格式接相机;M2 记录器与 M3 手动 UI 可在接口固定后并行。M4 可先用合成 session 开发,但阶段一只有在真实记录上重新打开并计算逐测点结果才算完成。Studio 的 `SessionController`、widget 和 `RecordingCoordinator` 保留在 Studio;Autocal 直接复用 shared `FingerAcquisitionWorker`、`SdkPacket` 和 sink,不跨应用导入私有模块。只有出现两端实际共用的逻辑时才移到 shared;SDK 不依赖 UI。
Studio 从 `app_window._start_run` 读取选择、解析 config、设置滤波并调用 worker `start`;`SessionController` 注册采集 sink,按首帧、错误和停止更新状态;`RecordingCoordinator.on_packet` 把包送往内存会话、标定采样器和文件记录器。Autocal 首版只需其中的设备采集与保存路径。
主代理负责接口、M3 和集成;一名子代理负责 M1/M2,另一名负责 M4 与合成会话验证。建议总计主代理加两名子代理,约 4–6 个工程工作日并留设备联调时间;单人约 6–9 日。估算不包括设备、FT 协议或硬件等待。当前计划不启动子代理。
| Studio 入口/现有位置 | Autocal 处理 | 原因及验证 |
|---|---|---|
| `shared/sensors` 的 `scan_sensor_catalog`、`CatalogEntry` | 直接调用,保存选择的 config 路径及身份 | 目录解析本来由 shared 拥有;拒绝不可运行的条目 |
| `shared/acquisition` 的 `FingerAcquisitionWorker`、`SdkPacket`、`RecordSinkMixin` | 首版只实例化 finger worker;视频路径或相机整数编号均调用公开 `start/stop/latest/add_sink/remove_sink` | 同一采集算法、帧号和基准预录;验证各自时间基准、首帧、断流、停止后 sink 解绑 |
| `Studio/ui/sensor_picker.py` | 首版在 Autocal 用简短选择控件调用 shared catalog;不搬 Studio widget | widget 用 Studio 文案和状态栏布局;只有界面行为真正一致时再迁入共享 UI |
| `Studio/ui/sensor_dialog.py` | 留在 Studio | 绑定 Studio window、校准文件热应用和面板;Autocal 只需本次原始采集的配置 |
| `Studio/session_controller.py` | 留在 Studio;Autocal 写仅管理所选 worker 的薄协调器 | 类内有 `QTimer`、Studio 状态、双 worker、记录计数;整类移动会改变现有生命周期 |
| `Studio/recording.py` | 复用底层 `shared/record`,新建 Autocal trial 协调;不移动整个类 | 现有类含 Studio session store、力阈值和标定采样器,语义不同 |
| `Studio/session_metadata.py` 中 `capture_metadata`、`filter_metadata`、`video_fps` | 两端都需要时提取到 shared;Studio 保留兼容导入并验证输出相同 | 通用的设备事实可共享;Studio 偏好设置、显示和文案仍留本地 |
接线顺序:先用视频路径和 finger config 打开 worker;再接一个只入队的 packet sink,UI 从 `latest()` 取预览。相机接入时只替换输入值,不另建处理或记录分支。获得首帧后允许创建 trial,开始输出视频前取预录;结束时先停试验写入并等待完成报告,再停采集,关闭窗口前解绑 sink。若输入打开失败或写入失败,状态为失败,不能产生“已完成” trial。运动服务继续独立管理平台,采集协调器不下达运动命令。
只有当 Autocal 和 Studio 实际出现相同的 worker 生命周期代码时,才将这部分无 widget 逻辑抽到 `shared/acquisition`,两端改为调用同一实现;不为本次仅一个调用方预建框架。抽取须保留 Studio 的非阻塞停止、首帧才进入 running、reset 生效事件和 capture drop 计数。配对运行 Studio session/sensor catalog/recording 测试与 Autocal 生命周期测试。
## 工作包与估算
单位为工程人时,包含针对性测试和代码审查,不是代理运行时承诺。按现有环境可用、无设备通信等待、首版采用人工档位估算;各行不重复计算集成工作。
| 包 | 内容及可观察交付 | 负责人/写入范围 | 依赖 | 人时 |
|---|---|---|---|---:|
| P0 | 固定 finger schema、视频/相机共用 worker 契约、事件 API、时间原点、状态及示例 session;验证输入路径并检查输出编码 | 主代理:契约及现有 worker 的针对性验证 | 无 | 4–6 |
| P1 | 视频输入先接通单 worker 生命周期、来源帧率核对、基准/预录、trial 输出视频、CSV/manifest 写入、排空与失败状态;再以相机输入跑同一路径;必要时迁移元数据辅助函数 | A:shared acquisition/record、Autocal `sensor/` 采集服务、Studio 兼容导入及测试;不改 UI | P0 | 13–19 |
| P2 | session/site/trial/step 控制、人工载荷确认、阶段时间及状态约束 | B:Autocal 无 Qt 的标定控制及测试 | P0 | 8–12 |
| P3 | 最小会话表单、测点表、预览、开始/到档/结束/中止、状态显示 | 主代理:Autocal UI、配置及集成入口 | P0 后可用桩;实接 P1/P2 | 8–12 |
| P4 | 新格式读取、逐事件回放、基准恢复、窗口特征重算、最小拟合与误差表 | B:离线处理及测试;共享提取先协调 | P2;集成依赖 P1 样本 | 6–10 |
| P5 | 故障、旧消费者回归、GUI 流程、实际采集样本验收与交接 | 主代理集成,A/B 修复各自模块 | P1–P4 | 5–8 |
| 合计 | 最小可采集、可回放并离线复核 | 主代理 + A + B | 按下表排程 | 44–67 |
## 并行安排与代理数量
| 配置 | 预期软件交付窗口 | 取舍 |
|---|---|---|
| 主代理单独执行 | 约 6–9 个工作日 | 所有开发串行 |
| 主代理 + 1 子代理 | 约 5–7 个工作日 | 主代理承担控制、UI 和回放 |
| 主代理 + 2 子代理 | 约 4–5 个工作日,建议预留第 6 天联调 | 推荐;采集存储与事件控制并行 |
| 主代理 + 3 子代理 | 通常仍约 4–5 个工作日 | 第三个仅在后期做独立审查/故障验证 |
按每日 8 小时有效工程时间估算;AI 编码可能更快,硬件、人工采样和联调不会按代理数等比加速。最短两三天可以优先完成采集里程碑,但不能把未完成的重算验收称为完整交付。
| 阶段 | 主代理 | A | B | 出口 |
|---|---|---|---|---|
| 第 1 天 | P0,随后做 UI 骨架 | P1 编码及采集验证 | P2 控制及合成事件 | 契约冻结,单 trial 合成数据能保存 |
| 第 2 天 | P3 接通控制与记录 | P1 写入与错误路径 | P2 收尾,开始 P4 | 合成事件通过,界面能显示采集状态 |
| 第 3–5 天 | P5 操作流程及集成 | Studio 兼容回归与性能修复 | P4,留出 trial 验证 | 先达 G1 多事件采集,再达 G2 重算对照 |
| 预留第 6 天 | 实际设备联调和交接 | 定向修复 | 定向修复 | 关闭实机问题或明确未验证项 |
依赖为 `P0 → (P1 ∥ P2 ∥ P3骨架) → P3实接`,随后 P4/P5 完成闭环。具体设备可用时间会改变日程,不能把等待藏进人时。
## 并行接口与文件所有权
P0 先提供一份被各包共用的模型和合成数据,避免三个代理自行定义不同 schema。函数名称在实施时确定,不为假想插件建立框架。
| 边界 | 必须固定的输入/输出 |
|---|---|
| 控制 → 记录 | session/trial/step 身份、阶段事件、姿态和参考有效时段;记录器返回写入状态 |
| 采集 → 记录 | `SdkPacket`、帧身份、采集时刻、图像及有效性;sink 不执行 UI 或阻塞磁盘写入 |
| 记录 → 回放 | manifest、视频逐帧索引、基准、配置快照及缺失标记 |
| UI → 控制 | 操作请求;控制检查状态后返回结果,UI 不直接改 manifest |
A 独占新格式文件写入与 Autocal `sensor/` 采集服务,B 独占 Autocal `calibration/` 业务控制并产生事件;主代理独占 `window.py`、`workspace.py` 及契约公共声明。修改 shared 行为必须保持 Studio 默认格式和生命周期。原记录器若不能满足事件视频路径,通过兼容的公共入口扩展,不能以 UI 层移动录像文件来补救。
## 风险、增量与验收
| 项目 | 处理及增量 |
|---|---|
| FT 自动输入 | 未找到现成 LF606 接口;规格书不含采集器协议。确认接口、样例和设备后暂估另加 8–20 人时;协议开发或采购等待须重估 |
| 编码不可用或有损 | P0/P1 做实际编码解码检查;不能悄悄用普通 MP4替代无损要求。可先交演示录像,但 G2 重算精度仍待验证 |
| 有状态算法回放 | P1 保存基准及初始化历史,P4 独立比较重算结果;失败时定位状态缺口,不只比较导出系数 |
| 自动加载/运动 | 暂不纳入;需要控制策略、传力验证和独立运动验收,不能只增加一个循环按钮 |
## 阶段一验收和后续
| 检查 | 通过条件 |
|---|---|
| G1 采集 | 至少两个测点、每点两个 trial;每 trial 包含正反载荷档位,视频连续且身份唯一 |
| G2 重算 | 全新进程读取文件,恢复基准/历史,重算窗口并对齐独立参考;完整 trial 留出验证 |
| 故障 | 中止、磁盘写失败、丢帧、参考缺失、相机关闭可见;未写完不标完成 |
| 回归 | Autocal 现有测试、shared 记录/生命周期/回放测试、Studio 相关消费者通过;GUI 与硬件证据分别报告 |
| 完成 | 文档和 lint 门禁通过;实际编码吞吐、容量及误差有证据;缺失设备不报通过 |
| 操作闭环 | 操作员对至少两个 finger 测点完成选择、设档、手动加载/卸载、记录、结束;每点至少两个 trial |
| 时间与数据 | 每帧、参考样本和事件可按电脑采集时间关联;原始输入与 trial 输出可区分;缺失或失同步显式标记 |
| 分析与呈现 | 每点可见参考力—原始信号曲线、灵敏度和有效性;加载/卸载分别展示,跨点差异在 UV 图可见 |
| 恢复与故障 | 全新进程重开会话可复核结果;中断、写盘失败及无效参考不显示成有效系数 |
| 硬件 | 实际运动只在确认设备、行程/载荷边界及停机条件后执行,软件离线通过不等于实机通过 |
首版通过 G1/G2 后停止扩展。当前 `sensor_type` 固定为 finger。P0 已用假设备验证视频路径/相机编号经同一 worker 输出,并用现有 DD02 视频验证真实 SDK 处理链的首批帧;`mp4v` 在本机可写入及重新解码 30 帧。示例 session 与时间语义见数据格式草稿。该视频约 20 fps 而配置为 30 fps;P1 必须处理时间不一致,才可对齐参考力。尚未验证真实相机、长时写入及图像保真度;Autocal UI 与 trial 写入也尚未接通。参考方式及设备可用性决定是否把 FT 增量纳入后续关键路径。
阶段二再增加自动测点遍历或自动加载:它们复用阶段一的 trial、事件、采集和分析接口,只替换人工动作及到档确认来源。FT/ECAT 自动参考接入可按设备可用性单独排期;测量延迟与钟偏通过实测确认。剪切、复杂空间模型和实时部署不属于阶段一。