4、手眼标定(Eye-to-Hand):机器人底座固定相机,标定相机与机器人基座的关系

好,咱们进入手眼标定的核心环节——Eye-to-Hand。

说白了,就是相机固定在机器人外面,比如天花板上、工作台支架上,它看着机器人干活。这时候我们要解决的,是相机坐标系和机器人基座坐标系之间的转换关系。

我个人习惯把这种布局叫做「旁观者清」。相机不跟着机器人动,它只负责看,然后告诉机器人:「你的手现在在哪儿,工件又在哪儿。」

核心目标:求取相机坐标系 → 机器人基座坐标系的变换矩阵,记为 CamInBase 或 BaseToCam。

4.1 为什么需要 Eye-to-Hand 标定?

想象一下这个场景:

  • 你有一个固定相机,拍到一个工件在像素坐标 (x, y)。
  • 机器人要去抓这个工件。
  • 但机器人只知道自己的基座坐标,不知道相机坐标。

所以,你必须把「相机看到的」翻译成「机器人能理解的」。这个翻译官,就是 CamInBase 矩阵。

我在一个3C电子组装项目里遇到过这种情况。当时相机装在流水线正上方,机器人从旁边抓取零件。一开始没标定好,机器人总是抓偏,差了大概2毫米。后来重新做了Eye-to-Hand标定,精度直接干到0.1毫米以内。嗯,标定这东西,真不能省。

4.2 Eye-to-Hand 的数学模型

咱们先理清几个坐标系:

符号 含义
Cam 相机坐标系
Base 机器人基座坐标系
Tool 机器人工具(法兰/抓手)坐标系
Obj 标定板(工件)坐标系

标定的核心方程是这样的:

BaseToCam * CamToObj = BaseToTool * ToolToObj

其中:

  • BaseToCam —— 我们要求的未知量。
  • CamToObj —— 相机拍到标定板,通过位姿估计得到。
  • BaseToTool —— 从机器人控制器读出来的当前工具位姿。
  • ToolToObj —— 标定板固定在工具末端,这个关系是固定的,但未知。

你看,一个方程里有俩未知数(BaseToCam 和 ToolToObj),所以需要多个位姿来解。这就是为什么标定要拍很多张不同姿态的图片。

我的经验:最少拍9张,推荐12~16张。姿态变化要大,平移和旋转都要覆盖。别偷懒,拍少了容易解出奇异解。

4.3 HALCON 中的实现流程

HALCON 提供了现成的算子,咱们不用自己手撕矩阵。但理解流程很重要。

4.3.1 准备阶段

  1. 标定板固定在机器人末端(法兰或吸盘上)。
  2. 相机固定,视野覆盖机器人工作范围。
  3. 机器人带着标定板走一系列位姿,每到一个位姿:
    • 记录机器人当前的 BaseToTool(从控制器读)。
    • 相机拍一张图,提取标定板位姿 CamToObj。

4.3.2 核心代码示例

* 创建标定数据模型
create_calib_data ('hand_eye_calibration', 'eye_to_hand', [], [], CalibDataID)

* 设置相机内参(假设已标定)
set_calib_data_cam_param (CalibDataID, 0, 'area_scan_division', CamParam)

* 设置标定板描述文件
set_calib_data_calib_object (CalibDataID, 0, 'caltab_30mm.descr')

* 循环添加每一组数据
for I := 0 to NumPoses - 1 by 1
    * 设置机器人位姿(BaseToTool)
    set_calib_data (CalibDataID, 'tool', I, 'tool_in_base_pose', BaseToToolPose[I])
    
    * 设置相机观察到的标定板位姿(CamToObj)
    set_calib_data (CalibDataID, 'calib_obj_pose', [0, I], 'pose', CamToObjPose[I])
endfor

* 执行标定
calibrate_hand_eye (CalibDataID, Errors)

* 获取结果:相机在机器人基座中的位姿
get_calib_data (CalibDataID, 'camera', 0, 'pose', CamInBasePose)

* 清理
clear_calib_data (CalibDataID)
注意:HALCON 的 set_calib_data 中,'tool_in_base_pose' 指的是工具坐标系在基座坐标系下的位姿,也就是你从机器人控制器读出来的值。千万别搞反了,我曾经见过有人把基座在工具下的位姿传进去,结果标定结果完全不对。

4.4 标定流程示意图

下面这张图帮你理清整个流程和数据流向:

Eye-to-Hand 标定流程 Eye-to-Hand 标定数据流 机器人控制器 读取 BaseToTool 固定相机 提取 CamToObj 标定板 固定在机器人末端 控制运动 被拍摄 数据收集(重复 N 次,N ≥ 9) ① 移动机器人到不同姿态 ② 记录 BaseToTool(从控制器) + 拍摄并提取 CamToObj ③ 确保标定板在相机视野内,且姿态变化足够大 HALCON 标定引擎 calibrate_hand_eye 输出:CamInBasePose 相机在机器人基座中的位姿

4.5 避坑指南

做 Eye-to-Hand 标定,有几个坑我踩过,分享给你:

  • 标定板不要太小:至少占视野的 1/4 到 1/3。太小了,角点提取精度不够。
  • 机器人姿态要多样化:别只在一个小范围内移动。平移、旋转、俯仰都要有。我见过有人只平移不旋转,结果标定出来的旋转分量全是错的。
  • 注意标定板的固定:一定要刚性连接,不能有晃动。我曾经用双面胶贴过,结果标定完一碰就歪了,白干。
  • 验证标定结果:标定完成后,让机器人走几个已知点,用相机测量坐标,反算到机器人基座下,看看误差。一般 0.5mm 以内算合格。
验证小技巧:标定完后,在机器人末端装一个尖针,相机视野里放一个已知位置的标记点。让机器人用尖针去戳那个点,看误差。这是最直观的验证方式。

4.6 什么时候用 Eye-to-Hand?

场景 推荐方案 原因
相机固定在天花板/支架上 Eye-to-Hand 相机不动,视野稳定,适合大范围定位
相机装在机器人手臂上 Eye-in-Hand 相机随动,适合近距离、高精度操作
流水线视觉引导 Eye-to-Hand 相机固定,适合传送带上抓取
装配对位 Eye-in-Hand 相机靠近工件,精度更高

嗯,Eye-to-Hand 标定就这些核心内容。说白了就是:固定相机看全局,通过标定板搭桥,算出相机和机器人基座的关系。数据采集时多花点心思,后面用起来就省心了。