ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

手眼标定实战指南:2D/3D相机与机械臂的AX=XB坐标变换详解

手眼标定实战指南:2D/3D相机与机械臂的AX=XB坐标变换详解 手眼标定这件事我在现场做过太多次了。不管是2D相机做定位抓取还是3D结构光相机做拆垛引导手眼标定永远是绕不开的第一道坎。很多工程师拿到标定算法跑一下旋转矩阵解出来人眼一看就是没法用的但又不知道卡在哪一步最后只能反复重标。这篇文章就把我做过的2D/3D相机手眼标定项目从原理到实操完整总结一遍包括坐标变换链怎么搭、AXXB为什么成立、采集数据怎么摆姿势、出问题怎么排查全程用现场口吻聊适合正在做视觉引导定位、机械臂抓取项目的工程师参考。1. 手眼标定到底在解决什么问题1.1 坐标变换链机器人要“看见”世界必须串起所有坐标系先别急着跑算法得先把坐标系之间的变换关系捋清楚。任何一个视觉引导场景里都同时存在好几个坐标系机械臂基座坐标系、机械臂末端法兰坐标系、相机坐标系以及标定板所在的物体坐标系。手眼标定要做的就是求出其中某个关键的坐标系变换矩阵让机械臂“知道”相机看到的点在它的世界坐标里到底在哪。如果把这件事说得更直白一点你用人眼去拿桌上的杯子大脑要同时知道眼睛看到的画面和手的位置之间是什么关系才能指挥手伸过去。机器人也一样相机是它的眼睛机械臂是它的手它们俩坐标系之间的相对关系就是通过手眼标定算出来的。在实际项目里这个需求会被无限放大。比如一个3D相机引导机械臂去抓取货箱相机识别出箱子在图像坐标系下的三维坐标但这个坐标是相对于相机坐标系而言的。机械臂只认它自己的基座坐标系所以你需要一个矩阵把相机坐标系下的坐标映射到机械臂基座坐标系下机械臂才能算出自己该靠哪个姿态、哪个位置过去抓。这个变换矩阵就是手眼矩阵通常记作 T_cam2base 或者 T_tool2cam取决于你的相机装在哪里。整个坐标变换链一般长这样像素/深度数据 → 相机坐标系 → 手眼矩阵 → 机械臂基座坐标系 → 机械臂运动学解算任何一个环节断掉整个视觉引导就废了。这也是为什么很多项目现场“算法看着没问题但就是抓不准”大概率不是识别算法的问题而是手眼矩阵本身就标歪了。1.2 眼在手上与眼在手外两种构型两种思路手眼标定根据相机的安装位置分为两种构型分别是“眼在手上”eye-in-hand和“眼在手外”eye-to-hand。这两种构型的坐标系变换链不同求解思路也不同。眼在手上就是相机固定在机械臂末端法兰上相机跟着机械臂一起动。这种方式的好处是视野灵活机械臂转个角度就能看清不同位置的目标常用于定位、抓取、装配等场景。眼在手上的标定目标是求出相机坐标系相对于末端工具坐标系的变换矩阵 T_cam2tool因为这层关系是固定的不随机械臂运动而改变。眼在手外就是相机固定安装在某个位置比如工作台上方或者侧方机械臂在相机视野范围内活动。这种方式视野固定稳定性好常用于上下料、拆垛、视觉引导定位等场景。眼在手外的标定目标是求出相机坐标系相对于机械臂基座坐标系的变换矩阵 T_cam2base。在现场听到最多的问题就是我到底该用哪种构型我的建议很简单看你的工艺需求。工作范围固定、机械臂活动范围不大的优先考虑眼在手外标定一次可以长期稳定使用需要频繁切换视角、目标位置不固定的用眼在手上更灵活。但眼在手上每次机械臂重新上电或者运动精度发生变化时可能需要重新标定一次这点要有心理准备。2. 从AXXB到手眼矩阵数学原理与求解算法2.1 为什么大家都绕不开AXXB手眼标定的核心公式听起来很简单AXXB。这个式子里的每个字母都是齐次变换矩阵A是相机在两次拍摄之间的相对运动B是机械臂末端在同样两次移动中的相对运动X就是要标定的手眼矩阵。为什么能构造出这个式子假设你在标定过程中让机械臂带动相机拍了两次标定板第一次拍到的标定板相对相机坐标系的变换是前一个位姿第二次是另一个位姿。把两次之间的相机运动记为A把机械臂末端两次之间的运动记为B实际发生的运动其实是由同一个手眼矩阵连接起来的于是就有了AXXB这个约束关系。用人话说就是机器人的手动了多少眼睛也观测到了对应的变化这两个变化之间一定隔着同一个转换关系。你只需要采集多组这样的运动数据就能把X反解出来。我在项目里常被人问至少要拍几组数据才能解理论上两组运动就能构造出两个方程但实际情况是两组数据噪声太大根本解不出稳定结果。我的经验是采集12到16组数据覆盖不同的机械臂姿态和标定板位置这样求解结果才会收敛得比较稳定。数据组数太少方程病态解出来看起来好像合理实际上精度很差放现场根本不能用。2.2 求解算法Tsai、Park、Daniilidis怎么选解决AXXB的经典算法有好几个。Tsai两步法最早提出先把旋转矩阵解出来再把平移向量代进去解思路清晰但在旋转误差较大的情况下精度容易受影响。Park用李代数把旋转部分转换成李代数形式求解整体稳定性更好。Daniilidis用对偶四元数同时求解旋转和平移号称一步到位噪声鲁棒性也更好一些。老实说如果只求“能解出来”用哪个算法都行。但如果追求“现场稳定可靠”我更推荐直接用Daniilidis或者基于李代数的方法。Tsai法在数据噪声大时有可能会出现旋转矩阵不正交的情况需要额外做正交化处理。而Daniilidis在对偶四元数框架下解算旋转和平移是联合优化的整体精度和稳定性在实测中会更好。实际项目里我遇到过极端情况用Tsai解出的旋转矩阵角度偏差在0.5度以内看起来还行但平移向量偏差达到十几毫米怎么都找不出原因。后来换成基于李代数的求解器同样的数据平移误差一下子掉到了2毫米以内。所以我的建议是现场手里至少要备两套不同数学原理的求解器互相交叉验证。如果两套算法结果差异巨大那基本可以断定数据有问题。2.3 2D相机与3D相机标定的本质区别2D相机和3D相机的手眼标定底层逻辑一致都是求解AXXB但实操差异很大。2D相机标定时标定板通常是一个棋盘格或者圆点阵列。相机拍到的是一张二维图像你需要从图中提取角点或圆心坐标然后利用标定板物理尺寸建立物体坐标系解出相机相对于标定板的外参。这个流程在OpenCV里很成熟先用cv2.findChessboardCorners提取角点再用cv2.solvePnP求外参接着配合机械臂末端位姿构造AXXB。而3D相机标定时输出的是一组三维点云你需要从点云里找平面、找球心或者找二维码特征。3D相机里最常见的方式是用标定球或者高精度陶瓷标定板从点云中拟合出球心坐标或者棋盘格角点的三维坐标作为相机坐标系下的观察值。因为3D相机存在深度噪声角点提取的精度往往比2D相机低一些这就需要更多的采样数据来平均误差。另外3D结构光相机本身有一个深度误差模型距离越远、斜射角度越大深度噪声越明显。所以标定3D相机时标定板的摆放距离和相机的工作距离要尽量接近标定板平面也尽量正对相机视角歪太多的话点云边缘精度会很差标出来的手眼矩阵精度直接受影响。3. 实操流程从摆标定板到出结果3.1 标定板与场景准备这些细节决定成败标定结果的精度从准备工作开始就已经被决定了。标定板的选择第一原则是刚性要好表面平整度高。2D标定棋盘格可以选陶瓷基板或者玻璃基板但玻璃基板反光严重在光线复杂的车间里容易导致角点误检我实际用下来陶瓷基板最稳。3D标定一般用高精度陶瓷标定板或者标准球标定板上全部布满特征点点云拟合精度才够。标定板的尺寸也要注意标定板的有效成像大小至少要占到相机视野的三分之一以上。有些人为了省事拿一张小棋盘格放到大视野里特征点只占画面的百分之几角点提取精度根本不够解出来的外参自然也是虚的。相机安装也是一个关键点。相机支架必须锁死螺栓不能用那种用手一推就晃的万向支架。标定完成后相机发生过任何轻微位移整个手眼矩阵就全部失效。这一点在现场很容易被忽视我见过一个项目标定精度本来挺稳结果第二天开机抓取又偏了最后发现是安全员把相机支架撞了一下整个标定白做。关于环境光2D标定时要特别留意反光和阴影尽量保证标定板表面光照均匀。3D结构光相机对环境光的容忍度高一些但强烈的红外干扰和太阳直射仍然会污染点云质量标定和实际使用尽量选择在相似的光照环境下进行。3.2 数据采集一组好数据的标准姿势数据采集是整个标定流程中最重要的环节。网上很多教程只说“让机械臂摆几个位置拍几张图”但摆位不好算法神仙都救不回来。我常用的采集策略是机械臂带动相机或标定板在相机视野内做5个以上不同位置、每个位置3个以上不同姿态的移动总共采集12到16组数据。位置要尽量覆盖整个视野范围包括视野中心、四个角和中间过渡区域姿态变化要包含不同角度绕X、Y、Z轴的旋转。采集时每移动到一个姿势需要同时记录两组数据一组是相机拍摄到的标定板位姿通过图像或点云解算得出另一组是机械臂当前末端位姿从机械臂控制器的示教器或SDK中读出。两组数据必须是在同一个时间点记录的时间戳偏差会导致手眼矩阵求解出现莫名其妙的误差。这里有个关键注意事项数据采集过程中机械臂末端姿态的变化幅度一定要足够大。如果机械臂只做平移、不做旋转或者姿态变化只有不到10度那方程组的条件数会很差旋转矩阵解出来基本是猜的。我一般要求相邻采集点之间的姿态变化至少在20度以上这样约束关系才充分。还有一个现场常见的坑在眼在手外的构型中标定板是装在机械臂末端的有的工程师为了省事不用标定板直接用机械臂末端戳一个尖端用尖端顶点当作特征点来标定。这个方法理论上可以但前提是你得准确知道末端工具的实际长度和方向。工具坐标系没设置对的话标定解出来必然是偏的。3.3 求解与结果验证怎么看标定准不准标定程序跑完输出一个4x4矩阵然后就大功告成了当然不是。你得先做一轮自检确认这组结果可信。自检的第一种方法是重投影误差验证。把标定板放在相机视野内机械臂移动到几个已知位置用当前手眼矩阵将标定板角点坐标从相机坐标系变换到机械臂基座坐标系再和机械臂实际位置对比。如果误差在几个毫米以内说明标定结果基本可靠如果偏差几十毫米那就是标定数据有问题别硬调算法。自检的第二种方法是直接跑一次静态精度测试。在机械臂末端装一个针尖让针尖去点标定板上的某个已知特征点。如果标定准确针尖应该能精确落在特征点上。这个测试简单直观很多国际集成商验收时都采用这种方案我现场也一定会做这一步。自检的第三种方法是拿激光位移传感器或者千分表测重复定位误差但普通项目用到这个级别的比较少。一般做两个点位比较已经能筛出90%的标定失败案例了。关于结果验证的频率我的建议是每次标定完现场立即验证不要等第二天再验。因为第二天机台可能已经被其他人动过再验证就只能发现问题而找不到原因了。4. 现场常见问题与排查技巧4.1 标定结果解析失败或偏差巨大先查这些标定结果差不外乎几个原因。我把最常见的几种现象和对应的排查思路整理成一张表现场可以直接对着查。现象可能原因排查方法旋转矩阵不平滑、有跳变数据组数太少或姿态变化太小增加采集点加大姿态旋转幅度平移向量偏差几百毫米甚至上千毫米机械臂末端工具坐标系未设置或设置错误重新设定工具坐标系确认TCP值算法解出明显错误矩阵标定板角点误检、图像和机械臂位姿时间不同步检查标定板是否被反光点遮挡同步时间戳每次标定结果不一致机械臂零点丢失或运动学标定偏差重新校准机械臂零点重启控制器3D相机点云标定板拟合不完整标定板反光太强或距离超范围调整曝光、改变角度、距离缩短2D相机角点提取失败光照不均、标定板边缘反光增加匀光光源调整标定板角度还有一个经常被忽略的原因法兰盘与末端工具之间的安装偏置。有的项目里相机和法兰盘之间加了一块转接板转接板的加工精度不高、偏心就会导致标定结果不准。这种情况下你需要把这部分偏心误差提前做补偿或者在标定数据采集时尽量避免多个偏心位置的组合。4.2 从标定精度到抓取精度标定只是起点手眼标定做完视觉引导精度未必就能达标。很多工程师以为标完手眼就万事大吉结果现场一测误差还是很大就开始怀疑手眼标定有问题。实际上抓取精度的链路远比手眼矩阵本身包含的内容要多。视觉系统的误差只是一个环节。识别算法的定位误差、机械臂自身的绝对定位精度、机械臂关节减速器的背隙误差、末端工具的安装误差这些变量都会叠加在最终精度上。假设手眼矩阵的平移误差是1毫米机械臂重复定位精度是0.1毫米识别算法定位误差0.5毫米工具安装误差0.5毫米最终到末端就是大约1.5到2毫米级别的总量。所以现场验收时我会先做一个误差分解把视觉识别误差单独测一遍把机械臂运动学误差单独测一遍最后再把整体联调误差测出来。哪个环节超标就处理哪个环节而不是一有问题就归罪于手眼标定。搞清楚了误差来源你才能心平气和地和客户谈精度指标。4.3 工程化标定的几个独家技巧第一采集数据时尽量让机械臂速度慢一点。快速运动时机械臂控制器读出来的位姿有滞后和抖动姿态数据容易带有偏差会导致标定数据前期就污染了。我一般用示教模式手动移动机械臂每个采集点停顿2到3秒确认稳定后再记录数据。第二巧用机械臂自带的“工具坐标系校准”功能。在眼在手上的构型里如果机械臂支持TCP自动标定可以先用针尖法把末端工具坐标校准好然后再做手眼标定。很多时候标定不准不是手眼算法问题而是你压根没有一个可靠的工具坐标系做参考这步千万别省。第三标定完一定要做一次“往返验证”。把机械臂移动到视野中心一个已知点记录该点的机械臂坐标然后把机械臂移开重新回到这个点用手眼矩阵反推相机观测值看两次结果是否一致。这一步能在几分钟内确认标定是否真正可用远比跑一堆统计指标更有说服力。5. 我的一点体会标定不是算法题是系统工程手眼标定这件事算法本身在开源库里到处都是随便搜一下就能找到求解代码。但真正决定项目成功率的从来不是算法而是你对整个坐标变换链的理解深度和现场操作的控制能力。数据采集干不干净、工具坐标系准不准、机械臂运动精度稳不稳定这些因素中的任何一个出问题都会直接毁掉最终的标定结果。根据我个人的经验一个新来的工程师做手眼标定前几次大概率是会失败的这不是算法理解的问题而是缺少对现场细节的敏感度。什么时候该换标定板、什么时候该怀疑机械臂零点漂移、什么时候该检查工具坐标系的定义这些判断只有踩过坑才能形成直觉。所以我建议所有做视觉引导项目的朋友把手眼标定当作一个系统工程来对待。别急着跑代码先把坐标系链路画清楚把每一个环节可能的误差来源列出来再动手去采集数据。磨刀不误砍柴工这句话在标定这个环节永远成立。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进