首页 - 文章教程 - STDR仿真 - 正文

11.在自定义地图中进行自动导航

0x00 概述

在前面的文章中,我们介绍如何自动导航时,都是基于使用gmapping或者hector_mapping创建的地图。当然使用其他的建图方法创建的地图也可以,但是目前为止,无论使用哪种建图方法。通过激光雷达或深度摄像头建立的地图仍然是存在误差的。下面我们可以来回顾一下看看使用gmapping建立的地图,如下图所示,可以看到右侧的地图就是扫描建立的地图,与左侧的地图基本上相同。现在可以思考一下,我们有没有可能不用激光雷达来扫描建图(这个slam过程真的是挺麻烦的),因为现在基本上在设计施工时都是有设计图纸的,如果我们将这些设计图纸拿来,修改一下直接就当作导航地图来用。这样不是就省去建地图的步骤了嘛,而且地图的与实际环境100%匹配(除非施工建造时没有按照图纸来做):

1533197143149011.png

0x01 创建自定义地图

在前面一篇文章10.在STDR中加载其他地图中,介绍了如何在stdr中加载自定义的地图。这张地图是从网上下载的一个两居室户型图,后来经过简单修改我们就可以在stdr中加载了。现在我们可以更进一步,可以将这张地图使用map_server加载。这样我们就可以把地图在rviz中直接加载,就可以在这张地图上进行自动导航了。下面先来看看我们上次创建的这个户型图,如下图所示:

1545298320572332.png

现在我们已经可以在stdr中加载这张地图了,现在我们要将这张地图使用map_server加载。那具体如何操作呢?我们可以先来看看使用gmapping建好的地图是使用什么格式来存储的。我们可以按照它的格式来修改一下这张地图不就可以了嘛,说干咱就开始动手操作:

(1)查看gmapping创建的地图

Screenshot from 2019-01-03 15:12:57.png

可以看出gmapping完成后,保存的地图格式为pgm,另外有一个配套的yaml文件。现在来简单介绍下这个pgm格式的图片,可能大多数人不了解这种格式。PGM 是便携式灰度图像格式(portable graymap file format),在黑白超声图像系统中经常使用PGM格式的图像,文件的后缀名为".pgm"。PGM格式图像格式分为两类:P2和P5类型。不管是P2还是P5类型的PGM文件都由两部分组成,文件头部分和数据部分。

[文件头部分]

文件头包括的信息依次是:

1.PGM文件的格式类型(是P2还是P5);

2.图像的宽度;

3.图像的高度;

4.图像灰度值可能的最大值;

文件头的这四部分信息都是以ASCII码形式存储的,下面我们可以看看gmapping建好的地图格式是P2还是P5,如下图所示:

Screenshot from 2019-01-03 16:49:01.png

可以看出这里使用的是P5格式,第二行为一个注释信息。第三行416 416就是这张图片的长和宽,最后一行就是图像灰度值的最大值。

[数据部分]

数据部分记录图像每个像素的灰度值,按照图像从上到下,从左到右的顺序依次存储每个像素的灰度值,对于像素灰度值的表示P2格式和P5格式有所不同。下面来重点介绍P5格式:

P5格式图片的数据部分是从上到下,从左到右排列灰度值。每个灰度值取值为[0,Maxval],其中0表示黑色,Maxval表示白色。每个灰度值由1个或2个字节的纯二进制表示。如果最大值小于256,则为1字节。否则,它是2字节。最重要的字节是第一个。

(2)安装KolourPaint4软件

一般从网上下载的照片格式是png或jpg的,这里我介绍一种简单的方式来将这些格式转换为pgm格式。需要安装一下KolourPaint4画图工具,这个软件就跟我们常用的画图软件类似,安装软件的命令如下:

sudo apt-get install kolourpaint4

安装好该软件后,就可以来打开了,下图就是这个软件的界面:

1546507243543976.png

(3)使用软件转换图片格式

使用KolourPaint软件打开png格式或jpg格式的地图软件,如下图所示:

1546507649696264.png

然后使用图片另存为pgm格式,如下图所示:

1546507889470504.png

最后来查看下该图片格式是否为P5:

Screenshot from 2019-01-03 17:43:35.png

(4)创建对应的yaml配置文件

这个yaml配置文件编写比较简单,我们按照gmapping中地图的yaml格式来修改就可以了。下面来看看自定义地图的yaml内容:

Screenshot from 2019-01-03 17:54:11.png

这里来简单介绍下yaml中两个参数的意义:

image:要加载的地图,这里的路径可以写绝对路径也可以写相对路径。这里由于pgm图片和yaml文件都放在同一个文件夹中,所以就可以直接写home.pgm,不用加其他路径了。

resolution:将图片解析成多少实际距离,从file命令中得知,图片分辨率为761*721。这里0.015意思是:米/像素,这样就可以计算出这个地图表示的实际大小为:761*0.015=11.415米,721*0.015=10.815米。这就表示地图为11.4*10.8=123平米的大小。


0x02 编写launch文件

现在已经将自定义的图片格式修改为pgm格式了,对应的yaml配置文件也编写好了。下面我们就可以来编写对应测试的launch文件,下面首先来看看用来加载地图的launch文件load_home_map.launch:

<!--   
Copyright: 2016-2019 ROS小课堂 www.corvin.cn   
Author: corvin   
Description: 该启动文件用于加载自定义的home地图,这样就可以进行自动导航了.   
History:     
    20190102: initial this file. 
--> 
<launch>   
    <!-- load home map -->   
    <node pkg="map_server" type="map_server" name="stdr_load_home_map" args="$(find stdr_navigation)/maps/home.yaml">     
        <remap from="map" to="/amcl/map" />   
    </node>
</launch>

下面来看看最后用来最终测试用的launch文件home_map_nav.launch:

<!--   
Copyright: 2016-2019 ROS小课堂 www.corvin.cn   
Author: corvin   
Description: STDR simulator robot auto navigation with amcl and move base packages.     
  load home_map to test.   
History:     
    20190102: 加载home_map地图进行自动导航测试. 
-->
<launch>   
    <!-- load stdr simulator with robot0 -->   
    <include file="$(find stdr_launchers)/launch/home_map_robot_gui.launch" />   
    <!-- startup move_base node -->   
    <include file="$(find stdr_move_base)/launch/stdr_move_base.launch" />   
    <!-- load home map -->   
    <include file="$(find stdr_navigation)/launch/load_home_map.launch" />
    <!-- startup amcl node -->   
    <include file="$(find stdr_amcl)/launch/home_map_amcl.launch" /> 
</launch>

其实这里所有的代码都已经提交到stdr_ws代码仓库中,如果你已经下载了本代码的话,就可以在本地直接拉取最新代码。不过目前我的代码都是优先往kinetic分支上提交,indigo分支会逐渐放弃维护。

https://code.corvin.cn:3000/corvin_zhang/stdr_ws


0x03 测试查看效果

要想开始测试,我们首先需要启动上面编写的launch文件,使用如下命令来启动测试:

roslaunch stdr_navigation home_map_nav.launch

下面通过动图来查看导航效果,我们可以直接在Rviz中使用“2D Nav Goal”功能来选取导航的目的地:

自动导航动图演示

0x04 References

[1]. corvin_zhang. 10.在STDR中加载其他地图. http://www.corvin.cn/1047.html

[2]. Netpbm. PGM Format Specification. http://netpbm.sourceforge.net/doc/pgm.html

[3]. 编号1993. Python pgm解析和格式转换. https://blog.csdn.net/u012005313/article/details/83685584

[4]. suonikeyinsu. ppm\pgm格式. https://www.cnblogs.com/black-mamba/p/6755295.html


0x05 Feedback

大家在按照教程操作过程中有任何问题,可以直接在文章末尾给我留言,或者关注ROS小课堂的官方微信公众号,在公众号中给我发消息反馈问题也行。我基本上每天都会处理公众号中的留言!当然如果你要是顺便给ROS小课堂打个赏,我也会感激不尽的,打赏30块还会被邀请进ROS小课堂的微信群,与更多志同道合的小伙伴一起学习和交流!

评论:

7条评论

83.33%好评

  • 1 星级:(0%)
  • 2 星级:(0%)
  • 3 星级:(0%)
  • 4 星级:(0%)
  • 5 星级:(100%)
  1. 海上一寸
    海上一寸 发表于: 

    请问多机器人相互之间躲避如何设置?我的仿真机器人相遇时会直接穿过去

    • admin
      admin 发表于: 

      现在只能通过机器人之间的tf坐标转换来获取到各自定位信息,然后再结合机器人的直径信息来增加costmap信息避障了,把除自己外的其他机器人都作为障碍物

      • Lei
        Lei 发表于: 

        怎么添加信息到COSTmap中?我也急需这个

  2. 安和桥
    安和桥 发表于: 

    想向您请教一个问题,在没有改变源码的基础上按照上述步骤执行home_map_nav.launch,可以通过键盘控制机器人移动,但是当使用2D Nav Goal发布目标位姿信息时总是提示fail to get robot angle to map,导致自主导航失败,请问如何解决?

    • admin
      admin 发表于: 

      感觉像是amcl定位有问题,你可以使用Rviz中的“2D Pose Estimate”来把机器人位置重新定位校准一下,看看这样行不行

      • 安和桥
        安和桥 发表于: 

        还是不行,只要是运行关于导航的launch文件都会报这种错,地图上有规划出的全局路径,但是机器人不会移动。

        • admin
          admin 发表于: 

          你执行下scrips目录下的setup_env.sh脚本试试,有可能你少安装ros软件包,执行这个脚本会自动安装必要的软件包,配置好环境

发表评论