多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# 9.1 地图 ## 9.1.1 直观印象 ROS中的地图很好理解,就是一张普通的灰度图像,通常为pgm格式。这张图像上的黑色像素表示障碍物,白色像素表示可行区域,灰色是未探索的区域。如下图所示, ![](https://img.kancloud.cn/91/a3/91a326bcac4b215ec8bce4f381090d49_390x389.png) 在SLAM建图的过程中,你可以在RViz里看到一张地图被逐渐建立起来的过程,类似于一块块拼图被拼接成一张完整的地图。这张地图对于我们定位、路径规划都是不可缺少的信息。事实上,地图在ROS中是以Topic的形式维护和呈现的,这个Topic名称就叫做`/map`,它的消息类型是`nav_msgs/OccupancyGrid`。 ## 9.1.2 锁存 由于`/map`中实际上存储的是一张图片,为了减少不必要的开销,这个Topic往往采用锁存(latched)的方式来发布。什么是锁存?其实就是:地图如果没有更新,就维持着上次发布的内容不变,此时如果有新的订阅者订阅消息,这时只会收到一个`/map`的消息,也就是上次发布的消息;只有地图更新了(比如SLAM又建出来新的地图),这时`/map`才会发布新的内容。 锁存器的作用就是,将发布者最后一次发布的消息保存下来,然后把它自动发送给后来的订阅者。这种方式非常适合变动较慢、相对固定的数据(例如地图),然后只发布一次,相比于同样的消息不定的发布,锁存的方式既可以减少通信中对带宽的占用,也可以减少消息资源维护的开销。 ## 9.1.3 nav_msgs/OccupancyGrid 然后我们来看一下地图的OccupancyGrid类型是如何定义的,你可以通过`rosmsg show nav_msgs/OccupancyGrid`来查看消息,或者直接`rosed nav_msgs OccupancyGrid.msg`来查看srv文件。 ``` std_msgs/Header header #消息的报头 uint32 seq time stamp string frame_id #地图消息绑定在TF的哪个frame上,一般为map nav_msgs/MapMetaData info #地图相关信息 time map_load_time #加载时间 float32 resolution #分辨率 单位:m/pixel uint32 width #宽 单位:pixel uint32 height #高 单位:pixel geometry_msgs/Pose origin #原点 geometry_msgs/Point position float64 x float64 y float64 z geometry_msgs/Quaternion orientation float64 x float64 y float64 z float64 w int8[] data #地图具体信息 ``` 这个srv文件定义了/map话题的数据结构,包含了三个主要的部分:header, info和data。header是消息的报头,保存了序号、时间戳、frame等通用信息,info是地图的配置信息,它反映了地图的属性,data是真正存储这张地图数据的部分,它是一个可变长数组,`int8`后面加了`[]`,你可以理解为一个类似于vector的容器,它存储的内容有width*height个int8型的数据,也就是这张地图上每个像素。