# 6.地图保存与编辑 ## 一、 安装NAV2_MAP_SERVER ```perl sudo apt install ros-$ROS_DISTRO-nav2-map-server ``` ## 二、 保存地图 ```bash ros2 run nav2_map_server map_saver_cli --help ``` 可以看到有下面的用法 ```shell Usage: map_saver_cli [arguments] [--ros-args ROS remapping args] Arguments: -h/--help -t -f --occ --free --fmt --mode trinary(default)/scale/raw NOTE: --ros-args should be passed at the end of command line ``` 我们的地图话题为map,文件名字我们用fishbot_map,所以有下面这个这样写的命令行。 ```shell ros2 run nav2_map_server map_saver_cli -t map -f fishbot_map ``` 接着我们就可以得到下面的两个文件 ```shell . ├── fishbot_map.pgm └── fishbot_map.yaml 0 directories, 2 files ``` 这两个文件就是对当前地图保存下来的文件,其中.pgm是地图的数据文件,.yaml后缀的是地图的描述文件。 ## 三、 地图数据文件.pgm介绍 OccupancyGrid由一个`.yaml格式`的元数据文件,和.pgm图片格式的地图数据文件组成。从上节课建图后保存的文件也可以看出。 ``` . ├── fishbot_map.pgm └── fishbot_map.yaml 0 directories, 2 files ``` ![image-20220514115948139](6.%E5%9C%B0%E5%9B%BE%E4%BF%9D%E5%AD%98%E4%B8%8E%E7%BC%96%E8%BE%91/imgs/image-20220514115948139.png) 打开上节课建好的地图,观察下,你应该会有几点疑问: 1. 不是说占据栅格地图每个栅格都有一个概率吗?为什么看不出来? 2. 立方体内和圆柱体内和墙之外的区域为什么是灰色的? 原因如下: 1. 一个栅格对应到图片上其实是一个像素,每一个像素的值在0-255之间,所以将像素值和占据率之间的映射即可,而像素值反应到图像上就是颜色的深浅,1.2图对应的像素颜色如下: ![image-20220506141320374](6.%E5%9C%B0%E5%9B%BE%E4%BF%9D%E5%AD%98%E4%B8%8E%E7%BC%96%E8%BE%91/imgs/image-20220506141320374.png) 2. 建图的时候物体内和墙之外的区域机器人并没有探索到,没有数据参考就认为其值是未知的。 ## 四、地图描述文件.yaml介绍 除了`fishbot_map.pgm`文件外,还有另外一个`fishbot_map.yaml`的文件,`fishbot_map.yaml`文件是地图的配置文件,该文件内容如下: ```yaml image: fishbot_map.pgm mode: trinary resolution: 0.05 origin: [-3.37, -2.88, 0] negate: 0 occupied_thresh: 0.65 free_thresh: 0.25 ``` - image:图像名称 - mode:图像模式,默认为trinary(三进制),还有另外两个可选项scale(缩放的)和raw(原本的值)。 - resolution:分辨率,一个栅格对应的物理尺寸,单位为m。0.05则表示一个栅格为0.05m - origin:地图原点位置,单位是m。 - negate:是否反转图像 - cooupied_thresh:占据阈值 - free_thresh:空闲阈值 #### 如何在地图上找出机器人原点的像素位置? 1. 图像的像素原点在左下角 2. 借张图左边的0,0是地图原点,右边的图是图像的像素原点 ![img](6.%E5%9C%B0%E5%9B%BE%E4%BF%9D%E5%AD%98%E4%B8%8E%E7%BC%96%E8%BE%91/imgs/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3o4MjQwNzQ5ODl5,size_16,color_FFFFFF,t_70.png) 3. 假如机器人地图原点是[-3.37m, -2.88m],除上分辨率则可得到像素原点[-67.4px,-57.6px]。`地图原点`在x和y轴分别偏移[-67.4px,-57.6px]就到了像素原点,反过来说,地图原点就在像素原点的[67.4px,57.6px]处。 ## 五、编辑地图 最后我们来说一下如何对地图进行编辑,地图编辑的方法有很多,你可以手动改图片,也可以通过opencv等图像处理库进行图像的去除噪点等操作。 这里小鱼介绍的是手动添加一个地图用PS进行编辑 。 打开网址:https://www.gaituya.com/ps/ 接着点击文件打开选择我们的.pgm文件,即可看到下图。 ![image-20220514221803090](6.%E5%9C%B0%E5%9B%BE%E4%BF%9D%E5%AD%98%E4%B8%8E%E7%BC%96%E8%BE%91/imgs/image-20220514221803090.png) 接着小鱼将下面的正方形给补上。 ![edit_map](6.%E5%9C%B0%E5%9B%BE%E4%BF%9D%E5%AD%98%E4%B8%8E%E7%BC%96%E8%BE%91/imgs/edit_map.gif) 保存后在文件选择导出为`png`格式即可,因为PS并不支持`pgm`格式的导出,所以我们选择`png`格式,幸运的是`png`格式的地图也是被map_server所支持的。 把导出的图片放到map文件夹下,接着我们需要修改下yaml配置文件中图片的后缀。 ``` image: fishbot_map.png mode: trinary resolution: 0.05 origin: [-3.37, -2.88, 0] negate: 0 occupied_thresh: 0.65 free_thresh: 0.25 ``` ## 六、总结 到这里我们总算把地图搞定了,接下来我们一起搞定导航。