2. 手眼标定基础:坐标系定义、标定板选择与方程推导
各位同学,欢迎来到第二章。这一章是手眼标定的地基,也是整个无序抓取系统里最容易出bug的地方。我见过太多项目,算法调得再好,标定一塌糊涂,最后抓取精度就是上不去。说白了,坐标系没对齐,后面全是白费功夫。
咱们这一章就干三件事:把坐标系理清楚、把标定板选对、把标定方程推导明白。别小看这些基础,我当年刚入行时,就因为搞混了工具坐标系和法兰坐标系,浪费了整整一周的调试时间。嗯,咱们开始吧。
2.1 坐标系定义:机器人基座/工具/相机/工件
一个典型的3D视觉无序抓取系统,至少涉及四个坐标系。它们之间的关系,就是手眼标定要解决的问题。
| 坐标系 | 符号 | 描述 | 典型原点位置 |
|---|---|---|---|
| 机器人基座坐标系 | {B} | 机器人世界的参考系 | 机器人安装底座中心 |
| 工具坐标系 | {T} | 固定在机器人末端执行器上 | 夹爪中心或吸盘平面 |
| 相机坐标系 | {C} | 3D相机自身的坐标系 | 相机光心 |
| 工件坐标系 | {O} | 描述被抓取物体的位姿 | 工件几何中心或特征点 |
你想想看,机器人要抓一个工件,它需要知道什么?它需要知道工件在它自己基座坐标系{B}下的位姿。但相机只能看到工件在相机坐标系{C}下的位姿。所以,我们必须找到一个变换矩阵,把{C}下的坐标转换到{B}下。
这个变换矩阵,就是手眼标定的核心目标。我个人习惯把它记作X,也就是相机到机器人基座的变换。
核心公式:
工件在机器人基座下的位姿 = 相机到基座的变换 × 工件在相机下的位姿
用符号表示:P_B = X * P_C
这里有个容易混淆的点:工具坐标系{T}。它和相机坐标系{C}之间也有一个固定变换,这个变换通常叫做手眼矩阵。在Eye-in-Hand(眼在手上)配置中,相机固定在机器人末端,所以X其实是工具到相机的变换,然后通过机器人正运动学再转换到基座。
我在项目中遇到过一种情况:工程师把工具坐标系原点设在了法兰盘中心,但实际夹爪中心偏移了50mm。结果每次抓取都偏那么一点点,调了好久才发现是工具坐标系没校准。所以,工具坐标系一定要用四点法或六点法精确标定,别偷懒。
2.2 标定板选择:棋盘格/圆点阵/ArUco
标定板是手眼标定的“尺子”。选对了,事半功倍;选错了,数据全是噪声。市面上常见的标定板有三种,我分别说说它们的优缺点。
| 类型 | 检测算法 | 精度 | 鲁棒性 | 适用场景 |
|---|---|---|---|---|
| 棋盘格 | 角点检测 | 高(亚像素级) | 中等(易受光照影响) | 2D相机标定、高精度场景 |
| 圆点阵 | 圆心拟合 | 高(椭圆拟合) | 高(抗畸变能力强) | 3D相机标定、大角度拍摄 |
| ArUco码 | 二维码解码 | 中等 | 极高(自带ID识别) | 多板标定、自动识别场景 |
棋盘格:我最常用的一种。角点检测精度可以做到亚像素级,但有个致命弱点——它要求标定板平面和相机成像平面尽量平行。如果角度太大,角点检测会失败。我记得有一次在产线上,相机安装角度比较刁钻,棋盘格死活检测不到,后来换成圆点阵就解决了。
圆点阵:说白了就是一堆排列整齐的圆点。它的优势在于,即使拍摄角度很大,圆变成椭圆,也能通过椭圆拟合精确找到圆心。对于3D相机来说,圆点阵是首选。我个人的经验是,用圆点阵做手眼标定,精度比棋盘格稳定10%-15%。
ArUco码:这东西自带ID,可以同时放多个标定板在场景里,相机自动识别每个板的ID和位姿。适合做全自动标定,不需要人工干预。但精度不如前两者,毕竟它是靠二维码解码来定位的,像素级精度。
我的建议:
如果你做的是高精度抓取(比如装配),用圆点阵标定板,尺寸选大一点(至少覆盖相机视场的1/3)。
如果你做的是快速部署、频繁换产,用ArUco码,配合自动标定脚本,省时省力。
2.3 标定方程推导
好,重头戏来了。手眼标定的核心方程,其实就是解一个AX = XB的问题。别被这个形式吓到,我来一步步拆解。
先看一个场景:机器人带着相机移动,在两个不同的位姿下,分别拍摄标定板。
- 位姿1:机器人工具坐标系为
T1,相机看到标定板的位姿为C1 - 位姿2:机器人工具坐标系为
T2,相机看到标定板的位姿为C2
这里,T1和T2是已知的(从机器人控制器读取),C1和C2也是已知的(从相机拍摄标定板计算得到)。未知的是手眼矩阵X。
我们定义一个关系:
- 机器人从位姿1到位姿2的变换:
A = T2 * inv(T1) - 相机从位姿1到位姿2的变换:
B = C2 * inv(C1)
那么,手眼标定方程就是:
AX = XB
为什么?因为标定板相对于机器人基座是固定不动的。机器人移动前后,标定板在基座下的位姿不变。通过这个约束,就能推导出AX = XB。
推导过程其实不复杂:
- 在位姿1下,标定板在基座下的位姿 =
T1 * X * C1 - 在位姿2下,标定板在基座下的位姿 =
T2 * X * C2 - 因为标定板不动,所以
T1 * X * C1 = T2 * X * C2 - 两边左乘
inv(T2),右乘inv(C1),得到inv(T2)*T1 * X = X * C2*inv(C1) - 即
A * X = X * B
解这个方程,常用的方法有:
- 两步法:先解旋转部分(用四元数或罗德里格斯公式),再解平移部分。Tsai和Lenz的经典方法。
- 单步法:把旋转和平移放在一起,用李代数或SVD分解一次性求解。精度更高,但计算稍复杂。
我个人习惯用两步法,因为调试时能分开看旋转误差和平移误差,方便定位问题。我曾经在一个项目里,旋转部分解出来误差只有0.1度,但平移误差有5mm,后来发现是标定板平面度和机器人定位精度的问题。
注意:
解AX = XB至少需要两组非平行的运动。也就是说,机器人至少要移动两次,而且两次的旋转轴不能平行。如果两次都是纯平移,方程会退化,解不出来。
我建议采集10-15组数据,覆盖机器人的工作空间,这样标定结果更鲁棒。
下面我用一个简单的SVG图,把整个手眼标定的流程串起来,方便你理解。
最后,我想强调一点:标定方程推导出来只是第一步,真正难的是数据质量。我见过太多人,方程背得滚瓜烂熟,但采集数据时随便拍几张就开算,结果标定误差大得离谱。记住,标定板要平整、光照要均匀、机器人移动要覆盖整个工作空间。这些细节,才是决定标定精度的关键。
嗯,这一章的内容就到这里。坐标系定义清楚了,标定板选对了,方程推导明白了,后面几章咱们就开始实战——写代码、采数据、算结果。