目录
- 全局路径规划
- 自定义全局路径规划
- 注意
- 参考
路径规划包括全局路径规划和局部路径规划。
全局路径规划
ROS 的navigation官方功能包提供了三种全局路径规划器:carrot_planner、global_planner、navfn。我们通常使用的是navfn,如果机器人执行一些特殊任务而navfn不支持的话就需要自己写一个全局路径规划区并注册到ROS系统。
ROS的全局路径规划器是以lib插件形式(pluginlib)存在的,通过配置move_base 中base_global_planner参数指定实际路径规划执行时采用的全局路径规划器,这种设计大大提高了navigation包的可扩展性。
ROS官网wiki有详细的教程指导如何为ROS添加自定义的全局路径规划器。主要思路是:直接拷贝一份现成的全局路径规划器代码包,将软件包中的相关名字修改成想要的,最后实现下自己的makeplan方法即可。
自定义全局路径规划
为了向ROS添加一个新的全局路径规划器,新的路径规划器必须遵守nav_core包中定义的。nav_core::BaseGlobalPlanner
C ++接口。一旦编写了全局路径规划器,它必须作为插件添加到ROS中,以便它可以被move_base包使用。
(1)编写路径规划类
Class Header/类头文件
第一步是为遵循nav_core::BaseGlobalPlanner的路径规划器编写一个新类,然后在该类中重写initialize
,makePlan
方法。。在carrot_planner.h中可以找到一个类似的例子作为参考。
(2)为全局规划类创建插件
1.注册规划器作为BaseGlobalPlanner插件:
这是通过指令PLUGINLIB_EXPORT_CLASS(global_planner::GlobalPlanner, nav_core::BaseGlobalPlanner)
完成的。其中,global_planner::GlobalPlanner
为自己定义的命名空间::类
。为此,必须包含库 #include <pluginlib/class_list_macros.h>
。
宏PLUGINLIB_EXPORT_CLASS
:允许一个类被动态加载,标记为一个导出的类。可以放在构成插件库的任何源(.cpp)文件中,通常放在导出类的.cpp文件的末尾。
插件描述文件:
XML文件,用于以机器可读格式存储有关插件的所有重要信息。它包含有关插件库的信息,插件的名称,插件的类型等。
举例rrt_star_planner_plugin.xml
:
<library path="lib/librrt_star_global_planner">
<class name="RRTstar_planner/RRTstarPlannerROS" type="RRTstar_planner::RRTstarPlannerROS" base_class_type="nav_core::BaseGlobalPlanner">
<description>This is RRT Star Global Planner Plugin by Rafael Barreto.</description>
</class>
</library>
在第一行 <library path="lib/librrt_star_global_planner">
我们指定插件库的路径。我们的例子,路径是lib/librrt_star_global_planner
,其中lib
是目录中的文件夹 ~/catkin_ws/devel/
。
在第二行中,我们首先指定我们将在move_base启动文件中使用的RRTstar_planner
插件的名称作为参数,它指定了要在nav_core
中使用的全局规划器。通常使用命名空间(RRTstar_planner
)后跟斜杠,然后使用类( RRTstarPlannerROS
)的名称来指定插件的名称。如果不指定名称,那么名称将等于该类型,在这种情况下将是RRTstar_planner::RRTstarPlannerROS
。它建议指定名称以避免混淆。该类型指定了实现插件的类的名称,在我们的例子中是RRTstar_planner::RRTstarPlannerROS
,而base_class_type
指定了实现插件的基类的名称,在我们的例子中是nav_core::BaseGlobalPlanner
。
第三行所述<description>
标记提供关于插件的简要说明。有关插件描述文件及其相关标签/属性的详细说明。
为什么我们需要这个描述文件? 除了代码宏,我们需要这个文件,以允许ROS系统自动发现,加载。插件描述文件还包含重要信息,如插件的描述,不适合加在宏定义里。
注册插件到ROS包系统:
待补充
2.makePlan()
方法实现:在开始和目标参数用来获取初始位置和目标位置。在该说明性实现中,以起始位置(plan.push_back(start)))作为开始的规划变量。然后,在for循环中,将在规划中静态插入虚拟位置,然后将目标位置作为最后一个位置插入规划。然后,此规划路径将发送到move_base全局规划模块,该模块将通过ROS话题nav_msgs/Path
进行发布,然后将由本地规划模块接收。
现在,全局规划类已经完成,您已准备好进行第二步,即为全局规划类创建插件,将其集成到move_base包的全局规划模块nav_core::BaseGlobalPlanner
中。
(3)编译
要编译上面创建的全局规划库,必须将其添加到CMakeLists.txt中。添加代码:
add_library(global_planner_lib src/path_planner/global_planner/global_planner.cpp)
然后在终端中运行catkin_make,在catkin工作空间目录中生成二进制文件。这将在lib目录中创建库文件 ~/catkin_ws/devel/lib/libglobal_planner_lib。观察到“lib”附加到CMakeLists.txt中声明的库名global_planner_lib
注意
bool makePlan(start,goal,plan)
的方法必须要重写。最终规划将存储在方法的参数std::vector<geometry_msgs::PoseStamped>& plan
中。该规划将通过插件自动发布为话题。
参考
ROS与navigation教程-编写自定义全局路径规划使用自定义RRT*全局规划器建图导航这篇文章很好上手,但是由于全局路径一直更新,加上使用的rrt算法,很有可能导致路径一直在变,需要改进。