ros导航框架-代价地图

2024-04-29 21:12
文章标签 框架 地图 ros 导航 代价

本文主要是介绍ros导航框架-代价地图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、Costmap2DROS

Costmap2DROS是代价地图与其他ROS模块的接口类,move_base中使用的代价地图就是Costmap2DROS对象。
Costmap2DROS负责对代价地图进行更新,以及发布代价地图,我们在rviz上看到的代价地图就是在这个类中进行发布的。
Costmap2DROS中最重要的一个成员就是layered_costmap_。

protected:LayeredCostmap* layered_costmap_;

LayeredCostmap类的作用是对各层代价地图进行管理以及数据整合。
LayeredCostmap类有两个重要的成员:

std::vector<boost::shared_ptr<Layer> > plugins_;// 各层地图插件
Costmap2D costmap_;     // master layer   各层插件地图合并后的代价地图

Costmap2D类
重要成员:
unsigned char* costmap_ : costmap的每一个栅格的代价值。
主要功能:提供对代价地图的操作接口-读取信息,修改数据。

在Costmap2DROS的构造函数中,可以看到,

  publisher_ = new Costmap2DPublisher(&private_nh, layered_costmap_->getCostmap(), global_frame_, "costmap",always_send_full_costmap);

1.1 代价地图的更新

代价地图的更新调用链:
Costmap2DROS::mapUpdateLoop(double frequency)->Costmap2DROS::updateMap()->void LayeredCostmap::updateMap(double robot_x, double robot_y, double robot_yaw)
可见最终进入到LayeredCostmap类中的updateMap函数。
void LayeredCostmap::updateMap(double robot_x, double robot_y, double robot_yaw)
1、根据机器人的位置对costmap_进行移动
2、遍历所有的插件地图 调用 updateBounds()
3、遍历所有的插件地图 调用 updateCosts()
将各层代价地图的代价值整合到costmap_上,costmap_就是master layer.

2、 obstacle_layer

障碍物层对应的类是ObstacleLayer,CostmapLayer的子类,通过读取各个传感器的观测数据进行更新,所使用的传感器可以在yaml参数文件中自行设置。
地图数据保存在哪? ObstacleLayer继承了CostmapLayer的父类,而CostmapLayer类又继承Layer类和Costmap2D类,因此ObstacleLayer的地图数据保存在继承于Costmap2D类的costmap_。
构造函数
对所使用传感器进行遍历,并一一构造ObservationBuffer放入observation_buffers_,

std::vector<boost::shared_ptr<costmap_2d::ObservationBuffer> > observation_buffers_;     // 保存所使用的传感器的观测buffer

costmap_2d::ObservationBuffer类中有一个重要成员-observation_list_,它会按照时序保存历史的观测数据,

std::list<Observation> observation_list_;

那么也有个函数void purgeStaleObservations() 负责对旧数据进行清理,成员变量observation_keep_time_用来决定数据保留的时间,早于这个时间的数据被丢弃。observation_keep_time_这个变量可以在我们的yaml参数文件中进行配置,一般设为0。

接着将该传感器的观测buffer,设置到marking_buffers_(用于在障碍物层地图山标记障碍),以及设置到clearing_buffers_(用于清除障碍物标记)。比如,我们一共使用激光雷达和超声波传感器来更新障碍物层,那么marking_buffers_和clearing_buffers_中就会有激光雷达和超声波这两个传感器的观测buffer。

   // marking_buffers_ 保存了每个传感器的ObservationBufferif (marking)marking_buffers_.push_back(observation_buffers_.back());   // check if we'll also add this buffer to our clearing observation buffers// clearing_buffers_ 保存了每个传感器的ObservationBufferif (clearing)clearing_buffers_.push_back(observation_buffers_.back());

最后就是设置读取相应传感器的回调函数。

2.x updateBounds

1、跟随机器人的位置移动地图。
2、根据观测数据更新自由空间

  // raytrace freespacefor (unsigned int i = 0; i < clearing_observations.size(); ++i){raytraceFreespace(clearing_observations[i], min_x, min_y, max_x, max_y);}

3、根据观测到的障碍信息,对costmap_进行更新。

2.x updateCosts

void ObstacleLayer::updateCosts(costmap_2d::Costmap2D& master_grid, int min_i, int min_j, int max_i, int max_j)

将当前层的代价数据更新到master_grid。从前面可以知道,这里传入到master_grid的是LayeredCostmap类的costmap_,也就是将该障碍物层的代价数据更新到LayeredCostmap类的costmap_上。
更新可采用两种方式-updateWithOverwrite和updateWithMax

void CostmapLayer::updateWithOverwrite(costmap_2d::Costmap2D& master_grid, int min_i, int min_j, int max_i, int max_j)
用当前层的代价数据直接覆盖master_grid的数据。

void CostmapLayer::updateWithAddition(costmap_2d::Costmap2D& master_grid, int min_i, int min_j, int max_i, int max_j)
叠加模式。

3、static_layer

静态层对应的类是StaticLayer, 同样是CostmapLayer的子类,因此,代价地图数据保存在继承于Costmap2D类的costmap_。

3.1 数据订阅

在构造函数中可见,map_sub_ = g_nh.subscribe(map_topic, 1, &StaticLayer::incomingMap, this);
订阅的话题是map_topic,数据类型StaticLayer::incomingMap, 回调函数StaticLayer::incomingMap,在回调函数中,将新接收到的静态栅格地图赋值给costmap_。

3.2 updateBounds

这里就是更新了一下地图的边界信息。

3.3 updateCosts

将当前层的代价地图数据costmap_更新到master layer上。

4、inflation_layer

膨胀层InflationLayer不订阅任何数据,要膨胀的地图通过引用传递给updateCosts的master_grid形参即可,

void InflationLayer::updateCosts(costmap_2d::Costmap2D& master_grid, int min_i, int min_j, int max_i, int max_j)

在LayeredCostmap::updateMap中,会将costmap_传入InflationLayer::updateCosts,而costmap_为之前各层插件地图的叠加。

这篇关于ros导航框架-代价地图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/947172

相关文章

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python GUI框架中的PyQt详解

《PythonGUI框架中的PyQt详解》PyQt是Python语言中最强大且广泛应用的GUI框架之一,基于Qt库的Python绑定实现,本文将深入解析PyQt的核心模块,并通过代码示例展示其应用场... 目录一、PyQt核心模块概览二、核心模块详解与示例1. QtCore - 核心基础模块2. QtWid

最新Spring Security实战教程之Spring Security安全框架指南

《最新SpringSecurity实战教程之SpringSecurity安全框架指南》SpringSecurity是Spring生态系统中的核心组件,提供认证、授权和防护机制,以保护应用免受各种安... 目录前言什么是Spring Security?同类框架对比Spring Security典型应用场景传统

使用Folium在Python中进行地图可视化的操作指南

《使用Folium在Python中进行地图可视化的操作指南》在数据分析和可视化领域,地图可视化是一项非常重要的技能,它能够帮助我们更直观地理解和展示地理空间数据,Folium是一个基于Python的地... 目录引言一、Folium简介与安装1. Folium简介2. 安装Folium二、基础使用1. 创建

Python结合Flask框架构建一个简易的远程控制系统

《Python结合Flask框架构建一个简易的远程控制系统》这篇文章主要为大家详细介绍了如何使用Python与Flask框架构建一个简易的远程控制系统,能够远程执行操作命令(如关机、重启、锁屏等),还... 目录1.概述2.功能使用系统命令执行实时屏幕监控3. BUG修复过程1. Authorization

SpringBoot集成图片验证码框架easy-captcha的详细过程

《SpringBoot集成图片验证码框架easy-captcha的详细过程》本文介绍了如何将Easy-Captcha框架集成到SpringBoot项目中,实现图片验证码功能,Easy-Captcha是... 目录SpringBoot集成图片验证码框架easy-captcha一、引言二、依赖三、代码1. Ea

Gin框架中的GET和POST表单处理的实现

《Gin框架中的GET和POST表单处理的实现》Gin框架提供了简单而强大的机制来处理GET和POST表单提交的数据,通过c.Query、c.PostForm、c.Bind和c.Request.For... 目录一、GET表单处理二、POST表单处理1. 使用c.PostForm获取表单字段:2. 绑定到结

修改若依框架Token的过期时间问题

《修改若依框架Token的过期时间问题》本文介绍了如何修改若依框架中Token的过期时间,通过修改`application.yml`文件中的配置来实现,默认单位为分钟,希望此经验对大家有所帮助,也欢迎... 目录修改若依框架Token的过期时间修改Token的过期时间关闭Token的过期时js间总结修改若依

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核