Hi, I'm facing an issue (that seem to be) related to the navigation stack's costmap.
Summary of the problem: The obstacle layer's laser scanner callback is never called with a low publication frequency of the laser scanner. Everything runs fine with a higher publication frequency, although Gazebo publishes at the correct rate.
I'm running ROS Melodic on Ubuntu 18.04 with a simulated Turtlebot 3 Burger in Gazebo. Localization is based on AMCL and for navigation I use move_base. I use to the following resources to spawn the robot: https://github.com/ROBOTIS-GIT/turtlebot3/tree/master/turtlebot3_description/urdf.
If I run the **laser scanner** with the normal frequency at **5 Hz** (`5 `) the **observation buffer** of the costmap is **not updated at all**. If I increase the update rate to **25 Hz everything runs fine** - just as expected.
My first guess was that the laser scanner messages are not published at the right rate or Gazebo can't keep up with the speed. However, `rostopic hz /scan` and `gz topic --hz /scan` tell me that the publication frequency is 5 Hz. Additionally, I compared the timestamps of the scan messages with the values of the `/clock` topic (`/use_sim_time` is true) - there aren't any large deviations. So it looks like like the problem isn't related to Gazebo.
Even with a rather generous `expected_update_rate: 0.50` and a `transforms_tolerance: 0.50` the observation buffer is not updated at all. AMCL runs fine and all the transforms in the transform tree look good. The scan messages are fine as well and correctly displayed in rviz.
So I went ahead, uninstalled the move_base package and reinstalled it from source to check what is happening internally.
I noticed that the `ObstacleLayer::laserScanValidInfCallback` (or any other callback) where the observation buffer is [updated](https://github.com/ros-planning/navigation/blob/9a91c74748debfccd30c650d39e82c580688c174/costmap_2d/plugins/obstacle_layer.cpp#L303) is never called. Hence, `ObservationBuffer::bufferCloud` is not called and `last_updated_` isn't
[updated](https://github.com/ros-planning/navigation/blob/9a91c74748debfccd30c650d39e82c580688c174/costmap_2d/src/observation_buffer.cpp#L185) as well. If the laser scanner publishes messages at 25 Hz the callback is called and I don't encounter the "The /scan observation buffer has not been updated for XY seconds, and it should be updated every XY seconds." warnings. I thought that the map update loop was maybe running too fast but deacreasing the `map_update_rate` didn't help as well.
**So why or how is the callback for the laser scanner messages related to the publication frequency of the sensor?** Did someone encounter this or a similar problem or has an idea where this comes from?
The global costmap is configured to use the map provided from the map server, which is also used by AMCL, as static layer. Additionally, the obstacle layer shall be updated based on new laser scans since there may be new dynamic or non-dynamic obstacles in the environment. The local costmap should do the same with a rolling window. Both costmaps use the inflation layer. With a 25 Hz sensor this works perfectly fine and the Turtlebot reaches its goal.
Here are the parameters I use:
common_costmap.yaml:
obstacle_range: 3.0
raytrace_range: 3.5
transform_tolerance: 0.5
footprint: [[-0.105, -0.105], [-0.105, 0.105], [0.041, 0.105], [0.041, -0.105]]
map_type: costmap
inflation_layer:
inflation_radius: 0.55
obstacle_layer:
observation_sources: base_scan
base_scan: {sensor_frame: scan_frame, data_type: LaserScan, topic: scan, marking: true, clearing: true, expected_update_rate: 0.50, inf_is_valid: true}
#track_unknown_space: true
global_costmap.yaml:
global_costmap:
global_frame: map
robot_base_frame: base_link
update_frequency: 5.0
static_map: true
#width: 80
#height: 80
#origin_x: -40
#origin_y: -40
plugins:
- {name: static_layer, type: "costmap_2d::StaticLayer"}
- {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"}
- {name: inflation_layer, type: "costmap_2d::InflationLayer"}
local_costmap.yaml:
local_costmap:
global_frame: odom
robot_base_frame: base_link
update_frequency: 10.0
static_map: false
rolling_window: true
width: 6.0
height: 6.0
origin_x: -12
origin_y: -12
plugins:
- {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"}
- {name: inflation_layer, type: "costmap_2d::InflationLayer"}
The parameters in the launch file for the move base node look like this:
↧