ROS: global_planner 整体解析

       在目前的ROS版本中,机器人全局路径规划使用的是navfn包,这在move_base的默认参数中可以找到 base_global_planner  (string, default: "navfn/NavfnROS")。而在navigation的源代码中还有一个global_planner的包,该包的源文件夹(navigation-hydro-devel\global_planner\src )下已经有了A*,Dijkstra等算法的实现。可是navfn的源程序中也有这两个算法的实现,貌似根本就没用到global_planner这个文件夹下的源程序。因此最开始直接看用于move_base全局导航的程序时有点一头雾水,为什么有两个用于全局导航的包在ROS里面?到底这两个包navfn和global_planner是什么关系?

       可以将navfn包和global_planner包理解成一个并列关系,因为他们两个都是用来做全局规划的,两个包里面也都实现了A*,Dijkstra算法。那是不是意味着这两者中的一个包就是多余的呢?其实不是,早期的开发中是用navfn包做导航的,那时候并没有global_planner这个包,并且在navfn的源代码里可以看到这个包默认是使用Dijkstra做全局路径规划,并且有A*的代码,那为什么没有使用A*呢?幸好有人在ROS answers里问了这个问题,也引来了众开发者回答:

      根据12年bhaskara的回答,意思是navfn里的A*算法存在bug,没人有时间去弄(在ros的各种答案里经常可以看到开发者说没时间弄,他们确实也相当的忙),直到13年David Lu 才完成了这部分工作,重新发布了global_planner包,修改好的代码封装性更强,更清晰明了。因此,也可以认为global_planner是navfn的替代者。也有人问David Lu为什么没用global_planner替代掉navfn?他的回答是为了和以前兼容。因此可以看到源代码中两个包都在,并且move_base的那个全局变量参数默认的是navfn,也就是说没用global_planner。那么如何使用global_planner包而不是navfn包呢?按理来说,只要将move_base的参数base_global_planner用global_planner/PlannerCore替代就行了。如:

<nodepkg="move_base" type="move_base" respawn="false"name="move_base" output="screen">

 <param name="base_global_planner"value="global_planner/GlobalPlanner"/>

       可是实际使用的时候(14年1月以前),却提示this planner is not registered,意思是这个包没有注册。幸好有人发现这个是bgp_plugin.xml里的bug,后来安装的ROS版本应该修复了这个问题。如果有这个错误,请按照github上的修复修改cmakelist.txt和bgp_plugin.xml就可以了。

       看到这,不得不提一个问题?这个文件是干嘛的,为啥要在这里面加上那几句。

       按照文件的名字就知道这是个跟插件有关。讲到这里,就有必要顺带了解一下move_base是如何调用各种global或者local planner的。在使用navigation的官方wiki教程里就提到过可以使用自己的路径规划算法,思路是使用ROS的插件机制。在自己写的global或者local planner算法里开头加上一句特定的程序(PLUGINLIB_EXPORT_CLASS(.....))就能注册插件机制,然后在xx_plugin.xml等文件里描述下这个插件,在package.xml显式的表明这个插件用来通知ROS我们将使用它,具体过程见官方wiki(ROS的插件机制)。弄完插件机制以后,我们就可以像上面一样将其用参数的形式直接传过去了。之前的bgp_plugin.xml有bug,因此就出现了那个问题。

       可是,我随便按照自己的思路去写global 或者local planner的函数就行吗?显然ROS有一个标准。你必须按照它提供给你的模板去实现你自己的算法,这些模板就是基类。如果觉得抽象,可以先通过官方的文档来了解插件是如何工作的

       

       在上图的这个例子中,假设你想使用一个形状画图模块,ROS的官方包中已经有了polygon_interface这个基类,它已经提供了标准的接口函数,并且有两个子类:矩形插件包rectangle_plugin package 和三角形插件包 triangle_plugin package。要想使用这两个子类你只要在相应文件中将它们注册为插件,告诉ROS我将使用这两个插件就行了。这个图中一个关键的中心点就是polygon_interface基类。

       联系到我们自己要写global 或者local planner的插件,这个图就告诉我们并不能天马行空的按照自己的方式编写相关的类或者函数,而必须按照ROS提供的模板去实现,而这正是nav_core这个包存在的意义。在navigation的源代码中你会看到这个nav_core包中仅仅只有几个头文件,正是这些头文件提供了多个模板: nav_core::BaseGlobalPlanner,nav_core::BaseLocalPlanner, nav_core::RecoveryBehavior,在官方的wiki文档里可以看到他们的相关介绍。所以按照这些模板的标准形式去写自己的planner算法就行了。

       了解了这些,也十分有助于我们去看别人写的各种planner的插件,如使用遗传算法的global planner,sbql global planner以及eband local planner等,当然也包括官方提供的用来完善之前遗留程序问题的插件包global_planner包和dwa_local_planner包。

       关于navfn中各代码的具体实现要深入进去,可以先学习一下A*、Dijkstra算法的实现,看懂了这两个算法再去读ROS的源码就容易很多了。当然也有一些细节,如这个网友所问的,可以参考参考。



(转载请注明作者和出处:http://blog.csdn.net/heyijia0327 未经允许请勿用于商业用途)


reference:

1.为什么navfn是用dijkstra? http://answers.ros.org/question/28366/why-navfn-is-using-dijkstra/

2. global_planner包和navfn包的关系?http://answers.ros.org/question/98511/global_planner-package-with-a-planner-question/

3.如何创建自己的全局路径规划插件http://wiki.ros.org/navigation/Tutorials/Writing%20A%20Global%20Path%20Planner%20As%20Plugin%20in%20ROS

4.ROS插件机制 http://wiki.ros.org/pluginlib 

5.关于global_planner 没有注册这个,ros answers上的回答 http://answers.ros.org/question/120736/global_planner-is-not-registered/

6.nav_core 官方wiki http://wiki.ros.org/nav_core

7.navfn具体代码的一些问题 http://answers.ros.org/question/11388/navfn-algorism/?answer=16891#answer-container-16891

  • 36
    点赞
  • 185
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
### 回答1: global_plannerROS中的一个全局路径规划器,它可以根据地图和起点终点信息,生成一条全局路径。该路径规划器的源码解析可以帮助我们更好地理解其实现原理和算法。 global_planner的源码主要包括以下几个文件: 1. global_planner.cpp:该文件是全局路径规划器的主要实现文件,其中包含了路径规划的核心算法和逻辑。 2. grid_path.cpp:该文件实现了栅格地图的路径规划算法,包括A*算法和Dijkstra算法。 3. orientation_filter.cpp:该文件实现了路径方向的滤波算法,可以使路径更加平滑。 4. potential_field.cpp:该文件实现了基于势场的路径规划算法,可以避免障碍物和局部最优解。 在global_planner.cpp文件中,主要实现了以下几个函数: 1. makePlan:该函数是全局路径规划器的入口函数,它接收起点和终点的坐标信息,并调用其他函数进行路径规划。 2. initialize:该函数用于初始化全局路径规划器,包括读取参数、订阅地图和起点终点信息等。 3. computePotential:该函数实现了基于势场的路径规划算法,它会根据地图和障碍物信息计算每个点的势能值,并生成一张势能地图。 4. getPlanFromPotential:该函数根据势能地图和起点终点信息,使用A*算法或Dijkstra算法生成一条全局路径。 5. publishPlan:该函数将生成的全局路径发布出去,供其他节点使用。 总的来说,global_planner的源码实现了多种路径规划算法,可以根据不同的场景和需求进行选择。同时,它还实现了路径方向的滤波和势场的优化,可以使路径更加平滑和避免局部最优解。 ### 回答2: global_plannerROS中的一个全局路径规划器,主要用于自动驾驶、机器人导航等领域。其核心算法是基于A*算法的Dijkstra和A*算法的融合。当起点和终点之间存在障碍物时,它会自动计算一条绕过障碍物的路径来达到终点。 global_planner的源码分为四个主要的文件:planner_core.cpp、dijkstra.cpp、astar.cpp和potential_fields.cpp。planner_core.cpp是这个路径规划器的主要文件,它定义了全局路径规划器的核心功能。 其中,Dijkstra算法是一个广度优先搜索算法,可以扩展当前可达节点的最短路径来找到起点到终点的最短路径。而A*算法则是在Dijkstra的基础上添加了启发式信息,即由启发式函数的估计值来指导搜索的方向,这样可以加快搜索速度。 在global_planner中,通过将Dijkstra算法和A*算法的两种算法进行融合,可以提高路径搜索的效率。同时,该算法还引入了potential_fields动力学概念,从而实现了避免障碍物的自适应路径规划,让机器人能够在不同场景下得到最有效的路径。 总的来说,global_planner的源码解析需要解释算法的原理、实现中的细节、运行过程中的各种参数以及算法效率等方面的内容。对于研究领域的专家和从事相关开发工作的人员,都需要有一定的数学和编程技能,才能够深入了解global_planner的工作原理和实现方式。 ### 回答3: global_plannerROS中一个非常重要的全局路径规划器,它能够帮助机器人在未知环境中规划一条全局路径,使机器人能够尽可能地到达目标点,并且避开障碍物。本文将针对global_planner的源码进行解析,帮助读者更好地理解和使用该工具。 global_planner的源码分为两个部分:头文件和源文件。头文件定义了全局变量和函数声明,源文件实现了各种函数和算法。 在头文件中,首先定义了ros/ros.h和std_msgs/MapMetaData.h两个ros消息,用于表示全局地图的元数据和地图本身。同时,头文件中还定义了CellData和Cell的两个子类,用于表示地图中的单元格和单元格的信息。此外,还定义了一个Costmap2D类,用于存储3D地图数据和提供相关函数。 源文件中实现了多种路径规划算法,包括Dijkstra、A*、ARA*和Wavefront等。其中,Wavefront算法是一种基于搜索的路径规划算法,它以机器人当前位置为起点,传播到目标位置时,遇到的障碍物通过标记颜色进行标识。Wavefront算法可以在具有稀疏障碍物的环境中生成平滑的路径。 在global_planner源码中,还实现了一个名为makePlan的函数,用于在地图上规划一条全局路径。该函数首先在地图上搜索到目标位置,并使用A*算法计算出到达目标位置的最短路径。然后,该函数使用ARA*算法对路径进行平滑,避免机器人在前进时发生急剧转弯。最后,该函数返回一个包含路径的向量,并将该向量发送到Topic,供其他节点使用。 总结而言,global_plannerROS中一个非常强大的全局路径规划器。它包含多种路径规划算法,可以在不同的场景下进行路径规划。在使用global_planner时,需要了解其中的算法与设计思路,才能更好地进行调用和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值