手眼标定——使用 easy_handeye 和 aruco

整个过程分为以下三步

  1. aruco_ros 的配置使用
  2. easy_handeye 的配置使用
  3. 标定过程

aruco 的配置使用

  1. clone aruco 项目 到 ros 工作空间。
  2. 前往 aruco marker 生成网站 打印 marker,注意:一定要选择original,其它版本的检测不出
  3. 修改 single.launch 文件(如果要使用多 marker,请自行配置)。下面是我的 single.launch 文件,可做参考,我会将每个参数说明。
<launch>

    <arg name="markerId"        default="582"/>
    <arg name="markerSize"      default="0.1"/>    <!-- in m -->
    <arg name="eye"             default="left"/>
    <arg name="marker_frame"    default="camera_marker"/>
    <arg name="ref_frame"       default=""/>  <!-- leave empty and the pose will be published wrt param parent_name -->
    <arg name="corner_refinement" default="LINES" /> <!-- NONE, HARRIS, LINES, SUBPIX -->

    <node pkg="aruco_ros" type="single" name="aruco_single">
        <remap from="/camera_info" to="/camera_info" />
        <remap from="/image" to="/image_raw" />
        <param name="image_is_rectified" value="True"/>
        <param name="marker_size"        value="$(arg markerSize)"/>
        <param name="marker_id"          value="$(arg markerId)"/>
        <param name="reference_frame"    value="stereo_gazebo_left_camera_optical_frame"/>   <!-- frame in which the marker pose will be refered -->
        <param name="camera_frame"       value="stereo_gazebo_left_camera_optical_frame"/>
        <param name="marker_frame"       value="$(arg marker_frame)" />
        <param name="corner_refinement"  value="$(arg corner_refinement)" />
    </node>

</launch>
  • /camera_info: 填入相机的内参 topic,这个topic一般由启动相机的节点发布,例如我用的是 uvc_camera 启动相机,他就会发布相机内参 topic。
  • /image: 图片 topic,同样我的也是由 uvc_camera 发布的,要填什么具体看你这个节点的名字。
  • reference_frame: marker 坐标系的参考坐标系,我们要获得的是marker 和相机的相对位姿,所以这里设置为相机坐标系,即和 camera_frame 一样。
  • camera_frame: 相机坐标系,随便写个名字
  • marker_frame:marker 坐标系,随便写个名字

easy_handeye的配置使用

  1. clone easy_handeye项目 到 ros 工作空间。
  2. 在 easy_handeye/docs/example_launch 文件夹下复制一份 launch 文件到 easy_handeye/easy_handeye/launch 文件夹下。这里注意一下,你可以将启动机械臂、相机、aruco、easy_handey的程序放到一个launch文件下一起启动(如 easy_handey 给的 example),也可以分别启动。为了清晰,我选择分开启动。所以这个复制的 launch 文件中我删去了启动机械臂和 aruco 的部分,只剩下启动手眼标定的部分。
  3. 修改复制的 launch 文件。下面是我的该 launch 文件的配置
<launch>
    <arg name="namespace_prefix" default="aubo_kinect_handeyecalibration" />

    <!-- start easy_handeye -->
    <include file="$(find easy_handeye)/launch/calibrate.launch" >
        <arg name="namespace_prefix" value="$(arg namespace_prefix)" />
        <arg name="eye_on_hand" value="true" />

        <arg name="tracking_base_frame" value="stereo_gazebo_left_camera_optical_frame" />
        <!-- camera_marker -->
        <arg name="tracking_marker_frame" value="camera_marker" /> 
        <arg name="robot_base_frame" value="base_link" />
        <arg name="robot_effector_frame" value="wrist3_Link" />

        <arg name="freehand_robot_movement" value="false" />
        <arg name="robot_velocity_scaling" value="0.5" />
        <arg name="robot_acceleration_scaling" value="0.2" />
    </include>

</launch>
  • eye_on_hand: true 时相机在机械臂上,marker固定。反之相反。
  • tracking_base_frame: marker的坐标系的参考坐标系,这里写相机坐标系的参考坐标系,也就是相机坐标系。
  • tracking_marker_frame: marker 坐标系,即 aruco 设置的 marker_frame

注意: 看似这些坐标系设置的挺乱,他的原则就是,这些坐标系放在一起组成一个集合,其中每个坐标系要能通过其他坐标系,得到每个坐标系之间的相互转换关系。所以上述两个launch文件提到的坐标系写法可以有很多,我选择了比较简单的。

标定过程

依次启动机械臂、相机、aruco、easy_hand。没问题就会出现三个在启动 easy_handeye 后会出现三个窗口。

  1. 将机械臂移动至 marker 在相机中出现(你可以使用rqt_image_view image:=(image的topic),rqt窗口里选择 aruco_ros/result–好像是这个名字…),就能看见图片和检测结果。
  2. 点击 check starting pose ,这步是确定marker 相对于相机的位姿。
  3. 你可以使用 easy_handeye 的自动化程序来移动机械臂标定,即点击next_pose…。但是这个自动移动机械臂经常时相机照不到marker,我建议手动移动机械臂,移动到哪?后面我会写出注意点。移动到合适的位置后,点击 take_sample
  4. 获得一些sample后,点击 compute 就能看到标定结果了。

如何移动机械臂获取sample

easy_handeye 作者给出建议:

  • Maximize rotation between poses.
  • Minimize the distance from the target to the camera of the tracking system.
  • Minimize the translation between poses.
  • Use redundant poses.
  • Calibrate the camera intrinsics if necessary / applicable.
  • Calibrate the robot if necessary / applicable.

这就好了吗??
如果真这么容易就好了!

问题即解决方案

  • ’module’ object has no attribute 'CALIB_HAND_EYE_TSAI’

handeye_calibration_backend_opencv.py 文件中 import cv2 改为

import sys
sys.path.remove('/opt/ros/kinetic/lib/python2.7/dist-packages')
import cv2
sys.path.append('/opt/ros/kinetic/lib/python2.7/dist-packages')

这个问题是由于 ros 安装的 python 和自己系统中安装的 python 调用时出问题,具体什么问题?我不知道。出处
如果还不行,卸载掉opencv相关包,重新安装opencv_contrib_python。如python版本也是2.7的话,将其版本指定 “==4.2.0.32”,具体支持见 opencv-python版本对应

  • xxx and xxx not part of the same tree.Tf has two or more unconnected trees.

这个问题是这两个坐标系不能联系起来,即一个坐标系通过已知的坐标系,求得另一个坐标系。一般是 aruco 中 reference_frame 和 camera_frame 设置不对,把这两个设为一样通常可解决。同时easy_hanyeye 里复制的launch文件中要参考 single.launch 设置对。

  • Requested time xxx but the latest data is at time xxx…

代码问题,将easy_handeye 中文件 handeye_sample.py 65行(左右)time = Time.now() 改为 time=Time(0)

可能有些问题忘了,一些细节没说清楚,请大家评论区批评指正。有问题评论我会回复。

### 关于ROS中机械臂手眼标定 #### 基础概念与准备知识 在讨论具体实现之前,了解一些基本的概念对于理解整个过程至关重要。空间位姿坐标系转换原理是手眼标定的基础之一[^2]。手眼标定的目标是在已知目标物体相对于摄像头位置的情况下,通过一系列变换矩阵来计算出末端执行器(通常是夹爪)相对基座的位置关系。 #### 实现方法概述 针对不同类型的配置——即“眼在手上”或“眼在外”,有不同的处理方式: - **眼在手上**:当摄像机安装在机械臂上时,需要先移动机械臂至多个预设姿态并记录对应的图像数据;之后利用这些信息求解相机到工具中心点之间的刚体运动参数。 - **眼在外面**:如果摄像机固定不动,则只需让机械臂携带特定标记物经过若干指定地点即可完成同样的任务。 两种情况下均涉及到`OpenCV calibrateHandEye()`函数的应用,该API能够简化上述流程中的核心运算环节。 #### 工具包介绍 为了便于开发人员快速搭建实验环境以及验证算法效果,社区提供了多种辅助资源支持库。例如,在ROS环境下可以借助`aruco_ros package`轻松检测ArUco码,并将其作为参照物参与后续的定位工作[^1]。此外还有专门用于手眼协调训练的任务框架如`easy_handeye`等可供选用[^3]。 #### 注意事项 在整个过程中需要注意几个方面以确保最终结果的有效性准确性: - 精确控制每次动作间的间隔距离; - 尽量减少外界干扰因素的影响程度; - 对采集的数据质量严格把关等等。 ```python import cv2 from easy_handeye.hand_eye_calibration import HandEyeCalibration calibrator = HandEyeCalibration() # 进行多次测量... result = calibrator.compute_transformation() print(f"Transform matrix:\n{result}") ```
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值