机器人抓取偏了几毫米,第一反应通常去查标定。我踩过一次反过来的坑:标定参数本身没问题,是 TF 树里少了一个关节,标定把这个结构性错误一起吸收进去了。

所以现在遇到“标定不准”,我会先去看树结构和关节值来源,再碰标定参数。

外参本身也不是一个精确常数。它是个带误差和适用范围的估计值,跟采集时的构型、运动范围、标定板可见性都有关。只报一个最终残差,看不出这组参数在真实工作空间里靠不靠得住。

确定相机装在哪→采多组位姿和观测→建立 AX = XB 约束→变换空间求外参→回到任务空间看残差→写清失效条件
标定证据链求解形式、采集构型和验证方式一起决定这组外参能不能被任务信任。
Eye-in-Hand相机在末端,标的是相机与法兰的关系。Eye-to-Hand相机在外部,标的是相机与基座的关系。AX = XB两次位姿之间的运动约束,两种装法已知量不同。构型覆盖只在一个小范围转动,有些自由度几乎不可观测。求解空间旋转平移量级不同,混着解会放大旋转误差。任务验证最终看的是重投影或抓取点误差。

先把两种装法分开

Eye-in-Hand:相机在末端,跟着机械臂动,标的是相机到末端法兰的关系。近距观察和随动抓取常用它,但线缆、遮挡和运动模糊都会影响采集。

Eye-to-Hand:相机固定在外部支架上,标的是相机到机器人基座的关系。视角稳定,但工作空间受视场限制,标定时要确保机械臂本体不挡住标定板。

两种装法经常都写成同一个 AX = XB,但哪个量已知、哪个量待求是不一样的。把公式和参数混用,是“看着差不多但就是抓不准”的常见来源之一。

约束是怎么来的

机械臂在两个位姿间移动,相机对标定板的观测跟着变。同一段物理运动,从机器人侧描述和从相机侧描述应当一致,这个一致性就是矩阵方程。

单个位姿差给不出完整解,因为旋转和平移耦合在一起。所以要多组运动,而且旋转轴要尽量散开。如果所有采集位姿都绕同一个轴小角度转,其他方向的约束就很弱,结果对噪声极其敏感。

采集时的几个经验:标定板在每个位姿都要完整可见;覆盖实际会用到的区域;别让关节靠近奇异位形;把每组关节值和图像都存下来,方便事后复算而不是重采。

旋转和平移别一起解

这是我见过最多的坑:把旋转和平移塞进同一个最小二乘。两者量纲不同,旋转误差会主导残差,把平移压到不合理的值上。

常规做法是先用旋转部分解出旋转,再回代求平移。历史上有很多种解法和变体,对噪声的敏感度不一样。不管用哪种,我都会保留中间量——如果旋转解本身就发散,后面的平移基本不可能可靠。

解完至少看两件事:每组重投影误差的分布,以及外参在不同子集上的稳定性。把数据随机分成两半分别求,如果两组外参差得很多,说明采集构型不够,或者数据里有明显的坏点。

用任务指标验,别只看方程残差

方程残差降下来不等于任务能用。更贴近使用的检查是:用标定外参把相机看到的目标位置变换到机器人坐标系,跟机器人实际到的位置比。这个误差才跟抓取成败直接相关。

1
2
3
4
5
# 记录验证点的关节值和对应图像
ros2 bag record /joint_states /camera/image_raw /camera/camera_info

# 用外参把检测结果变换到机器人坐标系
ros2 run my_robot transform_probe --once

验证点要铺在标定覆盖范围内以及边缘。只在中心附近验,误差看着很小,但任务实际发生在边界上的时候就露馅了。

失效条件得写下来

外参不是一劳永逸的。碰撞、换工具、相机支架松动、镜头重新装调、温度明显变化,都可能让它变掉。工程上至少记录标定时间、用了哪些构型、残差指标,以及什么情况下必须重标。

没验证的范围也要写清楚。只做过静态标定,推不出动态也准;只在一个子区域验过,推不到整个工作空间;只用仿真和虚拟标定板,替代不了真实相机加真实板子。

参考资料

证据边界:本文不含任何具体机器人、相机或标定板上的实测精度。文中的误差量和适用范围都要在实际系统上单独测;仿真、虚拟标定板和静态采集替代不了真实任务里的验证结论。