|
1 | | -# Elevation Mapping CuPy (ROS2) |
| 1 | +# Elevation Mapping CuPy (ROS 2, Jazzy) |
2 | 2 |
|
3 | | - |
| 3 | +This repo contains: |
| 4 | +- `elevation_map_msgs`: message definitions (ament_cmake). |
| 5 | +- `elevation_mapping_cupy`: GPU-accelerated elevation mapping node (Python, CuPy). |
4 | 6 |
|
5 | | -[Documentation](https://leggedrobotics.github.io/elevation_mapping_cupy/) |
| 7 | +## Supported Surface (Regression-Tested) |
6 | 8 |
|
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 | | - |
12 | | - |
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. |
35 | 19 |
|
36 | 20 | ## Requirements |
37 | 21 |
|
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` |
42 | 28 |
|
43 | | -## Installation |
44 | | - |
45 | | -### Clone the Repository |
| 29 | +## Quick Start (Docker, Recommended) |
46 | 30 |
|
47 | 31 | ```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 | + ' |
51 | 53 | ``` |
52 | 54 |
|
53 | | -### Install Dependencies |
| 55 | +## Run (golden path) |
54 | 56 |
|
55 | 57 | ```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 | + ' |
58 | 65 | ``` |
59 | 66 |
|
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) |
61 | 71 |
|
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. |
67 | 74 |
|
68 | | -### Docker (Alternative) |
| 75 | +## Build (native, non-Docker) |
69 | 76 |
|
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). |
71 | 78 |
|
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 | | - |
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) |
98 | 80 |
|
99 | 81 | ```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 |
209 | 85 | ``` |
210 | 86 |
|
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) |
214 | 93 |
|
215 | | -## License |
| 94 | +## Not Supported / Disabled |
216 | 95 |
|
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