Files
mujoco_linkerbot/tools/o30_right_calibration/README_v3.md
T

5.5 KiB
Raw Blame History

O30 右手多视角校准(V3)

基于用户认可的 V2,新增八张侧视图。左视图 1~4、右视图 5~8 都依次为食指、中指、无名指、小指捏合,控制值保持 samples.json 的四组原值。保留原五张正面/零位照片的约束。

使用

在项目根目录运行:

./hands/O30/scripts/run_o30_right_mujoco_plan.sh

默认读取 linkerhand_o30_right_multiview_calibrated.urdf,重新生成实际运行的 URDF/MJCF。订阅 /cb_right_hand_control_cmd(sensor_msgs/msg/JointState,20 路 SDK 0~255),顺序不变。启动零位仍为:

[0, 0, 255, 195, 100, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

零位偏移写入 URDF 关节 origin,行程写入关节 limit;桥接从实际 MJCF 读取行程,不重复叠加偏移。连杆长度、关节轴和 STL 几何未修改。

本次优化

fit_multiview.py 同时拟合 13 张图,共享一套关节零位/行程参数。接触点限制在指尖附近指腹,并保留相对法向、穿透、零位与 V2 参数正则约束。每张图有独立相机位姿,共享焦距;相机不是实测标定结果。

在 MuJoCo 中用多起点、有边界的非线性优化反复试算。正式四轮共 10,766 次目标评估,全部通过验收,保存其中目标值最低者。这是自动试错标定,没有训练强化学习策略。相对 V2 的零位偏移调整限制在 ±8°,行程比例调整限制在 ±0.3,绝对比例仍为 0.5~1.5;五个已知姿态中最大关节角变化为 9.42°。

照片没有可读的本地原文件。side_landmarks.json 是从聊天显示的 540×720 图片人工估计的关节中心,像素不确定性为 5~18 px。拇指根部等遮挡点权重较低;身份不明确的背景关节点未纳入。没有自动识别标记或测量三维坐标。

结果和取舍

V2 与 V3 各自拟合相机,在同一组人工标注上比较:

  • 侧视图较清楚的中间关节(目标手指 PIP/DIP、拇指 IP)RMS:9.00 → 5.62 px,降低约 38%。
  • 侧视图全部标注 RMS:12.47 → 8.96 px。
  • 全部 13 张图片 RMS:10.19 → 9.28 px。
  • 原五张正面/零位图片 RMS:8.08 → 9.52 px,有小幅回退。
  • 零位图片 RMS:6.56 → 6.55 px,基本保持。

正面回退是兼顾侧面中间关节姿态后的取舍。被遮挡的根部点仍有明显残差,不能将这些拟合误差解释为真实三维精度或独立测试误差。

实际启动模型四组指腹网格有符号距离依次为 −0.057、+0.018、+0.136、−0.017 mm(正为间隙,负为穿透),均满足 ±0.2 mm 仿真接触容差。指腹相对法向误差最大 2.81°;零位没有检测到穿透。接触指标针对 MuJoCo 碰撞网格,不代表真机达到亚毫米精度。

37 组输入检查通过:四组捏合、零位、全 0、全 255、30 组随机输入。导出模型与优化模型的连杆位置最大差异为 3.85e-10 m。随机输入只验证导出/映射一致,不证明未见姿态与真机一致或运动过程无碰撞。三个回归测试通过,包括真实 JointState 类型消息经过桥接回调后的四组姿态、启动零位、模型切换与无效限位处理。未发送真机控制指令。

对比图与参数

reports/o30_right_multiview_calibration/ 中:

  • left_comparison.png:四组左视图,上排 V2,下排 V3。
  • right_comparison.png:四组右视图,上排 V2,下排 V3。
  • front_zero_comparison.png:原正面四组捏合与零位。
  • *_pose.png:新版单张模拟图。
  • *_landmarks.png:青色为人工图片标注、红色为模型投影。这是模拟图诊断,不是原始照片叠图。
  • validation.json:原始标注哈希、相机参数、逐点误差、关节参数、搜索和实际模型验证结果。

对比图每列使用相同相机与材质,便于只比较关节形态。参数主文件为模型目录的 o30_right_multiview_calibration.json。

复现

O30_RIGHT_PREPARE_ONLY=1 ./hands/O30/scripts/run_o30_right_mujoco_plan.sh
OPENBLAS_NUM_THREADS=1 venv/bin/python tools/o30_right_calibration/fit_multiview.py --check --render

单独预览(可将 zero 换成 index、middle、ring、pinky):

venv/bin/python tools/o30_right_calibration/fit_multiview.py --preview zero

重新拟合后,先生成模型再检查:

OPENBLAS_NUM_THREADS=1 venv/bin/python tools/o30_right_calibration/fit_multiview.py --fit --starts 4 --max-nfev 180
O30_RIGHT_PREPARE_ONLY=1 ./hands/O30/scripts/run_o30_right_mujoco_plan.sh
venv/bin/python tools/o30_right_calibration/fit_multiview.py --check --render
source /opt/ros/jazzy/setup.bash
PYTHONPATH="$PWD/venv/lib/python3.12/site-packages:$PYTHONPATH" python3 tools/o30_right_calibration/test_calibration.py

保留上版

V2 已备份为 linkerhand_o30_right_photo_calibrated_v2.urdf 和 o30_right_photo_calibration_v2.json,说明见 README_v2.md,原有 V2 报告保留。临时切回:

O30_RIGHT_URDF="$PWD/src/linkerhand-sim/linker_hand_mujoco_ros2/linker_hand_mujoco_ros2/urdf/O30/linker_hand_o30_right/linkerhand_o30_right_photo_calibrated_v2.urdf" ./hands/O30/scripts/run_o30_right_mujoco_plan.sh

之后正常运行脚本即恢复 V3。原始 stock 和 V1 文件也保留。当前请使用 fit_multiview.py;fit_photos.py 是 V2 的历史实现。

这些照片不足以唯一确定全部零位和全行程。完整机械行程、未见动作以及真机动力学仍未标定;食指 DIP 等在已有指令中缺少激励的参数尤其不能视为实测值。