ROS导航包之costmap_2d

本文详细介绍了ROS中Costmap2D的相关类及其功能,包括Costmap2DROS、LayeredCostmap、Costmap2D等核心类的作用及关键函数接口。同时探讨了StaticLayer、ObstacleLayer和InflationLayer等插件类的工作原理与配置技巧。

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


Costmap2DROS类

主要作用是完成对Costmap2D类的ROS接口包装,提供包括机器人在地图中的位置查询,机器人脚印(footprint)在地图中的位置查询; 地图的更新和停止接口; 提供Costmap2D的访问接口,通过它可以方便地访问地图数据信息。
关键函数接口:
Costmap2DROS(std::string name, tf::TransformListener& tf);
bool getRobotPose(tf::Stamped<tf::Pose>& global_pose) const;
Costmap2D* getCostmap()
std::vector<geometry_msgs::Point> getRobotFootprint()

LayeredCostmap类

该类是图层的管理类,负责管理图层插件的更新和并将信息汇总到根图层costmap上, 提供给Costmap2DROS的调用接口。

Costmap2D类

该类是删格地图的数据结构类,主要提供根据坐标或者索引设置和查询地图的值的方法。

Layer类

这是一个虚基类, 定义各种图层的公用接口。 
虚函数接口包括:
  virtual void onInitialize();
  virtual void activate();
  virtual void deactivate();
  virtual void reset();
  virtual void updateBounds(double robot_x, double robot_y, double robot_yaw, double* min_x, double* min_y,double* max_x, double* max_y);     
  virtual void updateCosts(costmap_2d::Costmap2D& master_grid, int min_i, int min_j, int max_i, int max_j);
  virtual void matchSize();

CostmapLayer类

顾名思义了,就是Layer和Costmap2D的结合类。 两个类功能的组合体。

插件类StaticLayer

继承自CostmapLayer类,实现了Layer类定义的虚函数。
其初始化函数中订阅了map消息,所以必须要有mapserver提供map给它才行,nh.param("map_topic", map_topic, std::string("map"));
nh.param("track_unknown_space", track_unknown_space_, true);
这个参数也尤其重要,它的意思是是否要将unknow认为是free的,若设置为false,那么所有的未知区域都将被认为是free的,这就是为什么有时候全局规划路径会穿过灰色的未知区域的原因,就是因为只是设置了nav_fn中的allow_unknown参数为false是不够的,还需要将这个地方设置成true。

关于该层数据的更新,如果不是滑动窗口类型,那么坐标框架就是和mapserver提供的map主题是一样的,只需要将订阅的数据copy过来更新自己的Costmap2D的数据成员就可以了, 如果是滑动窗口那么注意作者的注解如下:// If rolling window, the master_grid is unlikely to have same coordinates as this layer, Copy map data given proper transformations。 证明即使是滑动窗口也是会利用全局图map提供的数据的。

插件类ObstacleLayer

继承自CostmapLayer类,实现了Layer类定义的虚函数。
此外,还实现了对于传感器数据的监听与回调处理函数,支持类型包括sensor_msgs::LaserScan, sensor_msgs::PointCloud, sensor_msgs::PointCloud2三类,将它们压入observation_buffer中。
一个问题尚未弄清楚,为毛当局部动态图的frame设置成/map之后,就无法显示障碍物了。貌似必须是/odom才行,暂时没搞懂。验证后好像不是这样的QAQ

插件类InflationLayer

继承自Layer类,实现了其定义的虚函数接口。
总的来说,该类干了这样一件事情,读取父层LayeredCostmap上costmap的障碍物信息,并对范围内的每一个点更新其cost值,依据的是点离其最近障碍物点的距离来指定损失值。损失值确定方式如下:
   1. 若距离为0,则COST为LETHAL_OBSTACLE(254)
   2. 若距离小于机器人内半径,则COST为INSCRIBED_INFLATED_OBSTACLE(253)
   3. 若距离比内半径远, 则按照距离越远COST越低取值
   4. 距离障碍物越远应该cost越低,所以factor应该根据距离递减,weight_由外部的cost_scaling_factor决定,默认为10,所以要是想要离inflation近的损失更大,应该减小cost_scaling_factor的值252/(e^(dist*weight))。
inline unsigned char computeCost(double distance) const
  {
    unsigned char cost = 0;
    if (distance == 0)
      cost = LETHAL_OBSTACLE;
    else if (distance * resolution_ <= inscribed_radius_)
      cost = INSCRIBED_INFLATED_OBSTACLE;
    else
    {
      double euclidean_distance = distance * resolution_;
      double factor = exp(-1.0 * weight_ * (euclidean_distance - inscribed_radius_));
      cost = (unsigned char)((INSCRIBED_INFLATED_OBSTACLE - 1) * factor);
    }
    return cost;
  }

    参数配置说明:
    1.ObstacleLayer和VoxelLayer在进行障碍物更新时会根据最小障碍物高度和最大障碍物高度,最小障碍物距离进行过滤,所以一定要确保自己想要让图层关注到的传感器信息在合理的范围内,也就是特别要注意雷达数据的z值不能想当然的设置为0,因为默认空间是(0,0.8)的开区间。在这上面吃过大亏。
    2.配置时要留心命名空间的问题,有时为了保证参数在正确的命名空间下,可以使用rosparam get ...来查看设置的参数是否起了作用。
    3.调试时,可以进行动态参数调整,避免反复修改文件,效率低下,命令为:`rosrun rqt_gui rqt_gui -s reconfigure`
    4.在确定pdist,gdist,occdist的相对大小关系时,在base_local_planner的设置中将publish_cost_grid设置为true,这样在rviz当中就可以查看相应的热力图来确定是否正确了。
    5.base_local_planner中速度限制不要设置太小,尤其是角速度和角加速度,否则有时候转弯很可能没法及时转过来而撞上障碍物。
    6.局部地图的窗口应该视环境复杂度而定,如果太大,有时候在转弯时,很可能以gdist目标为优先而撞上障碍物一般由小往大调,控制在1-3之内,调节时配合4中所述方法重点观察转弯时的轨迹。
<think>好的,用户想了解costmap_2d中static_layer、obstacle_layer和inflation_layer的类型及配置方法。首先,我需要回忆一下这些层的作用和配置方式。根据之前的引用,比如引用[1]和引用[2]提到插件配置示例,用户可能需要具体的参数设置方法。另外,引用[3]提到costmap在路径规划中的应用,所以可能需要解释各层如何影响路径规划。首先,static_layer通常用于加载静态地图,比如预先构建好的栅格地图。需要说明它的类型是"costmap_2d::StaticLayer",并且配置参数如map_topic是否指向正确的主题,比如/map。可能还需要提到它是否可滚动,一般静态层是不可滚动的,所以track_unknown_space参数可能设为true。接下来是obstacle_layer,类型是"costmap_2d::ObstacleLayer",负责实时障碍物检测。这里需要区分全局和局部costmap的不同配置,比如全局的可能使用激光雷达,而局部的可能用传感器数据。需要提到参数如observation_sources,以及如何配置传感器话题,比如激光雷达的topic:/scan。然后是inflation_layer,类型是"costmap_2d::InflationLayer",用于膨胀障碍物,生成代价值递减的区域。需要解释cost_scaling_factor和inflation_radius的作用,不同的值如何影响路径规划,比如较大的半径会让路径更远离障碍物。配置方法方面,用户可能需要在YAML文件中添加插件列表,如引用[1]中的示例,plugins的顺序可能影响层的叠加顺序。同时,要提到参数继承,比如global_costmap_params.yaml和local_costmap_params.yaml中的配置,如引用[2]所示。还需要注意不同层之间的依赖关系,比如inflation_layer通常放在最后,因为它依赖于前面层提供的障碍物信息。可能还要提到常见问题,比如层顺序错误导致的地图显示问题,或者参数设置不当导致的膨胀效果不佳。最后,生成相关问题需要考虑用户可能的后续疑问,比如如何添加自定义层、参数调优的方法,或者如何处理层之间的冲突。确保问题覆盖配置、优化和实际应用场景,帮助用户深入理解。</think>在`costmap_2d`中,`static_layer`、`obstacle_layer`和`inflation_layer`是三种核心插件类型,分别用于处理静态地图、动态障碍物和代价值膨胀。以下是具体类型说明及配置方法: --- ### 1. **static_layer(静态地图层)** - **类型**:`costmap_2d::StaticLayer` - **功能**:加载预先生成的静态栅格地图(如SLAM生成的全局地图),作为导航的基础参考。 - **关键参数**: ```yaml map_topic: /map # 静态地图的话题名称 track_unknown_space: true # 是否标记未知区域 use_maximum: false # 是否与其他层取最大值(通常设为false以保留静态地图原始数据) ``` - **用法示例**: ```yaml plugins: - {name: static_layer, type: "costmap_2d::StaticLayer"} ``` 引用示例:全局代价地图通常优先加载静态层以确保基础环境信息准确[^1]。 --- ### 2. **obstacle_layer(障碍物层)** - **类型**:`costmap_2d::ObstacleLayer` - **功能**:实时检测传感器(如激光雷达、深度相机)输入的动态障碍物,并更新到代价地图中。 - **关键参数**: ```yaml observation_sources: scan # 传感器数据源名称 scan: {sensor_frame: base_link, topic: /scan, data_type: LaserScan} # 传感器配置 max_obstacle_height: 2.0 # 障碍物最大高度 combination_method: 1 # 代价值融合方式(1表示取最大值) ``` - **用法示例**: ```yaml plugins: - {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"} ``` 引用示例:局部代价地图依赖障碍物层实现动态避障[^3]。 --- ### 3. **inflation_layer(膨胀层)** - **类型**:`costmap_2d::InflationLayer` - **功能**:对障碍物代价值进行膨胀处理,生成梯度递减的代价值区域,确保路径与障碍物保持安全距离。 - **关键参数**: ```yaml cost_scaling_factor: 10.0 # 代价值衰减速率 inflation_radius: 0.5 # 膨胀半径(需大于机器人半径) ``` - **用法示例**: ```yaml plugins: - {name: inflation_layer, type: "costmap_2d::InflationLayer"} ``` 引用示例:膨胀层通过梯度代价值影响路径规划算法(如A*或DWA)的决策[^3]。 --- ### **配置注意事项** 1. **插件顺序**:层加载顺序影响代价值融合逻辑。通常按`static_layer → obstacle_layer → inflation_layer`排列[^1]。 2. **参数继承**:全局(`global_costmap`)和局部(`local_costmap`)的配置需分开定义,例如: ```yaml # global_costmap_params.yaml plugins: - {name: static_layer, type: "costmap_2d::StaticLayer"} - {name: inflation_layer, type: "costmap_2d::InflationLayer"} # local_costmap_params.yaml plugins: - {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"} - {name: inflation_layer, type: "costmap_2d::InflationLayer"} ``` 3. **动态调参**:可通过ROS 2动态参数调整`inflation_radius`或`cost_scaling_factor`以优化路径安全性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值