在移动机器人仿真中,二维地图真值可以用来评价slam建图结果,也可以直接给路径规划算法提供输入。

利用gazebo进行仿真时,有很多方法都可以获取静态仿真环境的二维地图真值,本文将对以下链接:

hyfan1116/pgm_map_creator

进行使用测试。

该仓库的README对安装编译和使用已经讲解得比较清楚了:

pgm_map_creator

Create pgm map from Gazebo world file for ROS localization

Environment

Tested on Ubuntu 16.04, ROS Kinetic, Boost 1.58

Usage

Add the package to your workspace

  1. Create a catkin workspace
  2. Clone the package to the src folder
  3. catkin_make and source devel/setup.bash

Add the map and insert the plugin

  1. Add your world file to world folder
  2. Add this line at the end of the world file, before </world> tag:
    <plugin filename="libcollision_map_creator.so" name="collision_map_creator"/>

Create the pgm map file

  1. Open a terminal, run gzerver with the map file
    gzserver src/pgm_map_creator/world/<map file>
  2. Open another terminal, launch the request_publisher node
    roslaunch pgm_map_creator request_publisher.launch
  3. Wait for the plugin to generate map. It will be located in the map folder

Map Properties

Currently, please update the argument value in launch/request_publisher.launch file.

Acknowledgements

Gazebo Custom Messages
Gazebo Perfect Map Generator

总结起来就是,将该ros程序编译好后,在你需要获取地图真值的gazebo world文件中添加一个插件:

<plugin filename="libcollision_map_creator.so" name="collision_map_creator"/>

再运行gazebo打开此world文件(一般我都是通过roslaunch启动gazebo并加载world文件的),以程序包自带的udacity_mtv环境为例:

world

最后执行本ros包中的

roslaunch pgm_map_creator request_publisher.launch

就可以在指定位置生成一张二维栅格地图(pgm格式):
map
其间,打开gazebo仿真环境的窗口会有反馈:
在这里插入图片描述
在这里插入图片描述
显示生成地图成功。

下面解析一下request_publisher.launch文件中的参数:

<arg name="map_name" default="map" />
<arg name="save_folder" default="$(find pgm_map_creator)/maps" />

这两项是输出的地图文件名和文件路径。

<arg name="xmin" default="-15" />
<arg name="xmax" default="15" />
<arg name="ymin" default="-15" />
<arg name="ymax" default="15" />

这几项是生成地图的仿真环境坐标范围。

<arg name="scan_height" default="5" />

这项指的是从多高的高度向下扫描仿真环境。这里涉及了本程序获取仿真环境二维地图真值的原理:在以上坐标范围内从“scan_height”高度均匀向下发射射线,如果碰到了障碍物,那么二维栅格地图上这一格就为Occupied,通俗来讲就是这一格是黑色的。

<arg name="resolution" default="0.01" />

最后是二维栅格地图的分辨率,此处0.01表示栅格边长为1厘米。

需要注意的是,本程序检测的是gazebo模型中的<collision>元素,并且是模型<collision>元素的上表面,所以首先要保证模型有合理的碰撞属性,其次要注意发射射线的scan_height高度,否则地图上无法如愿显示出应有物体。

另外,从代码中看collision_map_creator.cc#L89

    double dist;
    std::string entityName;
    ignition::math::Vector3d start, end;
    start.Z(msg->height());
    end.Z(0.001);

射线的终点在0.001(1毫米)高度,也就是说如果地面ground_plane模型放置在0米高度,那么高度大于1mm的物体都会被检测到。换句话说,如果地面ground_plane模型或者其他充当地板的模型放置得高于1mm,那么二维地图中该地面范围内就会一片漆黑。可以通过修改代码中此处的射线终点高度,或者将终点高度也作为参数开放出来解决这一问题。