Files
linkerhand_retarget_ros2/src/linkerhand_calibration/O30_RIGHT_CALIBRATION.md
T
2026-09-22 23:17:15 +08:00

89 KiB
Raw Blame History

O30 右手:标定与原始 URDF 修正

入口为 calibrate_hand --config src/linkerhand_calibration/config/o30_right_product.yaml。 Profile 为 O30/right/o30_right_18/v1,20 个关节全部主动;原始 URDF 与外部 SDK 不被标定器改写。 当前产品配置绑定 2026-09-22 重新采集的 config/o30_three_camera_extrinsics_20260922_101452.yaml。 该外参的 SHA256 为 d28d3e8771f5bc20d4ca6c9bfd11977f26fefb8478d125a113c013fb7a208120; 三相机序列号及内参指纹均与现有文件一致。 软件测试包含合成数据和已记录的真实图像回归,不能作为整手现场精度报告。

当前默认:连续采集、离线联合求解、验收后修正 URDF

默认协议已切换为 raw_joint_2_plus_1。17 个任务各两轮训练加一轮独立验证, 不再执行旧的局部几何准备往返,不在采集中等待唯一父标签分支。 缺项队尾最多补采一次;硬件异常、反馈失联、参考移动仍保护停止。 归位后进行联合拟合、候选集合不确定度验收、第三轮冻结验证及最终文件检查。

首次新协议需要全手新采集和当前相机安装的实测光学核验:

ros2 run linkerhand_calibration calibrate_hand \
  --config src/linkerhand_calibration/config/o30_right_product.yaml \
  --no-resume --camera-optical-observations /绝对路径/optical_observations.json

完整实现、核验工具、断点条件和验收记录见 新协议说明。 软件合成验收已生成 JSON 和修正 URDF;没有更新实机 latest_passed,尚需新协议实测及姿态对照。

历史任务式采集说明(显式选择旧协议时适用)

2026-09-22:从头按每任务两轮训练+一轮验证采集

**历史实现边界(已被新默认入口替代):**下方旧入口的“两轮+验证”仍指扫描轮数,旧的逐级求解准备 动作尚未整体移除。现有小指延后求解采集已改为实际共三次完整往返,第一轮回程 保存参考观测,缺标签和硬件异常仍停止;该修改已通过虚拟运行测试,尚未实测。 不能把小指采集侧修改称为全手正式“采集→离线拟合→发布”已贯通,不能将原始 诊断记录改标为正式零位证据。下面命令也不是新采集优先链路的完成声明。

当时 O30 配置使用 taskwise_2_plus_1;旧 fixed 仅在显式选择时使用三轮训练+一轮验证。 新策略按每个任务连续完成训练 1、训练 2、独立验证,再进入下一个任务, 不先扫完整手、不自动补第三轮训练。内部验证轮编号仍为 3,不能当作训练数据。 17 个任务共 108 个方向/分段扫描单元(旧 fixed 为 144 个),不含必要归位与避让。 默认没有辅助侧摆或补采;先恢复整手基准,无名指侧摆基准为 127。

cd /home/lxp/projects/linkerhand_retarget_ros2
source /opt/ros/jazzy/setup.bash
source install/setup.bash
export ROS_DOMAIN_ID=99
ros2 run linkerhand_calibration calibrate_hand \
  --config src/linkerhand_calibration/config/o30_right_product.yaml \
  --no-resume

先加 --validate-only 可只检查配置而不启动硬件。实机运行前关闭 MVS 的相机连接, 确保只有一个控制者,保留安全运动空间。新计划/调度版本与旧断点隔离;相机已移动, 本次应使用 --no-resume,不能沿用旧几何证据。

上面的正式命令不启用辅助观测策略。正式 2+1 使用 capture_plan_v5 和 unified_schedule_v16_taskwise_bounded_recovery:任务首次准备遇到可恢复的几何 歧义时,将该任务及依赖它的任务整体移到队尾,先采其他独立任务,最多回访一次。 每任务仍按训练 0/1、验证 3 连续执行;已经开始扫描的任务不采用此重排。 回访仍失败则明确记录不可观测,跳过其尚未采集的依赖任务,完成其他任务并安全 归位后结束为 FAILED,保留数据且禁止拟合发布。缺失实时图像、参考变化、硬件异常 和数值求解超时仍走原有限恢复/暂停路径,不强选候选或无限重试。 回访预算随断点恢复,旧 v4/v15 调度不与新会话混用;两轮数据不能通过最终验收时也不会发布产物。 完整训练拟合、独立图像验证以及 JSON→URDF 一致性检查仍保留。

**现场限制:**旧基准下小指 MCP/PIP/DIP 的实验采集曾完成 18 个单元且零暂停; 但指令映射、候选不确定度和物理零位未通过正式验收,不能转成正式 JSON/URDF。 新基准下的完整实机 2+1 尚未验收, 以上命令不是“一次跑通”的保证。详见 本次稳定性分析。 下文关于四轮和 144 单元的描述指旧 fixed 策略。

正常摆放与固定基准

O30 使用 acquisition.fixed_reference_mode: stationary_image。机械手可正常摆放, 固定基准 ID0、ID3、ID16 可以正对各自相机;不再为获得唯一 PnP 法线而要求倾斜基准标签。 标签仍须平整、牢固、完整可见,手掌与相机在同次采集中保持固定。

固定基准的两个用途已分开:原始角点用于确认图像中的安装位置没有变化;计算转轴时使用 方向与相机一致的坐标系。该坐标系是明确的计算约定,不是对标签真实朝向的测量,原始两组 PnP 候选仍保留。坐标原点由至少十张静止图像的候选中心对称计算,仅改善数值条件; 结果回到公共坐标系后,不依赖选择哪一组固定标签法线。

运动 Tag 继续通过运动图像和已声明的串联几何约束判别转轴;固定坐标系不能消除运动 Tag 本身的不可观测性。图像质量、可观测性、三轮训练/第四轮独立验证以及最终 JSON/URDF 验收 保持原要求。固定基准当前角点相对冻结图像的 RMS 必须不超过 1.5 px,缺失或变化的图像不能 作为有效采样;全局超过 5 px、持续十帧的移位停机机制也保留。此实现不包含手掌晃动的动态补偿。

原始记录明确标记 stationary_image_reference、reference_frame_is_tag_pose: false, 保存初始图像、相机参数、坐标约定及内容指纹;准备、采集、文件回读均绑定同一参考。 调度版本为 unified_schedule_v11_stationary_image_reference_feedback_interleaved。 旧记录仍按原含义读取,不能作为这次新模式的断点混入;切换后应重新采集。

软件复核包含本次真实正面 ID0 角点、独立投影的转轴数据与采集/回读测试。 离线对照验证的是坐标变换不改变解算结果,不代表现场标定已通过。

当前范围与顺序:20 关节,四指侧摆最后

当前 scope.default_scope 为 full,共 17 个任务、108 个方向/分段扫描单元。顺序为:

  1. 拇指 roll、MCP、IP、yaw。
  2. 四指屈伸:小指、无名指、中指、食指,分别完成 MCP pitch、PIP、DIP。
  3. 四指侧摆 fingers_mcp_roll_front,先完成四指联动,再补足中指下半行程。

侧摆准备先恢复拇指及四指屈伸到既定基准,再执行侧摆归零路径。指令速度、避让、 图像质量、独立验证及停机门槛保持原要求。全部完成并通过验收后,才发布整手 JSON 和修正 URDF。

产品配置保留 resume_mode: passed 的历史恢复功能,但本次从头命令用 --no-resume 禁止恢复。 以下恢复说明以旧 fixed 会话为例,前提是配置、机械手、相机和标签安装位置均未变。 侧摆暂停后重新运行相同产品命令,直接复用前面采集检查已通过的 16 个任务(128 个扫描单元), 不再回放旧图像、不重新计算旧采样质量,也不复核已完成关节的零位。 未完成的侧摆会重新确认自己的四个零位并重跑整组;若侧摆整组也已通过,则直接复用。 准备阶段只执行当前设备就绪、必要归位和新图像采集;通信、故障、堵转保护与最终验收保持原要求。 未通过的侧摆不会发布为完整标定。需要完整恢复复核时,可将产品 resume_mode 改回 verify。

已通过模式的扫描样本和逐帧图像证据采用磁盘索引,导入时每批最多读取 64 条完整 记录;原始内容逐条绑定,源文件被改写时拒绝导入。零位和模型来源证据仍完整保留, 最终验收继续读取全部图像。20260919_213352 曾因整份断点展开导致内存压力并在 节点首条状态前超时;改用分批读取后,同一份 237,514 条记录实测准备耗时 29.26 秒, 峰值进程内存约 2.04 GiB,保留 88 个通过单元,下一任务为中指 PIP。

20260919_193652 已按此模式直接复用四个拇指任务的 32 个扫描单元,并进入小指 MCP。 当前小指 MCP 的 129 帧准备图像出现两组无法区分的姿态解,验证 RMS 分别为 0.578627 px 和 0.595443 px,程序按原门槛暂停;这不是拇指断点复核失败,未发布完整标定。 记录见该会话 passed_resume_attempt_summary.json。断点准备实测约 10.2 秒, 历史逐帧回放次数为 0;索引在实时回调开始前完成,导入仍分批持久化。

侧面 MCP 沿用正面已验证的解算流程

四指 MCP pitch 改用中节 Tag(ID4、6、8、10),与同指 PIP 共用;DIP 继续使用 中节→末节的相对观测。Tag 的实际安装链接保持原声明,MCP 扫描时 PIP/DIP 保持既定姿态, 中节 Tag 因而可以观测 MCP 运动。这与正面 ID1 同时观测 roll 和 MCP 的方式一致。 固定基准仍使用三机位通用的 stationary_image,候选仍由原有运动图像求解器判别。

对 20260919_193652 同时记录的 129 帧离线重放:末节 ID5 的两组解无法区分; 中节 ID4 的验证 RMS 为 0.360377 / 0.526887 px,校正后比较 p=0.0000062452, 满足原有 0.03 px 差异与 0.01 检验门槛。真实图像回归夹具为 test/fixtures/o30_side_mcp_observers.json.gz。这是准备阶段的验证,不代表四轮采集和最终 URDF 已验收。 其余三指采用相同观测结构,仍须各自通过现场图像检查。

四指 DIP 同时接入与拇指 IP 相同的 parent_reference 机制:使用本指 MCP pitch 在原零位建立的中节 Tag 姿态,以及本指 PIP 测得的 Tag—轴线关系;从原始 URDF 提取 PIP/DIP 平行轴与轴间距约束。两项来源都必须先通过各自的采集检查,DIP 的曲线 仍独立采集。这里只复核新任务所需的当前父 Tag 图像,不重新扫描 MCP/PIP。

恢复模型的固定图像参考按原模型身份保留:每个模型继续使用它建立时的坐标原点、 参考图像声明和哈希,用当前同帧固定 Tag 角点确认参考仍有效。新会话的固定参考 另行监测现场移动,不能替换旧模型的坐标声明;不同任务可以分别使用各自的参考。 同一帧的模型依赖链若声明互相冲突的固定参考,拒绝采样。恢复时只加载已通过的 不可变模型,不重放历史图像、不重新扫描已通过关节。当前角点缺失、移动或内参 变化仍会拒绝采样,保存的图像证据保留原参考,供最终产物回读验证。 父姿态模型、父关节轴线和共享 Tag 姿态统一通过 passed_pose_models_restored 记录绑定跨会话来源;记录必须匹配原模型哈希、证据身份、任务、观察代次和时间顺序。 缺少或篡改恢复记录时仍拒绝引用旧来源,不改写旧模型的观察代次。

20260919_202726 已通过 48 个扫描单元,暂停在 pinky_dip_side 父 Tag 检查。 test/fixtures/o30_resumed_parent_reference.json.gz 保存该次拒绝的十帧真实图像角点、 旧模型和两次固定参考:原逻辑复现 pose_image_motion_reference_binding_changed, 修正后可完成十帧父姿态检查及序列化回读。超时诊断改为显示当前参考关节的缺帧数 和实际 Tag 拒绝原因,不沿用上一关节的零位错误。本项离线回归不代表 DIP 实机采集 或整手 URDF 验收已完成。

本次没有增加辅助关节运动。已通过的拇指观测定义不变;Profile 哈希变化通过显式的 capture_observation_revision 派生断点记录,原始数据不改写。迁移只允许修改尚未取得 有效零位/扫描结果的观测项,保留已通过的 32 个拇指扫描单元,按 passed 模式恢复, 不重放旧图像或重新检查旧零位。小指 MCP 使用新观测重新准备和采集。 该次派生断点为 20260919_200132_observer_revision。 离线复核与迁移记录位于 calibration_output/O30_RIGHT_001/software_review_pinky_ambiguity/。

中指 DIP:已测父关节几何的误差传播

20260920_192330 中指 MCP/PIP 已通过 4 个扫描单元,DIP 仍因两候选不能区分 暂停。新增可显式选择的 observer_pose_policy: rigid_pair_v1:直接联合拟合既有 PIP 运动中、DIP 保持不动时的父子 Tag 原始角点。每帧父姿态是待估变量,旧父模型 仅用于初始化;通过消去逐帧姿态的 Schur 信息矩阵计算相对安装不确定度,不再重复 叠加仅属于旧父轴线模型的误差。既有父轴线传递仍保留自身误差预算和原几何边界。 独立训练/验证分组、候选检验、当前静止端点及最终发布门限保持不变。 此策略写入准备契约和 v2 observer 证据,正式回读会重算来源及受约束 DIP 模型; 缺来源不能回退成无约束结果。旧策略默认为 frozen_parent_v1,不改变历史证据含义。 已有真实数据离线回放得到相对安装约 0.391°/0.899 mm,DIP 留出误差约 0.350 px。 这些数字只证明该次已有图像可通过修复后的求解,不代表完整实机标定或产物已通过。 随后 20260920_195344 正式断点恢复复用了 MCP/PIP 的 4 个扫描单元, 中指 DIP 实机初始化通过,几何不确定度约 1.63°/1.05 mm,并进入正式双向扫描。 此处记录的是该关节的实机进展,整手独立验证与最终 JSON/URDF 尚需全部流程完成。 该会话随后完成 DIP 双向扫描,累计 6 个单元;拇指侧摆指令 223、反馈 189 时暂停。 停机后只读设备查询确认 thumb_roll: 执行器层判定堵转。 用户确认这是 O30 硬件问题,并明确要求断点恢复、已通过关节不再验证重标。 因此 staged 流程不再强制覆盖 resume_mode: passed 为 verify:已完整通过的访问 在原证据导入落盘后直接复用,审计记录声明安装不变及跳过现场零位复核;未完成访问、 后续训练和独立验证轮仍保留原检查。启动文件证据回读、重试预算和冻结训练边界继续生效。

用户随后指出应从食指恢复。核对确认 20260920_184615 已保留拇指、小指、无名指 20 个首轮通过单元;20260920_195344 新增中指 6 个。此前只沿用中指专项会话的 6 个单元造成多余拇指运动,已停止该次恢复。两份日志的受保护输入(除已审计的配置 差异)及固定基准一致,已通过关节的测量定义相同,且均未跨越冻结训练边界。 software_review_joined_resume/prepare_resume.py 保留原始记录字节并排除各来源的未通过 任务,生成 20260920_200951_joined_resume;原日志保持不变,来源哈希、原会话头与 基准完整写入审计。正式断点回读通过,保留 26 个单元,下一项为 index_mcp_pitch_side。 这些是首轮扫描通过记录,不能替代后续轮次及整手发布验收。

20260919_214048 已完成中指 PIP,累计保留 96 个通过单元;随后中指 DIP 初始化因图像误差暂停。检查发现,旧传递模型在拟合时把上一关节实测的轴线和 安装位置当作精确值,仅在拟合后追加来源不确定度。这会让测量误差变成无法调整的约束。

新模型 image_hinge_v4_uncertain_source_geometry 在来源记录的不确定度范围内 拟合当前轴向与轴间距,仍使用原始 URDF 的平行关系和距离。两个原始姿态候选分别拟合, 当前训练图像与验证图像保持分离;拟合后恢复完整几何自由度计算图像不确定度,再叠加 来源误差。1.5 px 图像门槛、3° / 3 mm 几何门槛及候选区分规则保持不变。 来源模型、来源误差与当前拟合误差均写入证据,回读检查来源绑定及约束范围。 旧版 v3 模型继续按原策略读取,不重写已通过单元,也不触发恢复时的旧图像重算。

对该次 129 帧真实准备图像离线重放,两候选验证 RMS 从 1.579 / 1.642 px 降至 0.215 / 0.220 px,最大单帧 RMS 从 2.820 / 2.885 px 降至 0.348 / 0.327 px。 但两种三维姿态仍不能可靠区分,结果仍为未通过,不能仅选取误差稍小的候选。 暂停提示 OBS-POSE-AMBIGUOUS-117 明确要求补充当前关节的独立观测;原样重复运动 不保证解决歧义。用户暂时不能调整 ID9,故本轮仅完成程序修复与离线验证,未启动硬件。 诊断和测试记录保存在 calibration_output/O30_RIGHT_001/software_review_middle_dip_transfer/。

修复后的 20260919_220723 恢复尝试使用 ROS_DOMAIN_ID=99,选中上述 96 单元断点, 但在初始基准恢复阶段暂停,尚未进入 DIP。346 帧记录显示无名指/小指 MCP 的指令 分别从 253/251 降到 155/154,反馈始终为 253/251;同组其他关节有反馈变化。 SDK 无活动故障,但不能据此否定机械或反馈异常。已停止运行栈,等待现场确认后继续。 停机诊断现在分别记录实际指令、反馈和反馈进展判据,避免将原 goal=250.5 误认为 发送目标;保护逻辑不变,相关回归 67 项通过。原断点保留,本次未发布 JSON/URDF。

共享 Tag 的零位姿态传递

完整共享零位参与新关节拟合(v4,当前流程)

20260919_210955 完成无名指 PIP、DIP 和中指 MCP,累计保留 88 个通过单元, 随后中指 PIP 暂停。仅共享方向的 v3 拟合与已测零位相差 5.228 mm,超过原有 5 mm 容差;其中相机深度方向占 5.219 mm。固定基准身份相同,原 MCP 模型对 本次十帧静止图像的最大姿态差为 0.146° / 0.167 mm。这支持独立拟合的深度偏差 解释,不能据此认定机械手实际移动了 5 mm。

当前 training_shared_zero_pose_holm_v4 将同一物理 Tag、同一姿态的已测方向和 位置共同用于新关节拟合。新转轴、枢轴及各帧角度仍从本次运动图像估计;Tag 安装 平移由 t0 = pivot + R0 * mount 确定,不复制前一关节的轴线、枢轴或安装参数。 共享零位只是测量约束,不是新的真值证明:仍先用原模型检查当前独立静止图像,再 检查新模型的独立运动验证图像与静止图像。原有 2° / 5 mm、1° / 1 mm 和 1.5 px 门槛全部保留。静止见证图像不参与拟合,SDK 数值不被解释为几何角度。

不确定度计算恢复全部方向、位置自由度,以完整图像 Jacobian 计算局部敏感度, 避免固定共享位置后低估转轴和枢轴的不确定度。新旧策略使用不同证据版本;最终 回读还检查模型是否确实使用了声明的共享方向和位置。旧 v2 / v3 证据保持原样读取, passed 恢复仍直接保留已通过任务,不重新求解旧图像或采集旧零位。

真实中指数据夹具 test/fixtures/o30_shared_tag_middle_pip.json.gz 下,两组初值 均收敛,独立运动验证 RMS 约 0.370 px,当前静止姿态差约 0.356° / 0.164 mm。 这些是离线软件验证结果,尚未代表剩余实机采集或整手 URDF 验收完成。

v3 共享方向改进记录

20260919_205013 已完成无名指 MCP,累计 64 个通过单元;无名指 PIP 暂停于 image_motion_shared_pose_unresolved。独立拟合的两个候选相对 MCP 零位分别偏转 2.53° / 11.47°,前者几乎全是转轴外倾斜。将本次十帧静止图像交给原 MCP 模型, 相对原零位最大变化仅 0.046° / 0.05 mm。这支持独立模型倾斜偏差的解释,不能把 两个模型的姿态差直接当成机械手实际移动量。

新增 training_shared_zero_orientation_holm_v3:先用已通过的原模型检查本次同姿态 静止图像,再让已测共享零位方向参与新转轴拟合。只共享方向;新关节的轴线、枢轴、 Tag 平移和每帧角度仍由本次运动图像估计。初始图像的角度也独立求解,避免误把 准备运动第一帧当成共享零位。所有原始 IPPE 初值仍运行,收敛到同一物理解时按 原有等价性规则处理,不强选某一平面法线。

十帧当前静止图像不进入拟合,运动图像仍划分独立训练/验证集;源模型当前姿态和 新模型共享零位都须通过原来的 2° / 5 mm 检查,静止散布和 1.5 px 图像门槛不变。 不确定度检查恢复全部可辨识的方向自由度,按完整图像 Jacobian 计算局部敏感度, 不因共享方向而报告虚假的零不确定度。该量仍是模型的局部图像敏感度,不能代替 现场精度验收或证明原模型没有系统偏差。

真实无名指夹具 test/fixtures/o30_shared_tag_ring_pip.json.gz 下,两组初值收敛到 同一模型,当前静止方向差约 0.11°,独立验证 RMS 约 0.312 px。方向约束的来源、 原零位和当前图像绑定写入证据;最终回读重新检查来源以及模型是否使用了声明的方向。 旧 v2 证据继续按原规则读取,已通过模型和旧扫描不重新拟合;恢复启动也不重放旧图像。 本项为离线软件验证,未启动实机或完成剩余关节及整手 URDF 验收。

v2 共享姿态验证记录

20260919_200527 实机完成小指 MCP 的四轮往返,累计保留 40 个通过单元; 小指 PIP 在准备初始化处暂停。PIP 两组解的验证误差为 0.408063 / 0.401892 px, 但其归零姿态与同一 ID4 已确认的 MCP 零位分别相差约 1.57° / 20.99°。 两任务在该姿态的相关通道指令和反馈一致。此前每个任务独立判别,未使用这项已有约束。

现由通用共享姿态模块连接同机位、同父/子物理 Tag、同基准姿态的前后任务。 程序从本次归零准备末端保留至少十张、跨度至少 0.2 秒的图像;这些图像与转轴训练/ 验证图像不重叠。旧任务的零位和模型只读加载,新任务仍独立拟合转轴、安装位置和角度。 两任务不满足共享姿态条件时,保持原有解算流程;有可用来源但当前姿态检查失败时明确暂停。

姿态一致性沿用 2° / 5 mm 容差,静止散布沿用 1° / 1 mm 门槛。 为避免把边界误差误判成错误分支,只有偏差超过两份姿态容差之和才排除候选; 位于中间区域时保持未确定。这是保守的一致性余量,不声称统计置信区间。 该约束先决定候选资格,再按原有训练误差选择模型和执行独立图像验证; 1.5 px 绝对图像门槛、0.03 px 差异门槛以及第四轮验收保持不变。

shared_tag_pose_bridges 绑定原零位、原模型身份、相关反馈通道和新图像内容哈希; 最终回读重新核对来源、姿态和 URDF 推导的通道依赖。passed 断点模式记录模型恢复的 当前观测 epoch,直接加载已通过模型;不会在启动时回放旧扫描或重采旧零位。 真实回归夹具为 test/fixtures/o30_shared_tag_pip.json.gz,包含原始 129 帧准备证据和 独立的十张末端图像。该数据在原流程下重现暂停,在共享姿态约束下通过初始化。

本次修改不改变 Profile、运动顺序、轨迹或受保护配置,无需迁移旧数据。 该次断点为 20260919_200527,恢复时保留拇指及小指 MCP,从小指 PIP 继续。 上述新逻辑已做离线回归,尚未完成新逻辑下的实机续采和整手 URDF 验收。

从原 16 关节断点扩展

普通断点恢复仍拒绝不同范围或保护配置。已有 without_finger_roll 断点只能通过显式离线操作扩展: python3 -m linkerhand_calibration.runtime.checkpoint_extension --source-profile <原受保护Profile> --target-product <当前产品配置> --source-checkpoint <原raw_samples.jsonl> --output-dir <新目录>。 该操作要求旧任务完整保留为新流程前缀;旧 Profile 扩展到目标范围后,除了原来未执行任务的位置, 整个声明必须与新 Profile 一致。相机、URDF、Tag 配置等其余输入必须同哈希。 旧合同和新合同都须逐帧校验通过,且可复用单元、零位和行程检查结果完全一致。

工具新建派生断点,原始样本行逐字保留,原文件不改写;记录原始采集头、固定基准、 源文件 SHA256、前后 Profile 快照及扩展审计信息。后续按产品的 resume_mode 执行恢复, passed 模式另记录安装未变声明及实际跳过的复核步骤。 可选的 without_finger_roll 部分模式仍保留,其产物不包含四指侧摆曲线,也不代表整手标定通过。

拇指 roll 姿态歧义诊断

需要检查图像证据时,可使用通用诊断入口,只采拇指 roll 一次往返:

ros2 run linkerhand_calibration calibrate_hand --config \
  src/linkerhand_calibration/config/o30_right_product.yaml \
  --training-policy fixed --diagnostic-capture o30_thumb_roll

该预设沿用原有 baseline、反馈保护、食指避让和退出恢复顺序。未能冻结三维零位时只保存 明确标记的原始诊断观测;诊断会话禁止用于正式结果发布或断点恢复。原始图像角点记录还包含 可见的其他 Tag,可用于离线检查刚性关系,但不会自动把辅助 Tag 作为通过验收的依据。

2026-09-19 的 20260919_150313 诊断中,准备阶段训练的两个转轴候选在随后两个方向的 独立图像上可区分,原有 0.03 px 差异要求和 0.01 检验门槛均保持。 双标签共享转轴的实验尚不足以排除所有候选,未接入正式解算。 这次诊断不能替代正式三轮训练、第四轮验证及最终 JSON/URDF 验收;标签正对相机并非禁用条件。

20260919_150751 的 roll、MCP 各四轮采集完成,但 IP 前的 yaw=0 MCP 父标签准备连续两次 无法区分候选。其相同回零姿态与已验证 roll 模型的旋转差分别约 1.5°、20°;该跨任务对照 仅作诊断,不直接授权候选。随后 20260919_152030 有限诊断尝试用 CMC roll 的独立 预备运动重新确认 ID1,保持 yaw=MCP=0,并保留食指避让。ID1 成功区分候选,但 IP 的 ID2 候选仍不能区分;该实验未通过完整验证,已停止,当时正式 Profile 恢复原配置。 实验配置与原始图像保存在诊断目录,禁止用于正式发布或混入断点。

父标签参考与相邻平行转轴的复用

后续离线核查确认:单独重复 MCP 扫描没有利用已有的刚性安装证据;仅凭某一组候选的 重投影误差更小,也不能可靠选解。现通过通用任务字段 parent_reference 分开声明两种来源:

  • pose_joint: thumb_cmc_roll:复用已验证的 ID1 图像模型。IP 前恢复 yaw=MCP=roll=0, 先静态采集至少十张当前图像,检查掌心与 ID1 姿态、祖先通道反馈及图像来源;不增加 MCP 扫描。 食指侧摆由原任务正常恢复到 255,不需要重新做 roll 避让。该检查不修改 roll 或 MCP 的零位。
  • geometry_joint: thumb_mcp:使用已通过独立图像检查的 MCP 轴线与 ID1 安装关系, 把转轴表达在刚性 ID1 坐标系中。它不随上游 yaw 或 MCP 自身转动改变。
  • 从受 SHA256 保护的原始 URDF 提取 MCP/IP 的平行关系和轴间距 0.048556745401643224 m;约束 IP 自己的图像解算,IP 曲线和限位仍须独立实测。 传递来源的不确定度计入 IP 的几何验收,不能因减少优化变量就把轴视作无误差。

候选仍用分开的准备阶段训练/验证图像判别,保留原 1.5 px 图像门槛、0.03 px 候选差异 及 0.01 检验门槛。无法区分时保存诊断并暂停,不自动重复相同扫描;短暂采图不足的有界恢复保留。 正式三轮训练、第四轮独立验证、稳态指令映射、几何零偏与 JSON/URDF 文件回读验收均保留。

记录同时绑定来源模型、安装不确定度、原零位、当前复核图像及 CAD 哈希。内部采图重试可以沿用 原安装证据,但必须记录版本衔接;停机重启通过原恢复流程重新确认来源。 新流程使用 unified_schedule_v10_verified_parent_geometry_feedback_interleaved, 旧流程的断点不能直接混入,需要新会话采集。旧格式记录仍可按其原有含义读取。

数值回放中,原始 IP 准备图像仍无法独立排除两组候选;加入已验证父参考与上述约束后, 两组候选的验证 RMS 约为 0.605 px 和 0.898 px,比较概率约 5.96e-8,通过原门槛。 该离线回放用了两个已停止会话的诊断图像,只证明算法在这些数据上的可辨识性, 不授权跨会话实机复用,也不代表完整标定、绝对转轴或最终产物已经验收通过。 对应图像已加入离线回归夹具 test/fixtures/o30_transferred_ip_geometry.json.gz。

本次新增 35 项算法、参考复核和证据回读测试通过,O30 产物及 G20/L6/O6/O12 相关回归已运行。 全量回归发现的旧测试夹具和断言已按现有合同更新:明确读取产品绑定的 URDF、保留全机位 原始图像日志、为合成 Profile 声明空保留范围,以及检查方向起点的运动采样。 仍保留一项可在修改前备份上同样复现的遗留失败: test_urdf_zero.py::test_end_on_phase_rejects_oblique_monocular_depth_bias, 使用 G20 legacy_11 兼容求解器,预期 4° 的偏置算得约 3.896578°,超出该测试的 ±0.05°。 未降低该断言,也未将它作为 O30 验收通过;O30 正式流程仍需重新采集并完成独立产物验收。

构建和加载环境

在当前工作区构建外部 SDK,构建、安装、日志目录均位于当前工作区。SDK 源码仍使用原目录。

cd /home/lxp/projects/linkerhand_retarget_ros2
source /opt/ros/jazzy/setup.bash
source install/setup.bash
colcon --log-base log/o30_calibration build \
  --base-paths src/linkerhand_calibration \
    /home/lxp/projects/linkerhand-o30-ros2/linker_hand_o30_ros2_sdk \
  --packages-select linkerhand_calibration linker_hand_o30_ros2_sdk \
  --build-base build/o30_calibration --install-base install/o30_calibration \
  --symlink-install
source install/o30_calibration/setup.bash

后续新终端按顺序加载 /opt/ros/jazzy/setup.bash、install/setup.bash、 install/o30_calibration/setup.bash。启动器自动启动 SDK;运行正式标定前退出其他 SDK 实例、GUI 控制器及占用相机的 MVS。

适配器 o30_ros 使用 SDK 原有话题:

功能 话题
位置指令 /cb_right_hand_control_cmd
位置反馈 /cb_right_hand_state
速度、力矩设置 /cb_right_hand_setting_cmd
身份及在线状态 /cb_right_hand_info

本配置使用 libcanbus、设备编号 0、30 Hz 反馈,关闭自动摆位、触觉和不使用的速度/电流查询。 设备速度及力矩设为 200;发送完整 20 通道位置向量。 准备、避让、零位预备和任务退出使用约 13.352 秒的全量程余弦轨迹,峰值为 30 指令单位/秒。 该过渡速度由 command_trajectory_full_range_seconds: 13.35176877775662 统一配置, 包括恢复 baseline;动作次序保持不变,到位与采样稳定性由实时反馈确认。 正式扫描使用 scan_trajectory_full_range_seconds: 13.35176877775662,峰值为 30 指令单位/秒。 扫描参数仅作用于运动扫描和稳态点之间的行程;整数指令存在一单位量化步进。 提速后的实机准确度仍须通过本次现场独立验证,软件测试不能替代现场验收。

当前反馈与指令职责(2026-09-19 恢复反馈模式)

O30 使用 motion_observation: feedback、feedback_travel_matches_command: false, 发布依据仍为 release_basis: steady_command。反馈参与运动与采集判断,反馈角度映射只作诊断。

环节 当前规则
最终 JSON 下发指令→视觉角度,独立验证指令映射及修正 URDF;反馈映射失败不单独阻止发布。
启动与采样 要求 20 通道有效、新鲜的反馈;程序先按配置顺序恢复完整 baseline,再锁定基准。稳态点和零位在反馈稳定后使用新图像。
恢复与避让 已测零位使用其原始反馈参考确认归位,拇指 roll 归位后才恢复食指侧摆。
采集质量 检查带同步图像的指令覆盖、各运动关节独立的反馈行程及分布、保持关节是否变化和图像时间关联。

目标值与反馈相差约 10 不构成单独的停止条件;不假设二者相等,也不事先强行用 指令跨度推算等比例反馈行程。例如指令 0 时实测反馈为 10,回零时核对的是该实测参考, 而不是等待反馈变成 0。同一保持姿态内的反馈漂移仍会影响稳定性判断,不能把目标偏差 容许量当作稳态抖动容许量。

反馈延迟跨过换向时,未建立指令/反馈比例关系的运动段按本段实际观测的转向点检查 所需方向的位移。20260919_165005 中,回程开始的反馈为 221,随后补报到 247, 再正常回落至 221;旧逻辑仍要求低于起始反馈,错误地等待 218.5。现在这段回程 可以作为运动证据,保持后的图像仍须通过原有稳定窗口和独立指令映射验收。 只有反向变化、完全静止、其他通道运动或重复时间戳均不能代替本关节所需方向的运动; 已测零位仍按绝对反馈参考确认。稳态点仍穿插在四轮往返中,没有增加独立稳态往返。

  • 反馈运动、方向和稳定性使用真实 SDK 样本,按消息时间戳去重;缺失、越界或超过 1 秒不更新仍会暂停。
  • O30 原 SDK 只提供消息级反馈时间,保留该时间与图像的关联,不生成逐通道测量时间。
  • 零位及稳态采样仍需至少 0.2 秒的独立反馈稳定窗口;采样期间反馈变化会清空当前稳态候选。
  • 指令覆盖按各自通道的指令区间检查,端点要求同步图像。反馈覆盖在各自实测区间检查样本数、分箱和空缺, 不把中指 0–80 的指令边界当作反馈边界;小于运动分辨阈值的噪声不能归一化成完整运动。
  • 固定关节按保持姿态的实测反馈比较,恒定偏差不等于关节移动;零位准备仍核对完整保持指令和反馈。 准备运动的几何保持检查按原始 URDF 和 Tag 安装连杆确定相关反馈通道;其他指及 Tag 下游关节的反馈 不会改变当前 Tag 的几何模型。完整 20 通道保持指令仍需一致,全部反馈仍原样记录。 例如 ID1 位于 thumb_proximal,检查 roll/yaw/MCP 三轴,IP 通道的变化不应使其几何证据失效。
  • SDK 身份、通信、异常/离线/过流/过温、竞争控制端、固定基准漂移及人工中止保护保持。 固件端点堵转标志继续保留诊断,实际无运动由反馈运动检查处理。
  • O30 的 acquisition.stall_timeout_seconds 为 4 秒,从明显运动需求开始且没有真实反馈推进时计时; 持续发送新指令不会重置计时。此调整给端点回程更多响应时间,不保证已确认的堵转能自行恢复。 反馈新鲜度、稳态采样、已测零位归位、运动覆盖和独立验收门限不变。其他型号仍为 2 秒。 本次参数调整更新了受保护配置哈希;旧断点保持原样保存,新配置不能直接复用旧配置下的断点。

指令与反馈的拟合输入保持分离。稳态节点的训练形状也使用指令→视觉观测, 不能因恢复反馈门控而重新依赖反馈角度拟合。JSON/URDF 的角度精度、几何可观测性、 原始 CAD 保护、端点证据和第四轮独立验收门槛不变。

当前配置哈希已更新,调度恢复为 unified_schedule_v8_approach_path_interleaved。 此前视觉门控会话保留只读,不能直接作为当前策略的完成断点;重新采集后仍可按当前策略断点恢复。 四指分组任务被中断后整组重做。本次仅修改软件并离线验证,实机保持停止,尚无新的现场验收产物。

相机移动后重标外参

仅改变相机位置和朝向,镜头、焦距、对焦及成像分辨率/裁剪均未改变时,可以沿用内参。 2026-09-20 已沿用 ~/.ros/camera_info/ 内三份文件,并重新求得三相机之间的外参: 重投影 RMS 为 0.907191 px,最大旋转重复性为 0.058985°,最大平移重复性为 0.770194 mm; FRONT+SIDE、FRONT+TOP 各 15 组有效观测,均无剔除,质量检查通过。 以下命令供下次移动相机后重新标定,输出到新文件以保留历史外参。

以下命令使用当前工具默认的 8×5 内角点、27 mm 方格;棋盘不一致时必须修改对应三个参数。

EXTRINSICS_FILE="$PWD/config/o30_three_camera_extrinsics_$(date +%Y%m%d_%H%M%S).yaml"
ros2 launch linkerhand_calibration three_camera_extrinsics.launch.py \
  front_camera_serial:=DB2163742 \
  side_camera_serial:=DB2163749 \
  top_camera_serial:=DB2163739 \
  front_camera_info_url:=$HOME/.ros/camera_info/hikrobot_DB2163742.yaml \
  side_camera_info_url:=$HOME/.ros/camera_info/hikrobot_DB2163749.yaml \
  top_camera_info_url:=$HOME/.ros/camera_info/hikrobot_DB2163739.yaml \
  checkerboard_columns:=8 checkerboard_rows:=5 square_size_m:=0.027 \
  output_file:="$EXTRINSICS_FILE"

在界面分别采集 FRONT+SIDE、FRONT+TOP 的不同棋盘姿态,每对至少 15 组有效观测,质量通过后点击 SAVE。 通用外参工具沿用 /g20_extrinsics/... 图像命名空间,此名称不会改变输出的相机身份或 O30 绑定。 退出外参工具,在同一终端计算新文件的 SHA256:

sha256sum "$EXTRINSICS_FILE"

将输出路径和 SHA256 分别填写到 src/linkerhand_calibration/config/o30_right_product.yaml 的 artifacts.camera_extrinsics 与 artifacts.camera_extrinsics_sha256;同时确认 serial_number 对应本台右手。 相机移动前的外参和采集记录仅保留作历史诊断,新外参绑定后应从头采集整手数据。 配置检查会核对三份内参指纹、相机序列号、外参质量和各输入文件 SHA256。

本机 O30 实机标定使用独立 ROS 域;标定、SDK 子进程及另开的监控终端需使用同一值。 它隔离其他域的话题发现,不隔离其他进程对同一 CAN 设备的直接访问,仍保留控制发布者检查。

分阶段回访/断点零位复核使用 staged_revisit_v2:根据本机操作者提供的正常重复到位范围, O30 跨次反馈与原零位反馈中位数的差值上限为 10 个 SDK 原始值(包含 10), 同一批采样的反馈极差上限仍为 2。检查仍覆盖整手保持反馈,并同时检查原图像姿态、安装证据 和新图像时间;不会重新定义冻结零位。该值不是角度精度声明,也不改变运动到位、几何求解、 角度或像素验收门限。每条新复核记录保存实际门限,离线严格核对;旧 staged_revisit_v1 记录继续按原跨次上限 4 回读,其他型号门限保持原值。

export ROS_DOMAIN_ID=99

ros2 run linkerhand_calibration calibrate_hand --config \
  src/linkerhand_calibration/config/o30_right_product.yaml --validate-only

ros2 run linkerhand_calibration calibrate_hand --config \
  src/linkerhand_calibration/config/o30_right_product.yaml --no-resume

通道、观测与任务

全部 Tag 使用 36h11,黑色外框边长 16 mm(2026-09-22 用户最终实测确认, 不含白边)。Profile、三路检测器与标定尺寸覆盖表已同步;新标定使用 --no-resume, 不要复用旧 16.5 mm 会话模型。手上 Tag 尺寸与棋盘格相机外参参数独立,本次保留外参。

2026-09-22 用户再次更正当前实机(无名指侧摆由 85 改为 127) LHO30-03.1-034-R-J-3-A 的 baseline:四指侧摆零位为竖直状态,小指 52、无名指 127、 中指 196、食指 255,其余关节为 0。此约定替代此前提供的 baseline;对应输出角度为 0。 配置指纹同步更新,旧 baseline 下的零位观测和断点不能复用,须重新采集。按 SDK 通道顺序,向量为:

[0, 0, 255, 196, 127, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
SDK 索引 SDK 名称 URDF 关节 baseline 指令增大时角度方向
0 thumb_roll thumb_cmc_roll 0 正
1 thumb_yaw thumb_cmc_yaw 0 正
2 index_yaw index_mcp_roll 255 负
3 middle_yaw middle_mcp_roll 196 负
4 ring_yaw ring_mcp_roll 127 负
5 little_yaw pinky_mcp_roll 52 负
6 thumb_root1 thumb_mcp 0 正
7–10 index/middle/ring/little_root1 对应四指 mcp_pitch 0 正
11–14 index/middle/ring/little_root2 对应四指 pip 0 正
15 thumb_tip thumb_ip 0 正
16–19 index/middle/ring/little_tip 对应四指 dip 0 正
任务顺序 关节与观测 固定姿态 / 收尾
1 thumb_cmc_roll,正面 0→1 食指侧摆 0;结束先拇指归零,再食指侧摆 255
2 thumb_mcp,正面 0→1 yaw=80;结束先 MCP 归零,再 yaw=0
3 thumb_ip,正面 1→2 其他拇指关节 0
4 thumb_cmc_yaw,顶部 16→17 其余关节保持 baseline,完成后 yaw 归零再进入下一任务
5–7 小指 pitch:3→4,pip:3→4,dip:4→5 每次仅一个关节运动,其他两个 0;完成后三关节置 255
8–10 无名指 pitch:3→6,pip:3→6,dip:6→7 保持小指避让;完成后再累加无名指避让
11–13 中指 pitch:3→8,pip:3→8,dip:8→9 保持小指、无名指避让;完成后再累加中指避让
14–16 食指 pitch:3→10,pip:3→10,dip:10→11 保持前三指避让
17 小/无名/中/食 mcp_roll,正面 0→12/13/14/15 先恢复屈伸 baseline,再执行下述四段联动

ID1 始终安装在 thumb_proximal,同时用于 roll 与 MCP。每个关节在自己的固定姿态下采集零位,不要求所有 Tag 同时可见。 四指零位准备使用 evidence_scope: path:先到联动低端点(中指 80,其余 0), 再到四指均为 255 的高端点,返回联动低端点,最后到各自 baseline。 初次摆到低端点的图像不参与建模;之后完整路径的图像确定转轴,baseline 图像单独冻结零位。 小指的短距离归零段不足以可靠确定转轴,因此不能只保留最后一段图像。 完整路径仍只保留最多 129 个指令分箱,并记录每张来源图像的真实运动段、会话身份和内容哈希; 重试会清空前次准备证据。其他型号默认 evidence_scope: arrival,保留原来的最后一段准备逻辑。 更改路径不改变零位或降低可观测性门槛;旧调度数据仍可读取,不能混入本调度的断点恢复。 共享 Tag 的图像运动模型按任务管理,不能把 roll 模型当作 MCP 曲线使用。 进入 IP 时在声明的 yaw=MCP=roll=0 姿态下静态复核 ID1,再使用 MCP 在 ID1 坐标系中的 实测安装几何约束 IP 解算;不再额外运动 MCP,不替换任何已冻结的关节零位。

四指侧摆每轮执行完整闭环:

  1. 小指、无名指、食指 0→255,中指 80→255,同一归一化进度联动。
  2. 同步反向,中指回到 80,其余回到 0。
  3. 其余三指保持 0,中指 80→0。
  4. 其余三指保持 0,中指 0→80。

80 只是分段边界,中指零位为 baseline 196。四指分别保留自己的指令、反馈和 Tag;中指独立段只要求 ID0、ID14。 独立稳态采样网格覆盖各 baseline 和分段边界,额外插入同步路径上其他通道所需的停留点;保持不动的通道不计入样本。 使用 command_capture_mode: interleaved,在同四轮路径中分别记录运动图像和停止后的稳态图像: 前三轮训练反馈映射、几何和指令映射,第四轮独立验证;验证停点使用训练网格中点及端点。 运动图像不充当稳态图像,指令曲线始终使用实测指令和独立图像角度。 每一小段扫描到达中间节点后交给紧接的稳态采集统一等待稳定,避免重复停留; 每个方向的起点、终点保留反馈到位停留,确保运动记录本身具有端点图像与完整反馈范围。 实际运动证据、反馈稳定窗口、独立图像数量和独立验证阈值均保留。 原六轮 separate 模式仍可用于其他配置,但其记录不能与当前四轮配置混合恢复。

对于普通单关节,六轮模式的纯运动时间约为 240.3 秒;当前四轮模式约为 106.8 秒。 此计算不包含零位、避让、反馈稳定和图像采样时间,不作为实机完成时限。 四指联动任务仍在每轮完成全部四段,中指低段不会因缩短采集而丢失。 单段采样不足允许一次同速重扫,段身份参与数据筛选。暂停或中断后,四指分组任务整体重做,并重新采零位;其余任务沿用逐关节零位复核后恢复的机制。

提速实测与当前限制

按用户后续要求,过渡轨迹也从峰值 20 调到 30;后续 184003 会话已执行前三个拇指任务的准备与恢复。 下面的现场记录发生在此变更之前,当时扫描峰值为 30,准备、避让与恢复峰值仍为 20。

2026-09-18 最终端点流程的会话 20260918_175403 中,拇指 roll 前五个方向均一次通过, 每程实际采集约 19.3–20.0 秒,包含中间稳态停点和起终点观测;按此速度估算普通关节四轮 约 2 分 40 秒,另加准备和归零。此估算不适用于有额外路径的四指联动任务,也不计重扫。

第三轮反向时,设备目标已经降至 223,反馈仍为 253;SDK 直接回读报告 thumb_roll: 执行器层判定堵转。设备速度、力矩的直接回读均为 200。 用户确认无外部卡住后,只做了一次从 253 开始的受控回零,仍触发无运动保护, 没有恢复避让食指。该会话不完整,没有生成可发布的标定 JSON 或修正 URDF。 记录与诊断位于该会话的 raw_samples.jsonl、paused_device_readback.json、 efficiency_trial_summary.json 和 supervised_return.jsonl。

当前保留三轮训练和第四轮独立验证,用于检查重复性、双向回差和未参与拟合的数据; 没有将两轮采集视为等效替代。提速仅减少额外往返、中间重复等待及扫描行程时间, 没有放宽角度误差、反馈覆盖、端点观测或无运动保护。 最终端点调度相关的执行、效率及完整 20 关节合成产物测试共 22 项通过; 此处记录的是 175403 会话的堵转;后续 184003 会话已完整采集前三个拇指任务。 合成测试不能证明当前实机的整手标定精度。

输出和验收边界

现场通过后,统一发布链路输出 JSON v3、修正 URDF、标定报告及独立验证报告。 每个主动关节都有独立验收的指令曲线,包括增大/减小分支;反馈曲线单独报告诊断状态。 没有跨指复制、被动关节或新增 mimic。

15 个非末端关节使用 CAD 串联轴几何求解零偏,执行数值可观测性及第四轮验证。 thumb_ip 和四指 dip 的 baseline 使用用户接受的原始 CAD 零位,报告标记 assumed_source_cad_zero,保留原 origin。 20 个关节都独立测量运动曲线,并用实测角度范围更新限位。 保持连杆尺寸、origin.xyz、轴、mesh、惯量和原 effort/velocity;包括原始无名指侧摆的零 effort/velocity,不自动替换为其他值。 修正结果由 JSON 重建、文件回读后验收;原始 linkerhand_O30i_right-V2_0819.urdf 始终作为只读输入。

软件验证记录(2026-09-18)

以下均为离线软件验证,没有启动硬件或发送运动指令:

验证 结果
标定包与外部 O30 SDK 按本文命令构建 2 个包成功;SDK 源文件内容保持不变
O30 配置、SDK、任务路径、观测与启动描述 9 项通过
20 主动关节独立合成数据、产物回读、分段恢复 2 项通过;15 个求解零偏误差小于 0.004 rad;JSON 重建 URDF 字节一致
标准 check_urdf 解析合成修正产物 通过
受影响模块回归 78 项通过;末次分段质量与恢复补测 32 项通过
全包回归,覆盖 G20/L6/O6/O12 首次 1639 通过、21 失败、1 跳过;后续处理见下文
正式产品配置 --validate-only 初次验证拒绝缺失的新外参;本次现场外参绑定后检查通过,未启动机械手标定

全包回归的 2 项失败来自新增运动接口后旧测试夹具缺少依赖,已改用正式 MotionCommand 并补齐采集接口,相关 8 项复跑全部通过。其余 19 项在修改前提交 a8eaa4c 的隔离代码中同样失败:

原有失败所在测试文件 数量
test_all_view_image_acceptance.py 5
test_axis_line_gauge.py 2
test_capture_journal.py 1
test_final_image_sources.py 1
test_image_motion_capture_evidence.py 3
test_runtime_pose_branch_guard.py 6
test_urdf_zero.py 1

这些既有失败涉及 O6 夹具的 Tag 尺寸、原始 URDF 文件选择、旧日志断言和几何误差断言。 本次没有放宽标定验收门槛;更新测试夹具后仅复跑受影响测试,未再次执行全包回归。 合成数据误差仅证明软件链路,现场精度仍须以实机第四轮独立验证和发布报告为准。 本次更新外参哈希后,产品文件绑定及 O30 启动描述两项针对性测试均通过。

指令与反馈的验收职责(2026-09-18 更新)

按现场确认,O30 使用 measurement.release_basis: steady_command。指令映射和修正 URDF 必须独立验收通过;反馈映射仅供诊断。其他 Profile 默认保留 feedback_and_command。

前三轮连续运动图像只确定冻结的视觉转轴和参考,不用运动中的指令值拟合实际角度。 前三轮稳态图像拟合独立的指令曲线,并用于 CAD 串联轴几何、Tag 安装位姿的训练; 第四轮稳态图像独立验证指令曲线、几何零偏及最终 JSON+URDF 的原始角点重投影。 全部 20 关节的限位取训练指令曲线的实测范围,五个末端关节保留已确认的 CAD 零位。

报告 quality.release_basis 和限位证据明确标记来源;反馈诊断放在各关节 feedback_diagnostic 和 feedback_mapping_diagnostics.json。反馈训练范围外的验证样本 记录数量和图像身份,不夹紧、不外推、不混入训练。2026-09-19 起位置反馈数值只作诊断; 设备健康报告失联、活动故障和视觉运动/回零验证失败仍会暂停,详见本页前述视觉运动策略。

181201 会话的拇指 roll 按新流程离线复核:60 张独立稳态验证图像,指令映射 MAE 0.347683°、P95 0.730440°、最大 0.872949°。反馈训练范围 3–250,验证 859 张中 71 张超出范围。这是单关节诊断,尚不是整手 URDF 或正式发布的验收。

184003 会话的前三个拇指任务各有 60 张独立稳态验证图像:roll 的 MAE/P95/最大误差为 0.185306°/0.464223°/0.684213°,MCP 为 0.152367°/0.424799°/0.547374°, IP 为 0.440852°/1.273472°/1.426604°。该会话在四指零位准备时停止,不是完整产物。

图像证据在内存中共享不可修改的冻结模型,逐帧图像诊断仍保持独立;JSON 内容、模型哈希 和完整回读校验保持一致。对上述实测日志中 1000 条含模型记录抽样,保留内存从 44.09 MiB 降至 15.13 MiB。运行日志另记录超过 50 ms 的控制循环和垃圾回收停顿,用于定位反馈处理延迟, 不改变反馈新鲜度门槛。独立 SDK 监测在上次暂停期间仍有连续反馈,具体停顿来源需要后续日志确认。

190152 会话记录到随采集增长的垃圾回收停顿,最大约 0.55 秒。正式 ROS 运行改用轻量采集索引: 内存只保留覆盖率、分段重试和训练停点选择需要的字段;原始图像、位姿、冻结模型和哈希仍完整落盘。 最终验收进程只读取已同步的日志边界,不能用轻量索引替代证据。相同 1000 条实测记录的索引 保留内存为 1.025 MiB,完整共享模型记录为 15.135 MiB。进程内验收与诊断模式保留完整记录接口。

该会话 roll 指令验证通过(MAE 0.278128°,P95 0.706998°,最大 0.709360°), MCP 则因初始零位与首轮回程后的视觉位置相差约 2.1°而未通过。最后一轮 MCP 的 856 张图像 全部保持 yaw 指令 80、反馈 76;随后 yaw=0 的 MCP 动作属于 IP 父标签准备。 用户随后检查并固定了 ID1。旧 roll/MCP 的安装证据不能拼接到新安装状态,本次会话不发布产物。

ID1 固定后的重采与当前断点

191601 会话重新采集后,roll 的 60 张独立稳态验证图像通过,MAE/P95/最大误差为 0.274847°/0.668562°/0.854174°。MCP 首次回零仍相对冻结零位变化约 1.39°, yaw 全程保持指令 80、反馈 76;因此停止该会话,没有以新的回零位置替换训练零位。 轻量采集索引在这次实机运行中将节点内存稳定在约 210–214 MiB,记录到的垃圾回收停顿 约 0.09–0.17 秒;此前 190152 会话最大约 0.55 秒。

随后分别检查连续/分段 MCP 路径、yaw 避让重新进入、roll 恢复后进入 MCP。 这些独立诊断保存于 mcp_path_diagnostic_20260918、mcp_entry_diagnostic_20260918 和 mcp_roll_entry_diagnostic_20260918,均位于 calibration_output/O30_RIGHT_001/。 连续/分段路径的五次视觉回零中位数跨度约 0.046°;roll 恢复后的四次运动回零跨度约 0.091°。 这些结果未复现正式任务初次回零的 1.39°变化,尚不能确定其原因;未据此添加额外预热往返, 也未把诊断记录纳入正式训练或验证。

193712 会话再次开始正式采集,roll 第一轮两个方向采集完成,第二轮正向在指令 223、 反馈 189 时触发 MOTION-STALL-303。关闭标定与 SDK 进程后,原 SDK 只读查询仍确认 目标 223、位置 189,并报告 thumb_roll: 执行器层判定堵转;通信错误为 0,速度/力矩均为 200。 保护日志中的 goal=191.5 是要求观察到的最小反馈推进量,不是下发指令。 该会话的 paused_device_readback.json 保存直接设备读数,restart_status.json 保存断点与继续条件。 必须先恢复正常硬件运动,再验证设备身份、固定基准及零位的一致性,才能判断哪些已完成单元可恢复。 本会话尚无可发布 JSON 或修正 URDF;SDK 的 61 个受保护文件及原始 URDF 哈希均保持不变。

195023 会话重新从头采集,roll、MCP、IP 指令独立验证均通过(各 60 张稳态验证图像), 最大误差分别为 0.841727°、0.513759°、1.443653°。小指侧摆零位准备两次均因转轴不确定度 超出 3°而停止:255→72 只提供约 16.5°的转动,转轴不确定度约 3.7°。 离线加密至逐整数指令抽样后仍约 3.07°,未通过原门槛,详见该会话的 pinky_sampling_diagnostic.json。据此新增上述完整路径证据能力,保留原始记录,不将其改写为通过。 新的 Profile 与调度尚需重新完成现场采集及整手独立验收。

200926 会话采用完整准备路径后,小指与无名指侧摆转轴建模均通过,转轴不确定度分别为 2.307°、1.200°;774 张来源图像以及 6 份冻结模型完成来源哈希和图像模型回读校验, 见 preparation_path_readback.json。同会话 roll/MCP/IP 指令验证最大误差分别为 0.663211°、0.559848°、1.473215°。 该会话在中指侧摆准备阶段停止:两次转轴不确定度均约 7.6°,中指 ID14 的单张图像 正方形拟合误差中位数约 0.80 px,小指/无名指约 0.17/0.20 px;不能仅以电机跟踪偏差解释。 已要求检查 ID14 的平整度、边框形状和刚性固定,未放宽验收;此时无整手正式产物。 保持固定基准、相机与拇指标签不变时,可在逐关节零位复核通过后恢复前三个拇指任务; 四指分组任务整体重新采集。保存的状态见该会话 restart_status.json。

2026-09-19 的 100934 恢复会话通过整场基准和拇指 roll 零位复核,但一次性导入旧零位 来源记录使控制回调阻塞 3.530 秒,触发通信保护。独立只读监测同期持续收到反馈,SDK 健康报告保持在线、通信错误为 0。零位来源记录现与扫描记录共用每批最多 64 条的导入机制: 批次之间继续处理反馈、安全检查及中止,原零位只有在全部来源与引用记录落盘后才能授权运动。 未放宽通信门槛,未更改配置或旧记录,因此仍可从 200926 断点恢复。 对 100934 的 32,291 条实测记录分批重放,最长单批 0.1863 秒,顺序与内容回读一致, 见该会话 resume_transfer_replay.json;这项验证不是整手精度验收。

随后 20260919_101609 会话成功复用 roll 的 8 个采集单元,导入期间未再触发通信暂停。 进入 MCP 零位准备时,MCP 指令升至 51,反馈连续停在 0,触发无运动保护。停机后直接 读取设备仍为目标 51、位置 0;yaw 目标 80、反馈 76,速度与力矩均为 200,通信错误为 0。 用户确认暂不处理该硬件问题,本次保留姿态并关闭标定、SDK、相机与只读监测;没有待执行动作。 最新断点说明见 20260919_101609/restart_status.json,设备读数见 paused_device_readback.json。

断点发现按同一次从头采集及其恢复会话中的完整单元数选择候选,同数优先较新记录; 重复完成记录不增加计数,显式从头采集的边界阻止回溯到更旧的被替代记录。 因此这次只导入 roll 的会话不会遮住 200926 中另外两个拇指任务。 对实际会话目录运行选择器,仍选择 20260918_200926,见 next_resume_selection.json。 这只选择候选数据:硬件恢复后仍须重新通过基准与各关节零位检查,MCP/IP 当前尚未授权复用, 四指侧摆整体重做,ID14 的几何可观测性仍待实机重验。启动状态明确显示“已请求断点恢复”, 不再在等待基准复核时误显示为从头采集。

位置反馈可选策略的软件验证(2026-09-19)

  • 20 个独立主动关节的非线性合成数据,分别使用变化的反馈、全部缺失的反馈、全部固定为 0 的反馈,均通过指令映射、15 个可观测零偏、五个 CAD 零位、限位及 JSON/URDF 回读检查;JSON 重建的 URDF 字节一致,无 mimic,原始 URDF 未改动。
  • 视觉监测单独覆盖缺图、实际不动、稳态抖动、回零未完成、每指独立观测、断点版本隔离,以及几何工作线程未运行时角点监测仍更新的情况。计算中的图像按自身时间戳取稳态证据,不能使用后续图像补证。
  • 本轮运行了 SDK、运动执行、采集、恢复、几何和产物相关回归;扩大回归中的 366 项通过,六项旧日志数量断言因新增全机位原始图像而失效。修正这组测试对“原始图像”和“有效关节样本”的区分后,相关视觉、分支保护及日志 46 项复跑通过。另有 58 项 SDK、统一引擎和产物检查通过。不将这些有重叠的测试数量相加;既有全包夹具问题仍按上文单独记录。
  • 对 20260919_101609 会话 MCP 的 112 帧原始图像进行只读重放:位置反馈为 0,实际相对角点行程为 28.736 px,视觉监测没有误报无运动。受控静止反例在原片段后额外延长 0.2 秒的合成帧后触发暂停。结果保存在该会话的 feedback_optional_visual_replay.json,明确不属于标定验收或端点证明。
  • 同会话拇指 roll 的 137 个历史稳态窗口,角点噪声中位数为 0.835 px、P95 为 1.528 px,98.54% 位于配置的 2 px 监测阈值内。此统计只用于运动监测参数检查,不替代独立角度精度验收。
  • 产品配置检查通过;外部 SDK 的 61 份源码文件及原始 URDF 哈希保持不变。本次没有启动机械手,也没有发布实机标定产物。

2026-09-19 110202 实机切换会话在基准恢复时发现,顶部两 Tag 相距约十个 Tag 边长, 原透视归一化将约 0.2 px 的检测波动放大为数像素,导致视觉稳定判断误暂停。 运动监测改为四角点最小二乘相似变换(relative_tag_corners_v2_similarity),仅消除共同 平移、旋转及均匀缩放;不把非共面的运动 Tag 投影到基准 Tag 平面,也不用于角度拟合。 对该会话 297 条原始角点记录离线重放,roll/yaw 稳态窗口最大波动分别为 0.126/0.387 px, 保持 2 px 稳定阈值即可通过基准恢复,见 110202/similarity_motion_replay.json。 运动、缺图、回零保护和独立角度验收门槛均保留;调度版本升至 v10,旧视觉策略记录不混用。 此重放不构成实机标定产物验收。 相似变换版本的运动、任务执行、就绪与 20 关节合成产物回归共 43 项通过。 再次重放 MCP 反馈恒为 0 的 112 帧记录,实际运动见证为 27.370 px,未误暂停; 静止反例仍在 3.901 秒触发无运动暂停,记录单独保存为 101609/feedback_optional_similarity_replay.json,保留此前算法诊断原件。 随后 110506 会话发现量程工位遗留非零目标(食指 MCP、无名指 PIP/DIP 等), 侧面仅可见 ID3/4/5,无法确认被遮挡关节回到基准,因此未执行该恢复路径。 本次没有完整采集单元和验收产物,已关闭 SDK/相机,等待操作者恢复实际基准姿态后继续。 SDK 的 61 份源码与原始 URDF 哈希再次确认未变。

随后用户明确要求程序启动时自行恢复基准。初始 BASELINE 现使用独立的 command_schedule 完成条件:从设备目标寄存器读取起点,按配置通道组顺序执行限速 轨迹及端点保持;通信、故障、重复控制端及指令范围保护持续有效,不要求被遮挡的 运动 Tag 同时可见。日志明确写入 physical_arrival_verified: false,不生成稳态或零位 证据。仅这一初始摆位阶段允许该完成条件,正式采集、任务间恢复、避让释放仍要求 各自的观测证据;初始摆位之后仍先锁定固定基准,再逐任务冻结实测零位。 对真实遗留目标姿态的虚拟时钟回归,完整发送基准目标、保持限速,且未生成有效样本、 关节零位或完成采集单元。视觉相关 28 项检查通过,另有 29 项引擎/执行/就绪回归通过。 110927 会话已自动恢复基准并完成拇指 roll 前两轮;第 3 轮正向 159→191 时视觉检测 停动,75 帧、2.534 秒内相对角点最大位移仅 0.115 px,SDK 同时报告执行器堵转。 本次按视觉停止,位置反馈数值仍不参与门控。19,692 条断点记录的视觉来源校验通过, 四个完整方向可作为恢复候选,见 110927/checkpoint_stop_audit.json。 用户随后确认关节运动已恢复,继续启动正式标定并重新复核实际基准/零位。 111353 恢复会话通过固定基准及拇指原零位检查,成功复用前两轮四个完整方向; 第 3 轮正向 191→223 再次发生视觉确认停动。用户要求停止标定以检查设备,已关闭 标定、SDK、三台相机和只读监测,未发出恢复动作,没有待执行的自动运动。 断点及回读结果分别保存在该会话的 restart_status.json、checkpoint_stop_audit.json。 尚未生成通过整手验收的 JSON/URDF。后续须由用户确认继续,并重新复核实际基准与零位。

恢复反馈模式的软件验证

2026-09-19 根据用户确认恢复反馈模式,产品 Profile SHA256 更新为 4f30ece86fef9857dea1cd2d5201541ed16c6c0c81eab8b41a65285303088d01。 运行、恢复、同步、SDK 启动器及 G20/L6/O6/O12 相关回归 154 项通过;采集稳定性、 时间关联、准备路径和 20 主动关节合成产物回归 158 项通过,两组有重叠,不合计数量。 新增检查覆盖目标/反馈相差 ±10、中指分段范围、测得零位反馈为 10 的归位、 反馈缺失/不新鲜、单指不动、只有小幅反馈噪声、指令映射不依赖反馈拟合。 20 关节合成验证保留独立方向曲线、15 个零偏、五个 CAD 零位、原始 URDF 不变及 JSON 重建修正 URDF 的一致性检查。缺失/恒定反馈的旧测试显式选择视觉策略, 不代表当前生产配置允许在缺失反馈时采集。 产品配置只读校验通过,外部 SDK 的 61 份源码和原始 URDF 哈希保持不变。 本次未启动实机;新的现场精度及正式产物仍需实际完整采集与独立验收。

遮挡条件下的独立姿态准备(2026-09-20,显式启用)

用户确认四指伸直侧摆时,侧面 ID4/6/8/10 会互相遮挡。因此不能要求四指侧摆的 同一段运动提供四个侧面 Tag 的证据,也不将 G20 的双视角侧摆验收直接套到 O30。 O30 正式四指侧摆仍用原正面观测;屈伸仍用原侧面观测。新增策略不修改 Tag、相机、 正式任务顺序、训练/独立验证网格、速度或发布门限。

occlusion_aware_witness_v1 为四个 MCP pitch 任务各声明一份准备证据:

  1. 按该任务原有分组进入避让/零位姿态,先完成外侧手指弯曲。
  2. 保持所有其他通道,仅当前手指侧摆通道往返一次,幅度最多为原通道范围的四分之一 (O30 为 63 个 SDK 原始单位)。回到相同姿态后,再执行原 MCP 屈伸准备。
  3. 侧面同一个物理 Tag 在侧摆弧上的独立图像拟合先通过自己的训练/留出验收, 全参数协方差包含轴、安装和每帧角度;重复端点图像不降低独立证据要求。
  4. 在新的 MCP 零位端点复核原姿态,用这份证据约束 MCP 候选。MCP 自己的图像、 几何及留出门限继续执行。准备路径缺失、参考变化、持续歧义均不得强选或反复试到通过。

正面相机可并行保存当前侧摆 Tag 的原始观测,但不作为所有屈伸关节的第二路角度测量, 不要求无关手指的 Tag 同时可见。PIP/DIP 继续复用原父几何/旁观证据链。 这一策略新增有界准备动作,需要单独验证运动及可见性;总耗时收益必须由实机测量, 不宣称“零额外动作”或已经保证整手连续通过。

启动前的纯软件配置检查(不启动相机/SDK):

export ROS_DOMAIN_ID=99
ros2 run linkerhand_calibration calibrate_hand \
  --config src/linkerhand_calibration/config/o30_right_product.yaml \
  --training-policy staged_2_to_3 \
  --preparation-policy occlusion_aware_witness_v1 \
  --validate-only

实机验证需全新会话:将 --validate-only 换成 --no-resume。新策略不会自动启用; 旧断点仍用原参数恢复,不能加此参数拼接旧策略。准备定义进入原 capture_plan_v2 的 运动契约和哈希;旧计划省略空定义,与 20260920_144151 的实际历史计划逐字段一致。 新策略同策略断点保留原证据和重试边界,重新核查参考后恢复;冻结零位的回访及最终 独立验证不重复侧摆准备。新会话清空内存证据,历史原始记录不改写。

软件验证:真实无名指 MCP 的 127 帧在无新增证据时仍拒绝;在其上加入明确标注的 合成独立侧摆观测后,正式准备/证据回读入口可判别候选。合成源以候选 0 构造, 不能据此认定真实机械手候选 0 正确。真实中指 DIP 仍拒绝,既有拇指 IP 和姿态转接 回归通过。最终针对遮挡版的 58 项软件检查约 14.12 秒。既有 O30 分阶段产物一致性 与取消发布共 2 项共享一次整手夹具,约 32.12 秒;它们不是新准备策略的整手实机验收。 本轮没有启动硬件,没有发布新的 JSON/URDF。

准备求解的有界数值恢复

20260920_154722 调整 ID2 后,零位 ID1/ID2 均已可见,但 IP 的一个候选在稀疏求解 中耗尽 150 次求值。它不属于缺 Tag 或已经证明的姿态歧义;未收敛也不能据此排除候选。

独立铰链、测量迁移、共享零位、姿态转接现在共用 image_bundle_optimizer:先按原 稀疏路径求解,仅在预算耗尽且结果有限时,从当前参数追加一次直接信赖域求解,默认 最多 50 次。参数、几何边界、角点和收敛容差保持一致;不得根据留出误差决定是否追加。 直接解法受维度和 Jacobian 大小限制,覆盖默认最多六个关系/72 个训练帧;计算仍受 既有工作进程的 120 秒超时及取消控制。已经收敛的历史模型不走恢复路径。

每个候选报告实际算法、预算、终止状态、总求值数及代价;发生恢复时,策略与过程写入 原准备记录并绑定证据哈希。恢复后仍需通过原几何可观测性、像素门限和独立留出比较。 OBS-SOLVER-118 区分计算预算不足与 OBS-POSE-AMBIGUOUS-117 的真实姿态歧义; 计算失败不触发重复机械运动,不覆盖冻结模型,也不更新发布指针。

本次真实 IP 数据恢复后通过软件准备及证据回读,额外直接求解为 6 次、实测约 0.05 秒。 这是离线计算耗时,不是整手标定提效或实机连续通过的证明;此软件修复轮未启动机械手。

辅助准备证据的适用性与短暂同步缺失

20260920_160630 实机恢复已通过拇指 IP:另一候选在原 150 次求值后追加 8 次收敛, 按原像素门限排除;共保留 8 个扫描单元。随后小指 MCP 的 219 帧辅助观测中有 2 帧 无同步指令,被旧辅助验证误报为采集身份变化。该任务辅助侧摆的两条候选均不满足 原 15° 最小转角要求;它自己的 MCP 准备运动则能够独立通过全部门限。此前的合成 辅助观测有足够转角,因此没有暴露真实硬件上的适用性问题。

新记录 preparation_witness_v2 分开处理原始身份、采样有效性和辅助几何适用性:

  • 对全部原始行检查身份、相机、已有指令和反馈。缺指令的帧若反馈显示保持关节变化, 仍拒绝;缺反馈的帧也不能隐藏已有指令的变化。非有限值或向量格式错误不作为缺样跳过。
  • 缺同步值的帧不参与拟合,不插值、不补造。比例不得超过既有 maximum_unobserved_fraction (默认 1/16);必须在同一运动分段内被有效帧包围,间隙不得超过既有稳定窗口 steady_window_seconds(O30 为 0.2 秒)。分段边界和连续稳态末尾仍须有效。 相机/状态的原 50 ms 同步门限保持不变。原始行、排除时间戳和原因全部绑定到证据中。
  • 在任何辅助拟合之前,仅当全部原始候选都不满足原最小转角时,明确记录 independent_before_fit。主准备运动随后独立通过全部候选、几何、像素及留出门限。 缺候选、身份变化不等于转角不足;一旦辅助拟合开始,失败不得改走独立路线。
  • 采用辅助证据和拟合前判定不适用这两种情况都必须保留辅助记录。离线从完整原始窗口 重算排除清单和适用性,再重算主模型。删去记录、丢掉缺样帧、改写排除原因仍拒绝。 v1 历史证据沿用原严格取样语义,不改写已保存记录。

本次小指软件回放经正式准备、证据哈希及原像素重算入口通过;真实无名指歧义仍拒绝。 运动路径、速度、Tag、训练/验证分组及发布门限没有修改。本次软件修复未启动硬件, 不能据此声明整手连续通过;若后续关节独立运动仍有歧义且辅助观测不适用,仍需停止。

2026-09-20:MCP → PIP → DIP 的双端姿态交接

20260920_163002 已实际复用原 8 个扫描单元并完成小指 MCP 双向扫描,随后在 PIP 准备停止。原交接把 PIP 回零后的图像再次投影到旧 MCP 单轴模型上;最后 10 帧中 4 帧 RMS 为 1.526–1.600 px,触发原 1.5 px 门限。继续保持时仍有类似波动,不能靠 删去超限帧或原样多等一次来证明通过。原模型误差并不直接证明 Tag 松动。

新的 two_sided_shared_pose_v1 使用同一物理基准的两端证据:

  • 原 MCP 模型检查 MCP 已有回基准运动中的最后完整原始图像窗口,必须早于 PIP 整段准备弧。PIP 模型检查 PIP 回基准的独立窗口,并继续通过准备训练/留出验收。
  • 两端都保留 1.5 px、姿态一致性 2°/5 mm、静止散布 1°/1 mm 等原门限。 固定窗口按时间选取,不能按误差筛选;命令、反馈、Tag 编号/尺寸、相机、轮次、 观察代次及像素哈希共同绑定,验证轮不能作为交接源。
  • 原 MCP 零位及模型不修改。进入 DIP 时,由已经通过上述交接的 PIP 图像模型观测 当前父 Tag,但仍与原 MCP 零位比较,不重新解释或替换原零位。记录为 parent_reference_verified v2;几何来源仍是实测 PIP,末节 CAD 假设保持原语义。
  • 实时侧仅保留每任务/机位的有限原始图像尾部,复用已有采集和状态机,不增加动作。 断点导入保留交接依赖图像;重复导入同一曝光只计一次,冲突副本拒绝。只有日志记录 的内部恢复可跨观察代次继承,重新启动仍需重新核验参考。历史记录按原策略读回。

该逻辑用于 staged_2_to_3 加 occlusion_aware_witness_v1 的准备流程;采集计划、 速度、避让、Tag 布局及最终发布策略没有变化,未完成任务可从原断点重新进入。 两端验证在准备求解时执行,不把上游通过等同于整指或整手通过。

真实 PIP 回放通过正式准备及证据回读:留出 RMS 0.3584 px,最大帧 RMS 0.7464 px。 回零姿态差最大约 1.973°,接近现有 2°门限;后续实测超限仍须拒绝。 DIP 只完成模拟后续访问的正式采集/父参考回读测试,使用真实 PIP 像素和明确标注的 合成下游模型外壳,不冒充真实 DIP 标定。整手连续通过及最终实测精度仍待实机验收。

准备采样预算与连续运行(2026-09-20)

staged_2_to_3 配合 occlusion_aware_witness_v1 时,单关节准备按 256 个指令区间 保留观测,每区间最多一帧;训练与独立留出各最多 144 帧。此预算在采集/拟合前确定, 不根据哪一个候选得分较好追加数据。静止重复帧不增加运动区间;四指同时运动仍使用原 128 区间、72/72 帧预算,保持多关节求解内存上限。运动速度、范围、3°/3 mm 几何门限、 1.5 px 图像门限、候选区分显著性与最终产物验收均未放宽。

原因:20260920_171710 的小指 PIP 原准备保留 129 帧,DIP 保留 128 帧;PIP 自身过关,但其不确定度传给 DIP 后,两候选均超过 3°。从同一原始运动窗口保留更完整 观测后,两关节各得到 248 帧。离线反事实回放还使用新 PIP 模型重新投影原 DIP 图像, 验证整条依赖链;不修改原零位或历史日志,不把旧断点直接重新标记为通过。

这项优化需要新采集的上游模型。新版会自动排除缺少当前准备契约的旧断点,重新采集 完整准备链;新版本同契约断点仍支持恢复。验证独立整场运行时使用 --no-resume。 正式运行命令:

ros2 run linkerhand_calibration calibrate_hand \
  --config src/linkerhand_calibration/config/o30_right_product.yaml \
  --training-policy staged_2_to_3 \
  --preparation-policy occlusion_aware_witness_v1 --no-resume

断点初始化现在发布 PREPARING_CHECKPOINT 心跳,独立加载上限为 900 秒。设备就绪 等待和 Start 服务仍使用各自原有时限;心跳不授权运动、不跳过历史图像校验,也不代表 加载变快。发布线程在正常回调开始前退出,初始化异常时同样清理。

软件验证和现场记录位于 calibration_output/O30_RIGHT_001/software_review_stability_density/。 真实像素回放通过与整手实机连续通过分别记录;合成 JSON→URDF 测试产物不能作为本机标定交付。

新准备记录将 image_sampling_policy: native_command_256_split144_v1 同时写入初始化 报告和按角色哈希绑定的证据。辅助运动、独立准备、断点与最终验收的重新拟合均读取 这项策略;无字段的旧日志继续使用原预算。删除策略、改写策略或使训练/留出帧数超过 对应预算会拒绝回读,不能让在线与离线分别选择不同的子集。

准备契约与时钟刷新修复(2026-09-20)

session_start.preparation_contract 记录实际准备图:单/多关节采样预算、求解参数、 父子来源、零位路径和辅助动作。自动发现断点先比较这份契约,缺失或不同则排除该断点, 不读入大日志后再进入原停点。节点的显式恢复入口同样校验;产物回读还检查声明的新 契约下不存在使用旧采样预算的已接受模型。旧原始记录保持可读、不会被重写。 resume_selection.json 保存候选排除原因;显式重新开始的会话阻止回溯更早的旧谱系。

这里采用整场重新准备,避免对冻结训练、共享 Tag 交接和派生角度进行局部替换。 后续同契约恢复仍需基准及逐关节复核。此变更修复新旧模型混用,不代表已实现整手 准备统一联合求解,也不保证所有现场视角都具备可观测性。

相机在通过原连续性检查后,根据实测相位漂移缩短下一次校时的间隔,并扣除当前锚点 已经经历的时间。刷新目标使用原 1 ms 漂移预算的四分之一;周期限制在 20–500 ms。 真正的时钟跳变、计数器复位、过期映射及未来/乱序图像仍按原规则拒绝。 这解决了固定 500 ms 刷新无法适应平滑漂移的机制;三台实机的具体异常仍需新日志验收。

辅助旁观姿态拟合在计算前检查继承误差是否已耗尽原 1°/1 mm 预算。不可行来源记录为 observer_parent_precision_budget_exhausted,不会通过重复拟合或降低门限试图挽救。

针对回归、真实像素回放、合成完整 JSON→URDF 链路与只读配置检查均已通过,详见 software_review_stability_repair/software_validation.json。本次设备被独立的 linkerhand_range_calibration 占用,未中断它,也未执行新的实机标定或发布标定产物。

后续实机 20260920_183257 完整重采已完成拇指 8 个扫描单元;三台相机全程没有 时钟失效/重同步记录,随后小指 MCP 因辅助端点缺样暂停。原始侧摆尾部三帧缺少 同步命令,打断了连续窗口,最后只有两帧;固定停留结束仍推进至主准备,导致较晚 才报告 preparation_witness_stationary_endpoint_missing。

控制器现在于辅助侧摆最后一段结束时,检查与离线完全相同的末尾最多 11 帧窗口: 至少 10 帧、跨度至少 200 ms、原反馈稳定性以及完整图像/命令证据。满足后才离开; 缺样时只保持当前目标,仍按轨迹结束时刻起的原 steady_timeout_seconds 上限暂停。 不重新走运动弧、不补写缺失命令,也不把准备求解放回实时回调。

修复后的实机续采 20260920_184615 已复核复用拇指 8 单元,并完成小指、无名指的 MCP/PIP/DIP 首轮,累计 20 个扫描单元。小指新 PIP 继承轴向界约 1.08°,DIP 下游轴向界约 1.70°,已越过旧父模型导致的停点。侧相机出现一次锁存计数器异常读数, 约倒退 42.95 秒后下一读数恢复,自动重同步成功;front/top 无失效,SDK 无报告故障。

该次最终仍在中指 MCP 准备暂停:219 帧主准备,110 训练/109 留出;两候选均收敛、 均满足自身精度要求,但比较 p=0.354507,未达到 0.01。辅助侧摆有 222 原始帧、 完整 11 帧静止尾部,命令 133–196、反馈 128–193,图像实际转角仅约 3.94°/3.90°, 小于原 15° 准入要求,因此在拟合前判定独立信息不足。不能降低门限、猜选候选或 原样重试冒充通过;需要另行设计并验证更有区分力的独立观测。 本轮未产出可交付标定 JSON/修正 URDF;完整记录在该会话的 assistant_recalibration_review.json,所有实机进程已正常退出。

中指优先的完整采集尝试(2026-09-20 晚)

用户要求优先完整采集并输出验收通过的 JSON/URDF,现场只能自动运动,不能调整 Tag。 保留默认配置,另存完整 20 关节 Profile,将中指 MCP/PIP/DIP 依赖链排在开头; 当前机位、Tag、行程、速度和验收精度不变。中指 MCP 的辅助观测改为同一避让姿态下 已声明的 PIP 归零路径,其余手指仍按旧策略。

20260920_190901 的 PIP 0→63→0 实测约 19.4°,转轴不确定度仍约 5.6°,未通过。 20260920_191232 使用既有完整 0→255→0 路径,起始保持通道反馈 193→189, 超过原 2 u8 稳定阈值,完整数据保留为失败。截取稳定段的计算只用于判断下一次采集 可行性,不能作为正式证据。20260920_191613 重新采集后保持通道全程稳定, 独立 PIP 辅助拟合通过,但原事后共享姿态检查仍拒绝 MCP:两段拟合差约 3.4°/7.2 mm。

对同一份完整真实图像,独立辅助源先通过运动留出和新的静止图像验证,再将其共享 零位姿态接入已有 shared_zero_pose_v2 拟合,两种初值收敛为同一模型,独立图像 RMS 约 0.537 px。新辅助记录 preparation_witness_v3 和选择策略 training_preparation_witness_shared_pose_holm_v1 绑定这种求解方式;只在完全复用 既有归零路径时启用,旧辅助记录和普通有界侧摆路径语义不变。 这项回放通过尚不代表新的完整实机采集或最终产物通过。

统一父子 Tag 策略与未完成断点升级(2026-09-20)

此前 rigid_pair_v1 只在中指专项配置中启用,整手配置中的食指仍走旧路径。 策略选择现在由 profiles/observer_policy.py 根据任务的父参考、测量类型、视图和 共享 Tag 关系统一编译,不再按手指名称逐项启用。新的 --preparation-policy 无取值调用使用 occlusion_aware_witness_v2;显式 v1 和旧序列化 Profile 保持原语义,已有断点不会被静默解释为新策略。

runtime.checkpoint_observer_upgrade 提供独立的离线迁移入口:源断点先按原配置 正式回读;已有零位及所有已接受模型对应的策略保持不变,只升级尚未测定的依赖; 目标再经过原采集单元和几何证据验收,单元、参考和首轮跨度必须完全一致。 训练已作出决策、运动路径/精度变化、保护输入变化均拒绝迁移。原日志不修改, 新日志只更新配置元数据并追加审计,其余原始行逐字节保留。

当前食指配置位于 calibration_output/O30_RIGHT_001/software_review_observer_policy/。 真实 20260920_202249 食指来源也纳入回归:换用双 Tag 后仍必须拒绝 rigid_pair_candidates_unresolved。两候选相差约 13.52°,留出 RMS 分别约 0.178/0.209 px,比较 p≈0.140,高于原 0.01 门限;最优候选的来源位置界 约 1.054 mm,也超过 1 mm。提高内部数值求解精度的离线诊断仍得到相同结论, 没有将该诊断修改并入生产求解器。该组观测不能因更换策略就宣布通过,后续需要 新的有效独立观测;本次配置修复不代表整手实机完成或已生成合格 JSON/URDF。

实际迁移结果为 20260920_204022_observer_upgrade:原/新策略正式静态回读均通过, 30 个已通过扫描单元、已有零位和首轮跨度保持一致;唯一变更为未通过的 index_dip: frozen_parent_v1 → rigid_pair_v1。原 20260920_202249 日志保持原样。 迁移报告为新断点中的 observer_upgrade.json;本轮没有再次启动硬件采集。

观测检查与有界补采(2026-09-20 晚,后续修复)

motion.observer_preparations 单独声明未测关节的辅助观测路径。编译器根据 Tag 共同祖先和 CAD 转轴关系选择非平行的驱动通道;其他通道保持原避让姿态,偏移不超过 声明行程的四分之一,最终返回原姿态。辅助路径由准备契约和 Profile 哈希保护, 不改变 CapturePlan 中已通过扫描单元的身份、训练/验证划分或质量门限。

正式关节准备前,先检查上游原始图像中的平面法线方向覆盖。画面内旋转不会被当成 视角变化;不足 15° 或来源不足会触发独立补采。该阈值只决定是否补采,不能代替 最终可观测性验收。预检查未触发、但原来源求解仍有歧义时,也只允许一次声明路径, 随后重新获取当前未通过关节的准备图像;硬件故障、安装变化和损坏证据不走此恢复。

补采使用现有轨迹、SDK 反馈、固定参考监控和超时。共同上游运动时不使用旧的保持 姿态模型解释新图像,直接保存原始角点;独立拟合枚举父/子 IPPE 初值,并对留出图像 的局部父姿态检查所有候选。父子相对姿态仍须满足 1°/1 mm、原像素误差和候选比较 门限,之后还要通过当前静止端点及正式 DIP 几何验收。observer_pose_bridge_v3 绑定完整计划、运动开始授权、分段完成记录、原始图像哈希和独立训练/留出划分。

运动开始授权在第一个非静止段前落盘,重启不会刷新已消耗的次数。尚未开始侧摆的 计划可以通过 observer_preparation_cancelled_before_excursion 审计后重新准备; 已开始但未完成的路径不会被静默当成完整证据,也不会自动重复。已经完整采集的 补采证据可随断点恢复,原始失败记录保持不变。

20260920_205911_active_observer 从前一断点迁移并通过静态回读,保留全部 30 单元, 仅为未通过的食指 DIP 添加辅助动作。首次实机 20260920_210259 已实际导入并跳过 30 单元,预检查正确触发补采,但在初始静止段误报图像过期,未开始侧摆。 新端点门控误用了 0.2 秒稳定窗口作为图像时效,现已改用既有 visual_stale_seconds 契约,并以该次真实 145 条计划/观测记录回归。未放宽测量精度或独立验收门限。

2026-09-20 21:29 增量验证:20260920_211220 已原样复用 30 个通过单元, 完整执行 index DIP 的第一步公共祖先侧摆(255→192→255),留下 238 帧侧相机原图像证据。 实际法线变化约 4.48°;独立求解及与原父关节旁观帧合并的离线诊断仍无法区分候选, 不把小幅运动完成当作观测充分。该会话实际暂停在父标签静止复核:原 SDK 反馈 247, 当前稳定反馈 255;旧复核误用 4 单位跨次差异,而已有 staged_revisit_v2 声明 O30 跨次重复性为 10。父复核统一调用该规则,新记录绑定规则及数值;旧记录缺省仍用 v1。 本轮稳定性 2 单位、图像姿态与求解/发布精度不改变,原关节零位不替换。

补采计划改为有限序列,第一步保留 1/4 行程,只有实际法线覆盖不足或正式求解仍有歧义 才执行第二步;第二步边界来自公共祖先已有零位准备路径,当前食指为 255→0→255。 始终保持 recipient 的原避让姿态和 DIP 命令。最多两次,决策记录保存序号、前次证据哈希、 起动授权及三段端点,重启不刷新预算。旧单步格式继续可读;升级只能给未通过 joint 的 计划追加该标准序列,源日志与已通过 30 单元保留,迁移需经过原回读校验。

20260920_213013 实机确认:完整复用 30 单元及旧第一步补采,直接完成第二步 255→0→255;三段端点和父标签复核通过,法线覆盖约 24.42°。DIP 正式准备仍以 rigid_pair_candidates_unresolved 暂停。随后离线发现逐帧父标签局部分支没有在训练中 充分重选;加入最多三次、仅使用训练图像的局部姿态重选与联合优化后,四个候选收敛到 同一相对安装(差异 <0.001°),源姿态 3σ 约 0.485° / 0.191 mm,原门限不变。 新的双 Tag 源通过,但该批 DIP 正式几何回放仍拒绝 image_motion_geometry_uncertain, 不能称食指已通过,也没有生成整手合格产物。用户随后要求先导出拇指,未再次启动实机。

拇指初版:calibration_output/O30_RIGHT_001/20260920_214650_thumb_preview/ 含 URDF、网格、469 KB 关键观测和说明/审计 JSON。四关节各一轮双向,共 8 个通过单元。 只使用拇指数据建立局部串联坐标,根部 CMC roll 保留 CAD 零位,避免将手掌基准朝向 与根关节零位混为独立测量;IP 保留原 CAD 零位假设。初步估计 CMC yaw +0.396168°、 MCP −1.085365°,仅用于预览。首轮数据的正式零位置信区间检查未通过且无独立验证轮, 因此不发布为合格标定,不更新 latest 指针。URDF 仅两个关节的 origin.rpy 与坐标换算后的 原限位改变;100 组 FK 换算最大矩阵误差 6.67e-16,其他关节/网格/惯量均未改。