
我做过的抓取项目不算少但真正把线激光和结构光两台传感器融合到一起还是头一回。先说结论这类项目最难的不是点云算法也不是机器人路径而是手眼标定。标定做不好后面所有“精准抓取”都是空中楼阁。这篇文章就围绕一条完整链路来讲——从标定球选型、球心提取到Eye-to-Hand和Eye-in-Hand两套手眼矩阵求解再到最终抓取时的位姿修正我把实际踩过的坑和验证数据一并写出来希望给正在做类似项目的朋友省点时间。1. 一个抓取项目为什么要同时融合线激光与结构光我接手的这个项目场景是料筐来料工件是金属异形件表面有油污、局部高反光筐内姿态杂乱。客户最初的方案只装了一台散斑结构光相机识别没问题但抓取时频繁出现夹爪碰件、零件滑脱原因是结构光给出的位姿误差在复杂表面上被放大了。后来我们在线激光和结构光之间做了分工才把抓取稳定性拉上来。1.1 两种传感器的原理和脾气完全不同散斑结构光相机的工作原理是向被测表面投射编码散斑图案通过相机观察图案因物体深度不同产生的位移再用三角测量或相关匹配解算出深度图。它的优势非常明显单帧就能拿到整个视场的三维数据适合做全局感知。缺点是深度精度有限而且对表面材质敏感——黑色吸光件、高反光面、深孔区域很容易丢点或产生毛刺。线激光轮廓传感器走的是另一条路。它把一条激光线打到物体表面相机从另一角度观察这条线在物体表面的形貌根据激光条纹在图像中的偏移解算轮廓高度。传感器和被测物体之间需要相对运动才能拼出完整三维轮廓。它的优势是Z方向精度高、抗环境光干扰能力强但单帧只有一条轮廓线覆盖面小速度慢。两种传感器单独拎出来都有明显短板放在同一个工位里恰好互补。结构光负责“看全局、找目标”线激光负责“盯局部、抠精度”。这是我在这个项目里最核心的设计思路。1.2 粗定位加精测量两台传感器怎么分工实际部署时我把散斑结构光相机固定安装在料筐正上方工作距离约1.2米视场覆盖整个料筐用于识别工件粗位姿线激光轮廓传感器装在机器人法兰上跟随机械臂运动在机器人靠近目标后对工件特定的定位面做短距离扫描输出高精度轮廓再通过配准计算位姿修正量。这套架构下来时间预算大概是结构光重建0.3到0.8秒识别0.2到0.5秒机器人移动到粗抓取点上方伸出线激光做短轨迹扫描0.5到1.2秒ICP或特征配准修正位姿50到200毫秒整个抓取节拍在2到3秒左右。比纯结构光方案慢一点但抓取可靠性是质变。这里有个很关键的点既然分为粗定位和精测量两个环节那么两台传感器必须统一到同一个坐标系里不然粗定位给线激光一个偏大的初始值精扫描轨迹可能直接偏出传感器视场。所以手眼标定不是可选项是整个融合方案的地基。2. 手眼标定的坐标关系两张关键矩阵和它们求解的AXXB手眼标定这个名词听起来吓人本质上就是求传感器坐标系和机器人坐标系之间的变换关系。一个抓取系统里传感器越多需要求的变换矩阵就越多。2.1 两种手眼关系眼在手外与眼在手上固定安装的结构光相机属于典型的眼在手外Eye-to-Hand要求解的是相机坐标系到机器人基座坐标系的变换矩阵。机械臂末端安装的线激光属于眼在手上Eye-in-Hand要求解的是激光传感器坐标系到机器人末端法兰坐标系的变换矩阵。这两个矩阵如果画成图一个连接的是“固定相机→机器人基座”另一个连接的是“激光传感器→机器人法兰”。它们方向不一样求解的输入数据不一样但数学本质是一样的都能写成AXXB的标准形式。理解AXXB可以这么想X是我们要找的那个固定变换A是某个坐标系下目标物体在两次观测之间的相对运动B是机器人末端在两次运动之间的相对运动。因为X不变所以A、B描述的是同一个刚体运动的两种不同表达联立起来就能解出X。2.2 标定球作为公共靶标时方程可以简化传统棋盘格手眼标定中A和B都是用位姿矩阵形式构造的最后用Tsai-Lenz、Park-Martin或Daniilidis等方法求解。但当我用标定球做靶标时有一个巨大的简化球心是一个点特征在任意坐标系下都能被稳定提取于是手眼标定可以退化为点云刚体变换求解。比如对固定结构光相机标定球固定不动机器人带动一个已知末端位置的工具去触碰或对准球心或者直接让球心在相机坐标系和机器人基座坐标系下都有坐标那么问题就变成了给定两组三维点集求一个刚体变换使它们对齐。这个用SVD分解或Umeyama算法就能解比AXXB更直观也更好写代码。对末端线激光同样如此线激光扫描标定球得到球心在激光坐标系的坐标机器人法兰位姿是已知的标定球在机器人基座坐标系下的真实位置也是已知的要求的就是那个让激光坐标系坐标变换到法兰坐标系、再变换到基座坐标系后与真实位置重合的变换矩阵X。可以写成非线性最小二乘min Σ || T_flange_base_i · X · p_laser_i − p_base ||²这个形式在工程上非常实用求解稳健而且能直观地把每一组的残差打出来用来判断数据质量。2.3 TCP标定和机器人绝对精度是不可忽略的前提我必须强调一件事手眼标定结果的天花板不取决于求解算法而取决于输入数据的质量。输入数据里最容易被忽视的是TCP工具中心点和机器人本身的绝对定位精度。如果TCP不准那么机器人末端位姿T_flange_base就是错的手眼矩阵再怎么优化都补不回来。我的做法是先用四点法或六点法把工具尖点标定好再把手眼标定里用的特征点定义到激光坐标系原点确保机器人读数和传感器坐标是同一个参考点。另外要清楚我们依赖的是机器人的绝对定位精度。工业机器人绝对定位精度通常在0.1到0.5毫米量级这基本就是手眼标定和最终抓取精度的下限。如果项目要求亚毫米级的绝对抓取精度光靠手眼标定不够还得配合视觉伺服或在线修正策略。这里有一个重复定位精度高、绝对定位精度低的问题容易坑人。机器人ABC重复精度能做到0.02毫米但绝对精度可能只有0.5毫米甚至更差。手眼标定用到的全部是绝对位姿所以标定出来的矩阵反映的是“这个机器人在当前区域的真实空间关系”换一个区域工作精度可能变化。这也是为什么后续要做区域化验证。3. 标定球让两台传感器读同一把尺子的靶标设计传统的棋盘格标定板在做三维传感器标定时并不好用。结构光得到的深度图边缘有混合像素角点在点云中的位置会漂移线激光对低纹理平面又很难提取特征点。标定球完全绕开了这些问题从任何角度观察球体在图像中的轮廓都是圆在点云中都是球冠球心是一个对视角不敏感的稳定几何特征。3.1 标定球选型与安装参数标定球不是随便找个钢球就能用。我整理了一份选型参考都是实际项目里验证过的参数项目推荐范围/要求说明直径25-60mm小视场用小球大视场用大球球径占视场宽度1/10到1/4较合适表面材质陶瓷或哑光钢球需要漫反射表面镜面球会导致结构光丢点、线激光反射饱和圆度误差≤0.01mm球心拟合精度受球面加工误差直接影响表面粗糙度Ra≤0.4μm降低散射噪声保证点云均匀安装方式刚性底座锁紧螺母标定过程中球体绝对不能有位移哪怕0.1毫米都会毁掉整组数据结构光视场约600×600毫米时我习惯用直径40到50毫米的球线激光测量宽度只有50毫米时25到40毫米的球比较合适。如果两台传感器共用一个球优先按线激光的测量范围选偏小的尺寸再调整结构光安装距离让球在深度图里占足够多的像素。3.2 结构光点云中的球心提取结构光重建后我先把相机深度图转成点云经过降采样和离群点移除再用RANSAC球拟合提取球心。RANSAC球拟合的流程很成熟随机选四个点求一个球面方程计算所有内点到球面的距离内点比例越高模型越好重复迭代几百次取最优模型最后用内点集合做一次最小二乘精拟合。这里有一个容易翻车的细节如果相机视角只能看到球冠的一部分且覆盖面积小于半个球面球心在深度方向上的约束会变得很弱拟合出的球心可能在Z方向上有明显跳动。所以结构光安装时要尽量保证标定球出现在视野中间偏下的位置让相机能看到球冠的大部分表面。实在受视角限制也可以采用多帧多视角数据融合后再拟合而不是单帧强解。3.3 线激光扫描球体求球心线激光测球心和结构光不同。线激光扫过一个球体得到的是多条圆弧轮廓每条圆弧都是激光平面与球面的交线理论上是一个圆。我可以对每条轮廓做圆拟合得到圆弧上的点和圆心位置但这些圆心并不是球心只是对应截面圆的圆心。工程上更省事的做法是让机器人带着线激光沿一个方向扫描球体扫过球冠区域足够多的断面后把所有轮廓点拼成一个局部点云然后同样用RANSAC球拟合求球心。这条路线和结构光数据处理统一调试方便。扫描时要注意机器人运动速度均匀速度突变会造成轮廓在扫描方向上拉伸或压缩直接影响球心Z向精度。我一般把扫描速度控制在10到30毫米每秒轮廓采样间隔0.5到1毫米这样每个球能采集到几百到上千条有效轮廓拟合球心的重复性很好。3.4 为什么不用棋盘格、圆点板前面提到过高光、反光的问题这里再补充一个几何层面上的原因棋盘格角点在二维图像中很锐利但到了三维点云里因为深度相机重建时像素深度不连续角点实际是模糊的亚像素定位非常困难。线激光就更不用说它对纯平面靶标没有稳定的几何特征。标定球则没有这个问题它的球心可以从任意角度的点云中拟合出来天然适合两种传感器共用。这是这个项目整个标定链路的基石。4. 从采集数据到验证结果手眼标定的完整实操链路与常见失败信号理论说完了下面是实打实的操作流程。我以一套标准球标定过程为例把数据采集、求解、验证和排错完整串起来。4.1 数据采集规范标定球固定在工作空间中央偏一侧的位置不能放在机器人可达范围边缘否则位姿抖动大球心提取噪声高。机器人示教一系列位姿让传感器以不同距离、不同角度观察标定球。每一组数据同时记录三样东西结构光相机求得的球心坐标固定相机坐标系线激光扫描求得的球心坐标激光传感器坐标系机器人法兰位姿从机器人控制器读出用齐次矩阵表示。数据组数我建议不少于15组条件允许就采20到25组。关键不是组数多而是位姿要有足够的多样性。相邻位姿之间旋转角度要有明显差异空间分布要覆盖传感器的整个测量范围避免所有数据集中在同一个视场角落。如果机器人只在同一个高度、同一个朝向采集数据求出的手眼矩阵在某个方向上的约束会退化标定结果看起来残差不大实际一抓就偏。另外每次采集前要确认标定球没有松动、表面没有油污。我遇到过球体被锁紧螺母固定了但底座支架是空心铝型材机器人运动时引起低频振动球心拟合的残差一直下不来。后来把支架换成厚壁实心结构问题立刻消失。4.2 固定结构光相机的手眼求解固定相机的标定我用球心点集做刚体变换估计。标定球在机器人基座坐标系下的真实坐标可以由机器人工具尖点接触球面推出来或者用示教器手动跑三点定心。拿到N组球心后令P_cam_i第i组结构光测得的球心坐标P_base_i通过机器人运动学换算出来的球心在基座坐标系的坐标。我们要求变换X使 P_base_i X · P_cam_i。这是典型的三维点集配准问题先用SVD求初始旋转和平移再整体做一次非线性优化。代码示意如下import numpy as np from scipy.spatial.transform import Rotation # 计算两组点集的质心 centroid_cam np.mean(p_cam, axis0) centroid_base np.mean(p_base, axis0) # 去质心后求协方差矩阵SVD求旋转 H (p_cam - centroid_cam).T (p_base - centroid_base) U, _, Vt np.linalg.svd(H) R Vt.T U.T if np.linalg.det(R) 0: Vt[-1, :] * -1 R Vt.T U.T t centroid_base - R centroid_cam求出来X之后我习惯再算每一组的重投影残差即 || X·P_cam_i − P_base_i ||。残差均值通常在1毫米以内如果超过2毫米就要回头查数据质量而不是急着用这个矩阵。4.3 末端线激光的手眼求解线激光在机器人末端标定球固定不动所以输入是激光坐标系下的球心p_laser_i机器人法兰位姿T_flange_base_i以及标定球在基座坐标系的固定位置p_base。我要优化的目标函数就是前面写的min Σ || T_flange_base_i · X · p_laser_i − p_base ||²这个式子可以直接用最小二乘迭代求解。先忽略法兰旋转用所有组的质心关系估计平移初值旋转初值置为单位阵或者用SVD做一次粗略估计再交给数值优化。实际项目里我用过Scipy的least_squares也用过Halcon的calibrate_hand_eye接口两者效果都不错。Halcon在处理这类问题时有个优势它的标定流程内置了参考点、标定板、机器人位姿的输入统一并且会输出每个位姿的误差统计。如果项目里已经有Halcon授权可以直接复用。但OpenCV路线更轻量适合自己定制数据采集和验证脚本。4.4 标定结果如何验证标定结果好不好光看训练残差没用一定要留验证集。我通常把20组数据分成17组训练、3组验证训练完用验证组数据重新计算球心变换到基座系后的位置误差。验证误差比训练误差小说明过拟合了验证误差明显偏大说明数据质量或位姿多样性有问题。我还会做一个实战验证用标定球在几个不同位置分别采集但不参与标定而是让机器人拿着一个尖锥工具去指示球心相机和激光分别计算球心坐标再看它们和机器人实际指示点的偏差。这一步能暴露手眼矩阵在空间不同区域的误差分布。如果整套标定做完球心距离误差在0.5毫米以内旋转误差隐约反映在机器人姿态偏差上也在0.3度左右这个结果就足够支撑精抓取了。4.5 常见失败信号和排查顺序我不是每次标定都顺利遇到过几次误差一直偏大的情况慢慢整理出一张排查表现象可能原因排查顺序所有验证点误差都大TCP不准、机器人绝对精度差先重新标定TCP再检查机器人部分区域误差大标定数据位姿覆盖不完整补充该区域的采集数据单组数据残差突然变大标定球松动、支架振动、传感器丢点检查机械结构剔除异常组线激光扫描轮廓错位机器人运动速度不均匀降低扫描速度检查轨迹结构光球心跳动大反光、表面油污、曝光参数不合适清洁球面调整相机曝光排查顺序我总结成一句话先机械再传感器后算法。机械上球要稳传感器内参和曝光要对最后才轮到算法参数。跳过前面任何一步后面所有操作都是白费。5. 融合两种传感器实现精准抓取从粗定位到精扫描的落地细节手眼标定完成后两台传感器终于处在同一个空间坐标系下。接下来要做的就是把标定成果转换成抓取动作。5.1 完整抓取流程整个抓取流程可以拆成八步料筐到位固定安装的结构光相机触发采集得到全场景点云点云预处理降采样、去背景、离群点移除工件识别用模板匹配或几何特征匹配得到工件在结构光坐标系下的粗位姿利用固定相机的手眼矩阵将粗位姿变换到机器人基座坐标系机器人按路径规划运动到粗抓取点上方安全高度末端线激光沿预设轨迹扫描工件关键定位面得到局部高精度点云将局部点云与CAD模型或离线模板做配准得到位姿修正量将修正量叠加到粗位姿机器人执行抓取、转移、放料。5.2 线激光的扫描轨迹设计线激光扫描轨迹设计是这里面最容易凭感觉做、但必须讲数据的地方。扫描轨迹要覆盖工件上特征最丰富的区域比如孔、台阶、棱边不要在平面上浪费时间。轨迹方向尽量与工件长轴一致扫描距离要落在激光传感器标称工作范围内。我遇到过一个问题结构光粗定位误差在2到3毫米时线激光扫描轨迹中心可能偏离工件关键特征导致扫描到的点云只有一半是有效工件表面。解决方式是加一道“由粗到精”的迭代扫描——第一遍用较宽的扫描范围速度放慢获得中精度定位第二遍依据第一遍结果把扫描范围收窄覆盖关键特征再做精配准。第二遍的扫描范围通常只有第一遍的三分之一到二分之一但精度直接影响最终抓取位姿。5.3 位姿修正算法位姿修正本质上是个点云配准问题。我用的主流方案是ICP配准将线激光扫描得到的局部点云作为源点云CAD模型或离线扫描的标准模板点云作为目标点云以结构光粗位姿作为初始变换迭代最近点收敛后输出刚体变换增量。初始位姿误差如果控制在5毫米以内ICP一般能稳定收敛超过这个范围就很容易陷入局部最优。对于强反光或表面特征很少的工件ICP容易漂移。我会在配准前用ROI把扫描点云裁剪到工件特征区域让参与配准的点尽量集中在孔和棱边上。金属件上有油污时点云会有少数离群点我在预处理阶段用统计滤波剔除效果比直接ICP好很多。5.4 抓取精度的验证方法验证不能只在仿真里做。我通常分两级第一级是静态重复精度测试把一个标准工件用台钳固定机器人重复执行完整抓取流程50次统计输出位姿的标准差。这一步看的是系统在静态条件下的稳定性好的结果可以做到平移标准差0.1到0.2毫米旋转标准差0.05到0.1度。第二级是抓取成功率测试在料筐中随机摆放若干工件连续运行一个班次统计漏抓、错抓、碰撞次数。如果抓取过程中出现夹爪碰到工件边缘的情况基本可以断定是粗定位给出的初始位姿偏差过大需要检查固定相机的手眼矩阵以及识别算法输出的位姿质量。一个有用的数据拆分技巧先把线激光精扫描环节禁用单独测结构光粗定位的抓取成功率再把精扫描启用测完整系统的抓取成功率。两条线的数据对比能清楚看到精度瓶颈在哪一环是识别问题、标定问题还是精扫描修正量计算问题。6. 标定之后几条可复用的工程经验与提醒项目收尾后复盘有一些经验我觉得非常值得沉淀下来。自动采集标定数据是首要建议。第一次做标定我一天手工示教了20多个位姿胳膊都酸了而且后期发现有几组数据质量不行要重采。后来我写了一个自动采集脚本机器人按预先规划好的位姿列表依次运动每个位姿停留时同步触发结构光和线激光采集全部数据自动归档。整个过程跑完不到一刻钟数据质量和一致性比手工采集好太多。标定球建议多买几个固定在工装的不同高度和区域。一次采集中让传感器分别对多个球取点再做整体优化空间约束更充分。单球多次采集最大的问题是某些位姿下球体可能落在传感器视野边缘拟合球心误差被放大多球分布能显著缓解这个问题。内参标定不要偷懒。结构光相机出厂参数运输后可能漂移到现场要先做内参校验具体做法是扫描一个已知尺寸的量块或球体看重建尺寸是否准确。线激光传感器出厂有X方向比例参数实际安装时因为支架角度、安装距离差异也需要用标准量块校准不然扫描出来的长度和真实长度对不上。这个问题在项目中期坑过我一次扫描轮廓很干净但配准结果偏了约1毫米最后查出来是X轴比例参数错了一位小数。和机器人厂家的沟通也要格外注意坐标定义。不同品牌对法兰坐标系的定义不完全一样有的叫flange有的叫tool0坐标系原点可能在法兰安装面也可能在末端工具末端。拿到机器人数据的第一件事就是确认坐标系原点和轴方向并在整个标定流程中保持统一。标定不是一劳永逸的。机器人碰撞过、相机拆装过、环境温度大幅变化后手眼矩阵都可能漂移。我现在的习惯是给现场留一个快速验证流程每周让机器人带着末端工具去触碰一次固定标定球同时让两台传感器各自测一次球心比对偏差。偏差超过预设阈值就触发重标定别等抓取开始不稳定了才排查。最后说一点个人体会整套融合方案从第一次布点到最终稳定抓取大概花了两三天时间真正用来求解矩阵的时间只有几毫秒大把时间都耗在保证输入数据的质量和一致性上。手眼标定的本质不是让算法跑出一个漂亮数字而是让机器人和传感器在同一个空间坐标系里信任彼此。只要这个信任建立起来了结构光负责大局、线激光负责细节的这套双传感器抓取架构会非常耐用。