栅格地图、障碍物地图与膨胀地图(栅格地图)

本文详细解释了ROS中栅格地图在2D激光SLAM中的作用,介绍了nav_msgs/OccupancyGrid消息格式,展示了如何创建和发布简单地图,以及move_base中对栅格地图的处理,特别是StaticLayer的代价地图转换机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在ROS中,地图是非常基本的元素,特别对于2D激光SLAM而言,栅格地图可以说是必不可少的元素。机器人在需要前往目标点时,需要在栅格地图中找到一条合适的路径从当前点到达目标点,这部分内容在move_base中有了详细的接口,可以直接调用并返回路径。但是作为一名工程师,不仅要知其然更要知其所以然,正好最近重新看了下这部分的内容,在此简单对地图这块的处理简单作个笔记,以备后续翻阅。
熟悉move_base的开发者会知道,在ROS中,地图大致可以分为三张:栅格地图、障碍物地图与膨胀地图。当然也可以按照局部地图与全局地图划分,但是那个不是本篇的重点,暂时先不考虑那种划分方式。栅格地图与后续两张地图可以说是存在密不可分的关系。首先,栅格地图是作为障碍物地图的基础而存在的,没有栅格地图,亦没有障碍物地图。同时,栅格地图也是膨胀地图的必须元素,深入了解过三张地图之间相互关系的开发者会知道,在move_base中,膨胀地图这个插件(inflaction_layer)本身是不维护地图的实体的,它对于地图的膨胀是在栅格地图(静态地图)的图层进行操作的。所以有必要先了解清楚栅格地图的基础内容,这也可以为我们后续学习另外两种地图打下比较好的基础。

1、地图的消息格式

在ROS中已经定义了官方的地图格式:

nav_msgs/OccupancyGrid

我们可以通过下述指令展开看看这个消息的具体包含:

rosmsg show nav_msgs/OccupancyGrid

得到的结果如下

std_msgs/Header header
  uint32 seq
  time stamp
  string frame_id
nav_msgs/MapMetaData info
  time map_load_time
  float32 resolution
  uint32 width
  uint32 height
  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

以上,就是一张地图消息格式的基本组成。我们从上往下看,首先是header部分,这里跟很多消息类型中的header是一样的,包含了一张地图的时间戳以及一个frame_id,对于地图这个东西而言,似乎时间戳并不是很重要。而frame_id则是一般会固定使用“map"。
其次,则是一个nav_msgs/MapMetaData实体info,其中的内容包含了较多信息。首先map_load_time,似乎也没什么用,所有地图设置的都是0。而resolution,则是地图中非常重要的一个参数,它直接关系到了地图的清晰度。一般而言,我们建图时使用的栅格大小就是这里的resolution,使用0.05代表一个栅格是5cm,而使用0.025则代表一个栅格是2.5cm。接下来的参数则是width与height,这两个参数与resolution共同构成了一张地图的实际长宽,例如:

resolution: 0.025
width: 2048
height: 2208

代表了地图的宽度为(0.025 * 2048=51.2)米,高度为(0.025 * 2208=55.2)米。最后面是一个geometry_msgs/Pose的实体,这个参数代表的则是这张地图上的一个坐标,开始时,我曾经一度以为这个坐标是指地图中心点的坐标轴,但是实际上并不是,它代表的是地图最左下角的点在地图上的坐标,这个问题我们可以通过一张实际的地图观察一下,首先我们拿到一张实际的地图的info信息:

map_load_time: 0.000000000
resolution: 0.025
width: 2048
height: 2208
origin: 
  position: 
    x: -20
    y: -35.2
    z: 0
  orientation: 
    x: 0
    y: 0
    z: 0
    w: 1

可以看到它的position为(-20,-35.2),然后我们在RVIZ中加载这张地图,并切换到地图坐标系下,可以看到地图大致显示如下:
在这里插入图片描述
这是一张51.2 * 55.2的地图,左上角处的栅格中心为(0,0)原点,大致就可以看出info参数中的position实际对应的就是地图的左下角部分。关于这个问题我们也可以后面通过一些简单的操作验证一下,先将数据结构看完。
剩下最后一个数据结构就是int8[] data这个字段,这个位置实际上存储的就是真正的地图实际数据,每一个栅格具体的值就是通过这里得到的,它的大小为info.width*info.height,同时,它的值只包含了三种数据:-1代表未知,也就是上图中灰色部分;0代表空闲,也就是图上的白色部分;100(注意是100不是1)代表障碍物,图上黑色部分。取一段实际地图数据,例如:

-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 0 0 0 -1 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶执念

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值