move base参数及global planner,local planner设置

Posted yaked19

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了move base参数及global planner,local planner设置相关的知识,希望对你有一定的参考价值。

前言

gmapping建图,然后可以利用建好的图来定位和避障。如果你来做这个任务,会很自然的想到,静态障碍和动态障碍分层处理,这也就是为啥会有,静态层、障碍物层和膨胀层。而让机器人到达目标位置,当前点和目标点之间如何到达,需要一个全局的“天眼”——global_planner,在全局规划的过程中,遇到障碍了,需要局部做调整,因此引入了local planer。

根据官网nav_core这里的描述,ROS1内置三种全局规划算法: global_planner、navfn和carrot planner。

其中navfn是最常见的也是默认的全局规划器,使用的是Dijkstra's算法来计算初始位置和目标位置之间的最短路径。carrot_planner的适用性不强,一般在某些特定的场景较为有效(比如让机器人移动到离障碍物尽可能近的场景)。global_planner可以说是navfn的升级版本,虽然navfn内置有Dijkstra's和A*的两种算法的实现,但是在早期版本中A*算法的实现有些bug未修复,故认为navfn使用的是Dijkstra's算法,而在之后版本的升级中为了兼容老版本,所以保留了navfn但也推出了global_planner,global_planner既提供了Dijkstra's和A*算法的实现,还支持自定义的全局规划器插件,可以说比navfn更为灵活。

实际来看就一种,第二种因为有遗留bug被第一种替代,第三种主要是当目标非常靠近障碍或在障碍里才使用,实际比较少见人配置使用。根据后面搜索还有这两种global planner,感兴趣的可以研究下:

http://wiki.ros.org/dlux_global_planner

https://github.com/ros-planning/navigation_experimental/tree/melodic-devel/sbpl_lattice_planner

总的来说move_base的配置离不开这6个文件,最多也就这几个了。

1. global_costmap & local_costmap共有文件,利用namespace分别加载
    costmap_common_params.yaml
2. global_costmap_params.yaml 全局代价地图的设置 

3. local_costmap_params.yaml 局部代价地图的设置

4. move_base_params.yaml 控制器move_base 本身的设置   

5. global_planner_params.yaml 全局规划器的设置

6. local_planner_params.yaml 局部规划器的设置

move_base.launch

<?xml version="1.0"?>

<launch>
  <!-- Arguments -->
  <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 robot_nav)/param/costmap_common_params.yaml" command="load" ns="global_costmap" />
    <rosparam file="$(find robot_nav)/param/costmap_common_params.yaml" command="load" ns="local_costmap" />
    <rosparam file="$(find robot_nav)/param/local_costmap_params.yaml" command="load" />
    <rosparam file="$(find robot_nav)/param/global_costmap_params.yaml" command="load" />
    <rosparam file="$(find robot_nav)/param/move_base_params.yaml" command="load" />
    <rosparam file="$(find robot_nav)/param/local_planner_params.yaml" command="load" />
    <rosparam file="$(find robot_nav)/param/global_planner_params.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节点时,前四个参数是配置代价地图相关参数,首先加载了costmap_common_params.yaml到global_costmap和local_costmap两个命名空间中,因为该配置文件是一个通用的代价地图配置参数,即local_costmap和global_costmap都需要配置的参数。然后下面的local_costmap_params.yaml是专门为了局部代价地图配置的参数,global_costmap_params.yaml是专门为全局代价地图配置的参数。而后面三个是配置路径规划相关参数。 

一、costmap_common_params.yaml 

#robot_radius: 0.20  
footprint: [[0.22, 0.22], [-0.22, 0.22], [-0.22, -0.22], [0.22, -0.22]] # Real is 0.2

# map_type: voxel # From turtlebot2, 3D map
# map_type: costmap # From turtlebot3, 2D map

obstacle_layer:
  enabled:              true
  obstacle_range: 3.0 # 规划考虑几米内障碍物
  raytrace_range: 3.5 # 实时清除几米内障碍物
  max_obstacle_height:  0.5
  unknown_threshold:    15
  mark_threshold:       0
  combination_method:   1
  track_unknown_space:  true    #true needed for disabling global path planning through unknown space
  origin_z: 0.0
  z_resolution: 0.2
  z_voxels: 2
  publish_voxel_map: false
  observation_sources:  scan 
  scan:
    data_type: LaserScan
    topic: scan
    marking: true
    clearing: true
    min_obstacle_height: 0.05
    max_obstacle_height: 0.5
  

# 膨胀层,用于在障碍物外标记一层危险区域,在路径规划时需要避开该危险区域
inflation_layer:
  enabled:              true
  cost_scaling_factor:  4.0  # 由于在公式中cost_scaling_factor被乘了一个负数,所以增大比例因子反而会降低代价 (default: 10)
  inflation_radius:     0.5  # max. distance from an obstacle at which costs are incurred for planning paths.

static_layer:
  enabled:              true

下面来依次解释下各参数的意义:

  • footprint:每一个坐标代表机器人上的一点,设置机器人的中心为[0,0],根据机器人不同的形状,找到机器人各凸出的坐标点即可,具体可参考下图来设置(如果是圆形底盘机器人,直接设置半径大小即可:例如 robot_radius: 0.5);如果是长方形小车:宽736,长1590

    顺时针:footprint:[[0.795, 0.368], [0.795, -0.368], [-0.795, -0.368], [-0.795, 0.368]]

    五边形:footprint:[[0.795, 0.368], [0.95, 0], [0.795, -0.368], [-0.795, -0.368], [-0.795, 0.368]]

  • map_type: 地图类型,这里为costmap(代价地图)。另一种地图类型为为voxel(体素地图)。这两者之间的区别是前者是世界的2D表示,后者为世界的3D表示。

  • obstacle_layer:配置障碍物图层

    • enabled: 是否启用该层
    • combination_method(default: 1): 只能设置为0或1,用来更新地图上的代价值,一般设置为1;
    • track_unknown_space (default: false): 如果设置为false,那么地图上代价值就只分为致命碰撞和自由区域两种,如果设置为true,那么就分为致命碰撞,自由区域和未知区域三种。意思是说假如该参数设置为false的话,就意味着地图上的未知区域也会被认为是可以自由移动的区域,这样在进行全局路径规划时,可以把一些未探索的未知区域也来参与到路径规划,如果你需要这样的话就将该参数设置为false。不过一般情况未探索的区域不应该当作可以自由移动的区域,因此一般将该参数设置为true;
    • obstacle_range(default: 2.5): 设置机器人检测障碍物的最大范围,意思是说超过该范围的障碍物,并不进行检测,只有靠近到该范围内才把该障碍物当作影响路径规划和移动的障碍物;
    • raytrace_range(default: 3.0): 在机器人移动过程中,实时清除代价地图上的障碍物的最大范围,更新可自由移动的空间数据。假如设置该值为3米,那么就意味着在3米内的障碍物,本来开始时是有的,但是本次检测却没有了,那么就需要在代价地图上来更新,将旧障碍物的空间标记为可以自由移动的空间
    • observation_sources: 设置导航中所使用的传感器,这里可以用逗号形式来区分开很多个传感器,例如激光雷达,碰撞传感器,超声波传感器等,我这里只设置了激光雷达;
      • data_type: 激光雷达数据类型;
      • topic: 该激光雷达发布的话题名;
      • marking: 是否可以使用该传感器来标记障碍物;
      • clearing: 是否可以使用该传感器来清除障碍物标记为自由空间;
      • max_obstacle_height(default: 2.0): 以米为单位插入costmap的任何障碍物的最大高度。此参数应设置为略高于机器人的高度。
      • min_obstacle_height: 传感器读数的最小高度(以米为单位)视为有效。通常设置为地面高度。
  • inflation_layer: 膨胀层,用于在障碍物外标记一层危险区域,在路径规划时需要避开该危险区域

    • enabled: 是否启用该层;

    • cost_scaling_factor(default: 10.0): 膨胀过程中应用到代价值的比例因子,代价地图中到实际障碍物距离在内切圆半径到膨胀半径之间的所有cell可以使用如下公式来计算膨胀代价:

      exp(-1.0 * cost_scaling_factor * (distance_from_obstacle – inscribed_radius)) * (costmap_2d::INSCRIBED_INFLATED_OBSTACLE – 1)

      公式中costmap_2d::INSCRIBED_INFLATED_OBSTACLE目前指定为254,

      注意: 由于在公式中cost_scaling_factor被乘了一个负数,所以增大比例因子反而会降低代价。

    • inflation_radius(default: 0.55): 膨胀半径,膨胀层会把障碍物代价膨胀直到该半径为止,一般将该值设置为机器人底盘的直径大小。

  • Static_layer: 静态地图层,即SLAM中构建的地图层

    • enabled: 是否启用该地图层; 

二、global_costmap_params.yaml 基座标系map

global_costmap:
  global_frame: map
  robot_base_frame: base_link
  update_frequency: 1.0  # 全局地图,通常会设定一个相对较小、在1.0到5.0之间的值。 单位为赫兹
  publish_frequency: 0.5 # 对于静态的全局地图来说,不需要不断发布
  static_map: true
 
  transform_tolerance: 0.5

  plugins:
    - name: static_layer,            type: "costmap_2d::StaticLayer"
    - name: obstacle_layer,          type: "costmap_2d::VoxelLayer"
    - name: inflation_layer,         type: "costmap_2d::InflationLayer"

下面是该全局代价地图配置文件中各参数的意义:

  • global_frame:全局代价地图需要在哪个坐标系下运行;
  • robot_base_frame:在全局代价地图中机器人本体的基坐标系,就是机器人上的根坐标系。通过global_frame和robot_base_frame就可以计算两个坐标系之间的变换,得知机器人在全局坐标系中的坐标了;
  • update_frequency:全局代价地图更新频率(单位:Hz),一般全局代价地图更新频率设置的比较小;
  • publish_frequency:全局代价地图发布的频率(单位:Hz)。
  • static_map:配置是否使用map_server提供的地图来初始化;如果不需要使用已有的地图或者map_server,最好设置为false;
  • rolling_window:是否在机器人移动过程中需要滚动窗口,始终保持机器人在当前窗口中心位置;
  • transform_tolerance:坐标系间的转换可以忍受的最大延时。
  • plugins:在global_costmap中使用下面三个插件来融合三个不同图层,分别是static_layer、obstacle_layer和inflation_layer,合成一个master_layer来进行全局路径规划。 

  三、local_costmap_params.yaml基座标系odom

local_costmap:
  global_frame: odom
  robot_base_frame: base_link
  update_frequency: 10.0   
  publish_frequency: 10.0
  static_map: false
  rolling_window: true
  width: 4.0 
  height: 4.0 
  resolution: 0.05
  transform_tolerance: 0.5
  
  plugins:
   - name: obstacle_layer,      type: "costmap_2d::ObstacleLayer"
   - name: inflation_layer,     type: "costmap_2d::InflationLayer"

下面是详细解释每个参数的意义:

  • global_frame:在局部代价地图中的全局坐标系,一般需要设置为odom_frame;
  • robot_base_frame:机器人本体的基坐标系;
  • update_frequency:局部代价地图的更新频率;
  • publish_frequency:局部代价地图的发布频率;
  • static_map:局部代价地图一般不设置为静态地图,因为需要检测是否在机器人附近有新增的动态障碍物;
  • rolling_window:使用滚动窗口,始终保持机器人在当前局部地图的中心位置;
  • width:滚动窗口的宽度,单位是米;
  • height:滚动窗口的高度,单位是米;
  • resolution:地图的分辨率,该分辨率可以从加载的地图相对应的配置文件中获取到;
  • transform_tolerance:局部代价地图中的坐标系之间转换的最大可忍受延时;
  • plugins:在局部代价地图中,不需要静态地图层,因为我们使用滚动窗口来不断的扫描障碍物,所以就需要融合两层地图(inflation_layer和obstacle_layer)即可,融合后的地图用于进行局部路径规划。 

四、move_base_params.yaml 

move_base - ROS Wiki

这里的参数可以在这里设置,也可以在顶层的launch文件中设置。比如有的时候会见到在launch中指定global或者local planner 。

base_global_planner—— default: navfn/NavfnROS

base_local_planner—— default: base_local_planner/TrajectoryPlannerROS

<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">

    <param name="base_global_planner" value="global_planner/GlobalPlanner" />
    <param name="base_local_planner" value="dwa_local_planner/DWAPlannerROS" />

另一个需要注意的是service: make_plan; 当你只需要规划的路径结果而不需要机器人实际去执行,可以call 这个service去获得。比如你需要一条路径,再用其他的跟踪器去跟踪就可以这么办。

#base_global_planner: navfn/NavfnROS
#base_global_planner: global_planner/GlobalPlanner
#base_local_planner: base_local_planner/TrajectoryPlannerROS
#base_local_planner: dwa_local_planner/DWAPlannerROS
controller_frequency: 10.0  # default 20.0
planner_patience: 5.0
controller_patience: 15.0
conservative_reset_dist: 3.0
recovery_behavior_enabled: true
clearing_rotation_allowed: true
shutdown_costmaps: false
oscillation_timeout: 10.0
oscillation_distance: 0.2
planner_frequency: 5.0

下面是详细解释每个参数的意义:

  • controller_frequency: default: 20.0
  • planner_patience (double, default: 5.0)‎在执行空间清理操作之前,计划程序将等待多长时间(以秒为单位)以尝试找到有效的规划结果。‎
  • controller_patience (double, default: 15.0)
  • conservative_reset_dist (double, default: 3.0) 
  • recovery_behavior_enabled (bool, default: true) ‎是否启用‎‎move_base‎‎的恢复行为以尝试重置空间。‎
  • clearing_rotation_allowed (bool, default: true) ‎确定机器人在尝试重置空间时是否将尝试就地旋转。注意:仅当使用默认恢复行为时,才使用此参数,这意味着用户尚未将 ‎‎recovery_behaviors‎‎ 参数设置为任何自定义。
  • shutdown_costmaps:default: false,当 move_base 处于非活动状态时是否关闭节点的 costmaps
  • oscillation_timeout (double, default: 0.0) ‎在执行恢复行为之前允许振荡的时间(以秒为单位)。值 0.0 对应于无限超时‎
  • oscillation_distance (double, default: 0.5)‎机器人必须移动多远才能被认为是不振荡的。将距离移动到此距离会将计时器计数重置为 ‎‎~oscillation_timeout‎
  • planner_frequency (double, default: 0.0)‎运行全局规划循环的速率(以 Hz 为单位)。如果频率设置为 0.0,则全局规划器将仅在收到新目标或本地规划器报告其路径被阻止时运行

五、global_planner_params.yaml

global_planner - ROS Wiki 官方解释

GlobalPlanner:
  allow_unknown: false  #默认true,是否允许路径穿过未知区域
  default_tolerance: 0.2  #默认0.0,目标容差
  visualize_potential: false #默认false,是否显示从PointCloud2计算得到的势区域
  use_dijkstra: true #默认true,true表示使用dijkstra's否则使用A*
  use_quadratic: true #默认true,true表示使用二次函数近似函数
  use_grid_path: false #默认false,true表示使路径沿栅格边界生成,否则使用梯度下降算法
  old_navfn_behavior: false #默认false,是否复制navfn规划器的结果
  lethal_cost: 253 #默认253,致命代价值
  neutral_cost: 50 #默认50,中等代价值
  cost_factor: 3.0 #默认3.0,代价因子
  publish_potential: true #默认true,是否发布costmap的势函数
  orientation_mode: 0 #默认0,设置点的方向
  orientation_window_size: 1 #默认1,根据orientation_mode指定的位置积分确定窗口方向

下面来依次解释下各参数意义:

  • allow_unknown(default: true): 是否允许规划器规划穿过未知区域的路径,只设计该参数为true还不行,还要在costmap_commons_params.yaml中设置track_unknown_space参数也为false才行。
  • default_tolerance(default: 0.0): 当设置的目的地被障碍物占据时,需要以该参数为半径寻找到最近的点作为新目的地点.
  • visualize_potential(default: false): 是否显示从PointCloud2计算得到的势区域.
  • use_dijkstra(default: true): 如果设置为true,将使用dijkstra算法,否则使用A*算法.
  • use_quadratic(default: true): 如果设置为true,将使用二次函数近似函数,否则使用更加简单的计算方式,这样节省硬件计算资源.
  • use_grid_path(default: false): 如果如果设置为true,则会规划一条沿着网格边界的路径,偏向于直线穿越网格,否则将使用梯度下降算法,路径更为光滑点.
  • old_navfn_behavior(default: false): 若在某些情况下,想让global_planner完全复制navfn的功能,那就设置为true,但是需要注意navfn是非常旧的ROS系统中使用的,现在已经都用global_planner代替navfn了,所以不建议设置为true.
  • lethal_cost(default: 253): 致命代价值
  • neutral_cost(default: 50): 中等代价值
  • cost_factor(default: 3.0): 代价地图与每个代价值相乘的因子
  • publish_potential(default: true): 是否发布costmap的势函数
  • orientation_mode(default: 0): 如何设置每个点的方向(None = 0,Forward = 1,Interpolate = 2,ForwardThenInterpolate = 3,Backward = 4,Leftward = 5,Rightward = 6)
  • orientation_window_size(default: 1): 根据orientation_mode指定的位置积分来得到使用窗口的方向。

典型建议值:

lethal_cost = 253

neutral_cost = 66

cost_factor = 0.55

六、local_planner_params.yaml

这里以常用的DWA 为例,DWA相较于TEB而言参数比较少,含义也很清晰,网上的资源会比较多一些。

dwa_local_planner - ROS Wiki

DWAPlannerROS:

# Robot Configuration Parameters
  max_vel_x: 0.26
  min_vel_x: 0.0

  max_vel_y: 0.0
  min_vel_y: 0.0

# The velocity when robot is moving in a straight line
  max_vel_trans:  0.26
  min_vel_trans:  0.13

  max_vel_theta: 1.82
  min_vel_theta: 0.9

  acc_lim_x: 2.5
  acc_lim_y: 0.0
  acc_lim_theta: 3.2 

# Goal Tolerance Parametes
  xy_goal_tolerance: 0.05
  yaw_goal_tolerance: 0.17
  latch_xy_goal_tolerance: false

# Forward Simulation Parameters
  sim_time: 2.0
  vx_samples: 20
  vy_samples: 0
  vth_samples: 40
  controller_frequency: 10.0

# Trajectory Scoring Parameters
  path_distance_bias: 32.0
  goal_distance_bias: 20.0
  occdist_scale: 0.02
  forward_point_distance: 0.325
  stop_time_buffer: 0.2
  scaling_speed: 0.25
  max_scaling_factor: 0.2

# Oscillation Prevention Parameters
  oscillation_reset_dist: 0.05

# Debugging
  publish_traj_pc : true
  publish_cost_grid_pc: true

以上是关于move base参数及global planner,local planner设置的主要内容,如果未能解决你的问题,请参考以下文章

ROS机器人底盘(14)-move_base(2)

7.1-Move_base 参数调整

gazebo仿真踩坑--rviz中设定机器人的目标位置,move_base后台日志报错

javascript global.moves

11.10-改造ARIA和move_base: action-mode and planning model

MOVE_BASE ERROR