4. 手眼标定原理:眼在手上与眼在手外
手眼标定,说白了就是解决一个核心问题:相机看到的物体,机器人怎么抓得到?
相机有自己的坐标系,机器人也有自己的坐标系。这两个坐标系之间是什么关系?不知道。那机器人就没办法根据相机看到的坐标去抓东西。标定,就是把这个关系算出来。
我刚开始做这个的时候,觉得不就是个坐标变换嘛,有啥难的?结果第一次现场调试,标定完一测试,机器人直接抓了个空。嗯,后来才发现是标定板放歪了。从那以后,我对标定这件事就特别较真。
4.1 两种安装方式,两种标定逻辑
相机装在机器人上,还是装在机器人外面?这决定了标定的方法完全不同。
4.1.1 眼在手上(Eye-in-Hand)
相机固定在机器人末端法兰盘上。相机跟着机器人一起动。
标定目标:求相机坐标系到机器人末端坐标系的变换关系。我们叫它 camTtool 或者 camTend。
标定原理:
- 机器人带着相机,从不同角度拍同一个标定板
- 标定板固定不动
- 每次拍照,记录机器人的位姿(从控制器读出来)
- 通过多组数据,解算出相机和末端的固定关系
数学上,这是一个 AX = XB 的问题。A 是机器人两次运动的变换,B 是相机两次看到的标定板变换。X 就是我们要求的。
我个人习惯:眼在手上标定,至少拍 12-15 张不同姿态的图片。姿态变化要大,平移和旋转都要有。只平移不旋转,解算会不稳定。
4.1.2 眼在手外(Eye-to-Hand)
相机固定在机器人工作空间外,比如装在支架上、天花板上。相机不动,机器人动。
标定目标:求相机坐标系到机器人基坐标系的变换关系。我们叫它 camTbase。
标定原理:
- 标定板装在机器人末端
- 机器人带着标定板,在相机视野里摆出不同姿态
- 每次拍照,记录机器人位姿
- 解算相机和机器人基座的固定关系
数学上,这也是一个 AX = XB 的问题。只是 A 和 B 的含义不同了。
避坑指南:我曾经在一条汽车产线上,相机装在龙门架上。标定完发现精度总差 2mm。查了半天,原来是龙门架有轻微振动。后来加了减振垫,问题解决。所以,眼在手外标定,相机支架的稳定性非常关键。
4.2 标定板设计
标定板不是随便画个棋盘格就行。设计不好,标定精度直接受影响。
4.2.1 常见标定板类型
| 类型 | 特点 | 适用场景 |
|---|---|---|
| 棋盘格 | 角点检测简单,精度高 | 最常用,通用场景 |
| 圆点阵列 | 圆心定位精度高,抗畸变好 | 大畸变镜头、高精度要求 |
| ChArUco板 | 棋盘格+ArUco码,可部分遮挡 | 视野受限、需要自动识别 |
我个人最常用的是棋盘格。简单、稳定、成熟。但如果你用的是广角镜头或者鱼眼镜头,圆点阵列会更好。
4.2.2 设计要点
- 尺寸:标定板在图像中至少占 1/3 到 1/2 的视野。太小了角点检测不准,太大了可能出视野。
- 方格大小:一般 10mm-30mm 之间。精度要求高,用大格子;视野小,用小格子。
- 精度:标定板的加工精度直接影响标定结果。我建议用玻璃基板或者陶瓷基板,热膨胀系数小。打印纸?嗯,临时用用可以,正式项目别用。
- 对称性:棋盘格的行列数最好一奇一偶。这样能唯一确定方向,不会出现 180 度旋转歧义。
注意:标定板不能反光!我曾经用亚克力板做标定板,结果灯光一打,反光严重,角点检测全乱套。后来换了哑光材质,问题解决。
4.3 标定流程(以眼在手上为例)
你想想看,实际做标定的时候,步骤其实不复杂。但每一步都有坑。
- 准备标定板:固定在机器人工作空间内,确保不会移动
- 示教机器人:手动控制机器人,让相机从不同角度拍摄标定板
- 记录数据:每拍一张,记录机器人的位姿(x, y, z, rx, ry, rz)
- 角点检测:用 OpenCV 等工具检测标定板角点
- 解算:用 Tsai 法或 Park 法求解 AX=XB
- 验证:让机器人抓一个已知位置的点,看相机引导的误差
这里有个关键点:标定板的姿态要覆盖整个工作空间。不要只在一个小区域里拍。我见过有人拍了 20 张,但全是同一个角度微调,结果标定完一换位置就偏。
4.4 代码示例:OpenCV 手眼标定
下面是一个简化的代码片段。实际项目中,你还需要处理异常、优化参数等。
import cv2
import numpy as np
# 假设你已经有了多组数据
# R_gripper2base: 机器人末端到基座的旋转矩阵
# t_gripper2base: 机器人末端到基座的平移向量
# R_target2cam: 标定板到相机的旋转矩阵
# t_target2cam: 标定板到相机的平移向量
R_cam2gripper, t_cam2gripper = cv2.calibrateHandEye(
R_gripper2base, t_gripper2base,
R_target2cam, t_target2cam,
method=cv2.CALIB_HAND_EYE_TSAI
)
print("相机到末端的旋转矩阵:\n", R_cam2gripper)
print("相机到末端的平移向量:\n", t_cam2gripper)
提示:OpenCV 的 calibrateHandEye 支持多种算法。Tsai 法速度快,适合大多数场景。Park 法对噪声更鲁棒。我一般先用 Tsai 法算一遍,如果残差大,再换 Park 法试试。
4.5 标定精度验证
标定完不是就完事了。你得验证。
我的做法是:
- 在机器人工作空间内选 5-10 个点
- 用相机识别这些点的坐标
- 让机器人去抓
- 测量实际位置和理论位置的偏差
一般工业场景,误差在 1mm 以内算合格。如果是高精度装配,可能需要 0.5mm 甚至 0.1mm。
警告:标定精度和机器人本身的绝对定位精度有关。如果你的机器人重复定位精度很高但绝对定位精度一般(比如 0.1mm 重复精度,但绝对精度 1mm),那手眼标定精度也会受限制。这时候可以考虑用视觉伺服来补偿。
4.6 小结
手眼标定,说白了就是建立相机和机器人的坐标关系。眼在手上适合小范围、高精度的抓取;眼在手外适合大范围、固定工位的应用。标定板的设计要讲究,流程要规范,验证不能省。
我做了这么多年,最大的体会是:标定不是一次性的。相机松动、机器人碰撞、温度变化,都可能导致标定失效。所以,定期重新标定,或者设计自动标定流程,才是工程上的好习惯。