当前位置: 首页 > 工具软件 > easy-sys > 使用案例 >

手眼标定——使用 easy_handeye 和 aruco

周伟泽
2023-12-01

整个过程分为以下三步

  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)

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

 类似资料: