坐标系基础:机器人基坐标系、工具坐标系、相机坐标系、世界坐标系、齐次变换矩阵

做手眼标定,说白了就是搞清楚几个坐标系之间的相对位置关系。你想想看,机器人要抓一个杯子,相机看到了杯子,但机器人得用自己的手去抓——这两个“看到”和“抓到”之间,差的就是坐标系变换。

我个人习惯,在开始标定之前,先把这几个坐标系在脑子里过一遍。不然参数调来调去,最后发现是坐标系定义错了,那就白忙活了。

1. 四个核心坐标系

手眼标定里,我们打交道最多的就是这四个坐标系。我列个表,方便你对照着看:

坐标系名称 符号 位置 作用
世界坐标系 {W} 用户自定义,通常在地面或工作台一角 全局参考,所有物体位置的最终基准
机器人基坐标系 {B} 机器人底座中心 机器人自身运动的参考原点
工具坐标系 {T} 机器人末端法兰或夹爪中心 描述工具(如相机、焊枪)相对于末端的位姿
相机坐标系 {C} 相机光心 图像中看到的物体,坐标原点在相机内部

关键点:手眼标定的本质,就是求解 {C} 相对于 {T} 的变换矩阵(眼在手上),或者 {C} 相对于 {B} 的变换矩阵(眼在手外)。

2. 齐次变换矩阵:坐标系的“翻译官”

坐标系之间怎么换算?靠的就是齐次变换矩阵。它长这样:

    ┌             ┐
    │ R   t │
T = │       │
    │ 0   1 │
    └             ┘

其中:

  • R:3×3 旋转矩阵,描述两个坐标系之间的朝向关系
  • t:3×1 平移向量,描述原点之间的偏移
  • 最后一行 [0 0 0 1]:保证矩阵可逆,方便连续变换

举个例子。我在项目里遇到过一种情况:相机装在机器人手腕上(眼在手上),相机看到标定板上的一个点,坐标是 p_c。我想知道这个点在机器人基坐标系下的坐标 p_b。怎么做?

先通过机器人正运动学得到工具坐标系相对于基坐标系的变换 T_b_t,再通过标定得到相机相对于工具坐标系的变换 T_t_c。那么:

p_b = T_b_t * T_t_c * p_c

你看,三个矩阵一连乘,坐标就翻译过来了。这就是齐次变换矩阵的妙处——把旋转和平移打包在一起,一次搞定。

我的习惯:写代码时,我一般用 4×4 的 numpy 数组存变换矩阵。乘法用 np.dot 或者 @ 运算符,注意顺序别搞反——左乘是相对于固定坐标系,右乘是相对于当前坐标系。

3. 坐标系之间的层级关系

这几个坐标系不是平级的,它们有父子关系。我画了一张图,帮你理清脉络:

坐标系层级关系与变换链 世界坐标系 {W} 机器人基坐标系 {B} 工具坐标系 {T} 相机坐标系 {C}(眼在手上) 相机坐标系 {C}(眼在手外) 说明: 实线箭头 = 眼在手上(相机固定在工具上),虚线箭头 = 眼在手外(相机固定在世界中)。

从图里你能看到:

  • 眼在手上:相机跟着机器人末端走,{C} 是 {T} 的子节点。标定目标是求 T_t_c。
  • 眼在手外:相机固定不动,{C} 是 {B} 的平级节点。标定目标是求 T_b_c。

我曾经踩过的坑:有一次做眼在手上的标定,我忘了把工具坐标系的原点设在法兰盘中心,而是设在了夹爪尖端。结果标出来的外参矩阵,平移分量总是差一截。后来花了半天才排查出来——坐标系定义错了,后面全是白算。

4. 齐次变换矩阵的运算规则

搞清楚了坐标系,接下来就是怎么算。我总结了几条铁律:

  1. 连续变换用左乘:从 {A} 到 {B} 再到 {C},变换矩阵是 T_a_c = T_a_b * T_b_c。
  2. 逆变换就是求逆矩阵:T_b_a = inv(T_a_b)。因为齐次变换矩阵是可逆的,直接用公式算就行。
  3. 注意单位:平移向量的单位要和机器人、相机的单位统一。我习惯用毫米,因为大多数工业机器人和相机标定板都用毫米。

举个例子,假设你有一个点 p 在 {C} 下是 (100, 50, 200),T_c_b 是:

T_c_b = [[0, -1, 0, 300],
         [1,  0, 0, 100],
         [0,  0, 1,  50],
         [0,  0, 0,   1]]

那么 p 在 {B} 下的坐标就是:

p_b = T_c_b * [100, 50, 200, 1]^T
    = [0*100 + (-1)*50 + 0*200 + 300,
       1*100 + 0*50   + 0*200 + 100,
       0*100 + 0*50   + 1*200 +  50,
       1]
    = [250, 200, 250, 1]^T

你看,旋转部分把 x 和 y 交换了,平移部分加了偏移。这就是齐次变换矩阵的直观效果。

一个小技巧:调试的时候,我经常用单位矩阵(I)作为初始猜测。如果标定结果收敛到单位矩阵附近,说明相机和工具坐标系几乎重合——这在物理上不太可能,通常意味着数据有问题。

5. 坐标系定义的最佳实践

最后,分享几条我在项目里总结出来的经验:

  • 世界坐标系尽量和机器人基坐标系对齐:省去一次变换,减少误差累积。
  • 工具坐标系的原点设在法兰盘中心:这是机器人厂商默认的,方便和正运动学对接。
  • 相机坐标系用右手系:z 轴指向相机前方,x 轴向右,y 轴向下(图像坐标系习惯)。
  • 标定板坐标系和世界坐标系对齐:标定板放平,让它的 z 轴朝上,这样标定出来的外参更稳定。

嗯,坐标系这块就讲到这里。你把这些概念吃透了,后面学手眼标定的算法就会顺很多。记住一句话:坐标系定义清楚,标定就成功了一半。