move_base是ROS下关于机器人路径规划的中心枢纽。它通过订阅激光雷达、map地图、amcl的定位等数据,然后规划出全局和局部路径,再将路径转化为机器人的速度信息,最终实现机器人导航。这里又要盗官网的图了。

上面这个图很好的展示了move_base的整个框架,下面我更加详细的介绍一下每个模块的功能及其是如何衔接的。

首先左上角的amcl模块是ROS的导航定位模块,amcl也叫自适应蒙特卡罗定位,amcl通过订阅scan、map和tf信息,发布出机器人的pose,以供move_base使用,这部分具体可以上官网看看,这里就不做详细介绍了,左下角odom,即机器人里程计信息,右上角,map,顾名思义,我们需要的先验地图信息,一般通过slam建图后保存,ROS中主流的slam算法有:

1.gmapping:需要激光雷达scan数据和里程计odom数据,采用的是PF(粒子滤波)。

2.hector :基于优化的算法(解最小二乘问题),优缺点:不需要里程计,但对于雷达帧率要求很高40Hz,估计6自由度位姿,可以适应空中或者地面不平坦的情况。初值的选择对结果影响很大,所以要求雷达帧率较高。

3.Cartographer:累计误差较前两种算法低,能天然的输出协方差矩阵,后端优化的输入项。成本较低的雷达也能跑出不错的效果。

好了,就不展开了,map_server包通过解析slam建好的地图并发布出去。右下角的传感器topic则在局部路径规划时起到作用,这部分就是costmap包起到的作用了,costmap为代价地图,目前主要的有inflation_layer、obstacle_layer、static_layer、voxel_layer四个plugins。分别为膨胀层、障碍物层、静态层和体素层。一般我们的全局路径需要静态层和膨胀层,因为全局规划应该只考虑到地图信息,所以一般都是静态的,而局部路径规划则需要考虑到实时的障碍物信息,所以需要障碍物层和膨胀层,这里你可能会有疑惑,为什么不把静态层放到局部路径规划里呢?因为我们的定位是会存在误差的,比如轮子打滑或其他情况,这个时候amcl会起到纠正作用,如果我们把静态层放到了局部中,这个定位会有问题,而且,假设当前机器人出现了定位的偏差,那么这个引入的静态层肯定是错误的,再加上局部的障碍物层(这里的障碍物层本应该和静态层重合的,但由于定位偏差,不会重合)可能会使得机器人误以为自己在障碍物层内,规划出现问题。

下面我们我们说说move_base核心的部分了,也就是框框内的部分,主要包括global planner和local planner以及一些修复机制,包括rotate_recovery和clear_cost_map_recovery。有人可能会问,global planner是怎么和local planner联通的呢,这里不同的算法可能使用了不同的方法了,但核心都是大致相同了,都是将global planner作为local planner的一个初始参考或者优化方向。这些在深入看两个源码时就会有更加深入的理解了。目前ROS中可以使用的global planner主要包括:A*和Dijkstra。local planner主要有:dwa、trajectory、teb和eband等。目前自我感觉teb local planner效果会好点,有时间会详细的介绍一样该算法的思路,下面我把我的关于move_base的一些配置放到下面。

首先,启动move_base的launch,包括解析map,move_base和amcl定位三个部分,这构成了一个完整的框架,下面我们主要来看move_base.launch里的配置。

<launch>
 
  <param name="use_sim_time" value="false" />
  
  <!-- EDIT THIS LINE TO REFLECT THE NAME OF YOUR OWN MAP FILE 
       Can also be overridden on the command line -->
  <arg name="map" default="test_map.yaml" />
 
  <!-- Run the map server with the desired map -->
  <node name="map_server" pkg="map_server" type="map_server" args="$(find dart_nav)/maps/dart.yaml"/> 
 
  <!-- Start move_base  -->
  <include file="$(find dart_nav)/launch/tb_move_base_test.launch" />
 
  <!-- Fire up AMCL -->
  <include file="$(find dart_nav)/launch/tb_amcl.launch" /> 
 
 
</launch>
下面是move_base.launch内的配置:

<launch>
  <node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen" clear_params="true">
    <rosparam file="$(find dart_nav)/config1/costmap_common_params.yaml" command="load" ns="global_costmap" />
    <rosparam file="$(find dart_nav)/config1/costmap_common_params.yaml" command="load" ns="local_costmap" />
    <rosparam file="$(find dart_nav)/config1/local_costmap_params.yaml" command="load" />
    <rosparam file="$(find dart_nav)/config1/global_costmap_params.yaml" command="load" />
    <rosparam file="$(find dart_nav)/config1/teb_local_planner_params.yaml" command="load" />
 
     <param name="base_global_planner" value="global_planner/GlobalPlanner"/> 
     <param name="planner_frequency" value="1.0" />
     <param name="planner_patience" value="5.0" />
 
     <param name="base_local_planner" value="teb_local_planner/TebLocalPlannerROS" />
     <param name="controller_frequency" value="15.0" />
     <param name="controller_patience" value="15.0" />
 <rosparam file="$(find dart_nav)/config1/costmap_conversion_params.yaml" command="load" />
 
  </node>
  
</launch>
如上所示,我使用的是global_planner这个包,它默认使用的是dijkstra,当然也可以使用A*全局路径规划,局部路径规划我使用的是teb,同样需要配置上面第3行到第7行的一些yaml,这些yaml是costmap和planner的一些配置文件。我们来主要看一下local_costmap_params.yaml和global_costmap_params.yaml。这里配置了上面提到的各个层(layers)的使用。

local_costmap_params.yaml:

local_costmap:
   global_frame: /odom
   robot_base_frame: /base_link
   update_frequency: 3.0
   publish_frequency: 1.0
   static_map: false
   rolling_window: true
   width: 6.0
   height: 6.0
   resolution: 0.05
   transform_tolerance: 1.0
   map_type: costmap
   plugins:
     - {name: obstacle_layer, type: "costmap_2d::VoxelLayer"}
#     - {name: social_layer,        type: "social_navigation_layers::ProxemicLayer"}   
#     - {name: social_pass_layer,        type: "social_navigation_layers::PassingLayer"}  
#     - {name: static_layer, type: "costmap_2d::StaticLayer"} 
     - {name: inflation_layer, type: "costmap_2d::InflationLayer"}
 
  #Configuration for the sensors that the costmap will use to update a map   
   obstacle_layer:
     observation_sources: scan  
     scan: {data_type: LaserScan, topic: /scan, marking: true, clearing: true, expected_update_rate: 0} 
   inflation_layer: 
      inflation_radius: 0.35
这里由于是局部层,所以我们要把static_map设为fasle,我们并不希望使用静态的地图,因为这不利于我们的局部避障,rollung_window设为true。下面的plugins就为各个层的设置了,在局部路径规划中我们只需要考虑障碍物的信息就可以了,不需要考虑我们之前slam建立的静态地图,所有我们添加了两个图层,即障碍物层和障碍物的膨胀层,下面这个很重要,我们需要声明我们的障碍物层的数据来源,即scan,要把topic对应你的scan的topic,否则你可能发现rviz里的local_costmap没有数据,这就是你没有声明的原因。最后两行为设置膨胀层的半径大小。

global_planner_params.yaml:

global_costmap:
   global_frame: /map
   robot_base_frame: /base_footprint
   update_frequency: 1.0
   publish_frequency: 0
   static_map: true
   rolling_window: false
   resolution: 0.05
   transform_tolerance: 1.0
   map_type: costmap
   plugins:
#     - {name: obstacle_layer, type: "costmap_2d::VoxelLayer"}
     - {name: static_layer, type: "costmap_2d::StaticLayer"} 
   
     - {name: inflation_layer, type: "costmap_2d::InflationLayer"}
   inflation_layer: 
      inflation_radius: 0.35
如上,由于在全局路径规划中,我们只应该考虑静态地图,即我们之前slam建立好的地图,所以我们把static_map设为true,rolling_window设为false,再看plugins:有两个层,静态层和膨胀层,这样就完成了global的yaml的配置,如果你需要把障碍物层也添加到全局地图中,plugins加入,同时别忘了在下面声明数据来源,但我个人不推荐将障碍物层加入到global中来。

下面就是我使用的teb的local_planner的yaml了:

TebLocalPlannerROS:
 
 odom_topic: odom
 map_frame: /odom
 
 # Trajectory
 
 teb_autosize: True
 dt_ref: 0.3
 dt_hysteresis: 0.1
 global_plan_overwrite_orientation: True
 max_global_plan_lookahead_dist: 3.0
 feasibility_check_no_poses: 5
 
 # Robot
 
 max_vel_x: 0.4
 max_vel_x_backwards: 0.15
 max_vel_theta: 0.4
 acc_lim_x: 2.0
 acc_lim_theta: 1.0
 min_turning_radius: 0.0
# footprint_model/type: "circular"
# footprint_model/radius: 0.40 # for type "circular"
 
 # GoalTolerance
 
 xy_goal_tolerance: 0.15
 yaw_goal_tolerance: 0.2
 free_goal_vel: False
 
 # Obstacles
 
 min_obstacle_dist: 0.45
 include_costmap_obstacles: True
 costmap_obstacles_behind_robot_dist: 1.0
 obstacle_poses_affected: 30
 costmap_converter_plugin: ""
 costmap_converter_spin_thread: True
 costmap_converter_rate: 5
 
 # Optimization
 
 no_inner_iterations: 5
 no_outer_iterations: 4
 optimization_activate: True
 optimization_verbose: False
 penalty_epsilon: 0.1
 weight_max_vel_x: 2
 weight_max_vel_theta: 1
 weight_acc_lim_x: 1
 weight_acc_lim_theta: 1
 weight_kinematics_nh: 1000
 weight_kinematics_forward_drive: 1
 weight_kinematics_turning_radius: 1
 weight_optimaltime: 1
 weight_obstacle: 300   #50
 weight_dynamic_obstacle: 10 # not in use yet
 alternative_time_cost: False # not in use yet
 
 # Homotopy Class Planner
 
 enable_homotopy_class_planning: False
 enable_multithreading: True
 simple_exploration: False
 max_number_classes: 4
 roadmap_graph_no_samples: 15
 roadmap_graph_area_width: 5
 h_signature_prescaler: 0.5
 h_signature_threshold: 0.1
 obstacle_keypoint_offset: 0.1
 obstacle_heading_threshold: 0.45
 visualize_hc_graph: False
这里没什么好说的,简单介绍一下teb算法,teb是一个基于图优化的局部路径规划,了解slam的应该都知道BA(bundle adjustment),这里类似,是通过把路径问题构建成一个图优化的问题,然后通过g2o开源库求解优化,teb中是通过对全局路径规划的点(A*或dijkstra)进行优化,也就是最小化误差,这里的误差项为速度,加速度,避障,追踪全局路径等等,最后优化出最优的局部路径,最近在研究teb的算法,有时间再开一个博客,上面大多都是自己的想法,如果有什么问题或错误,欢迎纠正。
--------------------- 
作者:需要努力的阿蒙 
来源:CSDN 
原文:https://blog.csdn.net/shenghuaijing3314/article/details/80005629 
版权声明:本文为博主原创文章,转载请附上博文链接!

一些关于ROS中move_base的理解相关推荐

  1. ROS学习手记 - 5 理解ROS中的基本概念_Services and Parameters

    ROS学习手记 - 5 理解ROS中的基本概念_Services and Parameters 上一节完成了对nodes, Topic的理解,再深入一步: Services and Parameter ...

  2. ROS中map、odom、base_link坐标系的理解和这三个坐标系在AMCL中的关系

    学了ROS快一年了,依旧对map坐标系.odom坐标系.base_link坐标系之间的关系不是很清晰,这段时间下定决心要捋清楚他们之间的关系. map坐标系:地图坐标系,是一个固定的坐标系: base ...

  3. ROS中map,odom坐标系的理解以及acml和robot_pose_ekf的对比和小车漂移方法解决

    之前一直不知道odom,map到底是什么关系,看了这个博客:https://blog.csdn.net/u012686154/article/details/88174195 才了解了一些.这边记录我 ...

  4. ROS中ENU坐标系与无人机中NED坐标系的转换关系理解

    ROS中ENU坐标系与无人机中NED坐标系的转换关系理解 项目地址 无人机中NED坐标理解 ENU与NED转换 无人机中NED坐标理解 机体坐标系:机体坐标系固连飞机,其原点 取在多旋翼的重心位置上. ...

  5. ROS中topic重映射理解及验证(remap标签)

    先附上个人总结: remap在node标签<node> ... </node>之外的作用域是其之后的所有节点: <node> ... </node> & ...

  6. ROS中使用摄像头的问题

    ROS中使用摄像头的问题 0.prepare 4 . 安装uvc_cam $ sudo apt-get install ros-indigo-uvc-camera     $ source /opt/ ...

  7. ROS中base_link, odom, fixed_frame, target_frame和虚拟大地图map的关系

    前面已经介绍了如何使用URDF建造机器人小车并显示在Rviz的仿真环境里面,但是小车是静止的.下面介绍如何让它在Rviz里面动起来,并理清URDF,TF 和 odom 的关系. 1. ROS中base ...

  8. 如何给定两个gps坐标 算出航向角_机器人开发如何配置ROS中的TF变换关系?

    当我们进行机器人开发时,常常需要面对TF坐标转换,本文以 Autolabor Pro1 与思岚激光雷达为例,介绍ROS TF的使用. Autolabor Pro1是什么? Autolabor Pro1 ...

  9. ROS中自定义复杂数据类型

    ROS中自定义复杂数据类型 先说一下需求,想要服务的请求数据为一个point(x,y,z)的数组.具体的形式表示如: [point1,point2,...] geometry_msgs::Point ...

最新文章

  1. html 显示搜索结果,搜索结果高亮显示(不改变html标签)
  2. Mono源码学习笔记:Console类(四)
  3. python sql语句生成_python Django 生成sql语句
  4. mysql error 1449_MySql错误:ERROR 1449 (HY000)
  5. php curl 模拟多线程,php利用curl 多线程 模拟 并发的详解
  6. shell脚本面试题
  7. Node.js mm131图片批量下载爬虫1.01 增加断点续传功能
  8. windows同时安装jdk8和jdk11
  9. ✿ iBm T60 水货入手了 满意 2005
  10. P4 用verilog描述单周期CPU的学习笔记和总结(基于P3)
  11. RJ45-线序 586B 白橙 橙 白绿 蓝 白蓝 绿 白棕 棕
  12. Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本
  13. 细数中国大学里的30个怪现状
  14. 学PS基础:Photoshop 技能167个
  15. 看地理标志产品苏尼特羊肉如何投放广告宣传打造品牌
  16. 整体理解抽象、封装、继承、多态
  17. 【面经】微软SWE暑期实习
  18. 重新运行一次阿里云服务器.从零开始搭建.?log-换-服务器
  19. 沃尔玛erp系统功能分析
  20. 微信小程序转发自定义图片

热门文章

  1. 日志log4cxx 封装、实例讲解、配置文件log4cxx.properties
  2. Day39:threading模块、ThreadLocal
  3. 1. 在虚拟机中 添加内容
  4. VB用API实现各种对话框(总结)(转载)
  5. [Leedcode][JAVA][第837题][新21点][动态规划][数学]
  6. 8次c语言上机作业答案,计算机二级C语言上机题库及答案2017
  7. python爬取百度贴吧中的所有邮箱_python写的百度贴吧邮箱采集(带界面)
  8. mysql数据库持续_MySql数据库--持续记录ing
  9. 1284B. New Year and Ascent Sequence
  10. c语言实现NRZ编码,CSC1001-课后笔记