0 写在前面

本博客将介绍如下内容:

  1. 基于AMCL工具包,在已知地图上使用move_base实现机器人自主导航
  2. 实现机器人自主导航

1 基于move_base的自主导航

move_base

move_base可以说是ROS中最主要的功能包之一,他的主要功能是提供机器人的自动导航功能,有关他的介绍可以参考文档,官方文档,以下是他的构造图:
move_base
我们来看他的组成,AMCL部分在上一步已经串联起来了,传感器之间的坐标转换关系由joint_state_publisherrobot_state_publisher提供,里程计odom由我们的控制器提供,万事俱备!
我们需要做的只是在上一篇文章包含AMCL节点的amcl_run.launch文件中再包含一个move_base节点即可,起名叫path_run.launch,具体的launch文件代码有如下:

<launch>
    <!-- 设置地图的配置文件 -->
    <arg name="map" default="map01.yaml" />
    <!-- 运行地图服务器,并且加载设置的地图-->
    <node name="map_server" pkg="map_server" type="map_server" args="$(find myNav)/map/$(arg map)"/>
    <!-- 启动AMCL节点 -->
    <include file="$(find myNav)/launch/amcl_my.launch" />

    <!-- 运行move_base节点 -->
    <include file="$(find myNav)/launch/path.launch" />
    <!-- 运行rviz -->
    <!-- <node pkg="rviz" type="rviz" name="rviz" args="-d $(find myNav)/rviz/nav.rviz" /> -->

</launch>

其中的path.launch文件主要配置了move_base中的参数,有如下:

<launch>

    <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen" clear_params="true">
        <rosparam file="$(find myNav)/param/costmap_common_params.yaml" command="load" ns="global_costmap" />
        <rosparam file="$(find myNav)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />
        <rosparam file="$(find myNav)/param/local_costmap_params.yaml" command="load" />
        <rosparam file="$(find myNav)/param/global_costmap_params.yaml" command="load" />
        <rosparam file="$(find myNav)/param/base_local_planner_params.yaml" command="load" />
    </node>

</launch>

操作

  • 第一步我们仍是启动xacro与gazebo与Rviz集成指令:
    roslaunch hw_car_gazebo.launch所在绝对路径
  • 第二步启动我们上一节编写的launch文件:
    roslaunch path_run.launch所在绝对路径
  • 最后利用Rviz中的2D nav goal即可实现机器人目标点设置,并且可以在map中订阅costmap用于显示代价地图,添加PoseArray用于显示机器人利用amcl估算的位置,添加Path用于显示路径

最终有如下效果:
amcl+move_base
其中绿线就是move_base工具包规划出的路径

2 机器人自主建图

任务描述

我们想要的效果有如下表述:

  • 抛弃SLAM中我们用键盘节点操作机器人移动的做法
  • 让机器人自主移动扩大感知到的地图,这可以通过:
  1. 复杂的方式,编写cpp程序随机取得机器人已经感知到地图的坐标点,并令机器人自主移动到该点,再过程中会获得未探索区域的地图
  2. 简单的方式,即利用2D nav goal手动导航至机器人已感知地图的边界,已此来保证效率
    在本博客中我们采用第二种方式
  • 当地图建设差不多时,调用map_save来保存地图

实现

如何让机器人自主移动呢?在上一节已经给出了答案,即使用move_base工具包,那么我们需要做的就是在博客中的gmapping建图launch文件中添加我们在上一节编写的path.launch文件即可:
<include file="$(find myNav)/launch/path.launch" />
而不包含path_run.launch的原因是gmapping已经提供了定位功能,即已经包含了一个类似于AMCL的定位节点,不用再包含AMCL用来提供信息。
起名为slam_nav.launch,其中的具体代码有如下:

<launch>
<param name="use_sim_time" value="true"/>
    <!--gmapping包-->
    <node pkg="gmapping" type="slam_gmapping" name="slam_gmapping" output="screen">
    <!--设置雷达话题-->
      <remap from="scan" to="scan"/>
      <param name="base_frame" value="base_footprint"/><!--底盘坐标系-->
      <param name="odom_frame" value="odom"/> <!--里程计坐标系-->
      <param name="map_update_interval" value="5.0"/>
      <param name="maxUrange" value="16.0"/>
      <param name="sigma" value="0.05"/>
      <param name="kernelSize" value="1"/>
      <param name="lstep" value="0.05"/>
      <param name="astep" value="0.05"/>
      <param name="iterations" value="5"/>
      <param name="lsigma" value="0.075"/>
      <param name="ogain" value="3.0"/>
      <param name="lskip" value="0"/>
      <param name="srr" value="0.1"/>
      <param name="srt" value="0.2"/>
      <param name="str" value="0.1"/>
      <param name="stt" value="0.2"/>
      <param name="linearUpdate" value="1.0"/>
      <param name="angularUpdate" value="0.5"/>
      <param name="temporalUpdate" value="3.0"/>
      <param name="resampleThreshold" value="0.5"/>
      <param name="particles" value="30"/>
      <param name="xmin" value="-50.0"/>
      <param name="ymin" value="-50.0"/>
      <param name="xmax" value="50.0"/>
      <param name="ymax" value="50.0"/>
      <param name="delta" value="0.05"/>
      <param name="llsamplerange" value="0.01"/>
      <param name="llsamplestep" value="0.01"/>
      <param name="lasamplerange" value="0.005"/>
      <param name="lasamplestep" value="0.005"/>
    </node>

    <node pkg="joint_state_publisher" name="joint_state_publisher" type="joint_state_publisher" />
    <node pkg="robot_state_publisher" name="robot_state_publisher" type="robot_state_publisher" />

    <node pkg="tf2_ros" type="static_transform_publisher" name="static_transform_publisher" args="0 0 0 -1.57 0 -1.57 /support /support_depth" />
    <include file="$(find myNav)/launch/path.launch" />
    <!-- <node pkg="rviz" type="rviz" name="rviz" /> -->
    <!-- 可以保存 rviz 配置并后期直接使用-->
    <!--
    <node pkg="rviz" type="rviz" name="rviz" args="-d $(find my_nav_sum)/rviz/gmapping.rviz"/>
    -->
</launch>

操作

  • 第一步我们仍是启动xacro与gazebo与Rviz集成指令:
    roslaunch hw_car_gazebo.launch所在绝对路径
  • 第二步启动自主建图指令:
    roslaunch slam_nav.launch所在绝对路径
  • 第三步在白色区域(移动机器人传感器感知位置)利用Rviz中的2D nav goal即可实现机器人目标点设置,机器人会自动移动到此处,并增大感知建图位置,当觉得地图构造差不多时,调用
    map_save.launch,map_save.launch同博客,即可保存地图
  • 最后可以利用指令rosrun rqt_gragh rqt_gragh观察 slam_nav.launch
    slam_nav节点图
    可以发现原理为 /move_base 订阅了 /slam_gmapping 中的 /tf 话题,即实现了简单的机器人自主建图功能,这也佐证了我们确实不用包含AMCL.
    最终自主建图有如下显示:
    slam_nav1
    slam_nav2
    slam_nav3
    通过绿色路线,可以知道我们的小车确实在已经感知的地图实现了自主导航,最终实现了自主建图

3 写在最后

  • 至此我们通过两个专栏,完整的实现了一个移动机器人研究平台的搭建,从搭建小车 -> 传感器和物理世界的集成和现实 -> 搭载控制器 -> 让小车动起来 -> 利用小车建图(手动的,主动的) -> 高层应用(AMCL定位,move_base自主导航)
  • 作为笔者个人见解,博客难免有不足之处,还望大家指出互相学习
  • 最后更是感谢大家的阅读与喜欢,不胜感激
  • 会在之后推出更多有质量的文章的!