ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

" Dynamic " Global Planner ?

asked 2020-11-25 07:48:17 -0600

jchodorowski gravatar image

updated 2020-11-30 04:34:13 -0600

Hi all,

I am using the ROS navigation library on a robot running ROS melodic on debian 9.13

I am using standard Global_Planner and TEB_local_planner.

I observe that the Global_Planner is not able to recalculate a path when the initial path turns out to be impossible. Typically I put a cardboard box in a hallway that it is impossible to bypass. There is an alternate path to the target. But Global_Planner does not reconsider the initial path even when I change target near the obstacle. So I understand the Global_Planner does not take into account the cumulative costs on the global_costmap and the local_costmap? Is it this ? If so, is it possible to reconfigure the navigation so that Global_Planner can offer another path?

Thank you in advance for your help.

Capture video RVIZ is available with this link

The configuration file for Global_Planner is:

  old_navfn_behavior: false 
  use_quadratic: true
  use_dijkstra: true
  use_grid_path: false

  allow_unknown: false

  lethal_cost: 253
  neutral_cost: 50
  cost_factor: 0.9

The configuration file for move_base is:

shutdown_costmaps: false

controller_frequency: 10.0

planner_patience: 5.0

controller_patience: 15.0

conservative_reset_dist: 3.0

planner_frequency: 5.0

oscillation_timeout: 10.0

oscillation_distance: 0.5

holonomic_robot: false

The (updated and working) configuration file comman for both global_costmap and local_costmap is:

footprint: [[-0.24, -0.27], [-0.24, 0.27], [0.24, 0.27], [0.24, -0.27]]
footprint_padding: 0.00

transform_tolerance: 0.2
map_type: costmap

always_send_full_costmap: true

 enabled: true
 obstacle_range: 3.0
 raytrace_range: 4.0
 inflation_radius: 0.2
 track_unknown_space: true
 combination_method: 1

observation_sources: laser_scan_sensor
laser_scan_sensor: {data_type: LaserScan, topic: scanf, marking: true, clearing: true}

  enabled:              true
  cost_scaling_factor:  10.0 
  inflation_radius:     0.5

  enabled:              true
  map_topic:            "/map"

The (updated and working) configuration file for global_costmap is:

  global_frame: map
  robot_base_frame: base_footprint
  update_frequency: 1.0
  publish_frequency: 0.5
  static_map: true

  transform_tolerance: 0.5
    - {name: static_layer,            type: "costmap_2d::StaticLayer"}
    - {name: obstacle_layer,          type: "costmap_2d::VoxelLayer"}
    - {name: inflation_layer,         type: "costmap_2d::InflationLayer"}

  inflation_layer: {cost_scaling_factor: 7.0, enabled: true, inflate_unknown: false,
    inflation_radius: 0.75}

The (updated and working) configuration file for local_costmap is:

  global_frame: map
  robot_base_frame: base_footprint
  update_frequency: 5.0
  publish_frequency: 2.0
  static_map: false
  rolling_window: true
  width: 5.5
  height: 5.5
  resolution: 0.1
  transform_tolerance: 0.5

   - {name: static_layer,        type: "costmap_2d::StaticLayer"}
   - {name: obstacle_layer,      type: "costmap_2d::ObstacleLayer"}
   - {name: inflation_layer,     type: "costmap_2d::InflationLayer"}

  inflation_layer: {cost_scaling_factor: 7.0, enabled: true, inflate_unknown: false,
    inflation_radius: 0.5}
    combination_method: 1
    enabled: true
    footprint_clearing_enabled: true
    max_obstacle_height: 2.0
    observation_sources: scan
    obstacle_range: 3.0
    raytrace_range: 3.5
    scan: {clearing: true, data_type: LaserScan, marking: true, max_obstacle_height: 2.0,
      min_obstacle_height: 0.0, sensor_frame: laser, topic: scanf}

The configuration file for TEB_local_planner is :


 odom_topic: odom

 # Trajectory

 teb_autosize: True
 dt_ref: 0.3
 dt_hysteresis: 0.1
 max_samples: 500
 global_plan_overwrite_orientation: True
 allow_init_with_backwards_motion: False
 max_global_plan_lookahead_dist: 3.0
 global_plan_viapoint_sep: -1
 global_plan_prune_distance: 1
 exact_arc_length: False
 feasibility_check_no_poses: 5
 publish_feedback: False

 # Robot

 max_vel_x: 0.4
 max_vel_x_backwards: 0.2
 max_vel_y: 0.0
 max_vel_theta: 0.3
 acc_lim_x: 0.5
 acc_lim_theta: 1.0
 min_turning_radius: 0.0 # diff-drive robot (can turn on place!)

   type: "point"

 # GoalTolerance

 xy_goal_tolerance: 0.2
 yaw_goal_tolerance: 0.1 ...
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2020-11-25 09:53:22 -0600

tryan gravatar image

Disclaimer: I do not want to request access to your video, so I did not watch it. If it contains important points, please make it readily available. Posting screenshots here could be useful, too, if you're able.

I'm not sure what you mean by "cumulative costs," but the global planner does use all of the costmap (total cost of its layers). Once a planner finds an acceptable path, its job is done unless you ask it to try again. That can happen based on timing or, as in your case, when the planned route becomes impossible.

The first thing to inspect is your move_base configuration file (move_base_params.yaml maybe). There is a planner_frequency parameter, which dictates how often in Hz the move_base node calls the global planner to retry. You may also be interested in recovery_behaviors, which controls how the robot tries to get itself out of trouble (can't find a path at all). The move_base documentation provides more details.

Although I answered your question as stated, I know what you're really after is functional navigation. If the above parameters are set appropriately, then move_base will call the planner until it has exhausted its options. Does the robot perform its recovery behaviors? Are you sure that the "alternate path" is viable and that the planner is able to see and evaluate it?

edit flag offensive delete link more


Thank you for your answer.

Sorry for the inconvenience about the video, I've updated the link and made a test with unconnected browser : the video is at least downloadable. I've updated my post with move_base params as well.

Total cost of all map layers was exactly what I called "cumulative costs", sorry if this term is inadequate.

The recovery behaviors set in move_base launchfile are those :

    <rosparam param="recovery_behaviors">
        [ { name: "aggressive_reset",      type: "clear_costmap_recovery/ClearCostmapRecovery" },
          { name: "geko_recovery_nav",     type: "geko_recovery_nav/GekoRecoveryNav"   } ]

The second one is a very simple move backward or forward, whatever cost less.

I hope you'll be able to have a look on a video, but yes, the "alternate path" is viable, the robot is able to go through it if adequate waypoints are set. What criteria applies to determine if the planner is able to see and evaluate a path ?

jchodorowski gravatar image jchodorowski  ( 2020-11-25 10:14:50 -0600 )edit

The video definitely helped me. Thank you for updating it. Based on that, it looks like the global and local planners still think the path is viable when it isn't. I noticed that the lidar-detected obstacles are not inflated, so it's possible the planner thinks it can squeeze through (between lidar returns?). In costmap configuration files, the obstacles layer is usually before the inflation layer like this:

    - {name: static_layer, type: "costmap_2d::StaticLayer"}
    - {name: obstacles_layer, type: "costmap_2d::VoxelLayer"}
    - {name: inflater_layer, type: "costmap_2d::InflationLayer"}

Can you post your costmap parameters for comparison?

tryan gravatar image tryan  ( 2020-11-25 10:49:47 -0600 )edit

There is a filter on lidar detection. In the video you can observe green points that are filtered points and white points that are all lidar detections. Only green points are used with navigation stack.

I've updated the original post with costmap configuration files

jchodorowski gravatar image jchodorowski  ( 2020-11-26 05:46:02 -0600 )edit

OK, thanks for bearing with me, and sorry I didn't answer your previous question:

What criteria applies to determine if the planner is able to see and evaluate a path ?

I meant that the alternate path is entirely on the cost map, unobstructed, and you could make the robot take that path in some manner (e.g., extra waypoints), which you've already confirmed.

I notice that your global_costmap doesn't have an obstacle_layer. It seems the global planner doesn't know the new obstacle exists. You can check this by turning off the local_costmap display in RViz and seeing that the path looks clear. I recommend adding an obstacle_layer to your global configuration before your inflation_layer.

Also, your local_costmap doesn't have an inflation layer, but if you're happy with how the local planner handles things, that may be fine.

tryan gravatar image tryan  ( 2020-11-26 08:40:36 -0600 )edit

Thank you very much for helping ! I wasn't exhaustive in my params files since there is some common params to both costmaps. I've made some runs in a simulator where I observe the awaited behaviour : when a path is blocked and if there is an alternative path as you defined it, the robot is able to compute a new global path. The difference between simulation and reality is - among others - an introduction of costmap_prohibition_layer. I'll try to find the configuration that works and be back with results here. Again, I am very grateful to you for taking the time to look at this case.

jchodorowski gravatar image jchodorowski  ( 2020-11-26 08:49:31 -0600 )edit

I've added costmap_common_params.yaml and updated global_costmap_params.yaml and local_costmap_params.yaml

In this empirical configuration the global planner makes updates with new paths that is no more going through obstacles.

I'll clean some redundancies and try to find the difference that make the global planner fail.

jchodorowski gravatar image jchodorowski  ( 2020-11-30 04:53:38 -0600 )edit

The global_costmap params used these plugins before:

    - {name: static_layer,            type: "costmap_2d::StaticLayer"}
    - {name: costmap_prohibition_layer,  type: "costmap_prohibition_layer_namespace::CostmapProhibitionLayer"}
    - {name: inflation_layer,         type: "costmap_2d::InflationLayer"}

Now, there's an obstacle layer (instead of the prohibition layer, but you could keep that, too). That is likely why the global planner now plans around new obstacles from sensor data when it did not before..

tryan gravatar image tryan  ( 2020-11-30 07:30:25 -0600 )edit

Thanks for all help provided tyran !

jchodorowski gravatar image jchodorowski  ( 2020-12-03 04:53:34 -0600 )edit

Question Tools



Asked: 2020-11-25 07:48:17 -0600

Seen: 788 times

Last updated: Nov 30 '20