9.1 地图
9.1.1 直观印象
ROS中的地图很好理解,就是一张普通的灰度图像,通常为pgm格式。这张图像上的黑色像素表示障碍物,白色像素表示可行区域,灰色是未探索的区域。如下图所示,
在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型的数据,也就是这张地图上每个像素。