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 标定流程(以眼在手上为例)

你想想看,实际做标定的时候,步骤其实不复杂。但每一步都有坑。

  1. 准备标定板:固定在机器人工作空间内,确保不会移动
  2. 示教机器人:手动控制机器人,让相机从不同角度拍摄标定板
  3. 记录数据:每拍一张,记录机器人的位姿(x, y, z, rx, ry, rz)
  4. 角点检测:用 OpenCV 等工具检测标定板角点
  5. 解算:用 Tsai 法或 Park 法求解 AX=XB
  6. 验证:让机器人抓一个已知位置的点,看相机引导的误差

这里有个关键点:标定板的姿态要覆盖整个工作空间。不要只在一个小区域里拍。我见过有人拍了 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 小结

手眼标定,说白了就是建立相机和机器人的坐标关系。眼在手上适合小范围、高精度的抓取;眼在手外适合大范围、固定工位的应用。标定板的设计要讲究,流程要规范,验证不能省。

我做了这么多年,最大的体会是:标定不是一次性的。相机松动、机器人碰撞、温度变化,都可能导致标定失效。所以,定期重新标定,或者设计自动标定流程,才是工程上的好习惯。