elevation_mapping_cupy builds the robot's map of the ground on the GPU
Elevation Mapping on GPU.
At a glance
- What is it?
- elevation_mapping_cupy is a MIT licensed ROS package from the Legged Robotics group that turns point clouds, images and semantic information into a multi-modal elevation map on the GPU with CuPy, fusing data into per cell layers that plugins then turn into traversability or line detection output. Its releases track ROS 2 Humble and Jazzy, while the quick start instructions in the README still show the ROS 1 catkin workflow.
- Who is it for?
- elevation_mapping_cupy suits a legged robotics or autonomous navigation team that needs a local map of the terrain under the robot, computed fast enough to run in the loop, and that is prepared to maintain a research grade package with pinned dependencies.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 20 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A map of the ground, not a map of the world
The Elevation Mapping CuPy package is described as an advancement in robotic navigation and locomotion. Integrating with the Robot Operating System and using GPU acceleration, the framework enhances point cloud registration and ray casting, which the README presents as important for efficient and accurate robotic movement, particularly in legged robots.
The emphasis is the author's, but the framing is worth understanding on its own terms, because this is not a general mapping stack. An elevation map is a local grid over the ground around the robot, where each cell holds a height and, in the richer version of this system, more than a height. For a legged robot, that is the map that matters, because the robot has to decide where to put its feet, whether a slope is climbable, and whether a step in front of it is an obstacle or a shadow artefact.
That framing explains the feature list. Height drift compensation tackles state estimation drifts that can create mapping artefacts, ensuring a more accurate terrain representation. Visibility cleanup and artefact removal use raycasting methods and an exclusion zone feature to remove virtual artefacts and correctly interpret overhanging obstacles, preventing their misidentification as walls. A learning based traversability filter assesses terrain traversability using local geometry, improving path planning and navigation. And versatile locomotion tools include smoothing filters and plane segmentation for movement across various terrains.
The audience is a robotics researcher or a team building an autonomous machine that has to make terrain decisions at control rate. A team that only wants a SLAM map does not need any of this.
Associate, fuse, then let plugins build the layers
The architecture section describes the data flow precisely enough to be useful, and the flow has three stages.
Input first. The framework takes multi-modal images, shown in purple in the diagram, and multi-modal point clouds, shown in blue. The multi-modal framing is not decoration, it is the difference between the base package and the MEM extension: a plain elevation map needs geometry, a multi-modal one needs the other channels too.
Then association. The data is associated to the cells of the elevation map, which is the step that turns a stream of unstructured points into a grid. The elevation map is a local grid, so a point cloud has to be registered to it, and that registration is where drift and artefacts enter the map.
Then fusion. The associated data is fused with different fusion algorithms into the various layers of the map. A layer is a per cell array of a particular kind of information, and different algorithms produce different layers, which is why a single fixed filter would not be enough.
Finally, post-processing. The map can be post-processed with various custom plugins to generate new layers, for example traversability, or to process a layer for external components, for example line detection.
That plugin step is the design that makes the package extensible. The traversability filter and the plane segmentation are not hard coded behaviours, they are the same kind of thing a user would write, and the framework is built so that adding a layer is a matter of writing a plugin rather than forking the map.
Overhangs and drift are the two artefacts the map has to fight
Two of the key features deserve a closer look, because they are the ones that separate a working elevation map from a plausible one.
The first is height drift compensation. A robot's state estimation drifts, and a height map built on top of a drifting estimate inherits that drift as terrain. The visible symptom is a map with structure that is not there, a slope where the floor is flat, which the README describes as mapping artefacts. Compensation means the map accounts for the drift so the terrain representation stays accurate.
The second is visibility cleanup and artefact removal, and this one is about a specific physical situation. When a sensor sees a table, a wall or an overhang, the ray casting that builds the map has to decide what the free space below that obstacle is. If it is wrong in one direction, the space under the table is filled in and the table becomes a wall. If it is wrong in the other direction, the table is erased and the robot plans into it. The exclusion zone feature is the mechanism for telling those cases apart, and the stated purpose is removing virtual artefacts and correctly interpreting overhanging obstacles so that they are not misidentified as walls.
For a legged robot this is a safety property, not a cosmetic one. A misidentified wall is a robot that stops for no reason; an erased overhang is a robot that walks into furniture.
The third feature, the learning based traversability filter, closes the loop. It assesses traversability using local geometry and turns the geometry into a decision, which is what the elevation map exists to support in the first place.
Traversability, plane segmentation and line detection are all layers
The plugin model means the same repository carries several quite different capabilities, and the repository layout shows how they are separated.
There is an elevation_map_msgs/ directory, which is where the message definitions live, and that separation is not cosmetic, because a message package is what allows another ROS package to read the map's layers without depending on the implementation.
Then there is the elevation_mapping_cupy/ package itself, the plane_segmentation/ directory, and a sensor_processing/ directory. The build instructions confirm the split, because building plane segmentation is a separate command from building the mapping package, and so is building the semantic sensors.
The examples in the README show what each of those optional pieces is for. There is a plain turtlesim example, a semantic pointcloud example for fusing semantics from a multi modal point cloud, a semantic image example for fusing RGB semantics or features from an image, and a plane decomposition example that uses the separately built convex_plane_decomposition_ros package. The plane segmentation is described in the key features as part of the versatile locomotion tools, alongside smoothing filters.
The last of the three features is the one that reads most like a research agenda rather than a feature, and it is worth naming separately, because it is where the package points at its own paper. The multi-modal elevation map framework is described as allowing the integration of diverse data like geometry, semantics and RGB information, and the citing section asks users to cite two papers, the IROS 2022 paper on elevation mapping for locomotion and navigation using GPU, and the IROS 2023 paper on MEM, multi-modal elevation mapping for robotics and learning.
CuPy on the GPU, with a ROS version gap in the instructions
The acceleration story is CuPy, which is why the package is named the way it is. The dependencies confirm the stack. The requirements file lists numpy, scipy, ruamel.yaml, opencv-python, simple-parsing, scikit-image, matplotlib, catkin-tools, networkx and shapely, with the cupy entry itself present but commented out. So CuPy has to be installed separately, and a user who installs the listed requirements and expects the GPU path to work will find it missing.
The pinned versions are also worth a look. scipy is pinned to 1.7, scikit-image to 0.19, networkx to 3.0 and shapely to 1.7.1, and the file is organised with two headings whose contents look transposed, since the block under the heading about requirements without version specifiers contains most of the pins, and the block under the heading about requirements with version specifiers contains only shapely.
The bigger issue is the ROS version. The releases are labelled for ROS 2, with v2.0.0 for ROS 2 Humble, v2.1.0 for ROS 2 Jazzy Latest, and v2.2.0 for ROS 2 Jazzy GPU correctness and throughput. The quick start instructions in the README, however, are written for ROS 1. They use catkin, catkin build, roslaunch and a catkin_ws, and the launch files are named turtlesim_simple_example.launch, which is the ROS 1 launch convention.
That gap is the single most important operational detail for an adopter. The package is on ROS 2, the tutorial is not, and a reader following the README literally on a Jazzy machine will hit the mismatch before anything else.
Install: a catkin workspace or the Docker image
The installation section gives two routes, and the Docker one is the shortest.
The source route is to clone into a catkin workspace:
mkdir -p catkin_ws/src
cd catkin_ws/src
git clone https://github.com/leggedrobotics/elevation_mapping_cupy.gitand then install the dependencies, with the requirements file as the reference.
The Docker route is described as already having all dependencies installed, and running the script pulls the image:
cd docker
./run.shYou can also build locally by running build.sh, and in that case you change IMAGE_NAME in run.sh to elevation_mapping_cupy:latest. The documentation site has a getting started installation page at leggedrobotics.github.io/elevation_mapping_cupy, which is where the fuller instructions live.
The build itself happens inside the container, and the commands show which optional packages are separate:
cd $HOME/catkin_ws
catkin build elevation_mapping_cupy
catkin build convex_plane_decomposition_ros # If you want to use plane segmentation
catkin build semantic_sensor # If you want to use semantic sensorsSo the mapping package is mandatory and the other two are opt in, which matches the plugin model described earlier. The build tooling is catkin and catkin-tools, the latter of which is in the requirements list.
Run the Turtlebot examples and drive it with the keyboard
The examples are launched from a Turtlebot, and every one of them starts by setting the robot model:
export TURTLEBOT3_MODEL=waffle
roslaunch elevation_mapping_cupy turtlesim_simple_example.launchThe semantic variants follow the same shape. Fusing semantics from a multi modal point cloud is turtlesim_semantic_pointcloud_example.launch, and fusing RGB semantics or features from an image is turtlesim_semantic_image_example.launch. Both are run with the same export of TURTLEBOT3_MODEL.
Plane segmentation needs the separately built package first, and then its own launch file:
catkin build convex_plane_decomposition_ros
export TURTLEBOT3_MODEL=waffle
roslaunch elevation_mapping_cupy turtlesim_plane_decomposition_example.launchTo drive the robot, the README says a new terminal window needs to be opened, and then the teleop package is launched:
export TURTLEBOT3_MODEL=waffle
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launchVelocity inputs are sent by pressing the keys a, w, d and x, and pressing s stops the robot completely.
The licence is MIT, the repository is not archived, and the last push was on 2026-10-03, with the most recent release v2.2.0 from 2026-07-20. The one obligation the project states beyond the licence is the citation request, which is worth honouring if your work uses the map, since the two papers describe the method and the multi-modal extension that the code implements.
Editorial conclusion
elevation_mapping_cupy suits a legged robotics or autonomous navigation team that needs a local map of the terrain under the robot, computed fast enough to run in the loop, and that is prepared to maintain a research grade package with pinned dependencies. It does not suit a project that needs a general mapping stack, since the design is aimed at locomotion and traversability rather than at mapping for its own sake, and it is the wrong choice if your ROS version is not one of the ones the releases name. Verify first which ROS distribution your release line targets, since the README's install and run instructions are still written for ROS 1, and install CuPy yourself, because the requirements file leaves it commented out.
Frequently asked questions
What does elevation_mapping_cupy do?
It is a ROS package that builds an elevation map for robotic navigation and locomotion using GPU acceleration with CuPy, enhancing point cloud registration and ray casting. It includes height drift compensation, visibility cleanup for overhanging obstacles, a learning based traversability filter, smoothing filters and plane segmentation, and a multi-modal elevation map framework.
Which ROS versions does elevation_mapping_cupy support?
The releases are labelled for ROS 2, with v2.0.0 for ROS 2 Humble, v2.1.0 for ROS 2 Jazzy Latest and v2.2.0 for ROS 2 Jazzy GPU correctness and throughput. The quick start instructions in the README still use the ROS 1 catkin and roslaunch workflow.
How do I install elevation_mapping_cupy?
Either clone the repository into a catkin_ws/src directory and install the dependencies, or use Docker, where cd docker and ./run.sh pulls an image that already has the dependencies installed. You can also build locally with build.sh by changing IMAGE_NAME in run.sh to elevation_mapping_cupy:latest.
Do I need to install CuPy myself?
Yes. In the requirements file the cupy entry is present but commented out, so the GPU dependency has to be installed separately from the listed requirements, which otherwise cover numpy, scipy, ruamel.yaml, opencv-python, simple-parsing, scikit-image, matplotlib, catkin-tools, networkx and shapely.
Which extra packages do I need for plane segmentation and semantic sensors?
They are separate catkin packages built with catkin build convex_plane_decomposition_ros for plane segmentation and catkin build semantic_sensor for semantic sensors. Only the elevation_mapping_cupy package itself is required for the basic setup.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/leggedrobotics-elevation-mapping-cupy)Was this useful?