UR5 kinect2 eye on base calibration

手眼標定是機械臂視覺的第一步. 原理說起來很簡單: 機械臂拿一個標誌物, 相機照幾張識別出標誌物姿態. 這個過程中只有標誌物到機械臂和機械臂底座到相機的關係兩個未知. 所以最少三次就可以標定出位置.

但自己做的時候就懵逼了, 感覺找不到好用的教程. 不過還好找到個easy_handeye, 讀一讀, 改一改, 調一調, 最後跑起來感覺還不錯, 所以寫個教程記錄一下.

prerequisite

  1. ros kinetic
  2. moveit ur5 setup
  3. pal-robotics/aruco_ros
  4. visp_hand2eye_calibration - ROS Wiki
  5. kinect2 setup
  6. easy_handeye

easy_handeye introduction

easy_handeye顧名思義, 就是簡化手眼標定過程. easy_handeye可以標定眼在手上和眼在手外兩種情況, 而且設計了兩個GUI, 一個可以記錄方程並優化求解, 一個可以控制末端自動走16個姿態, 可以說非常方便了. 然而, 實際使用中發現easy_handeye一堆依賴包沒詳細說, 怎麼根據自己的情況調也沒講, 只好自己讀代碼找出來了.

使用easy_handeye首先需要把UR5跟kinect2跑起來. 然後, 用aruco_ros識別末端上的標誌物, 得到camera_link到marker_link的轉換. 之後按照GUI控制機械臂在相機視野內產生16個姿態, 每次都把樣本記錄下來. 這16個姿態是第一步計算好的, 在開始姿態前後左右上下8個位置各2個角度. 最後點擊求解, easy_handeye會調用visp的代碼得到標定結果. 然後點save, 標定結果會被保存在~/.ros/easy_handeye/---.yaml. 之後就可以關掉標定程序,再跑publish.launch即可發布base_link到camera_link的轉換.

aruco_ros

aruco_ros是用來識別aruco這種圖案的. 識別需要知道aruco的ID跟邊長. 有個網站可以生成這種圖案.

aruco_ros需要配置兩個方面的參數. 首先是相機, 需要camera_info和image的topic, 還有image所在的frame. 還有一個是tf的關係,從reference_frame到marker_frame, 如果識別出marker就發布. 如果沒有特殊要求, 一般的reference_frame就配成相機的frame.

<!-- start ArUco --> <node name="aruco_tracker" pkg="aruco_ros" type="single"> <remap from="/camera_info" to="/kinect2/hd/camera_info" /> <remap from="/image" to="/kinect2/hd/image_color_rect" /> <param name="image_is_rectified" value="true"/> <param name="marker_size" value="$(arg marker_size)"/> <param name="marker_id" value="$(arg marker_id)"/> <param name="reference_frame" value="kinect2_rgb_optical_frame"/> <param name="camera_frame" value="kinect2_rgb_optical_frame"/> <param name="marker_frame" value="camera_marker" /> </node>

ur5

easy_handeye本身有一個launch文件可以跑, 但是其中關於ur5的部分多了一個limited參數. 一開始還沒在意, 可是後來規劃老失敗, 查了半天才發現這兒有問題. 把limited注釋掉就好.

start handeye

這一部分主要需要注意4個frame: tracking_base_frame就是相機的frame, tracking_marker_frame是標誌物的frame, 這兩者之間的關係由aruco_ros發布, 所以要對上; robot_base_frame就是機械臂底座, robot_effector_frame是末端, 這兩個跟UR5發布的要對上. 這幾個frame之間變化的都能被觀測到, 所以可以通過幾個樣本得出不變的相機到底座之間的關係. 注意namespace_prefix要跟publish.launch里的對上, 因為保存標定結果的時候文件名按照這個取的.

<!-- 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="false" /> <arg name="tracking_base_frame" value="kinect2_rgb_optical_frame" /> <arg name="tracking_marker_frame" value="camera_marker" /> <arg name="robot_base_frame" value="base_link" /> <arg name="robot_effector_frame" value="wrist_3_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>

steps

  1. 跑kinect2: roslaunch kinect2_bridge kinect2_bridge.launch
  2. 跑標定: roslaunch easy_handeye ur5_kinect_calibration.launch
  3. 點GUI里的check, 初始化16個姿態; 然後next pose一下就記錄一下sample
  4. 計算, 保存, 關掉標定程序
  5. 跑標定結果: roslaunch easy_handeye publish.launch
  6. 使用時通過tf查, base_link(底座)到kinect2_rgb_optical_frame(相機)

我們用的realsense,最後publish的時候發現相機跟點雲的約定xyz軸不一樣,我們把原來publish的frame改了下,在中間插了個tf解決這個問題:

推薦閱讀:

TAG:機器人操作平台ROS | 標定 |