
简介面向ROS机械臂与视觉标定开发者这份资料围绕Ubuntu 18.04下睿尔曼机械臂与RealSense D435相机的眼在手上手眼标定整理了一整套可复现的工程方案也适合需要从零搭建ROS melodic、OpenCV 3.2.0、Aruco识别与easy_handeye标定链路的入门及进阶用户。包内共1137个文件约62.24MB以launch启动文件、C/Python源码、消息与服务定义、cmake/make编译脚本、xacro/urdf机器人描述和yaml参数配置为主覆盖环境搭建、依赖配置、单目相机驱动、标定执行到Moveit!集成的完整环节。内容预览中出现多个launch与.bak备份配置便于读者在调试时对照原始设置减少误改参数带来的重复劳动。目前已吸引5153人学习适合正在搭建同类机械臂视觉系统、需要绕过环境配置坑的开发者。拿到后可直接复用功能包配置与标定流程还能够参考目录内的分类结构与测试记录快速定位问题、验证标定结果。 做机器人抓取和视觉分拣的朋友应该都绕不开这个场景Ubuntu下跑着ROS机械臂是睿尔曼的协作臂相机是Intel RealSense任务是从ROS话题里拿到目标坐标让机械臂准确抓过去。这套系统听起来不复杂真正动手时会发现坐标系对不上才是最大的坎——相机看到的点是在相机坐标系里机械臂执行操作是在基座坐标系里两个世界要对上必须先做一次手眼标定。这篇文章我把从零开始配齐睿尔曼机械臂和RealSense、完成手眼标定的整个过程记录下来包含具体的安装命令、标定流程和踩坑记录适合正在做视觉抓取、机器人分拣和毕业设计的同学参考。1. 先把整体思路盘清楚机械臂和视觉之间差的是什么1.1 这套系统到底解决什么问题机械臂加视觉核心是把“看得见”变成“够得着”。RealSense会把环境变成点云和深度图但给出的坐标是基于相机自身坐标系睿尔曼机械臂的运动学计算是基于基座坐标系。要完成抓取必须计算出这两个坐标系之间的固定变换关系这个变换就是手眼标定要解的东西。它的本质不是“把图像调清晰”而是“把两个坐标系缝在一起”。对于第一次搭这套系统的同学我建议不要上来就调抓取算法先把标定这步做扎实。标定不准后面的识别、规划、抓取全都会飘而且飘的方向还没有规律排查起来非常痛苦。很多开源项目demo跑起来好看一换到自己的工位上就失灵问题多数出在标定这层而不是算法本身。1.2 先选好模式eye-to-hand 还是 eye-in-hand机械臂和相机有三种相对关系。相机固定在机械臂以外的工作空间上方叫eye-to-hand相机装在机械臂末端跟着机械臂一起动叫eye-in-hand。还有一种情况是相机装在第三方支架上但也会移动工程上很少见这里不展开。从标定难度上讲eye-to-hand的优点是相机不动场景稳定标定一次之后只要不碰相机就长期有效缺点是机械臂移动时容易遮挡相机视野标定和工作时要给机械臂留出足够的活动空间。eye-in-hand则相反相机随末端移动视野始终跟着目标走适合结构紧凑的工位但标定后相机与末端的相对位姿必须固定固定支架一定要锁死否则标定结果就是废的。睿尔曼的协作臂加上RealSense深度相机两种模式我都试过最终项目里选的是eye-to-hand。原因很简单D455这类相机放在侧面支架上能看到整个抓取区域而且标定板贴在机械臂末端机械臂在相机视野里摆各种姿态时不容易走到相机盲区。这篇文章按eye-to-hand的主流程写但中间涉及的launch参数eye-in-hand只需要改一个参数我已经在对应小节里标出来。1.3 硬件和版本怎么搭配先确认你手上的RealSense是哪个型号。这几年的视觉抓取项目里D415、D455、D405、D457都有人用但它们的最佳工作距离差别很大直接影响标定板尺寸和安装位置。我整理了一张表型号深度工作范围大概适合场景D4150.15m ~ 10m老款适合中距离扫描目前新项目不建议选D4050.1m ~ 0.5m近距高精度适合小目标检测手眼标定时要放很小的板子D4550.4m ~ 6m中距离抓取定位深度精度高目前最均衡D4570.2m ~ 5m分辨率更高适合精细特征识别但算力要求也高如果你的目标是放在桌面上抓取小物件D405可能会更方便因为它离目标很近也能出图但标定板要用很小的尺寸否则机械臂末端的标定板离相机太近反而超出视野。我项目里用的是D455放在工作台侧面距离机械臂大概0.8米标定板用大约10cm的ArUco板识别和标定都比较稳。2. 环境准备Ubuntu、ROS和RealSense驱动三板斧2.1 Ubuntu 20.04 与 ROS Noetic 的选择这一套项目我建议锁在Ubuntu 20.04和ROS Noetic上。Ubuntu 22.04对应的ROS 2虽然也能用但睿尔曼驱动和realsense-ros的老版本包很多还是围绕ROS 1写的你不想在环境问题上浪费一个周末的话就直接用20.04。装ROS的方式有很多种最省事的是用网络上的“鱼香ROS一键安装”脚本它把换源、依赖安装都封装好了基本能做到一条命令装完。如果你更想手动装就用国内源替换默认源然后按官方wiki装ros-noetic-desktop-full。装完以后验证一下环境source /opt/ros/noetic/setup.bash roscore能正常起core说明ROS本体没毛病。这时候再顺手把工作空间初始化一下后面所有功能包都往这个空间里放mkdir -p ~/catkin_ws/src cd ~/catkin_ws catkin_make2.2 librealsense和realsense-ros怎么装RealSense要正常工作先装librealsense驱动库再装realsense-ros功能包。librealsense用Intel官方apt仓库装比较省心sudo mkdir -p /etc/apt/keyrings curl -sSf https://librealsense.intel.com/Debian/librealsense.pgp | sudo tee /etc/apt/keyrings/librealsense.pgp sudo add-apt-repository deb https://librealsense.intel.com/Debian/apt-repo $(lsb_release -cs) main sudo apt update sudo apt install librealsense2-dev librealsense2-utils装完用realsense-viewer打开相机能把RGB和深度图同时显示出来就说明SDK没问题。然后编译realsense-roscd ~/catkin_ws/src git clone https://github.com/IntelRealSense/realsense-ros.git -b 2.3.2 cd ~/catkin_ws catkin_make注意分支别选错了。realsense-ros的2.3.x系列对应ROS Noetic最新的main分支虽然也能编译但依赖可能有变化。编译完以后启动相机节点roslaunch realsense2_camera rs_camera.launch启动后可以用rqt_image_view订阅/camera/color/image_raw看彩色图订阅/camera/depth/image_rect_raw看深度图。这一步能过后面才有戏。2.3 睿尔曼机械臂的ROS驱动接入睿尔曼的机械臂比如常见的RM65、RM75系列官方提供了ROS驱动包一般包含机械臂描述文件URDF、驱动节点和消息定义三个部分。你把仓库clone下来放进src目录编译一下然后根据机械臂的通信方式启动。串口通信还是TCP通信官方文档里会有明确说明按实际接线和IP配置即可。启动驱动以后至少确认三件事关节状态话题有数据、机械臂能响应运动指令、TF树里有从base_link到各关节的完整变换。尤其是TF树没有它手眼标定根本没法定因为easy_handeye要拿机械臂末端的位姿来参与计算机械臂驱动必须先把末端坐标发出来。顺带说一个很多人纠结的问题要不要自己算DH参数。如果你的方案里只是用官方驱动和URDF完全不需要自己算DH。DH参数是描述机器人运动学的一种数学方式官方URDF里已经包含了这些几何关系驱动会帮你转成TF。只有在你要做Gazebo仿真、自己写正逆解或把机械臂模型移植到其他仿真框架时才需要去查官方给的DH表而且要特别注意单位——如果官方给的是毫米你建模型时用了米整个仿真就全是错的。3. 相机内参检查与标定板准备3.1 RealSense的内参到底要不要自己重标很多教程上来就让你用棋盘格标相机内参我觉得得分情况。RealSense出厂时是带内参标定数据的在realsense-viewer里能看到每个相机的焦距、主点、畸变系数。如果相机不是磕碰过的工程机这些内参在0.3-2米范围内做抓取定位完全够用。我自己做项目时除非发现点云有明显的弯曲变形或者要做毫米级测量否则不会单独再标一遍内参。不过有个点必须检查在标定手眼之前确认相机话题里的内参数据和相机实际一致。做法是在ROS终端里打印相机信息rostopic echo /camera/color/camera_info看width、height、K矩阵是否正常如果K是全零或者畸变参数异常说明相机节点没正常出内参这个问题一般要先解决。3.2 标定板的尺寸、打印和固定手眼标定通常用ArUco码而不是棋盘格因为ArUco可以单帧识别而且easy_handeye默认支持ArUco。我建议从网上生成一张ArUco 4x4或者6x6的marker打印尺寸控制在8-15cm之间。原则是相机工作距离远用大一点的码工作距离近用小一点的码。比如D455放在0.8米外10cm的ArUco识别很稳如果放到4cm识别率就会明显下降。打印和固定有四个坑要避开纸张不能软最好贴到硬纸板或者亚克力板上否则小幅弯曲会导致位姿估计误差直接放大打印出来后用尺子量一下实际边长把量出来的值填进标定配置里。打印机普遍有缩放误差填理论值等于自己给自己埋雷贴标定板时注意别让胶带覆盖到ArUco边缘边缘一旦反光或被遮挡检测到的角点就会偏移如果是eye-to-hand标定板贴在机械臂末端时尽量贴得和末端法兰面平行而且方向固定好不要每次换装都重新贴。4. 手眼标定实操从启动到拿到变换矩阵4.1 启动相机、ArUco检测和机械臂驱动在标定开始前需要同时跑起三部分相机节点、ArUco检测节点、机械臂驱动节点。相机用上一节的rs_camera.launch启动即可。ArUco检测可以用aruco_ros的单marker样例roslaunch aruco_ros single.launch markerId:10 markerSize:0.10 reference_frame:camera_color_optical_frame这里markerId要和你打印的ArUco编号一致markerSize填你实际量出来的边长米。reference_frame要填成realsense实际发布的彩色光学坐标系通常对应camera_color_optical_frame。如果你发现识别出的marker位姿在RVIZ里到处乱跳多半是reference_frame填成了camera_link或者camera_depth_optical_frame坐标系本身带了旋转解算出来的位姿自然就不对。4.2 easy_handeye的launch怎么写easy_handeye是这个任务里的核心工具。它通过机械臂末端位姿和相机观察到的标定板位姿求解手眼方程AXXB。可以简单理解为机械臂换个姿态标定板在相机视野里的相对变化和机械臂末端在世界里的变化这两组变化量之间藏着一个固定的变换解出这个变换就是标定结果。安装方式可以直接用apt装sudo apt install ros-noetic-easy-handeye我用的launch配置大概长这样eye-to-hand模式launch arg nameeye_on_hand defaultfalse/ node pkgeasy_handeye typeeasy_handeye nameeasy_handeye outputscreen param nameeye_on_hand value$(arg eye_on_hand)/ param namerobot_base_frame valuebase_link/ param namerobot_effector_frame valueee_link/ param nametracking_base_frame valuecamera_color_optical_frame/ param nametracking_marker_frame valuearuco_marker_frame/ /node node pkgeasy_handeye typerqt_easy_handeye namerqt_easy_handeye/ /launch如果你做的是eye-in-hand把eye_on_hand改成true并且把tracking_marker_frame换成固定在工作台上的标定板的坐标系名其他参数基本不用动。要注意的是robot_effector_frame这个名字不一定就叫ee_link有些机械臂的URDF里叫tool0或者flange你要根据自己机械臂的TF树实际名称来填。4.3 采样、计算和验证rqt_easy_handeye启动后界面里能看到相机的实时画面和marker识别结果。操作流程是先让机械臂带着标定板动到第一个位置确认marker在相机画面里居中、清晰然后点击“Set current pose”再点“Add sample”。接着继续换姿态重复采样。采样有两条硬性要求不要只让机械臂纯平移姿态变化要明显绕不同轴旋转都要有否则标定方程会退化成奇异问题算出来的结果看着合理实际全错每次采样时机械臂停在当前位置要停稳不要边动边采样也不要采样瞬间还在振动。我一般采12-15个点耗时十分钟左右。点太少算出来不稳点太多对工程时间不友好12-15个点是经验上的平衡点。采样结束后点“Compute”easy_handeye会把结果发布到TF树上你可以直接看到camera和robot_base之间多了一个固定变换。拿到结果后一定要做验证别急着标定完就开抓。我的验证方法是在相机视野里放一个相对较小的标记物识别出它在相机坐标系的坐标然后用标定出的变换转换到机器人基坐标系再用手动示教把机械臂末端移到这个坐标附近看看误差有多大。如果转换误差在1-2cm以内标定基本合格可以做普通抓取如果大于3cm建议重新检查采样姿态和marker尺寸。5. 常见问题与排查技巧实录5.1 RealSense在ROS里测不到深度最典型的三个原因USB带宽不够、多个RealSense同时接入占用了相同序列号、固件版本和librealsense不匹配。先用rs-enumerate-devices确认相机能被SDK发现再用dmesg | tail看内核日志看到usb相关报错就先换一个USB口最好是主板原生USB 3.0。多个相机接入时在realsense2_camera的launch里给每个相机分别指定serial_no。5.2 机械臂驱动起来了但TF树不完整如果RVIZ里看不到完整的base_link到ee_link先检查机械臂驱动有没有加载URDF很多驱动节点默认不会自动加载描述文件。驱动正常但缺少末端工具坐标时要手动加一个静态变换发布器把工具坐标系挂到末端下面easy_handeye里的robot_effector_frame就指向这个坐标系。5.3 标定误差大或者结果一直发散排查看两个方向一是ArUco识别出来的marker位姿是否稳定把marker固定在桌面上静止不动打印位姿话题如果数值波动很大说明是光照、反光或实际尺寸问题二是机械臂末端位姿是否准确睿尔曼机械臂重复定位精度很高但如果你让机械臂以较大的姿态角到达采样点而机械臂本身没有做负载补偿末端实际位置可能会和理论位置有偏差。我把这些常见问题整理成了速查表问题现象常见原因解决办法相机无深度数据彩色图正常深度图全黑强光干扰或相机距离目标过近调整视角和距离避免阳光直射给深度图设短距离上限marker识别不到RVIZ里看不到识别框markerId填错、尺寸填错、离相机太远核对打印的marker编号和实际边长调整相机位置标定结果漂移每次Compute结果差异大采样姿态单一、标记点太少重采加入旋转姿态增加到12个点以上转换误差大验证时投影到机器人坐标偏差超3cmmarker贴纸不平、ArUco尺寸量错重新贴平板重新量实际尺寸TF树报错找不到camera_color_optical_frame相机启动时disable了color话题或坐标系名不同rostopic list查看实际话题名用tf_prefix统一最后补充一个小技巧。标定完成之后如果你后面还要做深度相机引导抓取建议把标定出的静态变换保存下来写成固定TF发布器写进启动文件里不要每次启动都重新跑一遍rqt_easy_handeye也不要在相机没挪动的情况下反复重标。我自己在项目里就把相机支架做了一个固定的限位卡槽相机拆下来重装后可以直接卡回原位标定结果能保持很久。这套流程跑通之后后续再做视觉抓取基本就是标准化的活了。本文还有配套的精品资源点击获取