3. 坐标系与变换链:机器人基座、工具、相机、标定板之间的坐标变换关系

手眼标定,说白了就是搞清楚几个坐标系之间到底怎么转的。你想想看,机器人要抓一个东西,它得知道自己的手在哪儿,相机得知道看到的东西在哪儿,这两者之间得有个“翻译官”。这个翻译官,就是坐标变换链。

我刚开始做标定的时候,总觉得不就是几个矩阵相乘嘛,有什么难的?结果第一次现场调试,机器人撞了夹具,相机拍了半天找不到点。后来才发现,坐标系定义错了,整个变换链都是乱的。嗯,从那以后,我每次做标定前,都会先把坐标系图画出来。

3.1 四个核心坐标系

手眼系统里,我们主要跟四个坐标系打交道。记住它们的定义,后面就不会乱。

坐标系 符号 描述 典型原点
机器人基座坐标系 {B} 机器人的世界原点,所有运动都基于它 机器人底座安装面中心
工具坐标系 {T} 机器人末端执行器的位姿 法兰盘中心或工具尖端
相机坐标系 {C} 相机光心为原点,Z轴指向拍摄方向 相机光心
标定板坐标系 {P} 标定板上的特征点定义的世界 棋盘格左上角或中心

关键点:这四个坐标系不是孤立的。它们通过刚体变换(旋转+平移)连接在一起,形成一个闭环。任何一个环节定义错了,标定结果就是错的。

3.2 变换链的数学表达

我们用一个4x4的齐次变换矩阵来表示两个坐标系之间的关系。比如,BTT 表示从工具坐标系 {T} 到基座坐标系 {B} 的变换。

整个手眼系统的变换链可以写成:

B_T_P = B_T_T * T_T_C * C_T_P

其中:

  • B_T_P:标定板在机器人基座坐标系下的位姿(已知,由机器人运动学算出)
  • B_T_T:工具在基座坐标系下的位姿(从机器人控制器读取)
  • T_T_C:相机在工具坐标系下的位姿(这就是我们要标定的手眼矩阵!)
  • C_T_P:标定板在相机坐标系下的位姿(由相机拍摄标定板图像算出)

我的习惯:每次写代码前,我会在纸上把变换链画出来,标清楚每个矩阵的上下标。比如 B_T_T 的“B”是目标坐标系,“T”是源坐标系。这样写代码时不容易搞反。

3.3 两种典型配置:眼在手上 vs 眼在手外

根据相机安装位置,手眼系统分两种。我见过不少新手在这上面栽跟头。

3.3.1 眼在手上(Eye-in-Hand)

相机固定在机器人末端,跟着工具一起动。这是最常见的配置。

  • 变换链:B_T_P = B_T_T * T_T_C * C_T_P
  • 标定目标:求 T_T_C(相机相对于工具的位姿)
  • 特点:相机视野随机器人移动,适合大范围作业

3.3.2 眼在手外(Eye-to-Hand)

相机固定在工作台上,不随机器人移动。

  • 变换链:B_T_P = B_T_C * C_T_P
  • 标定目标:求 B_T_C(相机相对于机器人基座的位姿)
  • 特点:相机视野固定,适合小范围高精度作业

我曾经踩过的坑:有一次做眼在手外标定,我直接把眼在手上的代码拿过来改,结果变换链写反了。标定出来的矩阵,机器人抓东西差了5厘米。后来花了半天时间排查,才发现是 T_T_C 和 B_T_C 搞混了。所以,配置不同,变换链完全不同,千万别偷懒。

3.4 变换链的误差传递

为什么标定精度上不去?很多时候不是算法问题,是变换链里的误差在累积。

每个变换矩阵都有误差:

  • B_T_T 的误差:来自机器人运动学参数(连杆长度、关节零点等)
  • C_T_P 的误差:来自相机内参标定、角点检测精度
  • T_T_C 的误差:来自标定算法本身的数值稳定性

这些误差通过矩阵乘法一层层传递。最终标定结果的误差,是各个环节误差的叠加。我做过一个实验:

误差来源 典型误差量 对标定结果的影响
机器人运动学 0.1-0.5 mm 平移误差直接叠加
相机内参 0.1-0.3 像素 旋转误差放大
角点检测 0.05-0.2 像素 随机噪声
标定算法 0.01-0.1 mm 数值稳定性

结论:想提高标定精度,不能只盯着算法。你得先看看机器人本身准不准,相机标定做没做好。我曾经在一个项目里,花了两周优化标定算法,精度只提升了0.1mm。后来发现是机器人末端重复定位精度就有0.3mm,算法再怎么优化也没用。

3.5 坐标系与变换链的SVG结构图

下面这张图,是我每次做标定前都会画的。它把四个坐标系和变换关系一目了然地展示出来。

手眼标定坐标系与变换链结构图 手眼标定坐标系与变换链 机器人基座 {B} 工具 {T} 相机 {C} 标定板 {P} B_T_T 机器人运动学 T_T_C 手眼矩阵(待求) C_T_P 相机外参 B_T_P = B_T_T * T_T_C * C_T_P 说明: • 实线箭头表示直接测量或已知的变换关系 • 虚线箭头表示通过变换链计算得到的间接关系 • 红色节点 {T} 到绿色节点 {C} 的变换 T_T_C 是手眼标定的核心目标

3.6 实际项目中的变换链检查清单

每次做标定前,我会按这个清单过一遍。你可以直接拿去用。

  1. 确认坐标系定义:机器人基座原点在哪?工具坐标系是法兰盘还是工具尖端?
  2. 确认相机安装方式:眼在手上还是眼在手外?变换链公式选对了没?
  3. 确认标定板方向:标定板坐标系的原点和轴方向,跟算法里定义的是否一致?
  4. 验证单个变换:每个变换矩阵单独验证一下,比如 B_T_T 读出来的值跟机器人示教器上显示的是否一致?
  5. 闭环验证:用标定结果反算一个已知点,看看误差有多大。

一个小技巧:我习惯在标定前,先让机器人走几个固定姿态,用相机拍标定板,然后手动算一下变换链。如果算出来的结果跟预期差太多,说明某个环节定义错了。别急着跑标定算法,先排查问题。

3.7 常见坐标系定义错误

我整理了几个最常见的错误,你遇到了可以对照排查。

错误类型 现象 后果
基座坐标系方向搞反 机器人运动方向跟预期相反 标定结果旋转误差大
工具坐标系未更新 换了工具没重新标定TCP 平移误差可达数厘米
相机坐标系轴定义不一致 OpenCV的坐标系跟机器人坐标系不同 旋转矩阵完全错误
标定板原点选错 棋盘格左上角和右下角搞混 平移误差固定偏移

特别提醒:不同品牌的机器人,坐标系定义可能不一样。比如ABB的基座坐标系Z轴向上,而发那科的Z轴可能指向不同方向。做标定前,一定要看机器人手册,确认坐标系定义。我曾经因为没看手册,直接用默认配置,结果标定出来的矩阵在另一台机器人上完全不能用。

坐标系和变换链,是手眼标定的地基。地基没打好,上面盖的房子再漂亮也没用。我建议你每次做标定前,花10分钟把变换链画清楚,把每个矩阵的物理意义想明白。这10分钟,能帮你省下后面几小时的排查时间。