ROS中的二维导航功能包,简单来说,就是根据输入的里程计等传感器的信息流和机器人的全局位置,通过导航算法,计算得出安全可靠的机器人速度控制指令,然而,其自带的导航算法并不是适用所有的机器人和环境,在实际应用中我们经常需要更换导航算法来使机器人更能适应它所处的环境。
那么ROS中我们有哪些局部导航算法可供我们选择呢?不妨参考一下这篇文章
一、导航包的组成
在局部导航算法的介绍之前我们需要先理解导航功能包中的各个组成部分:
在ROS中,进行导航需要使用到的三个包是:
(1) move_base:根据参照的消息进行路径规划,使移动机器人到达指定的位置;
(2) gmapping:根据激光数据(或者深度数据模拟的激光数据)建立地图;
(3) amcl:根据已经有的地图进行定位。
他们之间的关系我们可以通过下面这张图来理解
在负责路径规划的move_base包中主要包含两个部分,全局路径规划(global planner)和局部路径规划(local planner)
● 全局路径规划(global planner):根据给定的目标位置进行总体路径的规划,在ROS的导航中,首先会通过全局路径规划,计算出机器人到目标位置的全局路线。这一功能是navfn这个包实现的。navfn通过Dijkstra或A*等最优路径的算法,计算costmap上的最小花费路径,作为机器人的全局路线。
全局路径规划所依赖的算法有以下几种,感兴趣的朋友可以去研究一下:A*、Dijstra、prm、人工势场、单元分解、快速搜索树(RRT)等
● 局部路径规划(local planner):根据附近的障碍物进行躲避路线规划。本地的实时规划是利用base_local_planner包实现的。该包使用Trajectory Rollout 和Dynamic Window approaches算法计算机器人每个周期内应该行驶的速度和角度(dx,dy,dtheta velocities)。
base_local_planner这个包通过地图数据,通过算法搜索到达目标的多条路经,利用一些评价标准(是否会撞击障碍物,所需要的时间等等)选取最优的路径,并且计算所需要的实时速度和角度。
其中,Trajectory Rollout 和Dynamic Window approaches算法的主要思路如下:
(1) 采样机器人当前的状态(dx,dy,dtheta);
(2) 针对每个采样的速度,计算机器人以该速度行驶一段时间后的状态,得出一条行驶的路线。
(3) 利用一些评价标准为多条路线打分。
(4) 根据打分,选择最优路径。
(5) 重复上面过程。
局部路径规划有以下几种
二、局部规划算法
局部路径规划中我们一般常用的是base_local_planner、dwa_local_planner、teb_local_planner,下面我们将介绍这几种算法及其使用方法。
1. base_local_planner(或者TrajectoryPlannerROS)
base_local_planner::TrajectoryPlannerROS对象是base_local_planner::TrajectoryPlanner对象的ROS封装,在初始化时指定的ROS命名空间使用,继承了nav_core::BaseLocalPlanner接口。它是move_base默认的局部规划包。该软件包提供了对平面上本地机器人导航的轨迹展开和动态窗口方法的实现。根据计划遵循和成本图,控制器生成速度命令以发送到移动基站。该软件包支持完整和非完整机器人,可以表示为凸多边形或圆形的任何机器人足迹,并将其配置公开为可在启动文件中设置的ROS参数。此包的ROS包装器遵循nav_core包中指定的BaseLocalPlanner接口。与dwa_local_planner思路接近。
唯一区别是DWA与“TrajectoryPlanner”的不同之处在于如何对机器人的控制空间进行采样。在给定机器人的加速度极限的情况下,TrajectoryPlanner在整个前向模拟周期内从可实现的速度集合中进行采样,而DWA在给定机器人的加速度极限的情况下仅针对一个模拟步骤从可实现的速度集合中进行采样。在实践中,我们发现DWA和轨迹展示在我们的所有测试中都具有相同的性能,并建议使用DWA来提高效率,因为其样本空间更少。
base_local_planner配置方法
可输入下面的命令进行安装
$ sudo apt-get install ros-melodic-base-local-planner
base_local_planner使用方法
可参考以下代码编写launch文件,其中需要加载的设置参数可根据自己的需要选择加载对应的参数文件
<launch>
<!-- 设置地图的配置文件 -->
<arg name="map" default="cloister_gmapping.yaml" />
<!-- 运行地图服务器,并且加载设置的地图-->
<node name="map_server" pkg="map_server" type="map_server" args="$(find ares_navigation)/maps/$(arg map)">
</node>
<!-- 运行move_base节点 -->
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen" clear_params="true">
<!--开启base_local局部导航节点-->
<param name="base_local_planner" value="base_local_planner/TrajectoryPlannerROS" />
<!--加载设置参数-->
<rosparam file="$(find teb_local_planner_tutorials)/cfg/omnidir/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find teb_local_planner_tutorials)/cfg/omnidir/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find teb_local_planner_tutorials)/cfg/omnidir/local_costmap_params.yaml" command="load" />
<rosparam file="$(find teb_local_planner_tutorials)/cfg/omnidir/global_costmap_params.yaml" command="load" />
<rosparam file="$(find ares_navigation)/config/ares/base_local_planner_params.yaml" command="load" />
</node>
<!-- 启动AMCL节点 -->
<include file="$(find amcl)/examples/amcl_omni.launch" >
</include>
<!-- 运行rviz -->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find ares_navigation)/rviz/nav.rviz">
</node>
</launch>
base_local_planner使用效果
base_local_planner的使用效果并不是很好,局部路径规划很短,小车行动缓慢且经常偏离轨迹,一般不会直接使用它作为局部路径规划算法。
2、dwa_local_planner算法
DWA算法全称为:Dynamic Window Approach,中文为动态窗口法,其原理主要是在速度空间(v,w)中采样多组速度,并模拟这些速度在一定时间内的运动轨迹,再通过一个评价函数对这些轨迹打分,最优的速度被选择出来发送给下位机。
动态窗口的意思是根据移动机器人的加减速性能限定速度采样空间在一个可行的动态范围呢。
DWA算法基本思路如下:
1.在机器人控制空间进行速度离散采样(dx,dy,dtheta)
2.对每一个采样速度执行前向模拟,看看使用该采样速度移动一小段段时间后会发生什么
3.评价前向模拟中每个轨迹,评价准则如: 靠近障碍物,靠近目标,贴近全局路径和速度;丢弃非法轨迹(如哪些靠近障碍物的轨迹)
4.挑出得分最高的轨迹并发送相应速度给移动底座
5.重复上面步骤.
dwa_local_planner配置方法
1.可输入下面的命令进行安装
$ sudo apt-get install ros-melodic-dwa-local-planner
2.检测是否安装成功
$ roscd dwa_local_planner
3.创建launch文件 如下
<launch>
<!-- 设置地图的配置文件 -->
<arg name="map" default="cloister_gmapping.yaml" />
<!-- 运行地图服务器,并且加载设置的地图-->
<node name="map_server" pkg="map_server" type="map_server" args="$(find ares_navigation)/maps/$(arg map)"/>
<!-- 运行move_base节点 -->
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen" clear_params="true">
<!--开启dwa局部导航节点-->
<param name="base_local_planner" value="dwa_local_planner/DWAPlannerROS" />
<!--加载设置参数-->
<rosparam file="$(find ares_navigation)/config/ares/costmap_common_params.yaml" command="load" ns="global_costmap" />
<rosparam file="$(find ares_navigation)/config/ares/costmap_common_params.yaml" command="load" ns="local_costmap" />
<rosparam file="$(find ares_navigation)/config/ares/local_costmap_params.yaml" command="load" />
<rosparam file="$(find ares_navigation)/config/ares/global_costmap_params.yaml" command="load" />
<rosparam file="$(find ares_navigation)/config/ares/move_base_params.yaml" command="load" />
<rosparam file="$(find ares_navigation)/config/ares/dwa_local_planner_params.yaml" command="load" />
</node>
<!-- 启动AMCL节点 -->
<include file="$(find amcl)/examples/amcl_omni.launch" />
<!-- 运行rviz -->
<node pkg="rviz" type="rviz" name="rviz" args="-d $(find ares_navigation)/rviz/nav.rviz"/>
</launch>
4.运行该文件
我们可以看到绿色的线是全局规划的路线,蓝色的短线表示局部规划的路线
3、teb_local_planner(本质是插件)
teb_local_planner则是2D导航堆栈的base_local_planner的插件。实现了一个在线优化的本地轨迹规划器,用于导航和控制移动机器人,作为ROS 导航包的插件。全局规划器生成的初始轨迹在运行时期间进行优化,最小化轨迹执行时间(时间最优目标), 与障碍物分离并符合动力学约束,例如满足最大速度和加速度。当前的实施符合非完整机器人(差动驱动和类似汽车的机器人)的运动学。
通过求解稀疏的标量化多目标优化问题,可以有效地获得最优轨迹。用户可以为优化问题提供权重,以便在目标冲突的情况下指定行为。
teb_local_planner配置方法
1.打开teminal,输入
$ sudo apt-get install ros-melodic-teb-local-planner
2.验证是否安装成功
$ roscd teb_local_planner
若能进入teb_local_planner的目录,则表明安装成功
teb_local_planner使用方法
关于teb局部导航的使用方法,官网是有给出示例设置的。
可以在http://wiki.ros.org/teb_local_planner_tutorials网址中找到使用舞台模拟器的示例设置。
1.安装[teb_local_planner_tutorials](http://wiki.ros.org/teb_local_planner_tutorials)软件包
2.检查参数/配置文件
3.启动diff_drive设置:
$ roslaunch teb_local_planner_tutorials robot_diff_drive_in_stage.launch
4.使用rosrun rqt_reconfigure rqt_reconfigure或修改文件来修改参数。
运行效果:
我们可以看到绿色线段表示全局规划路径,红色线段表示teb_local_planner的局部规划路径。
我们一共介绍了base_local_planner、dwa_local_planner和teb_local_planner三种算法,在最后的效果中,我们可以看到,base_local_planner的效果相对而言并不是很理想,我们一般会更多的使用后面两种算法,其中dwa_local_planner算法前瞻更短,小车基本会保持运行在全局路径左右,而teb_local_planner算法前瞻相对较长在遇到障碍时,局部路径会自动规划避过障碍物,但是如果小车处在比较复杂的环境下,局部路径会比较容易出现混乱的现象。
dwa_local_planner teb_local_planner