Radix is a C++ library for semantic occupancy grid mapping, integrated as a ROS 2 node. It continuously fuses incoming point clouds from rosbag replay or manual insertion into a sparse 3D voxel grid and exposes the live map to downstream applications via ROS 2 services.
Radix is built on top of Bonxai by Davide Faconti, a high-performance sparse voxel grid library that serves as the underlying data structure.
Radix is built from the following modules, listed bottom-up from the core data structure to downstream usage:
- radix_ros2_pkg/bonxai_core — Header-only sparse hierarchical voxel grid Bonxai, the foundational data structure Radix is built on.
- radix_ros2_pkg/radix_map — Core mapping library. Fuses incoming point clouds into the Bonxai grid using Bayesian log-odds occupancy updates and ray-casting for free-space clearing. A key feature of Radix is its behavior-based design: custom mapping logic can be introduced through minimal, well-scoped modifications. Each behavior defines the voxel data layout and insertion logic (e.g. occupancy probability only, geometry statistics, or per-class semantic label distributions).
- radix_ros2_pkg/radix_ros — ROS 2 server node wrapping the above. Subscribes to
/semantic_cloud(sensor data or rosbag replay) per default, continuously builds the occupancy grid, and exposes it via ROS 2 services. - radix_msgs_ros2_pkg — Custom ROS 2 message and service definitions (
Chunk,Render,BirdsEyeView,Save,Load,RayHit, …). These are the communication protocol between the Radix server and any downstream client. - radix_clients — Python client library. Wraps the ROS 2 service calls into simple functions that return numpy arrays for downstream applications.
- radix_examples — Runnable Python scripts demonstrating the full workflow against a live Radix server using a bundled KITTI point cloud snippet (publish cloud, retrieve chunk, render, ray cast).
Requirements: Ubuntu 22.04, ROS 2 Humble, C++17, colcon. For the Docker option, only Docker is required.
Clone the required repositories:
mkdir -p ros2_ws/src
cd ros2_ws/src
git clone https://github.com/ProjectVERUM/radix_ros2_pkg
git clone https://github.com/ProjectVERUM/radix_msgs_ros2_pkgThen build the packages:
cd ros2_ws
colcon build --packages-select radix_ros radix_msgs --symlink-install
source install/setup.bashThe image can be built locally. The resulting image will contain a fully configured ROS 2 Humble environment with Radix (radix_ros2_pkg and radix_msgs_ros2_pkg) and all dependencies pre-installed and ready to use.
To build the image manually, ensure you cloned the required repositories as described above and run from the workspace root:
cd ros2_ws
docker build -f src/radix_ros2_pkg/Dockerfile -t radix_ros2_pkg:latest .Alternatively, pre-built Docker images can be pulled directly from the repository's package registry, e.g.:
docker pull ghcr.io/projectverum/radix_ros2_pkg:latestSource the workspace and launch the server with the desired behavior:
source install/setup.bash
ros2 launch radix_ros radix_basic.launch.py
ros2 launch radix_ros radix_gaussian.launch.py
ros2 launch radix_ros radix_semantic.launch.py
ros2 launch radix_ros radix_icp.launch.pyConfiguration files for each behavior live at:
radix_ros/params/<behavior>/
├── main_params.yaml # core settings: topic names, resolution, occupancy probabilities, …
├── label_params.yaml # semantic label definitions and colors
└── rules.yaml # optional rule-based voxel filtering
Edit main_params.yaml before launching to change, e.g., the input topic or voxel resolution:
cloud_in_topic: /your/sensor/topic # input PointCloud2 topic
resolution: 0.5 # voxel edge length in metersAlternatively, override individual parameters at launch time without editing the file:
ros2 launch radix_ros radix_semantic.launch.py cloud_in_topic:=/your/sensor/topicSimply run the container (defaults to ros2 launch radix_ros radix_semantic.launch.py):
docker run radix_ros2_pkg:latestTo specify a different launch file:
docker run radix_ros2_pkg:latest ros2 launch radix_ros radix_semantic.launch.pyTo use custom parameters, modify the parameter files under radix_ros/params/ and mount the directory into the container:
docker run -t --rm \
--name radix_ros2_pkg \
-v ./radix_ros/params/:/ros2_ws/src/radix_ros2_pkg/radix_ros/params/ \
radix_ros2_pkg:latestMake sure the point cloud topic published by the rosbag matches cloud_in_topic in main_params.yaml (default: /semantic_cloud). If Radix is running and receiving messages, you should see log output confirming that points are being inserted into the occupancy grid.
ros2 bag play <folder_name>Radix re-publishes the voxel grid after every point cloud insertion (publish_on_insert: true by default), which allows live inspection of the map as it is built. Note that publishing on every insertion adds runtime overhead, for large clouds or high-frequency sensors, consider setting publish_on_insert: false instead.
To visualize the voxel grid, open Rviz2:
rviz2Add the topic /radix_point_cloud_centers, set the display type to PointCloud2, style to e.g. Boxes, and set the size to match the voxel resolution (default 0.5 m).
Radix supports four interchangeable behaviors out of the box that determine the voxel type, expected input point cloud format, and map update logic. These behaviors are not fixed, if you need to store different or additional information per voxel (e.g. intensity, timestamp, custom uncertainty), a new behavior can be added with minimal, well-scoped changes: define the voxel data struct, the corresponding point type, and the insertion logic. The existing behaviors serve as ready-to-use templates for this.
| Behavior | Voxel stores | Input point cloud | Use case |
|---|---|---|---|
basic |
Occupancy probability | XYZ only | Lightweight obstacle mapping |
gaussian |
Occupancy + geometry statistics (μ, Σ) | XYZ | Geometry-aware mapping, planarity estimation |
semantic |
Occupancy + per-class label distribution + dominant label | XYZ + semantic label field |
Semantic mapping from labeled sensor data |
icp |
Occupancy + geometry statistics + semantic labels | XYZ + semantic label field |
Semantics-assisted odometry (SOCC-ICP) |
Select the behavior via the launch file or by setting the behavior parameter.
For details on available behaviors and how to use them, see Behaviors.
The Radix server exposes the following ROS 2 services (all under the /radix_server namespace by default). Service request/response fields are defined in radix_msgs_ros2_pkg.
| Service | Type | Description |
|---|---|---|
~/chunk |
radix_msgs/Chunk |
Extract occupied voxels from a bounding box as PointCloud2 |
~/render |
radix_msgs/Render |
Ray-cast render from a camera pose → 4 images |
~/birds_eye_view |
radix_msgs/BirdsEyeView |
Orthographic top-down render → 4 images |
~/save |
radix_msgs/Save |
Save map to file |
~/load |
radix_msgs/Load |
Load map from file |
~/check |
radix_msgs/Check |
Validate voxel integrity around a query point |
~/check_ray_hit |
radix_msgs/RayHit |
Test line-of-sight; returns first hit voxel coordinates |
~/config |
radix_msgs/Config |
Query current server configuration |
~/rules |
radix_msgs/Rules |
Apply rule-based filtering to a bounding box |
~/reset |
std_srvs/Empty |
Clear the entire map |
~/publish |
std_srvs/Empty |
Trigger immediate map publication |
More detailed explanations for each service can be found in ./docs. They can be served locally with mkdocs:
pip install mkdocs==1.6.0 mkdocs-material==9.5.21 jinja2==3.1.4
mkdocs serve # serves on http://127.0.0.1:8000/For the chunk, render, and birds_eye_view services, the level field controls the grid hierarchy at which the operation runs:
| Level | Voxel size | Note |
|---|---|---|
"cell" |
resolution (default) |
Full resolution |
"leaf" |
coarser | Faster, lower detail |
"inner" |
coarsest | Fastest, lowest detail |
Warning: "leaf" and "inner" levels are not fully supported for all services yet.
This repository uses pre-commit to run automated checks.
Install pre-commit:
pip install pre-commitInstall the Git hooks for this repository:
pre-commit installOnce installed, the checks will run automatically on every git commit. Checks can also be run with pre-commit run -a.
Radix is a general-purpose semantic occupancy grid mapping library. The work below demonstrates one concrete application, semantics-assisted LiDAR odometry, for which Radix was adapted and used. It also contains a brief introduction to the library. If you find this repository useful for your research, please consider citing it.
J. Scherer, S. Hirt, H. Meeß, "SOCC-ICP: Semantics-Assisted Odometry based on Occupancy Grids and ICP" arXiv:2605.15074 | IEEE
