0x00 概述
在前面的文章中,我们介绍如何自动导航时,都是基于使用gmapping或者hector_mapping创建的地图。当然使用其他的建图方法创建的地图也可以,但是目前为止,无论使用哪种建图方法。通过激光雷达或深度摄像头建立的地图仍然是存在误差的。下面我们可以来回顾一下看看使用gmapping建立的地图,如下图所示,可以看到右侧的地图就是扫描建立的地图,与左侧的地图基本上相同。现在可以思考一下,我们有没有可能不用激光雷达来扫描建图(这个slam过程真的是挺麻烦的),因为现在基本上在设计施工时都是有设计图纸的,如果我们将这些设计图纸拿来,修改一下直接就当作导航地图来用。这样不是就省去建地图的步骤了嘛,而且地图的与实际环境100%匹配(除非施工建造时没有按照图纸来做):
0x01 创建自定义地图
在前面一篇文章10.在STDR中加载其他地图中,介绍了如何在stdr中加载自定义的地图。这张地图是从网上下载的一个两居室户型图,后来经过简单修改我们就可以在stdr中加载了。现在我们可以更进一步,可以将这张地图使用map_server加载。这样我们就可以把地图在rviz中直接加载,就可以在这张地图上进行自动导航了。下面先来看看我们上次创建的这个户型图,如下图所示:
现在我们已经可以在stdr中加载这张地图了,现在我们要将这张地图使用map_server加载。那具体如何操作呢?我们可以先来看看使用gmapping建好的地图是使用什么格式来存储的。我们可以按照它的格式来修改一下这张地图不就可以了嘛,说干咱就开始动手操作:
(1)查看gmapping创建的地图
可以看出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,如下图所示:
可以看出这里使用的是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
安装好该软件后,就可以来打开了,下图就是这个软件的界面:
(3)使用软件转换图片格式
使用KolourPaint软件打开png格式或jpg格式的地图软件,如下图所示:
然后使用图片另存为pgm格式,如下图所示:
最后来查看下该图片格式是否为P5:
(4)创建对应的yaml配置文件
这个yaml配置文件编写比较简单,我们按照gmapping中地图的yaml格式来修改就可以了。下面来看看自定义地图的yaml内容:
这里来简单介绍下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小课堂的微信群,与更多志同道合的小伙伴一起学习和交流!