ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

第128篇 TF2实战——手眼标定中的坐标变换链

第128篇 TF2实战——手眼标定中的坐标变换链 面试翻车现场去年面试一家做机械臂抓取的公司面试官问了个很实在的问题手眼标定做过没有说说坐标变换链是怎么推的。我当时心里一慌手眼标定我知道是标定相机和机械臂的关系但具体变换链怎么推说实话有点模糊。我就说了个大概就是用TF2把各个坐标系列出来然后手眼矩阵就是相机到末端的变换。面试官追问了一句那你说是eye-in-hand还是eye-to-hand两种情况的变换链有什么区别我支支吾吾没答上来。后来才知道这个问题在机器人抓取领域几乎是必问的。手眼标定的本质手眼标定要解决的核心问题是相机看到的点和机械臂末端执行器之间到底差了多少工业场景里你经常需要让机械臂去抓一个物体。相机能看到物体在相机坐标系下的位置但机械臂需要知道物体在基坐标系下的位置才能规划运动。这两个坐标系之间的转换关系就是手眼标定要算出来的。根据相机安装方式不同分两种情况。Eye-in-hand眼在手上相机装在机械臂末端跟着末端一起动。相机看到的物体位置要经过相机→末端法兰→基座这条变换链才能转到基坐标系下。Eye-to-hand眼在手外相机固定在外部不随机械臂运动。这时候变换链是相机→基座→末端法兰。两种情况的数学模型不一样但本质上都是在解一个坐标变换链的问题。两种方案怎么选实际项目中选eye-in-hand还是eye-to-hand取决于具体场景。Eye-in-hand的好处是相机跟着末端走视野始终对准抓取目标精度高。缺点是工作空间受限于机械臂臂展而且相机重量会增加末端负载。适合精度要求高、工作范围不大的场景比如桌面分拣。Eye-to-hand的好处是相机视野大能看到整个工作区域不受机械臂运动影响。缺点是需要精确知道相机和基座之间的位置关系而且如果标定板被机械臂遮挡就麻烦了。适合工作范围大、需要全局视野的场景比如大型工件的上下料。我参与的一个项目就是用的eye-to-hand方案相机架在机械臂上方1.5米处俯视整个工作台。好处是视野覆盖了整个抓取区域坏处是相机分辨率在远距离下不够小物体检测精度受限。最后换了个长焦镜头才解决。AXXB问题手眼标定的经典数学模型是AXXB。这个方程看着简单背后的含义很深刻。A是机械臂末端在两个不同位姿之间的相对变换这个可以从机械臂的正运动学算出来精度很高。B是相机在两个不同位姿之间的相对变换这个通过视觉算法比如检测标定板算出来。X就是我们要求的手眼矩阵——相机和末端之间的固定变换。为什么叫AXXB因为你让机械臂动到两个不同位置末端动了A已知相机也动了B已知但它们之间的相对关系X是不变的。列出来就是AXXB。解这个方程需要至少两组不同的位姿实际中一般用十几组甚至几十组来提高精度。常用的求解算法有Tsai-Lenz方法、Park方法、Horaud方法等OpenCV里都有现成的实现。TF2中的变换链回到ROS2里怎么用TF2来处理这个问题。不管是eye-in-hand还是eye-to-hand你都需要在TF2中维护一棵完整的变换树。以eye-in-hand为例树上至少要有这些节点base_link → link1 → link2 → ... → link6 → tool0 → camera_link → camera_optical_frame。前面那些link是机械臂的运动链由URDF和关节状态定义。tool0是末端法兰。camera_link是相机本体坐标系camera_optical_frame是相机光学坐标系Z轴朝前X朝右Y朝下和OpenCV的图像坐标系一致。当你需要把相机看到的某个点转换到基坐标系时TF2会自动沿着变换树找到路径把所有中间变换串起来。你不需要手动做矩阵乘法直接查camera_optical_frame到base_link的变换就行。这就是TF2强大的地方——你只需要把各个坐标系之间的静态或动态变换定义好查询时它自动帮你算。实际标定流程在ROS2中做手眼标定一般有这么几步。第一步准备标定板。通常用棋盘格或者AprilTag。把标定板放在机械臂工作空间内确保相机能看到。第二步采集数据。让机械臂运动到多个不同的位姿建议15-20个覆盖足够大的工作空间每个位姿记录一次机械臂的关节角度和相机中标定板的位姿。第三步运行标定算法。ROS2生态里有easy_handeye这个包它封装了OpenCV的手眼标定算法支持eye-in-hand和eye-to-hand两种模式。你只需要把采集到的数据喂给它它就能算出手眼矩阵。第四步验证结果。把算出来的手眼矩阵作为静态变换发布到TF2中。然后让机械臂运动到某个位姿用相机检测标定板中心点看TF2转换到基坐标系后的位置是否和标定板的实际位置吻合。如果误差在可接受范围内通常几个毫米标定就完成了。标定结果怎么用到系统里呢核心是把4x4的变换矩阵拆成translation和rotation然后用static_transform_publisher发布。比如eye-in-hand的标定结果是tool0到camera_link的变换你就发布ros2 run tf2_ros static_transform_publisher --x 0.05 --y -0.02 --z 0.1 --roll 0 --pitch 0 --yaw 0 --frame-id tool0 --child-frame-id camera_link。实际参数当然要从标定结果里取。这个静态变换发布后TF2树就连通了任何节点都可以查询相机和基座之间的变换。常见踩坑点第一个坑是坐标系定义搞混。相机的图像坐标系和ROS中的坐标系定义不一样。OpenCV里图像是Z朝前、X朝右、Y朝下但很多3D相机比如RealSense输出的点云用的是X朝右、Y朝下、Z朝前其实是一样的。但有些相机用的是X朝前、Y朝左、Z朝上的ROS标准坐标系。这个搞混了标定结果就差十万八千里。第二个坑是标定板检测不稳定。如果标定板在图像中的姿态变化不够大比如都是正对着相机标定结果会很差。要确保标定板有足够的倾斜角度变化。第三个坑是TF2中的静态变换没发布对。手眼标定的结果是一个4x4的齐次变换矩阵你需要把它转成translation quaternion然后作为静态变换发布。发布的时候parent和child frame搞反了整个变换链就全错了。第四个坑是机械臂的正运动学不准。手眼标定依赖A矩阵的准确性如果机械臂的DH参数本身就有偏差标定出来的手眼矩阵也会不准。这种情况下需要先做机械臂的运动学校准。标定完成后建议做一轮交叉验证用新的位姿组合重新检测标定板位置对比TF2转换后的坐标和实际坐标的偏差。如果偏差随位姿变化明显说明标定数据覆盖不够充分需要补充更多样化的标定姿态。定期复检也很必要机械振动和温度变化都可能导致标定结果缓慢漂移。手眼标定的实战经验手眼标定是机器人视觉中的经典问题。核心是求解相机和机械臂末端之间的固定变换关系。常用的方法有Ax加xb方程求解ROS中有easy_handeye包可以用。实际操作中标定精度取决于采样点的数量和分布建议在不同姿态下采集15到20组数据。标定完成后一定要验证重投影误差如果误差过大要检查是否有异常采样点。标定工具的使用建议除了easy_handeye还有calib手眼标定工具可以选择。标定时注意几个要点标定板要固定牢靠不能有晃动采集数据时姿态变化要尽量大覆盖机器人的工作空间标定完成后用独立的数据集验证精度。这些实操细节在面试中提出来能证明你确实做过手眼标定。面试中怎么聊面试官问手眼标定你可以说手眼标定分eye-in-hand和eye-to-hand两种。数学模型是AXXB用多组位姿的相对变换来求解。ROS2中用TF2维护完整的变换链标定结果作为静态变换发布。实际项目中要注意坐标系定义的一致性标定板姿态要足够多样化还要确保机械臂正运动学的准确性。上一篇第127篇 TF2进阶——变换树管理、时间同步和延迟处理下一篇预告第129篇 Rviz2可视化——机器人调试的眼睛
返回列表