Universal grid map library for mobile robotic mapping
This is a C++ library with ROS interface to manage two-dimensional grid maps with multiple data layers. It is designed for mobile robotic mapping to store data such as elevation, variance, color, friction coefficient, foothold quality, surface normal, traversability etc. It is used in the Robot-Centric Elevation Mapping package designed for rough terrain navigation.
Features:
This is research code, expect that it changes often and any fitness for a particular purpose is disclaimed.
The source code is released under a BSD 3-Clause license.
Author: Péter Fankhauser
Affiliation: ANYbotics
Maintainer: Maximilian Wulf, [email protected], Magnus Gärtner, [email protected]
With contributions by: Simone Arreghini, Tanja Baumann, Jeff Delmerico, Remo Diethelm, Perry Franklin, Magnus Gärtner, Ruben Grandia, Edo Jelavic, Dominic Jud, Ralph Kaestner, Philipp Krüsi, Alex Millane, Daniel Stonier, Elena Stumm, Martin Wermelinger, Christos Zalidis
This projected was initially developed at ETH Zurich (Autonomous Systems Lab & Robotic Systems Lab).
This work is conducted as part of ANYmal Research, a community to advance legged robotics.
If you use this work in an academic context, please cite the following publication:
P. Fankhauser and M. Hutter,
“A Universal Grid Map Library: Implementation and Use Case for Rough Terrain Navigation”,
in Robot Operating System (ROS) – The Complete Reference (Volume 1), A. Koubaa (Ed.), Springer, 2016. (PDF)
@incollection{Fankhauser2016GridMapLibrary,
author = {Fankhauser, P{\'{e}}ter and Hutter, Marco},
booktitle = {Robot Operating System (ROS) – The Complete Reference (Volume 1)},
title = {{A Universal Grid Map Library: Implementation and Use Case for Rough Terrain Navigation}},
chapter = {5},
editor = {Koubaa, Anis},
publisher = {Springer},
year = {2016},
isbn = {978-3-319-26052-5},
doi = {10.1007/978-3-319-26054-9{\_}5},
url = {http://www.springer.com/de/book/9783319260525}
}
These branches are currently maintained:
Pull requests for ROS 1 should target master
.
Pull requests for ROS 2 should target rolling
and will be backported if they do not break ABI.
An introduction to the grid map library including a tutorial is given in this book chapter.
The C++ API is documented here:
To install all packages from the grid map library as Debian packages use
sudo apt-get install ros-$ROS_DISTRO-grid-map
The grid_map_core package depends only on the linear algebra library Eigen.
sudo apt-get install libeigen3-dev
The other packages depend additionally on the ROS standard installation (roscpp, tf, filters, sensor_msgs, nav_msgs, and cv_bridge). Other format specific conversion packages (e.g. grid_map_cv, grid_map_pcl etc.) depend on packages described below in Packages Overview.
To build from source, clone the latest version from this repository into your catkin workspace and compile the package using
cd catkin_ws/src
git clone https://github.com/anybotics/grid_map.git
cd ../
catkin_make
To maximize performance, make sure to build in Release mode. You can specify the build type by setting
catkin_make -DCMAKE_BUILD_TYPE=Release
This repository consists of following packages:
GridMap
class and several helper classes such as the iterators. This package is implemented without ROS dependencies.Additional conversion packages:
Run the unit tests with
catkin_make run_tests_grid_map_core run_tests_grid_map_ros
or
catkin build grid_map --no-deps --verbose --catkin-make-args run_tests
if you are using catkin tools.
The grid_map_demos package contains several demonstration nodes. Use this code to verify your installation of the grid map packages and to get you started with your own usage of the library.
simple_demo demonstrates a simple example for using the grid map library. This ROS node creates a grid map, adds data to it, and publishes it. To see the result in RViz, execute the command
roslaunch grid_map_demos simple_demo.launch
tutorial_demo is an extended demonstration of the library’s functionalities. Launch the tutorial_demo with
roslaunch grid_map_demos tutorial_demo.launch
iterators_demo showcases the usage of the grid map iterators. Launch it with
roslaunch grid_map_demos iterators_demo.launch
image_to_gridmap_demo demonstrates how to convert data from an image to a grid map. Start the demonstration with
roslaunch grid_map_demos image_to_gridmap_demo.launch
grid_map_to_image_demo demonstrates how to save a grid map layer to an image. Start the demonstration with
rosrun grid_map_demos grid_map_to_image_demo _grid_map_topic:=/grid_map _file:=/home/$USER/Desktop/grid_map_image.png
opencv_demo demonstrates map manipulations with help of OpenCV functions. Start the demonstration with
roslaunch grid_map_demos opencv_demo.launch
resolution_change_demo shows how the resolution of a grid map can be changed with help of the OpenCV image scaling methods. The see the results, use
roslaunch grid_map_demos resolution_change_demo.launch
filters_demo uses a chain of ROS Filters to process a grid map. Starting from the elevation of a terrain map, the demo uses several filters to show how to compute surface normals, use inpainting to fill holes, smoothen/blur the map, and use math expressions to detect edges, compute roughness and traversability. The filter chain setup is configured in the filters_demo_filter_chain.yaml
file. Launch the demo with
roslaunch grid_map_demos filters_demo.launch
For more information about grid map filters, see grid_map_filters.
interpolation_demo shows the result of different interpolation methods on the resulting surface. The start the demo, use
roslaunch grid_map_demos interpolation_demo.launch
The user can play with different worlds (surfaces) and different interpolation settings in the interpolation_demo.yaml
file. The visualization displays the ground truth in green and yellow color. The interpolation result is shown in red and purple colors. Also, the demo computes maximal and average interpolation errors, as well as the average time required for a single interpolation query.
Grid map features four different interpolation methods (in order of increasing accuracy and increasing complexity):
For more details check the literature listed in CubicInterpolation.hpp
file.
The grid map library contains various iterators for convenience.
Grid map | Submap | Circle | Line | Polygon |
---|---|---|---|---|
Ellipse | Spiral | |||
Using the iterator in a for
loop is common. For example, iterate over the entire grid map with the GridMapIterator
with
for (grid_map::GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) {
cout << "The value at index " << (*iterator).transpose() << " is " << map.at("layer", *iterator) << endl;
}
The other grid map iterators follow the same form. You can find more examples on how to use the different iterators in the iterators_demo node.
Note: For maximum efficiency when using iterators, it is recommended to locally store direct access to the data layers of the grid map with grid_map::Matrix& data = map["layer"]
outside the for
loop:
grid_map::Matrix& data = map["layer"];
for (GridMapIterator iterator(map); !iterator.isPastEnd(); ++iterator) {
const Index index(*iterator);
cout << "The value at index " << index.transpose() << " is " << data(index(0), index(1)) << endl;
}
You can find a benchmarking of the performance of the iterators in the iterator_benchmark
node of the grid_map_demos
package which can be run with
rosrun grid_map_demos iterator_benchmark
Beware that while iterators are convenient, it is often the cleanest and most efficient to make use of the built-in Eigen methods. Here are some examples:
Setting a constant value to all cells of a layer:
map["layer"].setConstant(3.0);
Adding two layers:
map["sum"] = map["layer_1"] + map["layer_2"];
Scaling a layer:
map["layer"] = 2.0 * map["layer"];
Max. values between two layers:
map["max"] = map["layer_1"].cwiseMax(map["layer_2"]);
Compute the root mean squared error:
map.add("error", (map.get("layer_1") - map.get("layer_2")).cwiseAbs());
unsigned int nCells = map.getSize().prod();
double rootMeanSquaredError = sqrt((map["error"].array().pow(2).sum()) / nCells);
There are two different methods to change the position of the map:
setPosition(...)
: Changes the position of the map without changing data stored in the map. This changes the corresponce between the data and the map frame.
move(...)
:
Relocates the region captured by grid map w.r.t. to the static grid map frame. Use this to move the grid map boundaries
without relocating the grid map data. Takes care of all the data handling, such that the grid map data is stationary in the grid map
frame.
Note: Due to the circular buffer structure, neighbouring indices might not fall close in the map frame.
This assumption only holds for indices obtained by getUnwrappedIndex().
setPosition(...) |
move(...) |
---|---|
This RViz plugin visualizes a grid map layer as 3d surface plot (height map). A separate layer can be chosen as layer for the color information.
This package provides an efficient algorithm to convert an elevation map into a dense 3D signed distance field. Each point in the 3D grid contains the distance to the closest point in the map together with the gradient.
This node subscribes to a topic of type grid_map_msgs/GridMap and publishes messages that can be visualized in RViz. The published topics of the visualizer can be fully configure with a YAML parameter file. Any number of visualizations with different parameters can be added. An example is here for the configuration file of the tutorial_demo.
Point cloud | Vectors | Occupancy grid | Grid cells |
---|---|---|---|
grid_map_topic
(string, default: “/grid_map”)
The name of the grid map topic to be visualized. See below for the description of the visualizers.
/grid_map
(grid_map_msgs/GridMap)
The grid map to visualize.
The published topics are configured with the YAML parameter file. Possible topics are:
point_cloud
(sensor_msgs/PointCloud2)
Shows the grid map as a point cloud. Select which layer to transform as points with the layer
parameter.
name: elevation
type: point_cloud
params:
layer: elevation
flat: false # optional
flat_point_cloud
(sensor_msgs/PointCloud2)
Shows the grid map as a “flat” point cloud, i.e. with all points at the same height z. This is convenient to visualize 2d maps or images (or even video streams) in RViz with help of its Color Transformer
. The parameter height
determines the desired z-position of the flat point cloud.
name: flat_grid
type: flat_point_cloud
params:
height: 0.0
Note: In order to omit points in the flat point cloud from empty/invalid cells, specify the layers which should be checked for validity with setBasicLayers(...)
.
vectors
(visualization_msgs/Marker)
Visualizes vector data of the grid map as visual markers. Specify the layers which hold the x-, y-, and z-components of the vectors with the layer_prefix
parameter. The parameter position_layer
defines the layer to be used as start point of the vectors.
name: surface_normals
type: vectors
params:
layer_prefix: normal_
position_layer: elevation
scale: 0.06
line_width: 0.005
color: 15600153 # red
occupancy_grid
(nav_msgs/OccupancyGrid)
Visualizes a layer of the grid map as occupancy grid. Specify the layer to be visualized with the layer
parameter, and the upper and lower bound with data_min
and data_max
.
name: traversability_grid
type: occupancy_grid
params:
layer: traversability
data_min: -0.15
data_max: 0.15
grid_cells
(nav_msgs/GridCells)
Visualizes a layer of the grid map as grid cells. Specify the layer to be visualized with the layer
parameter, and the upper and lower bounds with lower_threshold
and upper_threshold
.
name: elevation_cells
type: grid_cells
params:
layer: elevation
lower_threshold: -0.08 # optional, default: -inf
upper_threshold: 0.08 # optional, default: inf
region
(visualization_msgs/Marker)
Shows the boundary of the grid map.
name: map_region
type: map_region
params:
color: 3289650
line_width: 0.003
Note: Color values are in RGB form as concatenated integers (for each channel value 0-255). The values can be generated like this as an example for the color green (red: 0, green: 255, blue: 0).
The grid_map_filters package containts several filters which can be applied a grid map to perform computations on the data in the layers. The grid map filters are based on ROS Filters, which means that a chain of filters can be configured as a YAML file. Furthermore, additional filters can be written and made available through the ROS plugin mechanism, such as the InpaintFilter
from the grid_map_cv
package.
Several basic filters are provided in the grid_map_filters package:
gridMapFilters/ThresholdFilter
Set values in the output layer to a specified value if the condition_layer is exceeding either the upper or lower threshold (only one threshold at a time).
name: lower_threshold
type: gridMapFilters/ThresholdFilter
params:
condition_layer: layer_name
output_layer: layer_name
lower_threshold: 0.0 # alternative: upper_threshold
set_to: 0.0 # # Other uses: .nan, .inf
gridMapFilters/MeanInRadiusFilter
Compute for each cell of a layer the mean value inside a radius.
name: mean_in_radius
type: gridMapFilters/MeanInRadiusFilter
params:
input_layer: input
output_layer: output
radius: 0.06 # in m.
gridMapFilters/MedianFillFilter
Compute for each NaN cell of a layer the median (of finites) inside a patch with radius.
Optionally, apply median calculations for values that are already finite, the patch radius for these points is given by existing_value_radius.
Note that the fill computation is only performed if the fill_mask is valid for that point.
name: median
type: gridMapFilters/MedianFillFilter
params:
input_layer: input
output_layer: output
fill_hole_radius: 0.11 # in m.
filter_existing_values: false # Default is false. If enabled it also does a median computation for existing values.
existing_value_radius: 0.2 # in m. Note that this option only has an effect if filter_existing_values is set true.
fill_mask_layer: fill_mask # A layer that is used to compute which areas to fill. If not present in the input it is automatically computed.
debug: false # If enabled, the additional debug_infill_mask_layer is published.
debug_infill_mask_layer: infill_mask # Layer used to visualize the intermediate, sparse-outlier removed fill mask. Only published if debug is enabled.
gridMapFilters/NormalVectorsFilter
Compute the normal vectors of a layer in a map.
name: surface_normals
type: gridMapFilters/NormalVectorsFilter
params:
input_layer: input
output_layers_prefix: normal_vectors_
radius: 0.05
normal_vector_positive_axis: z
gridMapFilters/NormalColorMapFilter
Compute a new color layer based on normal vectors layers.
name: surface_normals
type: gridMapFilters/NormalColorMapFilter
params:
input_layers_prefix: normal_vectors_
output_layer: normal_color
gridMapFilters/MathExpressionFilter
Parse and evaluate a mathematical matrix expression with layers of a grid map. See EigenLab for the documentation of the expressions.
name: math_expression
type: gridMapFilters/MathExpressionFilter
params:
output_layer: output
expression: acos(normal_vectors_z) # Slope.
# expression: abs(elevation - elevation_smooth) # Surface roughness.
# expression: 0.5 * (1.0 - (slope / 0.6)) + 0.5 * (1.0 - (roughness / 0.1)) # Weighted and normalized sum.
gridMapFilters/SlidingWindowMathExpressionFilter
Parse and evaluate a mathematical matrix expression within a sliding window on a layer of a grid map. See EigenLab for the documentation of the expressions.
name: math_expression
type: gridMapFilters/SlidingWindowMathExpressionFilter
params:
input_layer: input
output_layer: output
expression: meanOfFinites(input) # Box blur
# expression: sqrt(sumOfFinites(square(input - meanOfFinites(input))) ./ numberOfFinites(input)) # Standard deviation
# expression: 'sumOfFinites([0,-1,0;-1,5,-1;0,-1,0].*elevation_inpainted)' # Sharpen with kernel matrix
compute_empty_cells: true
edge_handling: crop # options: inside, crop, empty, mean
window_size: 5 # in number of cells (optional, default: 3), make sure to make this compatible with the kernel matrix
# window_length: 0.05 # instead of window_size, in m
gridMapFilters/DuplicationFilter
Duplicate a layer of a grid map.
name: duplicate
type: gridMapFilters/DuplicationFilter
params:
input_layer: input
output_layer: output
gridMapFilters/DeletionFilter
Delete layers from a grid map.
name: delete
type: gridMapFilters/DeletionFilter
params:
layers: [color, score] # List of layers.
Additionally, the grid_map_cv package provides the following filters:
gridMapCv/InpaintFilter
Use OpenCV to inpaint/fill holes in a layer.
name: inpaint
type: gridMapCv/InpaintFilter
params:
input_layer: input
output_layer: output
radius: 0.05 # in m
Kinetic | Melodic | Noetic | |
---|---|---|---|
grid_map | |||
doc |
Please report bugs and request features using the Issue Tracker.