(三)用自己的数据包运行cartographer

前面已经运行了几个demo,其实运行自己的包只需要录制和之前格式一致的rosbag即可。里面可以根据自己的需要,主要包括:激光(scan)、齿轮编码器(odom)、惯导(imu)、静态路标(landmark)等。

第一步:验证数据包

cartographer提供了cartographer_rosbag_validate程序来检测数据包的是否符合cartographer的运行格式。官网文档说这个cartographer_rosbag_validate程序功能强大,不仅能够检测是否数据完整还能给出合理的数据格式建议,不过小编在实际使用中并未发现,此处吐槽一下。
不过这个工具还是有用的,下面要说小编最常用到的是,通过这个工具可以知道每个数据的frame_id,这个挺重要的,frame_id就是urdf里面的每个部件的名称。
[为什么?] urdf是什么?urdf是描述机器人各个硬件之间的3维空间连接关系,urdf有什么用呢?如果你只有激光laser数据源可能urdf的功能体现不出来,但是如果你同时有相机和激光数据源,slam过程中需要显示激光地图下相机看到的landmark路标,那么就需要把相机看到的landmark转换到激光坐标系下,而这时候我们就需要知道相机在激光坐标系下的空间位姿(相机和激光之间的外参),这个urdf就是的手动提供外参的输入文件,这下明白了吧。你可能还想问:我干嘛要把相机看到的landmark转换到激光坐标系下呢?这个答案是上一篇文章讲到的static landmark的作用,即用于机器人的快速定位。相机一但看见landmark,即马上知道自身的地图位置,继而可以进行导航、巡航。可以接受urdf提供的参数有些小误差,cartographer可以修正这些小的位姿误差,但是如果urdf提供的外参风马牛不相及,cartographer也不是万能的。

使用方法

rosrun cartographer_ros cartographer_rosbag_validate -bag_filename your_bag.bag
第2步:创建.lua配置文件

cartographer高度灵活可以配置各种机器人运行时的参数,这种配置文件是用lua文本来编写的,其目录在src/cartographer_ros/cartographer_ros/configuration_files下
注意:理想情况下一份lua配置文件对应一种机器人,而不是对应一个数据包。
[待解决问题] 其实根据我们前面跑的demo可以拿过来直接用,需要提供lua文件里对应的map_frame、tracking_frame、published_frame 和 odom_frame。经过验证你只要把tracking_frame和pubilish_frame填对就可以了,tracking_frame和pubilish_frame一般对应base_link即可,即机器人中心坐标系,具体功能细节待补充(即map_frame、tracking_frame、published_frame 和 odom_frame分别在程序的作用)。

一些参数介绍:

  1. num_laser_scans:使用激光雷达的数量,话题类型sensor_msgs/LaserScan
    注释:如果只是用一个激光雷达,cartographer的话题接口为/scan
    如果用多个激光雷达,则cartographer对应的话题接口为/scan_1、/scan_2。
  2. num_multi_echo_laser_scans:使用多回波激光器的数量,话题类型sensor_msgs/MultiEchoLaserScan
    注释:同num_laser_scans一样,只是使用了不同类型的雷达数据
  3. num_point_clouds:使用点云发射器的数量,话题类型sensor_msgs/PointCloud2
    注释:同num_laser_scans一样,只是使用了不同类型的数据
  4. use_landmarks:是否有landmark数据源输入
  5. use_nav_sat:是否有用GPS数据(还没尝试用过,很想试试)
  6. num_accumulated_range_data:就是积累几个topic的激光数据作为一个完整的scan传给cartographer的前端处理,还有一个参数num_subdivisions_per_laser_scan与num_accumulated_range_data参数有联系,num_subdivisions_per_laser_scan就是把一帧激光数据分为几份,每一份记做per_s的话,num_accumulated_range_data就是积累几个per_s。
    [为什么?] 为什么要把激光分成几份,然后又积累起来?这要从2d激光发射器说起,2d激光雷达只有一个发射点,但为什么可以扫描整个2d平面呢?因为这个装置有一个高速旋转器,可以带动这个发射点高速旋转,然后就形成了2d平面,那这个与上面的问题有什么联系呢?举个例子,一个激光2d平面可能是由360个激光点组成(我们叫一帧数据),每个激光点间隔1度,由于这种旋转成像原理,每个激光点之间形成的顺序就有先后之分,所以每个激光点的时间戳不同,那这个和上面num_subdivisions_per_laser_scan这些参数又有什么联系?我们知道机器人是每时每刻都是运动的,如果机器人运动的很快,可能激光一帧还没扫完,机器人已经走到别的位置了,这样机器人在多个位置获得一帧激光数据,显然这样的数据是有问题的(这个问题就是激光雷达的运动畸变问题),如何解决呢?就是把一帧激光的每一个激光点用当前机器人的位姿来矫正(一般使用odom和imu来矫正,因为它们的频率比较高,可以到100hz每秒),那这个好像和把激光分成几份好像无关吧?是的是无关,这是因为我们只考虑了只有一个激光雷达的情况,如果我们有2个激光雷达同时工作,那样分成几份之后就可以把2个激光雷达的数据按照时间顺序进行对齐,为什么要对齐?你说为什么,好了打完收功。
    (三)用自己的数据包运行cartographer_第1张图片
    剩下的option里的参数一般不会改变,但是其实有些还是要改的,见到案例再说。附上我的lua文件
    (三)用自己的数据包运行cartographer_第2张图片
第3步:根据你的机器人创建.launch文件

根据之前运行的demo,自己尝试一下配置好你的urdf(不用urdf需要自己发布tf),看看你的tf树的激光、imu、odom的frame_id是否在urdf或者/tf中正确对应。tracking_frame和pubilish_frame好如base_link,其他我认为没有问题了,附上我的launch文件,Good luck!
(三)用自己的数据包运行cartographer_第3张图片
运行demo截图

你可能感兴趣的:(slam)