ROS navigation功能包简单来说就是输入传感器信息和机器人位姿,通过导航算法输出机器人的速度控制指令实现机器人的2D路径规划。
贴出代码库:navigation github官方仓库
以下是ROS官方的文档:navigation官方仓库
navigation提供如下功能节点:
功能包较多,根据功能可以分成以下类别:
整体框架如下:
分析:
主要功能可以分为定位、建图、路径规划(局部路劲规划、全局路径规划)、姿态估计,
根据功能挨个介绍功能包
map_server:地图服务器,主要功能是保存地图和导入地图。
costmap_2d:可以生产代价地图,以及提供各种相关的函数。
robot_pose_ekf:扩展卡尔曼滤波器,输入是里程计、IMU、VO中的任意两个或者三个,输出是一个融合之后的pose。
localization:这里是两个定位用的package。fake_localization一般是仿真用的,amcl才是实际定位用的package。
nav_core:这里面只有三个文件,对应的是全局路径规划、局部路径规划、recovery_action的通用接口定义,具体功能实现则是在各个对应的规划器package里。
move_base:这里实现的是整个导航的流程。什么时候调用全局路径规划、什么时候调用局部路径规划、什么时候调用recovery_action都是这个package管的。就是下图中间方框里做的事情,可以说是整个navigation stack的核心。
以上参考博客:功能包分析
每个模块的接口、解释文档可以参考:功能包详细描述
在这可以切换功能包的描述:
navigation中的功能实现方式的切换是通过切换插件的形式完成的(比如说local planner从local_planner切换到dwa实现),首先官方插件的编写生成可以参考以下链接:插件的创建基于插件的形式能够使文件的功能更加明显,接口更加统一。以上rotate_ercoverynavfn、base_local_planner、move_slow_and_clear、global_planner、dwa_local_planner、clear_costmap_recovery、carrot_planner都是以插件的形式编写存在以及调用。
对于不同插件扥调用,可以在move_base.cpp当中进行更换:
接下来看turtlebot对于move_base的基本调用,官方链接turtlebot navigation的使用
<launch>
<!-- Arguments -->
<arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
<arg name="map_file" default="$(find turtlebot3_navigation)/maps/map.yaml"/>
<arg name="open_rviz" default="true"/>
<arg name="move_forward_only" default="false"/>
<!-- Turtlebot3 -->
<include file="$(find turtlebot3_bringup)/launch/turtlebot3_remote.launch">
<arg name="model" value="$(arg model)" />
</include>
<!-- Map server -->
<node pkg="map_server" name="map_server" type="map_server" args="$(arg map_file)"/>
<!-- AMCL -->
<include file="$(find turtlebot3_navigation)/launch/amcl.launch"/>
<!-- move_base -->
<include file="$(find turtlebot3_navigation)/launch/move_base.launch">
<arg name="model" value="$(arg model)" />
<arg name="move_forward_only" value="$(arg move_forward_only)"/>
</include>
<!-- rviz -->
<group if="$(arg open_rviz)">
<node pkg="rviz" type="rviz" name="rviz" required="true"
args="-d $(find turtlebot3_navigation)/rviz/turtlebot3_navigation.rviz"/>
</group>
</launch>
launch文件当中< Turtlebot3>部分选择了机器人本体部分,
<launch>
<!-- Arguments -->
<arg name="model" default="$(env TURTLEBOT3_MODEL)" doc="model type [burger, waffle, waffle_pi]"/>
<arg name="cmd_vel_topic" default="/cmd_vel" />
<arg name="odom_topic" default="odom" />
<arg name="move_forward_only" default="false"/>
<!-- move_base -->
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<param name="base_local_planner" value="dwa_local_planner/DWAPlannerROS" />
<rosparam file="$(find turtlebot3_navigation)/param/costmap_common_params_$(arg model).yaml" command="load" ns="global_costmap" />
<rosparam file="$(find turtlebot3_navigation)/param/costmap_common_params_$(arg model).yaml" command="load" ns="local_costmap" />
<rosparam file="$(find turtlebot3_navigation)/param/local_costmap_params.yaml" command="load" />
<rosparam file="$(find turtlebot3_navigation)/param/global_costmap_params.yaml" command="load" />
<rosparam file="$(find turtlebot3_navigation)/param/move_base_params.yaml" command="load" />
<rosparam file="$(find turtlebot3_navigation)/param/dwa_local_planner_params_$(arg model).yaml" command="load" />
<remap from="cmd_vel" to="$(arg cmd_vel_topic)"/>
<remap from="odom" to="$(arg odom_topic)"/>
<param name="DWAPlannerROS/min_vel_x" value="0.0" if="$(arg move_forward_only)" />
</node>
</launch>
move_base.launch部分当中读取了yaml文件中的参数,启动了最终控制导航的move_base节点。
move_base相当于是对外部功能开放到并且交互的部分,具体内部实现着重理解下图:
ps:虽然ROS navigation的实现算法比较简单,但是对于路径规划的入门还是非常合适的,另外整体代码框架,编写格式还是值得思索学习。