0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ROS Navigation Stack的整体设计思路和功能包

3D视觉工坊 来源:深蓝AI 2023-02-01 11:20 次阅读

前言

ROS Navigation Stack是ROS提供的一个二维的导航功能包集合,通过输入里程计、传感器信息和目标位姿,输出控制机器人到达目标状态的安全速度指令。

ROS Navigation Stack为移动机器人的导航规划提供了比较好的参考,通过实现功能包集合提供的接口,也可以比较容易地将自己的算法应用到移动机器人上。本文将帮助大家理解ROS Navigation Stack的设计思路,并对各个功能包进行讲解。

01 概述

dc4a67ac-a1c5-11ed-bfe3-dac502259ad0.png

点击可查看大图 通过ROS wiki上的这张图,我们可以比较清楚的看到ROS Navigation Stack的整体设计思路:整个功能包集合以move_base为核心,将里程计信息、传感器信息、定位信息、地图以及目标点输入给move_base,move_base经过规划后会输出速度指令。move_base包括三个关键部分:global_planner(全局规划器)、local_planner(局部规划器)和recovery_behaviors(恢复行为)。

这三个部分都是以插件的形式实现的,通过插件机制可以方便地切换不同算法实现的规划器。恢复行为会在机器人移动过程中出现了异常状态时被触发,目的是帮助机器人摆脱异常状态。另外,move_base还包括了global_costmap(全局代价地图)和local_costmap(局部代价地图),规划器需要在代价地图上进行导航规划。下面我们来详细看一下上面提到的各部分内容。

02 odometry(里程计)

简单来说,里程计的作用就是估计机器人运动的距离和速度。通过阅读源码可以得知,在ROS Navigation Stack中,里程计信息有两个作用,一个作用是提供给局部规划器,当局部规划器选取最优路径和判断机器人是否停止的时候会使用到里程计的速度信息,另一个作用就是将估计位姿信息用于定位。

里程计信息一般从机器人底盘的轮式编码器获取,当然根据不同的机器人也可以选择使用视觉里程计,还可以使用扩展卡尔曼滤波对轮式里程计和IMU进行数据融合,得到更加准确的位姿估计。消息类型nav_msgs/Odometry中包括了机器人的位姿和速度以及各自的协方差。

nav_msgs/Odometry.msg

dc6db45a-a1c5-11ed-bfe3-dac502259ad0.png

03 sensor(传感器)

传感器数据一般来自于激光雷达、IMU和深度相机,可以用于定位和避障。使用传感器需要设定传感器参考系与机器人参考系之间的坐标变换关系,也就是常说的tf变换,这样做是为了表示传感器感知到的环境与机器人参考系之间的关系。如果使用amcl算法,激光雷达数据会用来与静态地图进行匹配,修正机器人的位姿,得到更加准确的定位。

激光雷达也可以感知到环境中障碍物的位置,通过将障碍物加入到代价地图中,实现避障。具体使用哪几种传感器,依赖于使用的机器人平台。理论上来说,使用的传感器种类越多,定位和避障的效果更好。

04 tf

tf是一个让用户随时间跟踪多个参考系的功能包,它使用一种树型数据结构,根据时间缓存并维护多个参考系之间的坐标变换关系,可以帮助用户在任意时间,将点、向量等数据的坐标,在两个参考系中完成坐标变换。

机器人系统通常有许多随时间变化的三维参考系,例如世界参考系和机器人参考系。tf会随着时间的变化跟踪这些参考系。基于ROS Navigation Stack实现移动机器人的自主导航,必须维护一棵完整的tf树,即map->odom->base_link->sensor_link。 实际上,我们所说的定位,就是维护map->base_link之间关系的过程。tf树中记录了机器人参考系与地图参考系之间的关系,也就得到了机器人在地图中的哪个位置,tf树也记录了传感器参考系与机器人参考系的关系,也就得到了感知的数据与机器人之间的关系。

dc8eeec2-a1c5-11ed-bfe3-dac502259ad0.png

dcb29444-a1c5-11ed-bfe3-dac502259ad0.png

点击可查看大图

从上面这张图我们就可以直观地理解什么是tf变换了,由tf树帮助我们管理激光雷达与机器人底盘之间的坐标变换关系,当激光雷达感知到某个位置存在障碍物时,通过tf变换就能得到障碍物与机器人底盘之间的距离。

05 map_server

map_server在ROS Navigation Stack中是可选的,其主要的作用就是给机器人导航提供地图。提供地图有两种方式,一种方式是通过SLAM提供实时地图,另一种方式是提供SLAM提前建立并保存或者通过其他方式制作的地图,常用的SLAM算法有gmapping和hector_slam等。

一般在比较规则的场景,可以制作高精度地图提供给机器人,定位和规划都会有比较好的效果。通过SLAM提供实时地图,需要把实时地图以话题的形式发布。通过map_server提供的地图为pgm格式,通过加载yaml配置文件,将地图以话题的形式加载到系统中。在yaml文件中可以配置地图的分辨率,原点以及表示占据/空闲的概率。下面为yaml配置文件的内容:

dcbde146-a1c5-11ed-bfe3-dac502259ad0.jpg

·地图的默认参考系为map。占据的概率occ = (255 – color_avg) / 255.0,其中color_avg为像素RGB的平均值。

06 amcl(自适应蒙特卡洛定位)

amcl是ROS Navigation Stack中唯一指定的定位算法,全称为自适应蒙特卡洛定位,它是一种用于在二维环境中移动的机器人的概率定位系统。简单概括一下它的原理就是通过在全局地图中撒粒子,粒子可以理解为机器人的可能位姿。

按照评价标准,例如激光雷达数据与地图的匹配程度给粒子打分,分数越高代表机器人在这个位置的可能性越大,经过粒子滤波器以后留下的就是分数高的粒子了。

经过多次撒粒子,粒子就会集中到机器人位置可能性高的地方,称之为粒子收敛。自适应其实简单理解就是会根据粒子的平均分数或者粒子是否收敛来增加或减少粒子数,它能够有效地解决机器人绑架问题和粒子数固定问题。 dcc84ea6-a1c5-11ed-bfe3-dac502259ad0.gif

上图中红色的粒子簇即为amcl在全局地图中撒下的粒子,可以看到一开始的粒子簇集中在给定的起始位姿周围,此时的粒子簇还是比较分散的,随着机器人的移动,粒子簇逐渐收敛,定位效果还是不错的。

dd07e2aa-a1c5-11ed-bfe3-dac502259ad0.png

点击可查看大图

amcl在ROS Navigation Stack中的作用就是输出map->odom的tf变换,来弥补里程计的漂移误差,它要求在机器人的定位系统中要存在里程计位姿估计,即odom->base_link的tf变换,并给定起始位姿和输入传感器数据。

07 costmap_2d(代价地图)

costmap_2d功能包提供了一种二维代价地图的实现方案,该方案从实际环境中获取传感器数据,构建二维或三维的栅格占用地图,以及基于占用栅格地图和用户定义膨胀半径的二维代价地图。该包也支持基于map_server初始化代价地图,基于滚动窗口的代价地图,以及订阅和配置传感器话题。

在ROS Navigation Stack中,代价地图分为全局代价地图和局部代价地图,全局代价地图使用基于map_server初始化代价地图,也就是Static Map Layer(静态地图层),局部代价地图为基于滚动窗口的代价地图。 代价地图还包括Obstacle Map Layer(障碍物层)和Inflation Layer(膨胀层),有时候根据应用场景的需要也可以加入用户自定义层,用户自定义层可以用插件来实现。障碍物层是将传感器感知到的障碍物加入到代价地图中。 在规划的时候,我们会把机器人看做是一个质点,并没有考虑机器人的实际模型,因此在代价地图中需要膨胀层,来尽量保证规划出的路径不会使机器人和障碍物发生碰撞。

dd280332-a1c5-11ed-bfe3-dac502259ad0.png

点击可查看大图

上面这张图为ROS wiki上的一个示例,可以看到图中灰色部分即为静态地图,红色部分为传感器感知到的障碍物,蓝色部分为膨胀层。红色多边形表示机器人的形状,为了避免碰撞,机器人形状不应该和红色部分相交,机器人中心点不应该和蓝色部分相交。

08 move_base

move_base是整个ROS Navigation Stack的最顶层,它将各个功能模块组合起来,通过SimpleActionServer接收目标点并完成导航任务。move_base支持任何遵循在nav_core包中指定的nav_core::BaseGlobalPlanner接口的全局规划器和任何遵循在nav_core包中指定的 nav_core::BaseLocalPlanner 接口的局部规划器。

move_base执行的流程是通过状态机来控制是执行规划行为还是恢复行为,当规划失败就会执行恢复行为,如果所有恢复行为也都失败就会退出导航并报告问题。规划的流程是通过回调函数接收目标点,同时会有一个线程不断地跑全局规划器,然后局部规划器以一定频率对规划出来的路径进行跟踪,计算出速度指令,最终到达目标点就重置规划状态。

09 nav_core

nav_core功能包为用于导航的机器人行为提供了通用的接口,其中定义了三个抽象类,分别是BaseGlobalPlanner、BaseLocalPlanner和RecoveryBehavior。

dd40ad24-a1c5-11ed-bfe3-dac502259ad0.png

点击可查看大图

从上图我们也可以清楚地看到move_base的整个导航流程以及各部分使用的nav_core功能包定义的接口。通过阅读源码我们可以知道,BaseGlobalPlanner中定义了纯虚函数makePlan(),makePlan()用于实现规划全局路径。

BaseLocalPlanner中定义了纯虚函数setPlan()、isGoalReached()和computeVelocityCommands(),setPlan()用于实现设定局部规划器跟踪的路径,isGoalReached()用于实现判断是否到达目标点,computeVelocityCommands()用于实现计算安全的速度指令。RecoveryBehavior定义了纯虚函数runBehavior(),runBehavior()用于实现执行恢复行为。

10 global_planner(全局规划器)

对于move_base的全局规划器,我们主要了解global_planner功能包。global_planner功能包实现了两种路径规划算法:A*和dijkstra,并实现了OrientationFilter类,用于对路径进行优化。

global_planner功能包的GlobalPlanner继承了nav_core:: BaseGlobalPlanner,实现了makePlan()函数。makePlan()函数的基本流程就是输入起点和终点,读取代价地图,使用A*或者dijkstra算法进行规划,调用OrientationFilter类中的方法对路径进行优化,将规划好的路径以话题的形式发布。

11 local_planner(局部规划器)

局部规划器是move_base中最复杂的部分,实现局部规划器需要继承nav_core包的BaseLocalPlanner类。常用的局部规划器是dwa_local_planner,dwa_local_planner提供了在二维平面进行局部路径规划的动态窗口法的实现。动态窗口法主要是在速度空间中采样多组速度,并模拟机器人在这些速度下一定时间内的轨迹。在得到多组轨迹以后,对这些轨迹进行评价,选取最优轨迹所对应的速度来驱动机器人运动。

局部规划器的一个基本流程就是读取局部代价地图,设定要跟踪的全局路径,对全局路径进行分段,根据分段的全局路径的坐标进行局部规划,计算机器人每个周期(采样周期)内的线速度、角速度,使之尽量符合全局最优路径,并实现实时避障。

以DWA局部规划器为例,当规划全局路径的线程planThread在控制循环中输出新的路径时,新的路径将通过setPlan()传递给DWAPlannerROS,直接保存为global_plan_。如果isGoalReached()返回false,程序继续执行调用computeVelocityCommands()。

在computeVelocityCommands()中会调用getLocalPlan()对全局路径进行分段,并调用dwaComputeVelocityCommands()使用DWA算法计算最优速度,最后在move_base中发布速度指令。当机器人到达目标位姿且速度小于停止速度时,isGoalReached()返回true。

12 recovery_behaviors(恢复行为)

ddc67378-a1c5-11ed-bfe3-dac502259ad0.png

点击可查看大图

上图是move_base默认的恢复行为的执行流程,可以理解为机器人通过旋转底盘,来清除代价地图中的障碍物,经过清除以后如果可以找到可走的路径,就继续导航,否则认为目标点不可达并报告终止导航任务。

从源码来看,move_base中包括了clear_costmap_recovery、move_slow_and_clear和rotate_recovery这三个有关恢复行为的功能包。clear_costmap_recovery实现的是将给定区域内的障碍物从代价地图中清除。

move_slow_and_clear实现的是清除代价地图中的障碍物,并在用户给定的限制速度下移动一定的距离,这可能会导致机器人发生碰撞。rotate_recovery实现的是通过使机器人旋转一周来清除代价地图中的障碍物。

13 总结

本文介绍了ROS Navigation Stack的整体设计思路和各个功能包的作用以及它们之间的联系,希望能够帮助大家更好地理解ROS Navigation Stack,感谢大家的阅读。

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2526

    文章

    48077

    浏览量

    740002
  • 机器人
    +关注

    关注

    206

    文章

    27030

    浏览量

    201383
  • 移动机器人
    +关注

    关注

    2

    文章

    718

    浏览量

    33315
  • ROS
    ROS
    +关注

    关注

    1

    文章

    271

    浏览量

    16680
  • STACK
    +关注

    关注

    0

    文章

    11

    浏览量

    2707

原文标题:ROS Navigation Stack的整体设计思路和功能包

文章出处:【微信号:3D视觉工坊,微信公众号:3D视觉工坊】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    安装ros和重德智能教学

    ros入门(1)-安装ros与开发包
    发表于 03-22 07:10

    ROS navigation功能添加自定义的全局路径规划器(Global Path Planner)

    ROSnavigation官方功能提供了三种全局路径规划器:carrot_planner、global_planner、navfn。我们通常使用的是navfn,如果机器人执行一些
    发表于 05-16 19:17

    ROS与STM32之间的联系

    ROS与STM32之间的联系简介ROS主要实现的功能STM32主要实现的功能两者之间的关系两者之间的通信简介1、如何实现ROS与stm32之
    发表于 06-28 07:49

    HarmonyOSAPP开发-JAVA-Navigation体验分享

    一、总体1.技术相关项目名称: Navigation项目语言: JAVA体验模板:Navigation工具:deveco studio2.内容相关主要用于手势导航场景。3.效果如下二、体验开发步骤1
    发表于 08-04 16:32

    ROS与STM32是如何进行通信的

    ROS与STM32通信2020.8.1主要内容制作ROS,将控制命令传给STM32,并将接收到的数据作为话题进行发布STM32接收数据并将姿态数据传回给ROS接收:期望角速度、期望线
    发表于 08-11 07:25

    ROS机器人定位导航仿真

    大作业——ROS机器人定位导航仿真一、安装插件与相关配置1.下载源码2.安装相应插件(1)ros-kinetic-driver-base(2
    发表于 12-17 06:15

    如何利用ROS去创建一种工作空间与功能

    如何利用ROS去创建一种工作空间与功能呢?
    发表于 02-14 06:58

    如何在ROS上使用serial进行串口通信

    如何在ROS上使用其提供的serial进行串口通信。我的环境介绍:PC:使用的是Ubuntu 16-04 ROS-Kinetic嵌入式端:STM32F071ROS机器人操作系统是用于
    发表于 02-21 07:27

    在FirePrime开发板上编译安装ROS jade

    ,底层设备控制,常用功能实现,进程间消息以及数据包管理。ROS是基于一种图状架构,从而不同节点的进程能接受,发布,聚合各种信息(例如传感,控制,状态,规划等等)。感兴趣的可以去ROS Wiki,那里有
    发表于 07-07 11:21

    ROS教程之ROS机器人操作系统基础知识概述资料免费下载

    ROS文件系统介绍 (1)快速了解ROS文件系统概念 • 软件包集(Stack):如果你将几个具有某些功能的软件包组织在一起,那么你将会获得一个软件包集。在
    发表于 10-15 08:00 18次下载
    <b class='flag-5'>ROS</b>教程之<b class='flag-5'>ROS</b>机器人操作系统基础知识概述资料免费下载

    Navigation源码解析

    Navigation源码解析 谷歌推出Navigation主要是为了统一应用内页面跳转行为。本文主要是根据Navigation版本为2.1.0 的源码进行讲解
    的头像 发表于 06-15 16:38 1535次阅读

    如何配置ROS驱动功能

    配置ROS驱动功能包 将WHEELTEC 100N的 ROS_SDK 保存在工作空间的src文件夹下。 通过 catkin_make 进行编译。 刚装的ros环境会报错,如下: Mak
    的头像 发表于 11-22 18:13 580次阅读
    如何配置<b class='flag-5'>ROS</b>驱动<b class='flag-5'>功能</b>包

    如何创建新的ROS工作空间

    创建新的ROS工作空间 由于ROS Motion Planning运动规划库与Navigation导航包存在一些同名但源码和功能不同的功能
    的头像 发表于 11-26 17:09 882次阅读
    如何创建新的<b class='flag-5'>ROS</b>工作空间

    在TogetherROS中如何安装ROS2功能

    安装ROS2功能包 接下来,还有一个很重要的配置,那就是安装ROS2功能包,我们说TogetherROS是基于ROS2深度优化的,很多模块还
    的头像 发表于 12-01 16:02 454次阅读
    在TogetherROS中如何安装<b class='flag-5'>ROS</b>2<b class='flag-5'>功能</b>包

    ROS机器人如何使用Navigation导航包实现实时定位

    本篇文章主要分析,常规的ROS机器人是如何使用Navigation导航包实现实时定位的,定位精度的决定性因素等内容,结构上分为详细介绍、概括总结、深入思考三大部分。
    的头像 发表于 12-03 11:00 1334次阅读
    <b class='flag-5'>ROS</b>机器人如何使用<b class='flag-5'>Navigation</b>导航包实现实时定位