手眼标定目录
背景
最近在做机器人抓取的相关研究,卡在手眼标定这一块了。网上也有一些大佬的博客在写,不过没有看到realsense和kinova的相关实验。小弟在此试错一周,奉上此博客,希望对有需要的小伙伴有所帮助。标定大概是,先启动编写完成的launch文件(相机,机器人,moveit,easy_handeye等),然后手动采集20个点,计算得到机器人base到相机的坐标变换关系,然后进行save,会被默认保存在~/.ros/easy_handeye文件夹下的一个yaml文件,然后进行publish就可以将而这的坐标变换发布到tf中。
标定过程
机器人的手眼标定主要参考开源项目easy_handeye,我再稍微罗嗦一下步骤,需要具备一下几个方面的内容。
easy_handeye
cd ~/catkin_ws/src # replace with path to your workspace
git clone https://github.com/IFL-CAMP/easy_handeye
cd .. # now we are inside ~/catkin_ws
rosdep install -iyr --from-paths src
catkin build
需要先进行rosdep。这个过程我就报错了
错误1-缺少库transforms3d
解决方案
pip install transforms3d
运行easy_handeye
参考issue,需要先将calibrate.launch文件中的第十三行move_group的default value改为arm,如下
<arg name="move_group" default="arm" doc="the name of move_group for the automatic robot motion with MoveIt!" />
这里需要编写一个launch文件,启动相机,机器人,moveit-kinova,以及easy_handeye,aruco等工具,我的launch文件放在代码部分
错误2-cv2.CALIB_HAND_EYE_TSAI
这个问题开始怀疑是opencv-python的版本不对,更换了几次,仍然有问题。后在issue74中有大佬给出解决方案,我的解决方案如下
1.首先安装opencv-contrib
python -m pip install opencv-contrib-python
2.在cv2.CALIB_HAND_EYE_TSAI报错的文件中作如下修改
将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库位置不一样,所以import cv2是从ros的python库环境中导入,而我们的cv2是安装在计算机的python库中,所以需要先屏蔽掉默认的ros库导入,此时python的库已经切换到了计算机的python库。
错误3-Cannot calibrate from current position
这一个错误是由于未能调出image-view,无法采样,但是在rqt中我始终无法找到plugin菜单栏,报错Cannot calibrate from current position最后,不得已,我只能重新开启一个rqt(只需要运行rqt即可),选择空的rqt中的plugin栏目,选择image-view,topic选择**/aruco_track/result**,此时,只要相机视野中有坐标系,就可以进行采样操作了,这个过程由参考链接5得到启发
ros-realsense(d435)
参考ros-realsense自行安装
验证相机可用:
roslaunch realsense2_camera rs_camera.launch
然后就可以看到相机节点信息
kinova机器人ros驱动
参考ros-kinova自行安装
验证机器人可用:
roslaunch kinova_bringup kinova_robot.launch kinova_robotType:=j2n6s300
另还需要moveit工具进行轨迹规划
验证moveit
roslaunch j2n6s300_moveit_config j2n6s300_demo.launch
这个成功就表明在rviz内虚拟机器人与现实中的机器人的状态是同步的,并且可以在rviz中拖动机器人末端,进行轨迹规划(plan)和执行(execute)
重要:以上步骤配置完成可以看到三个图,见参考链接6,却一不可,如果可以手动进行规划,check starting pose那个图不需要使用,只要点击check starting pose没有错误就可。take sample那里也需要没有错误。
publish
采集完成20个点,计算,然后保存,最后进行publish
roslaunch easy_handeye calibrate.launch eye_on_hand:=true
相关代码
kinova_realsense.launch文件
需要注意的几个点(个人建议):
1.aruco
在aruco中生成marker,我选择的是ID为14,size为100mm,保存pdf打印出来(对应于launch文件中的两个参数,“marker_size”,“marker_id”)。标定过程中保持marker不动,同时marker要处于平整的桌面上
错误2.几个工具都运行后,通过查看当前的tf变换,查看具体的frame名称
查看tf变换命令
rosrun rqt_tf_tree rqt_tf_tree
注意参数reference_frame,camera_frame,tracking_base_frame,tracking_marker_frame的value值(我参考easy_handeye作者编写)完成
<launch>
<arg name="namespace_prefix" default="kinova_d435_handeyecalibration" />
<!--<arg name="robot_ip" doc="The IP address of the UR5 robot" />-->
<arg name="marker_size" value="0.1" />
<arg name="marker_id" value="14" />
<!-- start the Kinect -->
<!--<include file="$(find realsense2_camera)/launch/ggcnn_points.launch" >-->
<!--<!–<arg name="depth_registration" value="true" />–>-->
<!--</include>-->
<!-- <arg name="camera_frame" default="camera_rgb_optical_frame"/> -->
<!-- <arg name="reference_frame" default="camera_rgb_optical_frame"/> -->
<!-- <arg name="camera_marker" default="camera_link"/> -->
<!-- start the Camera -->
<include file="$(find realsense2_camera)/launch/rs_camera.launch" >
</include>
<!-- start ArUco -->
<node name="aruco_tracker" pkg="aruco_ros" type="single">
<remap from="/camera_info" to="/camera/color/camera_info" />
<remap from="/image" to="/camera/color/image_raw" />
<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="camera_link"/>
<param name="camera_frame" value="camera_depth_optical_frame"/>
<!--<param name="camera_frame" value="_color_optical_frame"/>-->
<param name="marker_frame" value="camera_marker" />
</node>
<!-- start the robot -->
<include file="$(find kinova_bringup)/launch/kinova_robot.launch">
</include>
<include file="$(find j2n6s300_moveit_config)/launch/j2n6s300_demo.launch">
</include>
<!-- 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="camera_link" />
<arg name="tracking_marker_frame" value="camera_marker" />
<arg name="robot_base_frame" value="j2n6s300_link_base" />
<arg name="robot_effector_frame" value="j2n6s300_link_6" />
<!--disable automatic robot movement-->
<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>
结果
最终标定结果
最终发布的tf变换
参考链接
参考链接1:kinova与kinect手眼标定1
参考链接2:kinova与kinect手眼标定2
参考链接3:easy_handeye issue19
参考链接4:easy_handeye issue74-对于我的问题解非常重要,其实就是我提的issue啦啦啦
参考链接5:rqt-plugin师兄的博客博客
参考链接6:师弟的博客