ROS2从入门到精通5-1:详解代价地图与costmap插件编写(以距离场ESDF为例)

目录

  • 0 专栏介绍
  • 1 代价地图介绍
    • 1.1 基本概念
    • 1.2 代价定义
  • 2 代价地图配置
    • 2.1 通用配置
    • 2.2 障碍层配置
    • 2.3 静态层配置
    • 2.4 膨胀层配置
  • 3 代价地图插件案例
    • 3.1 构造地图插件类
    • 3.2 注册并导出插件
    • 3.3 编译与使用插件

0 专栏介绍

本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。

🚀详情:《ROS2从入门到精通》


1 代价地图介绍

1.1 基本概念

机器人导航必须依赖于地图,而SLAM构建的地图为静态地图,在导航中一般不可以直接使用,因为导航过程中障碍信息是可变的,因此地图信息需要时时更新。

在这里插入图片描述

代价地图就是ROS定义的用于动态导航的地图数据结构,其在静态地图基础上添加了一些辅助信息,主要分为以下图层:

  • 静态地图层(Static Map Layer):通常是由SLAM建立的静态地图
  • 障碍地图层(Obstacle Map Layer):用于动态记录传感器感知到的障碍信息
  • 膨胀层(Inflation Layer):在以上两层地图基础上进行障碍膨胀,主要目的是防止机器人靠近障碍物边缘时,因惯性、不规则形体等原因与障碍产生碰撞,因此需要让机器人充分远离障碍物
  • 其他图层(Other Layers):可以通过插件形式自定义代价地图层

1.2 代价定义

关于代价地图代价的定义,摘录官方说明:如图所示,横轴是距离机器人中心的距离,纵轴是代价地图中栅格的灰度值,灰度越高代价越大

  • 致命障碍:栅格值254,此时障碍物与机器人中心重叠,必然发生碰撞
  • 内切障碍:栅格值253,此时障碍物处于机器人的内切圆内,必然发生碰撞
  • 外切障碍:栅格值[128,252],此时障碍物处于其机器人的外切圆内,处于碰撞临界,不一定发生碰撞
  • 非自由空间:栅格值(0,127],此时机器人处于障碍物附近,属于危险警戒区,进入此区域,将来可能会发生碰撞
  • 自由区域:栅格值0,此处机器人可以自由通过
  • 未知区域:栅格值255,未探明是否有障碍物

在这里插入图片描述
看一个实例:其中紫色区域为致命障碍;浅蓝色区域为内切障碍;红色区域为外切障碍与非自由障碍空间,颜色越深代价越高;蓝色为自由空间。

在这里插入图片描述

2 代价地图配置

2.1 通用配置

通用配置如下所示:

ros__parameters:update_frequency: 1.0publish_frequency: 1.0global_frame: maprobot_base_frame: base_linkuse_sim_time: Truerobot_radius: 0.22resolution: 0.05track_unknown_space: trueplugins: ["static_layer", "obstacle_layer", "inflation_layer"]
  • global_frame:在全局/局部代价地图中的全局坐标系,一般全局设置为地图坐标系map,局部设置为里程计坐标系odom
  • robot_base_frame:机器人基坐标系通过global_framerobot_base_frame就可以计算两个坐标系间的变换,得知机器人在代价地图位置坐标
  • update_frequency:代价地图的更新频率
  • publish_frequency:代价地图的发布频率
  • robot_radius:机器人等效半径,单位是米

2.2 障碍层配置

obstacle_layer:plugin: "nav2_costmap_2d::ObstacleLayer"observation_sources: scanscan:topic: /scanmax_obstacle_height: 2.0clearing: Truemarking: Truedata_type: "LaserScan"raytrace_max_range: 3.0raytrace_min_range: 0.0obstacle_max_range: 2.5obstacle_min_range: 0.0
  • observation_sources:设置导航中所使用的传感器,例如激光雷达、碰撞传感器、超声波传感器等。每个传感器需要进行配置:
    • sensor_frame:传感器坐标系名称
    • data_type:传感器数据类型
    • topic:传感器发布的话题名
    • marking:是否可使用该传感器来标记障碍物
    • clearing:是否可使用该传感器来清除障碍物标记
  • obstacle_range:设置机器人检测障碍物的最大范围,只有进入该范围内才把该障碍物当作影响路径规划和移动的障碍物

2.3 静态层配置

static_layer:plugin: "nav2_costmap_2d::StaticLayer"map_subscribe_transient_local: True

2.4 膨胀层配置

inflation_layer:plugin: "nav2_costmap_2d::InflationLayer"cost_scaling_factor: 3.0inflation_radius: 0.55
  • inflation_radius:膨胀半径,膨胀层会把障碍物代价膨胀直到该半径为止,一般将该值设置为机器人底盘的直径大小。如果机器人经常撞到障碍物就需要增大该值,若经常无法通过狭窄地方就减小该值,代价膨胀公式:

    exp(-1.0 * cost_scaling_factor * (distance_from_obstacle - inscribed_radius)) * (INSCRIBED_INFLATED_OBSTACLE - 1)

    其中,distance_from_obstacle - inscribed_radius是机器人到实际障碍物与内切圆半径之差(且该差值小于膨胀半径),INSCRIBED_INFLATED_OBSTACLE设定为254

  • cost_scaling_factor:膨胀过程代价比例系数,增大比例因子会降低代价

3 代价地图插件案例

然而,这些默认的图层可能并不能满足实际需要。举例而言,社交地图层(Social Costmap Layer)用于机器人在导航过程中考虑与人类之间的社交交互,这个层级允许机器人更加智能地导航,并遵循一些社交规则,以更好地与人类共享空间,避免产生不适或危险的行为;禁区地图层(Prohibition Costmap Layer)用于标记和表示机器人不能进入的区域。这个层级的作用是在机器人的导航过程中限制其进入特定的区域(例如高压区、悬崖边缘、深水区等),从而确保机器人在导航时遵守特定的规则和限制,防止可能的事故和损坏。

3.1 构造地图插件类

所有全局规划插件的基类是nav2_costmap_2d::Layer,该基类提供了7个纯虚方法来实现控制器插件,一个合法的控制插件必须覆盖这7个基本方法:

  • onInitialize()非必须覆盖:在插件初始化结束时调用。通常会在方法里声明ROS参数。任何需要初始化的操作都应该在该方法里完成。
  • updateBounds()必须覆盖:更新costmap层边界
  • updateCosts()必须覆盖:每次需要重新计算costmap时都会调用方法。它仅在其边界窗口内更新costmap层
  • matchSize()非必须覆盖:在每次更改地图大小时调用更新地图尺寸
  • onFootprintChanged()非必须覆盖:在每次更新机器人footprint位置时调用
  • reset()必须覆盖:重置costmap层
  • isClearable()必须覆盖:是否需要在该costmap层执行清除操作

按照上述标准,本文案例中ESDF地图插件的基本成员函数和变量如下所示

class DistanceLayer : public Layer
{
public:DistanceLayer() = default;virtual ~DistanceLayer() = default;void onInitialize() override;void updateBounds(double robot_x, double robot_y, double robot_yaw, double* min_x, double* min_y, double* max_x,double* max_y) override;void updateCosts(nav2_costmap_2d::Costmap2D& master_grid, int min_i, int min_j, int max_i, int max_j) override;void reset() override;bool isClearable() override;
};

3.2 注册并导出插件

在创建了自定义地图插件的前提下,需要导出该控制器插件以便地图服务器可以在运行时正确地加载。在ROS2中,插件的导出和加载由pluginlib处理。

  • 源文件配置导出宏

    #include "pluginlib/class_list_macros.hpp"
    PLUGINLIB_EXPORT_CLASS(nav2_costmap_2d::DistanceLayer, nav2_costmap_2d::Layer)
    
  • 配置插件描述文件xxx_costmap_plugin.xml,例如本案例为distance_layer_costmap_plugin.xml文件。此XML文件包含以下信息:

    • library path:插件库名称及其位置;
    • class name:地图算法类的名称;
    • class type:地图算法类的类型;
    • base class:地图层基类的名称,统一为nav2_costmap_2d::Layer
    • description:插件的描述。

    实例如下

    <library path="esdf_plugin"><class name="nav2_costmap_2d/DistanceLayer" type="nav2_costmap_2d::DistanceLayer" base_class_type="nav2_costmap_2d::Layer"><description>This is a nav2 distance layer plugin.</description></class>
    </library>
    
  • 配置CMakeLists.txt文件
    使用cmake函数pluginlib_export_plugin_description_file()来导出插件。这个函数会将插件描述文件安装到install/share目录中,并设置ament索引以使其可被发现,实例如下

    pluginlib_export_plugin_description_file(nav2_costmap_2d distance_layer_costmap_plugin.xml)
    
  • 配置package.xml描述文件,实例如下:

    <export><build_type>ament_cmake</build_type><nav2_core plugin="${prefix}/distance_layer_costmap_plugin.xml" />
    </export>
    

3.3 编译与使用插件

编译该插件软件包,接着通过配置文件使用插件。

参数的传递链如下:首先在simulation.launch.py中引用配置文件navigation.yaml

declare_params_file_cmd = DeclareLaunchArgument('params_file',default_value=os.path.join(simulation_dir, 'config', 'navigation.yaml'),description='Full path to the ROS2 parameters file to use for all launched nodes')

接着在navigation.yaml中修改插件配置,默认如下,是用的是静态层、障碍层和膨胀层插件:

plugins: ["static_layer", "obstacle_layer", "inflation_layer"]obstacle_layer:plugin: "nav2_costmap_2d::ObstacleLayer"...static_layer:plugin: "nav2_costmap_2d::StaticLayer"...inflation_layer:plugin: "nav2_costmap_2d::InflationLayer"...

将上述替换为自己的插件,本案例为:

plugins: ["static_layer", "obstacle_layer", "inflation_layer", "distance_layer"]distance_layer:plugin: "nav2_costmap_2d/DistanceLayer"...obstacle_layer:plugin: "nav2_costmap_2d::ObstacleLayer"...static_layer:plugin: "nav2_costmap_2d::StaticLayer"...inflation_layer:plugin: "nav2_costmap_2d::InflationLayer"...

接着运行即可看到距离层地图被发布

在这里插入图片描述

完整代码通过下方博主名片联系获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/377049.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GIT使用_提交IDEA代码到GIT分支上

以下是本人常用的GIT提交与上传代码&#xff0c;请选择适配自己的方式&#xff0c;仅供参考。 第一步&#xff0c;一般来说&#xff0c;我们从GIT上拉下来项目分支代码后&#xff0c;做些修改什么的&#xff0c;相关的代码都会变色。当然我们提交的部分就是我们修改的部分。有的…

算法思想总结:字符串

一、最长公共前缀 . - 力扣&#xff08;LeetCode&#xff09; 思路1&#xff1a;两两比较 时间复杂度mn 实现findcomon返回两两比较后的公共前缀 class Solution { public:string longestCommonPrefix(vector<string>& strs) {//两两比较 string retstrs[0];size…

Flutter实现局部刷新的几种方式

目录 前言 1.局部刷新的重要性 1.概念 2.重要性 2.局部刷新实现的几种方式 1.使用setState方法进行局部刷新 2.使用StatefulWidget和InheritedWidget局部刷新UI 3.ValueNotifier和ValueListenableBuilder 4.StreamBuilder 5.Provider 6.GetX 7.使用GlobalKey 前言 …

实战:功能强大齐全BBS论坛项目Echo简介

项目简介 Echo 是一套前后端不分离的开源社区系统&#xff0c;基于目前主流 Java Web 技术栈&#xff08;SpringBoot MyBatis MySQL Redis Kafka Elasticsearch Spring Security ...&#xff09;&#xff0c;并提供详细的开发文档和配套教程。包含帖子、评论、私信、系…

HarmonyOS NEXT:一次开发,多端部署

寄语 这几年特别火的uni-app实现了“一次开发&#xff0c;多端使用”&#xff0c;它这个端指的是ios、安卓、各种小程序这些&#xff0c;而HarmonyOS NEXT也提出了“一次开发&#xff0c;多端部署”&#xff0c;而它这个端指的是终端设备&#xff0c;也就是我们的手机、平板、电…

记录些MySQL题集(2)

MySQL 不使用limit的分页查询 limit问题&#xff1a;limit&#xff0c;offset递增问题。随着offset的增加&#xff0c;条数不变&#xff0c;耗时却增加了。 limit 0,10 耗时1ms limit 300000,10 耗时152ms limit 600000,10 耗时312ms 毫秒级别可能没感觉。假…

gitlab 搭建使用

1. 硬件要求 ##CPU 4 核心500用户 8 核心1000用户 ##内存 4 G内存500用户 8 G内存1000用户 2. 下载 链接 3. 安装依赖 yum -y install curl openssh-server postfix wget 4. 安装gitlab组件 yum -y localinstall gitlab-ce-15.9.3-ce.0.el7.x86_64.rpm 5. 修改配置文…

使用Python的Turtle模块绘制小猪佩奇

引言 在编程学习中&#xff0c;Turtle是一个非常有趣且实用的模块&#xff0c;尤其适合初学者。它允许用户通过控制一个可以在屏幕上移动的小海龟来绘制图形&#xff0c;从而直观地理解坐标、角度和循环等概念。本篇博客将介绍如何使用Python的Turtle模块来绘制一个可爱的卡通…

PostgreSQL日志文件配置,记录所有操作记录

为了更详细的记录PostgreSQL 的运行日志&#xff0c;我们一般需要修改PostgreSQL 默认的配置文件&#xff0c;这里整理了一些常用的配置 修改配置文件 打开 PostgreSQL 配置文件 postgresql.conf。该文件通常位于 PostgreSQL 安装目录下的 data 文件夹中。 找到并修改以下配…

IDEA实现热部署

什么是热部署&#xff1f; 热部署&#xff08;Hot Deployment&#xff09;是指在应用程序运行过程中&#xff0c;无需停止整个应用程序或重新启动服务器&#xff0c;就能够部署新的代码、资源或配置文件&#xff0c;使其立即生效。这种部署方式有助于提高开发效率和系统的可用性…

【边缘计算网关教程】4.西门子PPI协议对接

前景回顾&#xff1a;【边缘计算网关教程】3.创建第二个流程-CSDN博客 目录 1. 硬件连接 2. PLC串口参数 2.1. 打开STEP7软件 2.2. 查看通信参数 3. 网关设置 3.1. PLC连接设置 3.2. 数据点位设置 3.3. 测试 西门子 PPI 协议 适配PLC&#xff1a;S7-200 西门子S7-200 PLC…

【RHCE】综合实验0710综合实验

题目&#xff1a; 主服务器192.168.244.130 防火墙允许服务的放行&#xff1a; selinux放行 [rootlocalhost ~]# ll -Z /nfs/rhce 总用量 4 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 8 7月 10 16:52 index.html -rw-r--r--. 1 nobody nobody system_…

推荐一款uniapp拖动验证码插件

插件地址&#xff1a;易盾验证码 - DCloud 插件市场 具体使用方式访问插件地址自行获取

企业网三层架构

企业网三层架构&#xff1a;是一种层次化模型设计&#xff0c;旨在将复杂的网络设计分成三个层次&#xff0c;每个层次都着重于某些特定的功能&#xff0c;以提高效率和稳定性。 企业网三层架构层次&#xff1a; 接入层&#xff1a;使终端设备接入到网络中来&#xff0c;提供…

什么叫图像的双边滤波,并附利用OpenCV和MATLB实现双边滤波的代码

双边滤波&#xff08;Bilateral Filtering&#xff09;是一种在图像处理中常用的非线性滤波技术&#xff0c;主要用于去噪和保边。它在空间域和像素值域上同时进行加权&#xff0c;既考虑了像素之间的空间距离&#xff0c;也考虑了像素值之间的相似度&#xff0c;从而能够有效地…

西安明德理工学院师生莅临泰迪智能科技开展参观见习活动

为进一步深化校企合作&#xff0c;落实高校应用型人才培养。7月8日&#xff0c;西安明德理工学院与广东泰迪智能科技股份有限公司联合开展学生企业见习活动。西安明德理工学院金融产业学院副院长刘敏、金融学专业负责人张莉萍、金融学专业教师曹艳飞、赵浚妤、泰迪智能科技董事…

板级调试小助手(2)ZYNQ自定义IP核构建属于自己的DDS外设

一、前言 在上期文章中讲述了小助手的系统结构和原理。在PYNQ的框架开发中&#xff0c;我们一般可以将PL端当做PS端的一个外设&#xff0c;通过读写寄存器的方式来操作外设的功能&#xff0c;就类似于在开发ARM和DSP中操作外设一样&#xff0c;不同时的是&#xff0c;我们可以通…

【实战】Nginx+Keepalived高可用部署,后端Tomcat

目录 一、下载Tomcat安装包 二、安装Tomcat 三、 运行测试Tomcat是否安装成功 四、开放8080端口 五、Tomcat服务脚本 一、环境说明&#xff1a; 三、安装Keepalived 3.1、主机安装配置 实战目的是为了Nginx和后端的Tomcat都可以实现高可用&#xff0c;防止单节点故障的…

AWS-S3实现Minio分片上传、断点续传、秒传、分片下载、暂停下载

文章目录 前言一、功能展示上传功能点下载功能点效果展示 二、思路流程上传流程下载流程 三、代码示例四、疑问 前言 Amazon Simple Storage Service&#xff08;S3&#xff09;&#xff0c;简单存储服务&#xff0c;是一个公开的云存储服务。Web应用程序开发人员可以使用它存…

方便好用的C#.Net万能工具库Masuit.Tools

文章目录 简介开发环境安装使用特色功能示例代码1. 检验字符串是否是Email、手机号、URL、IP地址、身份证号等2.硬件监测(需要管理员权限&#xff0c;仅支持Windows&#xff0c;部分函数仅支持物理机模式)3.html的防XSS处理&#xff1a;4.整理Windows系统的内存&#xff1a;5.任…