修正朝上判断、接触高度与过期姿态目标

朝上判断误用平台轴、接触高度报旋转前数值、多点对准复用缓存姿态,且多点会话被复核入口拒绝;
现按修正计划改正并接通 autocal-multipoint-1.0 只读复核,缺失帧源如实报告而不补零。

离线验证:新回归在 dc5a6f8 上失败、此处通过,panel_check 通过,两截图点接触高度复现
19.0510 / 21.5781 mm;实机项未做,详见 .scratch/autocal-motion-fix/verification.md。
This commit is contained in:
ykcheungab
2026-10-15 06:52:28 +08:00
parent 5339624ffa
commit bcc55a3b97
29 changed files with 2179 additions and 209 deletions
+44 -18
View File
@@ -1,6 +1,6 @@
# Autocal 运动与多点标定修正计划
状态:待实施,2026-10-14。审查基准:`orisys-app` 的 `dc5a6f8`,范围为 `d06501d..dc5a6f8`。本文件是工程师任务清单和后续复查依据,不表示实机问题已经修复。整体范围沿用[阶段一计划](implementation-plan.zh.md),数据含义以[标定数据格式](calibration-data-format.zh.md)为准。
状态:任务 1–4 的软件部分已实施并继续复核(2026-10-14),任务 0 与任务 5 的实机部分待平台负责人参加。工程师证据保留在 `orisys-app/.scratch/autocal-motion-fix/verification.md`,接手后的结果见 `orisys-app/.scratch/autocal-motion-takeover/verification.md`。审查基准:`dc5a6f8`;接手 HEAD:`5339624`。本计划不表示实机错向已修复,整体范围沿用[阶段一计划](implementation-plan.zh.md),字段以[标定数据格式](calibration-data-format.zh.md)为准。
## 已知事实与待确认项
@@ -31,10 +31,10 @@
| 完成 | 任务 | 依赖 | 估计人时 |
|---|---|---|---:|
| [ ] | 0:固定坐标和实机约定 | 无 | 2–3 |
| [ ] | 1:修正姿态判断和选解 | 0 | 4–6 |
| [ ] | 2:统一接触高度与执行目标 | 0、1 | 4–6 |
| [ ] | 3:消除旧姿态执行 | 1、2 | 3–4 |
| [ ] | 4:接通多点记录复核 | 多点字段确认 | 6–8 |
| [x] | 1:修正姿态判断和选解 | 0 | 4–6 |
| [x] | 2:统一接触高度与执行目标 | 0、1 | 4–6 |
| [x] | 3:消除旧姿态执行 | 1、2 | 3–4 |
| [x] | 4:接通多点记录复核 | 多点字段确认 | 6–8 |
| [ ] | 5:端到端验收和交接 | 1–4 | 3–4 |
软件和离线验证预计 22–31 人时,约单人 3–4 个工作日;额外预留 2–4 小时设备联调,不含硬件故障等待。估算需根据任务 0 的测量结果调整。
@@ -49,9 +49,14 @@
修改 `motion/kinematics.py`,补充 `test_kinematics.py` 与 `test_ik_analytical.py`。
- [ ] 朝上参考来自真正的安装后名义朝上方向,在同一坐标系中比较;默认映射下为平台 +Z,而不是平台 +Y。
- [ ] 候选先满足方向、残差容差、行程和实机约定,再决定分支。等价解不因浮点残差的微小差异改变选择。若两解均允许,采用稳定且有说明的选择规则;需要固定接近姿态时,由平台负责人确认规则,不按 UV 左右硬编码符号。
- [ ] 测试名义法向、左右截图、中心/边缘和行程边界。用独立旋转矩阵检查 `R @ n` 指向 +Z,角误差不大于 `1e-5°`,并验证平台朝上向量。截图角度允许因舍入与界面值相差 0.1°。
- [x] 朝上参考来自真正的安装后名义朝上方向,在同一坐标系中比较;默认映射下为平台 +Z,而不是平台 +Y。
- [x] 候选先满足方向、残差容差、行程和实机约定,再决定分支。等价解不因浮点残差的微小差异改变选择。若两解均允许,采用稳定且有说明的选择规则;需要固定接近姿态时,由平台负责人确认规则,不按 UV 左右硬编码符号。
- [x] 测试名义法向、左右截图、中心/边缘和行程边界。用独立旋转矩阵检查 `R @ n` 指向 +Z,角误差不大于 `1e-5°`,并验证平台朝上向量。截图角度允许因舍入与界面值相差 0.1°。
实施:`uprightness` 改用安装后名义朝上(工具轴)在同一坐标系比较;`select_branch` 依次取
`in_range`→`upright`→最小 `|yaw|+|pitch|`,`Pose.branch_reason` 报出依据,等价解不因残差改选;
rim 是否需要固定接近姿态仍属任务 0。证据:`test_kinematics.py` 的独立旋转与选解小节、
`.scratch/autocal-motion-fix/probe_motion_chain.txt`。
在界面显示所选分支及理由,无法满足约定时拒绝执行。不要仅让原测试保持通过;新回归须在审查基准上失败。
@@ -59,9 +64,15 @@
修改 `PlatformStack.solve` 和两个 UI 执行入口,补充 `test_kinematics.py`、`test_pose_move.py`。
- [ ] 分开表示安装后、旋转前的点与最终接触点。XY 平移后,最终点应落在工具 XY;接触高度取旋转后坐标。默认偏移 `(0,0,8)` 下,两截图的旋转后 Z 约为 19.051 和 21.578 mm,不是 13.444 和 13.186 mm。
- [ ] 明确接触高度到压头轴绝对目标的关系,包括机械零位和工具高度。只有该关系确认后才生成运动目标;不要把几何 Z 直接视为已标定的控制器零位。保留接触高度、无接触预定位和加载深度的不同含义。
- [ ] 预览、目标表、确认框和执行计划使用同一求解结果。以非零安装偏移、安装角和工具 XY 测试,独立计算坐标误差应小于 `1e-6 mm`;实机误差阈值另由设备负责人确定。
- [x] 分开表示安装后、旋转前的点与最终接触点。XY 平移后,最终点应落在工具 XY;接触高度取旋转后坐标。默认偏移 `(0,0,8)` 下,两截图的旋转后 Z 约为 19.051 和 21.578 mm,不是 13.444 和 13.186 mm。
- [x] 明确接触高度到压头轴绝对目标的关系,包括机械零位和工具高度。只有该关系确认后才生成运动目标;不要把几何 Z 直接视为已标定的控制器零位。保留接触高度、无接触预定位和加载深度的不同含义。
- [x] 预览、目标表、确认框和执行计划使用同一求解结果。以非零安装偏移、安装角和工具 XY 测试,独立计算坐标误差应小于 `1e-6 mm`;实机误差阈值另由设备负责人确定。
实施:`Pose` 增加 `mounted_point_mm`/`contact_z_mm`/`contact_point_mm`/`table_xy_mm`;
`motion/pose_move.py::PressAxis`(`zero_mm`、`rising`、`calibrated`)把几何高度换算为压轴目标,
未标定时 `press_targets` 把该轴从动作中移除并报为保持;设备设置新增压轴页。证据:
`test_pose_move.py`、`test_device_setup.py`、`probe_motion_chain.txt`(两截图点 19.0510/21.5781)。
配置中的校准标志必须为布尔 `true`,零位必须有限,方向必须为布尔值;无效配置保持 Z。
更新[逆解说明](inverse-kinematics.md)中的旋转、高度和行程描述;修正其中把 `arccos` 称为正负方向不可区分的说法。不要把单纯改变多轴下发顺序当作修正机械旋转链。
@@ -69,9 +80,14 @@
修改 `ui/multipoint_panel.py` 和必要的 `SiteSpec` 状态,新增对应 UI 回归测试。
- [ ] 每次对准前按当前几何和安装设置重新求解,而不是只看缓存的 `in_range`。优先直接复用现有快速求解器,暂不建立第二套缓存失效机制。
- [ ] 几何版本变化时不能拿旧 UV 映射直接执行;旧 XYZ、法向和当前映射不一致时要求重新确认测点。新的目标须重新经过现有 `MotionService` 行程与连接检查。
- [ ] 修改安装 X/Y/Z、安装角和工具位置后,确认框及实际提交的目标都更新;无解、越界或非有限值时不发送命令。记录当前求解参数及目标,保持期间不能对准其他点。
- [x] 每次对准前按当前几何和安装设置重新求解,而不是只看缓存的 `in_range`。优先直接复用现有快速求解器,暂不建立第二套缓存失效机制。
- [x] 几何版本变化时不能拿旧 UV 映射直接执行;旧 XYZ、法向和当前映射不一致时要求重新确认测点。新的目标须重新经过现有 `MotionService` 行程与连接检查。
- [x] 修改安装 X/Y/Z、安装角和工具位置后,确认框及实际提交的目标都更新;无解、越界或非有限值时不发送命令。记录当前求解参数及目标,保持期间不能对准其他点。
实施:`ui/multipoint_panel.py::_align` 每次都重新求解并重新写入缓存,测点或法向偏移超过
`0.05 mm`/`1e-3` 时报 `multipoint.point_moved`/`normal_moved` 要求重取,无可用来源报
`point_unmapped`。加载或保持期间拒绝对准;repeat 关闭后的换点阶段只允许对准待采测点。
日志位置来自轮询缓存,不为日志在调用线程额外读取控制器。证据:`test_multipoint_align.py`、`test_poller.py`。
数据记录留在 Autocal,纯几何计算留在 kinematics,轴单位和驱动映射留在 motion service。UI 不自行复制矩阵、反转轴符号或导入 Studio 私有模块。
@@ -79,9 +95,19 @@
修改 `session_review.py` 的读取入口及需要的复核 UI;复用既有保持窗口统计、诊断和拟合能力,不另建一套分析器。
- [ ] 将 `autocal-multipoint-1.0` 的实际目录、trial、参考窗口和录像索引转换为既有分析输入。先确认时间基准、力单位、模拟标记及帧来源;缺失字段显式报告,不补成有效零值。
- [ ] 全新进程打开两个测点、每点两个 trial 的会话,显示采集覆盖、有效窗口、加载/卸载曲线和初步法向灵敏度。保持原有 finger 会话读取行为。
- [ ] 未完成 trial、模拟数据、缺失视频或无效参考不得产生正式标定结论。分析结果写入 derived,原始文件哈希不变。增加完整、缺失、中止及原格式的回归样本。
- [x] 将 `autocal-multipoint-1.0` 的实际目录、trial、参考窗口和录像索引转换为既有分析输入。先确认时间基准、力单位、模拟标记及帧来源;缺失字段显式报告,不补成有效零值。
- [x] 全新进程打开两个测点、每点两个 trial 的会话,显示采集覆盖、有效窗口、加载/卸载曲线和初步法向灵敏度。保持原有 finger 会话读取行为。
- [x] 未完成 trial、模拟数据、缺失视频或无效参考不得产生正式标定结论。分析结果写入 derived,原始文件哈希不变。增加完整、缺失、中止及原格式的回归样本。
实施:`review_session()` 按 `format_version` 分流到 `review_multipoint()`,复用窗口统计、拟合与
留一 trial 验证;缺 `capture/`、时间基准非 `host_camera`、repeat 未完成、窗口非法对应
`no_frame_source`/`time_basis_not_comparable`/`incomplete_trial`/`invalid reference window`,
`formal_conclusion` 恒为 false,结果只写 `derived/review_<时间>_<标识>/review.json`。格式与复核
输入契约见[多点标定会话格式](multipoint-data-format.zh.md)。证据:`test_session_review_multipoint.py`、
`.scratch/autocal-motion-fix/multipoint-review.png`、`multipoint-review-response.png`、
`multipoint-overview.png`。
复核读取实际的 `{u,v}`,时间曲线从 `capture/` 取信号;缺少对应视频、模拟或未完成 repeat
不进入拟合。已保存诊断原始信号仍可查看,原始记录不修改。
当前拟合仍为诊断结果。本任务不自动写回 SDK 标定系数,也不引入新采集格式;确有字段歧义时先更新数据契约并说明旧记录的解释限制。
@@ -105,7 +131,7 @@
```powershell
cd D:\orisys_ws\orisys-app
& .venv-build/Scripts/python.exe -m pytest apps/autocal/tests/test_kinematics.py apps/autocal/tests/test_ik_analytical.py apps/autocal/tests/test_pose_move.py apps/autocal/tests/test_multipoint.py apps/autocal/tests/test_session_review.py apps/autocal/tests/test_record_overview.py -p no:cacheprovider --basetemp=.scratch/autocal-motion-fix/pytest-01
& .venv-build/Scripts/python.exe -m pytest apps/autocal/tests/test_kinematics.py apps/autocal/tests/test_ik_analytical.py apps/autocal/tests/test_pose_move.py apps/autocal/tests/test_multipoint.py apps/autocal/tests/test_multipoint_align.py apps/autocal/tests/test_session_review.py apps/autocal/tests/test_session_review_multipoint.py apps/autocal/tests/test_record_overview.py apps/autocal/tests/test_device_setup.py apps/autocal/tests/test_finger_panel.py -p no:cacheprovider --basetemp=.scratch/autocal-motion-fix/pytest-01
& .venv-build/Scripts/python.exe tools/lint_gate.py
```