Skip to content

Commit 2e355ee

Browse files
committed
Jazzy: pointcloud-only bring-up + synthetic demo + tests
- Target ROS 2 Jazzy / Ubuntu 24.04 / CUDA (updated Dockerfile) - Remove legacy image/semantic fusion surface; fail loudly on unsupported configs - Add synthetic TF+PointCloud2 demo launch + RViz config - Add/expand regression tests (GPU smoke + launch_testing + save/load services) - Overhaul README and Sphinx docs to match supported surface - Add Docker-based CI workflow; disable heavy plane_segmentation by default
1 parent c51667c commit 2e355ee

File tree

78 files changed

+1650
-4875
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1650
-4875
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Jazzy (Docker)
2+
3+
on:
4+
push:
5+
branches: [ "ros2", "jazzy" ]
6+
pull_request:
7+
branches: [ "main", "ros2", "jazzy" ]
8+
workflow_dispatch:
9+
10+
jobs:
11+
build_test:
12+
# Requires a GPU-capable self-hosted runner with Docker + NVIDIA container runtime.
13+
runs-on: [ self-hosted, Linux, X64 ]
14+
steps:
15+
- uses: actions/checkout@v4
16+
17+
- name: Build Docker image (Jazzy)
18+
run: |
19+
set -euo pipefail
20+
docker build -f docker/Dockerfile.x64 -t elevation_mapping_cupy:jazzy .
21+
22+
- name: Colcon build + test inside container
23+
run: |
24+
set -euo pipefail
25+
26+
WS=/tmp/ros2_ws_emcupy
27+
rm -rf "$WS"
28+
mkdir -p "$WS/src"
29+
cp -a "$GITHUB_WORKSPACE" "$WS/src/elevation_mapping_cupy"
30+
31+
docker run --rm --gpus all --net=host \
32+
-v "$WS":/ws -w /ws elevation_mapping_cupy:jazzy bash -lc '
33+
set -e
34+
source /opt/ros/jazzy/setup.bash
35+
colcon build --symlink-install \
36+
--build-base build_jazzy --install-base install_jazzy \
37+
--packages-select elevation_map_msgs elevation_mapping_cupy \
38+
--packages-ignore-regex "^grid_map.*" \
39+
--event-handlers console_direct+
40+
source install_jazzy/setup.bash
41+
colcon test --packages-select elevation_mapping_cupy \
42+
--build-base build_jazzy --install-base install_jazzy \
43+
--packages-ignore-regex "^grid_map.*" \
44+
--event-handlers console_direct+
45+
colcon test-result --verbose --test-result-base build_jazzy
46+
'
47+

.github/workflows/python-tests.yml

Lines changed: 0 additions & 40 deletions
This file was deleted.

README.md

Lines changed: 72 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -1,217 +1,97 @@
1-
# Elevation Mapping CuPy (ROS2)
1+
# Elevation Mapping CuPy (ROS 2, Jazzy)
22

3-
![python tests](https://github.com/leggedrobotics/elevation_mapping_cupy/actions/workflows/python-tests.yml/badge.svg)
3+
This repo contains:
4+
- `elevation_map_msgs`: message definitions (ament_cmake).
5+
- `elevation_mapping_cupy`: GPU-accelerated elevation mapping node (Python, CuPy).
46

5-
[Documentation](https://leggedrobotics.github.io/elevation_mapping_cupy/)
7+
## Supported Surface (Regression-Tested)
68

7-
## Overview
8-
9-
GPU-accelerated elevation mapping for robotic navigation and locomotion. This package provides real-time terrain mapping using CuPy for GPU acceleration, integrating with ROS2 for point cloud registration, ray casting, and multi-modal sensor fusion.
10-
11-
![screenshot](docs/media/main_repo.png)
12-
![screenshot](docs/media/main_mem.png)
13-
14-
## Branch Information
15-
16-
| Branch | Status | Description |
17-
|--------|--------|-------------|
18-
| `ros2` (this branch) | **Actively maintained** | Python bindings only, core elevation mapping |
19-
| `ros2_cpp` | Work in progress | C++ bindings (external contribution, not currently running) |
20-
| `main` | Legacy | ROS1 version |
21-
22-
## Key Features
23-
24-
- **Height Drift Compensation**: Tackles state estimation drifts that can create mapping artifacts, ensuring more accurate terrain representation.
25-
26-
- **Visibility Cleanup and Artifact Removal**: Raycasting methods and an exclusion zone feature remove virtual artifacts and correctly interpret overhanging obstacles.
27-
28-
- **Learning-based Traversability Filter**: Assesses terrain traversability using local geometry, improving path planning and navigation.
29-
30-
- **Multi-Modal Elevation Map (MEM) Framework**: Seamless integration of geometry, semantics, and RGB information for multi-modal robotic perception.
31-
32-
- **Semantic Layer Support**: Fuse semantic segmentation data from external sources (point clouds or images) into the elevation map using various fusion algorithms.
33-
34-
- **GPU-Enhanced Efficiency**: Rapid processing of large data structures using CuPy, crucial for real-time applications.
9+
We intentionally keep the supported surface small and deterministic:
10+
- PointCloud2 input only (no image/semantic fusion in this repo).
11+
- One “golden path” bring-up:
12+
- Synthetic TF (`map -> base_link`) + synthetic depth-like `PointCloud2`
13+
- `elevation_mapping_node.py` publishes `grid_map_msgs/msg/GridMap`
14+
- RViz config to verify the map shifts correctly with the robot motion
15+
- Menzi config is kept in-tree for Moleworks usage:
16+
- `elevation_mapping.launch.py robot_config:=menzi/base.yaml`
17+
Legacy multi-modal examples (image/semantic fusion, turtlebot pipelines, etc.) were removed from this branch
18+
to keep the bring-up scope tight and regression-tested.
3519

3620
## Requirements
3721

38-
- **ROS2**: Jazzy (recommended)
39-
- **CUDA**: 12.x
40-
- **Python**: 3.10+
41-
- **GPU**: NVIDIA GPU with CUDA support
22+
- ROS 2 Jazzy (Ubuntu 24.04)
23+
- NVIDIA GPU + CUDA (CuPy uses CUDA)
24+
- Python deps not managed by rosdep:
25+
- `cupy-cuda12x`
26+
- `torch` (CUDA build)
27+
- `simple-parsing`
4228

43-
## Installation
44-
45-
### Clone the Repository
29+
## Quick Start (Docker, Recommended)
4630

4731
```bash
48-
mkdir -p ~/ros2_ws/src
49-
cd ~/ros2_ws/src
50-
git clone -b ros2 https://github.com/leggedrobotics/elevation_mapping_cupy.git
32+
cd ~/ros2_ws/src/elevation_mapping_cupy
33+
docker build -f docker/Dockerfile.x64 -t elevation_mapping_cupy:jazzy .
34+
35+
# Build + test in a mounted Jazzy workspace (keeps Jazzy artifacts separate).
36+
# Note: in Moleworks, `ros2_ws/src/grid_map` exists but conflicts with Jazzy binaries.
37+
# We ignore any in-workspace `grid_map*` packages and use /opt/ros/jazzy instead.
38+
docker run --rm --gpus all --net=host \
39+
-v ~/ros2_ws:/ws -w /ws elevation_mapping_cupy:jazzy bash -lc '
40+
set -e
41+
source /opt/ros/jazzy/setup.bash
42+
colcon build --symlink-install \
43+
--build-base build_jazzy --install-base install_jazzy \
44+
--packages-select elevation_map_msgs elevation_mapping_cupy \
45+
--packages-ignore-regex "^grid_map.*"
46+
source install_jazzy/setup.bash
47+
colcon test --packages-select elevation_mapping_cupy \
48+
--build-base build_jazzy --install-base install_jazzy \
49+
--packages-ignore-regex "^grid_map.*" \
50+
--event-handlers console_direct+
51+
colcon test-result --verbose --test-result-base build_jazzy
52+
'
5153
```
5254

53-
### Install Dependencies
55+
## Run (golden path)
5456

5557
```bash
56-
cd ~/ros2_ws
57-
rosdep install --from-paths src --ignore-src -r -y
58+
# Headless:
59+
docker run --rm --gpus all --net=host \
60+
-v ~/ros2_ws:/ws -w /ws elevation_mapping_cupy:jazzy bash -lc '
61+
source /opt/ros/jazzy/setup.bash
62+
source install_jazzy/setup.bash
63+
ros2 launch elevation_mapping_cupy synthetic_depth_demo.launch.py launch_rviz:=false
64+
'
5865
```
5966

60-
### Build
67+
What you should see:
68+
- TF tree contains `map -> base_link`
69+
- RViz shows the GridMap updating on `/elevation_mapping_node/elevation_map`
70+
- As the robot frame moves, the map stays consistent in the world (no axis swap)
6171

62-
```bash
63-
cd ~/ros2_ws
64-
colcon build --packages-select elevation_map_msgs elevation_mapping_cupy
65-
source install/setup.bash
66-
```
72+
Tip: if you run `ros2 topic echo` / tooling from a *second* container, set `FASTDDS_BUILTIN_TRANSPORTS=UDPv4`
73+
to avoid shared-memory transport issues between containers.
6774

68-
### Docker (Alternative)
75+
## Build (native, non-Docker)
6976

70-
A Docker setup is available for easy deployment:
77+
Native install is possible, but you must install the Python CUDA deps yourself (see above).
7178

72-
```bash
73-
cd ~/ros2_ws/src/elevation_mapping_cupy/docker
74-
./run.sh
75-
```
76-
77-
## Usage
78-
79-
### TurtleBot3 Simulation Example
80-
81-
![Elevation map examples](docs/media/turtlebot.png)
82-
83-
```bash
84-
# Terminal 1: Launch elevation mapping with TurtleBot3 simulation
85-
export TURTLEBOT3_MODEL=waffle
86-
ros2 launch elevation_mapping_cupy elevation_mapping_turtle.launch.py
87-
```
88-
89-
```bash
90-
# Terminal 2: Control robot with keyboard
91-
export TURTLEBOT3_MODEL=waffle
92-
ros2 run turtlebot3_teleop teleop_keyboard
93-
```
94-
95-
Use `w`, `a`, `s`, `d`, `x` keys to control the robot.
96-
97-
### Custom Robot Configuration
79+
## Tests (regressions)
9880

9981
```bash
100-
ros2 launch elevation_mapping_cupy elevation_mapping.launch.py robot_config:=<your_config.yaml>
101-
```
102-
103-
Available example configurations in `config/setups/`:
104-
- `turtle_bot/` - TurtleBot3 configurations
105-
- `anymal/` - ANYmal robot configurations
106-
- `menzi/` - Menzi Muck configurations
107-
108-
## Services
109-
110-
The node provides three services for map management:
111-
112-
| Service | Type | Description |
113-
|---------|------|-------------|
114-
| `/elevation_mapping_cupy/save_map` | `grid_map_msgs/srv/ProcessFile` | Save map to rosbag2 file |
115-
| `/elevation_mapping_cupy/load_map` | `grid_map_msgs/srv/ProcessFile` | Load map from rosbag2 file |
116-
| `/elevation_mapping_cupy/masked_replace` | `grid_map_msgs/srv/SetGridMap` | Replace map regions using a mask |
117-
118-
### Service Examples
119-
120-
```bash
121-
# Save current map
122-
ros2 service call /elevation_mapping_cupy/save_map grid_map_msgs/srv/ProcessFile \
123-
"{file_path: '/tmp/elevation_map', topic_name: ''}"
124-
125-
# Load saved map
126-
ros2 service call /elevation_mapping_cupy/load_map grid_map_msgs/srv/ProcessFile \
127-
"{file_path: '/tmp/elevation_map', topic_name: ''}"
128-
```
129-
130-
## Configuration
131-
132-
Configuration is done through YAML files. Key configuration areas:
133-
134-
- **Core parameters**: `config/core/core_param.yaml` - Map resolution, sensor noise, variance settings
135-
- **Plugin configuration**: `config/core/plugin_config.yaml` - Post-processing plugins
136-
- **Robot setups**: `config/setups/<robot>/` - Robot-specific configurations
137-
138-
### Subscribers
139-
140-
Configure point cloud and image inputs:
141-
142-
```yaml
143-
subscribers:
144-
front_cam:
145-
topic_name: '/camera/depth/points'
146-
data_type: 'pointcloud'
147-
channels: ['rgb']
148-
```
149-
150-
### Publishers
151-
152-
Configure output map topics:
153-
154-
```yaml
155-
publishers:
156-
elevation_map:
157-
layers: ['elevation', 'traversability', 'variance']
158-
basic_layers: ['elevation']
159-
fps: 5.0
160-
```
161-
162-
## Plugins
163-
164-
Available post-processing plugins:
165-
166-
- `min_filter` / `max_filter` - Morphological operations
167-
- `smooth_filter` - Smoothing filter
168-
- `inpainting` - Fill missing values
169-
- `erosion` - Morphological erosion
170-
- `robot_centric_elevation` - Robot-centric perspective
171-
- `semantic_filter` - Semantic class visualization
172-
- `semantic_traversability` - Semantic-aware traversability
173-
- `features_pca` - PCA feature visualization
174-
175-
## Citing
176-
177-
If you use Elevation Mapping CuPy, please cite:
178-
179-
**[Elevation Mapping for Locomotion and Navigation using GPU](https://arxiv.org/abs/2204.12876)**
180-
181-
Takahiro Miki, Lorenz Wellhausen, Ruben Grandia, Fabian Jenelten, Timon Homberger, Marco Hutter
182-
183-
```bibtex
184-
@inproceedings{miki2022elevation,
185-
title={Elevation mapping for locomotion and navigation using gpu},
186-
author={Miki, Takahiro and Wellhausen, Lorenz and Grandia, Ruben and Jenelten, Fabian and Homberger, Timon and Hutter, Marco},
187-
booktitle={2022 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
188-
pages={2273--2280},
189-
year={2022},
190-
organization={IEEE}
191-
}
192-
```
193-
194-
If you use multi-modal features (color or semantic layers), please also cite:
195-
196-
**[MEM: Multi-Modal Elevation Mapping for Robotics and Learning](https://arxiv.org/abs/2309.16818v1)**
197-
198-
Gian Erni, Jonas Frey, Takahiro Miki, Matias Mattamala, Marco Hutter
199-
200-
```bibtex
201-
@inproceedings{erni2023mem,
202-
title={MEM: Multi-Modal Elevation Mapping for Robotics and Learning},
203-
author={Erni, Gian and Frey, Jonas and Miki, Takahiro and Mattamala, Matias and Hutter, Marco},
204-
booktitle={2023 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
205-
pages={11011--11018},
206-
year={2023},
207-
organization={IEEE}
208-
}
82+
cd ~/ros2_ws
83+
colcon test --packages-select elevation_mapping_cupy --event-handlers console_direct+
84+
colcon test-result --verbose
20985
```
21086

211-
## Contributing
212-
213-
Contributions are welcome! The semantic fusion infrastructure is available and working - contributions for specific research use cases are appreciated.
87+
The suite includes:
88+
- Pure-python config sanity checks (no ROS1 substitutions, no deprecated keys).
89+
- GPU smoke tests (CuPy + kernel compile + one update step).
90+
- launch_testing integration:
91+
- TF -> map shifting -> GridMap publishing
92+
- save/load services (rosbag2)
21493

215-
## License
94+
## Not Supported / Disabled
21695

217-
MIT License - see [LICENSE](LICENSE) for details.
96+
- Image input and semantic fusion: removed from the supported surface.
97+
- `plane_segmentation/`: disabled by default via `COLCON_IGNORE` (heavy deps, not part of bring-up).

0 commit comments

Comments
 (0)