ROS(Kinetic和Melodic)下使用cartographer踩坑记录和部分谣言终结

最近在机器人上尝试跑cartographer进行建图,途中遇到了不少坑,写下来记录分享一下。

测试环境1:

机器人 PC
NanoRobot(两轮差速底盘,树莓派3B,ubuntu mate 16.04,ROS Kinetic,单线激光雷达) Ubuntu16.04 ROS Kinetic(虚拟机)

机器人和PC端安装cartographer都使用二进制包方式安装(因为懒)

sudo apt-get install ros-kinetic-cartographer*

接下来是写cartographer.launch文件,照猫画虎写出来是这样的,没什么特别要注意的,use_sim_time根据实际设置,仿真中用true,实体机器人上用false,把你地激光雷达话题remap成scan(大多数单线雷达默认就是用scan,所以省略掉remap那一句也可以)

<launch>  
   
  <param name="/use_sim_time" value="$(arg simulation)" />  
  
  <node name="cartographer_node" pkg="cartographer_ros"  
        type="cartographer_node" args="  
            -configuration_directory $(find package_name)/config  
            -configuration_basename config.lua"  
        output="screen">  
        <remap from="scan" to="scan" />
  node>  
launch>

接下来是修改config.lua文件,这个lua文件只要是用来向cartographer_node传递参数(个人理解),这里我就掉进了第一个坑,在网上找了别人写好的的一些lua文件(根据我的计划,是只使用激光雷达,不使用里程计不使用imu),copy过来改吧改吧直接跑,果然,报错了,报错信息大概如下:

lua_parameter_dictionary.cc:83] Check failed: status == 0 (2 vs. 0) [string "-- Copyright 2016 The C..."]

一开始我以为是lua语法格式或者是lua解释器的问题,折腾一番,未果。
然后想到,可以参考一下cartographer下提供的demo的文件,跳转到cartographer_ros安装目录下,“检阅”了一遍launch和configuration_files文件夹下文件,相中了demo_revo_lds.launch和配套的revo_lds.lua文件(和我的测试环境基本吻合),把revo_lds.luacopy到我包的config目录下出来,做简单修改,只需要修改两句:

  tracking_frame = "horizontal_laser_link",
  published_frame = "horizontal_laser_link",

修改为base_laser_link是我雷达的雷达关节名称,使用其他名称自行替换

  tracking_frame = "base_laser_link",
  published_frame = "base_laser_link",

再修改下launch文件中引用的lua文件名为revo_lds.lua(对,我懒到懒得改文件名,其实主要还是保留这个名称方便知道这个文件是从哪里移植过来的)
再运行,正常启动,跑一圈,效果还可以。
rosrun map_server map_saver -f map即可保存地图
ROS(Kinetic和Melodic)下使用cartographer踩坑记录和部分谣言终结_第1张图片

测试环境2

这个测试主要是因为树莓派3B+目前ubutnu mate官方只有18.04版本(民间有大神修改的16.04版本,但是实测打开CSI摄像头接口会导致系统崩溃),所以只好又在18.04和ROS Melodic上做了一遍测试

机器人 PC
NanoCar(阿克曼转向底盘,树莓派3B+,ubuntu mate 18.04,ROS Melodic,单线激光雷达) Ubuntu16.04 ROS Kinetic(虚拟机)

机器人和PC端安装cartographer都使用二进制包方式安装(还是因为懒)
理所当然的把之前写好的包直接拿过来跑,理所当然的报错了(内心毫无波澜)
简单看一下报错信息,大概是SPARSE_POSE_GRAPH参数不存在之类的,有了之前踩坑教训,这次学乖了,还是去copy官方demo下的文件来修改,注意要copy Melodic版本下的,稍后会解释。
修改完成后再跑,没有报错,报了一个小警告,根据我这个三流程序员的尿性,WARN可以无视(手动滑稽)

[ WARN] [1567651528.953127469]: W0905 10:45:28.000000  2208 pose_extrapolator.cc:168] Queue too short for velocity estimation. Queue duration: 0 ms

打开rviz,一脸懵圈,我是来建图的,图呢,没图说个JB
ROS(Kinetic和Melodic)下使用cartographer踩坑记录和部分谣言终结_第2张图片
检查话题列表,确实没有map话题,但是submap_list是有的,rviz订阅之,机器人端报错

[ERROR] [1567651902.925774803]: Client [/rviz] wants topic /submap_list to have datatype/md5sum [cartographer_ros_msgs/SubmapList/5486c1cb2dbd0e42fa7ce803a38fcb70], but our version has [cartographer_ros_msgs/SubmapList/6efe809c4a0e69266aa99b3bea531f2a]. Dropping connection.

看到这里你应该能猜到了,cartographer版本问题,检查一下cartographer_ros版本
Kinetic:0.2.0,Melodic:1.0.0
定位到是版本问题,换18.04的虚拟机测试一下,rviz订阅submap_list看起来是正常的,所以基本推断配置和运行都是正常的,所以接下来解决没有map的问题
在ROS API reference documentation中看到一个奇怪的API
Occupancy grid Node
根据描述,这个节点是订阅submap_list,发布map
我大概翻译一下:那些古老的导航只能够处理占据栅格地图,所以我们就提供了这个节点来给你们实现submaps到occupancy_grid 的转换,等到哪天导航系统能够直接支持我们Cartographer submaps,这个节点也就没啥用了,还有我告诉你啊,从submaps到occupancy_grid又慢又费算力,map更新速度是秒级,你可以选择优化,具体的你去看节点的help吧。
Google从0.2.0版本到1.0.0版本的变迁中(不清楚0.3.0版本是怎么设计的,没用过,有用过的同学希望能有在评论中说明一下),剥离了这个节点功能,估计是为了让用户可以自由选择来降低cpu负载。
所以这个也就解释了现在为什么没有map话题了,手动启动这个节点
rosrun cartographer_ros cartographer_occupancy_grid_node
果然,地图出来了,测试下来效果感觉比Kinetic版本效果要好(主观评价,没有量化比较)
测试保存地图也正常
题外话:Google将这个节点剥离出来是有好处的,可以降低cpu计算负载,我这里启动这个节点只是为能正常出地图,我更倾向的是做建图过程订阅submap_list来观察建图效果,需要保存地图再将submap转化为occupancy_grid 地图,具体过程回头测试过再补充
ROS(Kinetic和Melodic)下使用cartographer踩坑记录和部分谣言终结_第3张图片
因为我写的这个包需要在Kinetic和Melodic两个版本下使用,所以我将两个版本下的lua文件分别命名为revo_lds_kinetic.luarevo_lds_melodic.lua,launch文件则修改为

<launch>  
   
  <arg name="version" default="$(env ROS_DISTRO)"/>
  <param name="/use_sim_time" value="$(arg simulation)" />  
  
  <node name="cartographer_node" pkg="cartographer_ros"  
        type="cartographer_node" args="  
            -configuration_directory $(find robot_navigation)/config  
            -configuration_basename revo_lds_$(arg version).lua"  
        output="screen">  
  node>  
  <group if="$(eval version == 'melodic')">
      <node pkg="cartographer_ros" type="cartographer_occupancy_grid_node" name="cartographer_occupancy_grid_node"/>
  group>
launch>

到这里Cartographer 在目前两个主要的ROS版本下的坑算是踩完了,总结一下:
1、启动文件可以参考官方demo中的launch和配置文件来修改,实测这是不容易翻车的方法
2、Kinetic和Melodic版本下面都提供Cartographer 的二进制安装包,但是版本号不同,接口不兼容,行为也不一致
自己实际跑了一圈也证明了有两个说法是谣言
1、Cartographer 官方要求配置是64-bit, modern CPU (e.g. 3rd generation i7),16 GB RAM树莓派差得太远完全跑不动,实际测试树莓派3B和3B+都可以正常跑,小环境(100平米)效果还挺好,更大的环境没有测试过
2、Cartographer 不能使用map_saver保存地图,实际测试只要有map话题就可以保存地图,保存的地图也是正常的,和其他slam算法生成的地图别无二致。
3、Cartographer 建图中必须使用官方demo中的launch文件启动rviz,否则显示不正常,实际测试只要版本匹配,选择正确的话题,不存在显示不正常的问题

你可能感兴趣的:(ROS)