This is a collaborative SLAM system. The main input should come from a camera, either monocular, or stereo, or RGB-D. It also supports wheel odometry, IMU and 2D LiDAR data as auxiliary input. The output include the estimated pose of the camera and visualization of the internal map. All inputs and outputs are in standard ROS formats.
There are four components:
- The tracker is a visual SLAM system with support for odometry, inertial and 2D LiDAR input. It estimates the camera pose in real-time, and maintains a local map. It can work as a standalone node. But if the server is online, it will communicate with the server to query and update the map.
- The server maintains the maps and communicates with all trackers. For each new keyframe from a tracker, it detects possible loops, both intra-map and inter-map. Once detected, the server will perform map optimization or map merging, and distribute the updated map to corresponding trackers.
- The msgs package defines the message between server and tracker.
- The slam package that contains the code of the SLAM algorithm.
Refer to this paper for more explanation of the system.
Prepare the target system following the official documentation.
We support Ubuntu 22.04 with ROS 2 Humble and Ubuntu 24.04 with ROS 2 Jazzy.
Building Collaborative SLAM packages requires significant system resources:
- Minimum RAM: 16GB (use
make safe-packagefor memory-constrained systems) - Recommended RAM: 32GB or more (for
make packagewith full parallelism) - Disk Space: ~10GB free space for build artifacts
- CPU: Multi-core processor (4+ cores recommended)
- oneAPI: Intel oneAPI 2025.x (provides
libsycl.so.8) for SYCL/GPU support
Important: Building with SYCL/oneAPI support is memory-intensive. Each parallel compilation job can consume 1-2GB of RAM. On systems with limited memory, use the safe build option to prevent system crashes.
To build debian packages, export ROS_DISTRO env variable to desired platform and run the appropriate build command.
Collaborative SLAM requires Intel oneAPI 2025.x with SYCL 8 (libsycl.so.8) for GPU acceleration support. The build system pulls ORB extractor dependencies from Intel ECI/AMR repositories.
For local development with custom ORB extractor: If you have a locally built ORB extractor with SYCL 8 support, you can use it during the build:
export LOCAL_ORB_PATH=/path/to/orb-extractor
ROS_DISTRO=jazzy make safe-packageThis ensures your local SYCL 8 ORB extractor packages are used instead of repository versions.
For systems with limited memory (16-24GB), use the safe build option that automatically calculates optimal parallel job count:
ROS_DISTRO=jazzy make safe-packageThis prevents memory exhaustion and system crashes by limiting parallelism based on available memory (approximately 2GB per parallel job).
Environment variables:
LOCAL_ORB_PATH- Optional path to local ORB extractor packages (for SYCL 8 development)PARALLEL_JOBS- Optional override for parallel jobs (default: auto-calculated)http_proxy,https_proxy,no_proxy- Proxy configuration for corporate networks
For systems with ample memory, you can use full parallelism:
ROS_DISTRO=humble make packageOr manually specify parallel jobs:
ROS_DISTRO=jazzy PARALLEL_JOBS=8 make safe-packageNote: CI/CD systems typically have sufficient resources and should use make package after SYCL 8-compatible ORB extractor is published to repositories.
After build process successfully finishes, built packages will be available in the <ROS_DISTRO>_cslam_deb_packages/ directory.
You can list all built packages:
$ ls humble_cslam_deb_packages/|grep -i .deb
ros-humble-univloc-msgs_2.0.1-1_amd64.deb
ros-humble-univloc-server_2.0.1-1_amd64.deb
ros-humble-univloc-slam_2.0.1-1_amd64.deb
ros-humble-univloc-tracker_2.0.1-1_amd64.debTo clean all build artifacts:
make cleanWe depend on Eigen, OpenCV and yaml-cpp. They should have already been in your system if you have the full ROS installation. If not, try with sudo apt install libeigen3-dev libopencv-dev libyaml-cpp-dev libsuitesparse-dev.
We also depend on DBoW2, g2o, nlohmann/json and spdlog. They are included in this repo as git submodule, so that you do NOT have to download or install them manually.
If Ubuntu 22.04 with Humble is used, then run
source /opt/ros/humble/setup.bashIf Ubuntu 24.04 with Jazzy is used, then run
source /opt/ros/jazzy/setup.bashImportant: For systems with oneAPI 2025.x, ensure you have the SYCL 8-compatible ORB extractor installed. If you built packages with LOCAL_ORB_PATH, install the local ORB extractor first:
# If using local SYCL 8 ORB extractor
sudo dpkg -i /path/to/orb-extractor/liborb-lze_*.deb
sudo apt --fix-broken install -y # Install any missing dependenciesFinally, install the Debian packages that were built via make package or make safe-package:
sudo apt update
sudo apt install ./$(ROS_DISTRO)_cslam_deb_packages/*.debThere is a set of prepared Makefile targets to speed up the development.
In particular, use the following Makefile target to run code linters.
make lintAlternatively, you can run linters individually.
make lint-bash
make lint-clang
make lint-githubactions
make lint-json
make lint-markdown
make lint-python
make lint-yamlTo run license compliance validation:
make license-checkTo see a full list of available Makefile targets:
$ make help
Target Description
------ -----------
clean Clean up all build artifacts
clean-colcon Clean up Colcon build and test artifacts
clean-debian Clean up Debian packaging artifacts
license-check Perform a REUSE license check using docker container https://hub.docker.com/r/fsfe/reuse
lint Run all sub-linters using super-linter (using linters defined for this repo only)
lint-all Run super-linter over entire repository (auto-detects code to lint)
lint-bash Run Bash linter using super-linter
lint-clang Run clang linter using super-linter
lint-githubactions Run Github Actions linter using super-linter
lint-json Run JSON linter using super-linter
lint-markdown Run Markdown linter using super-linter
lint-python Run Python linter using super-linter
lint-yaml Run YAML linter using super-linter
package Build Debian package
safe-package Build Debian package with memory-safe parallel job limits (recommended for systems with <32GB RAM)
source-package Create source package tarballTo leverage GPU, check this guide for environment setup.
The tracker and server are ROS programs. All the configurations are passed with ROS parameters. Check tracker.launch.py
and server.launch.py for all available parameters and comments.
For ROS2, parameters and launch file are separated and parameters are stored in tracker.yaml.
There are ready-to-use configurations for RealSense D400-Series RGBD camera or the OpenLORIS-Scene dataset (tracker.launch.py), the TUM RGBD dataset (tum_rgbd.launch.py), the EuRoC dataset (euroc_mono.launch.py or euroc_stereo.launch.py), the KITTI dataset (kitti_mono.launch.py or kitti_stereo.launch.py).
Collaborative SLAM currently supports total 4 operating modes, including mapping, localization, remapping and re-localization modes. We provide slam_mode option for the tracker and server_mode option for the server to configure.
The default values of these two options are "mapping" and a mismatch of the tracker and server modes may lead to unpredictable result. Currently, the re-localization mode is more for a developer or debugging use-case.
To support multi-robot or multi-camera or loop closure or map saving, launch univloc_server first; otherwise, only launching univloc_tracker is enough.
# For stereo/rgbd/visual-inertial cases
ros2 launch univloc_server server.launch.py
# For monocular case
ros2 launch univloc_server server.launch.py fix_scale:=falseOn each robot run the tracker node with unique ID:
# remember to replace <if_specific> and <unique_id> with your own setup
ros2 launch univloc_tracker tracker.launch.py camera:=<if_specific> publish_tf:=false queue_size:=0 ID:=<unique_id> rviz:=false gui:=false camera_fps:=30.0If the server is on another machine, choose a domain ID between 0 and 101 (inclusive) and set ROS_DOMAIN_ID for both machines; remember to source environment setup file afterwards. See ros2 official doc for a reference.
The server will publish map elements on the topics of /univloc_server/{keypoints,keyframes}, which can be visualized in RViz.
# Terminal A - run the server
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_server server.launch.py fix_scale:=<mono:false rgbd:true>
# Terminal B - run the tracker for RGBD case
# Please change the value of camera_fps that represents the real FPS of input camera images, the default value is 30.0 if you don't specify it
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_tracker tracker.launch.py camera:=camera get_camera_extrin_from_tf:=false pub_tf_child_frame:=camera_link camera_fps:=30.0
# Terminal B - or run the tracker for monocular case
ros2 launch univloc_tracker tracker.launch.py camera_setup:=Monocular camera:=camera get_camera_extrin_from_tf:=false pub_tf_child_frame:=camera_link camera_fps:=30.0
# Terminal C - start realsense camera
ros2 launch realsense2_camera rs_launch.py align_depth:=true align_depth.enable:=true init_reset:=trueCollaborative SLAM supports the OpenLORIS-Scene Dataset. The ROS bag files for the sequences can be downloaded after filling the form. In order to run the OpenLORIS-Scene dataset in RGBD or monocular case, do the following:
# Terminal A - run the server
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_server server.launch.py fix_scale:=<mono:false rgbd:true>
# Terminal B - run the tracker for RGBD case
source YOUR_COLCON_WS/install/setup.bash
# define an unlimited queue size to make sure every frame is processed
ros2 launch univloc_tracker tracker.launch.py camera:=d400 publish_tf:=false queue_size:=0 camera_fps:=30.0
# Terminal B - or run the tracker for monocular case
ros2 launch univloc_tracker tracker.launch.py camera_setup:=Monocular camera:=d400 publish_tf:=false queue_size:=0 camera_fps:=30.0
# Terminal C - run the ROS bag file
sudo apt install ros-humble-rosbag2-bag-v2-plugins libroscpp-dev libroslz4-dev # install rosbag2_bag_v2 and dependency if you don't have
source /opt/ros/noetic/setup.bash
source /opt/ros/humble/setup.bash
ros2 bag play -s rosbag_v2 OPENLORIS/market1-1.bagCollaborative SLAM supports the TUM RGB-D Dataset. The ROS bag files for the sequences can be downloaded in the detailed description of sequences. Note that the downloaded ROS bag files are compressed,
it can be decompressed using command like rosbag decompress xxx.bag. In order to run the TUM RGB-D dataset in RGBD or monocular case, do the following:
# Terminal A - run the server
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_server server.launch.py fix_scale:=<mono:false rgbd:true>
# Terminal B - run the tracker for RGBD case
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_tracker tum_rgbd.launch.py gui:=false rviz:=false publish_tf:=false log_level:=warning fr<sequence_number>:=true
# Terminal B - or run the tracker for monocular case
ros2 launch univloc_tracker tum_rgbd.launch.py camera_setup:=Monocular gui:=false rviz:=false publish_tf:=false log_level:=warning fr<sequence_number>:=true
# Terminal C - run the ROS bag file
source /opt/ros/noetic/setup.bash
source /opt/ros/humble/setup.bash
ros2 bag play -s rosbag_v2 TUM/rgbd_dataset_freiburg1_floor.bagSupported sequence group: fr1, fr2, fr3.
Collaborative SLAM supports the EuRoC MAV Dataset. The ROS bag files for the sequences can be downloaded in the "ROS bag" section. In order to run the EuRoC dataset in stereo(+imu) or monocular(+imu) case, do the following:
# Terminal A - run the server
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_server server.launch.py fix_scale:=<mono:false stereo/mono-imu/stereo-imu:true> correct_loop:=true
# Terminal B - run the tracker for stereo case
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_tracker euroc_stereo.launch.py camera_setup:=Stereo gui:=false rviz:=false publish_tf:=false log_level:=warning
# Terminal B - or run the tracker for monocular case
ros2 launch univloc_tracker euroc_mono.launch.py gui:=false rviz:=false publish_tf:=false log_level:=warning
# Terminal B - or run the tracker for stereo+imu case
ros2 launch univloc_tracker euroc_stereo.launch.py camera_setup:=Stereo_Inertial gui:=false rviz:=false publish_tf:=false log_level:=warning clean_keyframe:=true
# Terminal B - or run the tracker for monocular+imu case
ros2 launch univloc_tracker euroc_mono.launch.py camera_setup:=Monocular_Inertial gui:=false rviz:=false publish_tf:=false log_level:=warning clean_keyframe:=true
# Terminal C - run the ROS bag file
source /opt/ros/noetic/setup.bash
source /opt/ros/humble/setup.bash
ros2 bag play -s rosbag_v2 EuRoC/V2_01_easy.bagCollaborative SLAM supports the KITTI odometry grayscale dataset. In order to run the KITTI dataset in stereo or monocular case, do the following:
# Terminal A - run the server
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_server server.launch.py fix_scale:=<mono:false stereo:true>
# Terminal B - run the tracker for stereo case
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_tracker kitti_stereo.launch.py camera_setup:=Stereo gui:=false rviz:=false publish_tf:=false log_level:=warning s<sequence_number>:=true
# Terminal B - or run the tracker for monocular case
ros2 launch univloc_tracker kitti_mono.launch.py gui:=false rviz:=false publish_tf:=false log_level:=warning s<sequence_number>:=true
# Terminal C - run the ROS bag file
source /opt/ros/noetic/setup.bash
source /opt/ros/humble/setup.bash
ros2 bag play -s rosbag_v2 kitti_data_odometry_gray_sequence_<sequence_number>.bagSupported sequence group: s00_02, s03, s04_12.
source YOUR_COLCON_WS/install/setup.bash
ros2 launch univloc_tracker tracker.launch.py camera:=d400 publish_tf:=false queue_size:=0 ID:=0 namespace:=robot1 camera_fps:=30.0
# In another terminal:
source /opt/ros/noetic/setup.bash
source /opt/ros/humble/setup.bash
# remap the topics subscribed to by the tracker, to be listed under the specified namespace i.e robot1
ros2 bag play -s rosbag_v2 market1-1-multi.bag --remap /d400/aligned_depth_to_color/image_raw:=/robot1/d400/aligned_depth_to_color/image_raw /d400/color/camera_info:=/robot1/d400/color/camera_info /d400/color/image_raw:=/robot1/d400/color/image_rawTo enable/disable resetting the system if consecutively lost for a specified number of frames.
# Disable resetting (default option)
ros2 launch univloc_tracker tracker.launch.py camera_fps:=30.0
# Enable resetting if consecutively lost for 10 frames
ros2 launch univloc_tracker tracker.launch.py camera_fps:=30.0 num_lost_frames_to_reset:=10-
Disabling resetting the system is the same strategy adopted in OpenVSLAM and it will try to relocalize using the local map after lost, which avoids the generation of multiple trajectory output files.
-
Enabling resetting the system is useful for large-scale scenarios where the robot constantly explores new environments and it is difficult to relocalize using the local map.
Collaborative SLAM, besides mapping, localization and remapping, has a relocalization mode which is used only for
debugging. The map already needs to be created and one can use relocalization mode for a short
sequence to verify if a robot can be relocalized in a specific place on the map. Relocalization mode does
not support publishing tf. Therefore publish_tf parameter needs to be set to false.
Command example can be found below (command used after the area has been mapped):
#Server
ros2 launch univloc_server server.launch.py server_mode:=relocalization fix_scale:=true load_map_path:=/path/to/saved/map/map.msg
#Tracker
ros2 launch univloc_tracker tracker.launch.py publish_tf:=false queue_size:=0 rviz:=false gui:=true slam_mode:=relocalization traj_store_path:=/path/to/saved/map/ map_frame:=map-0 camera_fps:=30.0Collaborative SLAM can generate both a 3D Volumetric Map and a 2D Occupancy Grid (used for navigation) by enabling
Fast Mapping support. By default, Fast Mapping support is disabled, but setting enable_fast_mapping parameter to true
will enable Fast Mapping that will result in the topics map(2D) and fused_map(3D) maps being published.
The parameters for configuring Fast Mapping are present in the tracker.yaml.
If you encounter errors like:
error while loading shared libraries: libsycl.so.7: cannot open shared object file
error while loading shared libraries: libSyclUtils.so: cannot open shared object fileCause: Version mismatch between installed oneAPI (SYCL 8) and packages built against older oneAPI (SYCL 7).
Solution:
-
Verify oneAPI version:
ls -l /opt/intel/oneapi/redist/lib/libsycl.so* # Should show libsycl.so.8 for oneAPI 2025.x
-
Check ORB extractor version:
apt-cache show liborb-lze-dev | grep -E "Version|Depends.*sycl" # Should show version >= 2.3-2 with oneAPI 2025.x dependencies
-
Rebuild packages: If repositories have outdated versions, rebuild with local SYCL 8 ORB extractor:
export LOCAL_ORB_PATH=/path/to/sycl8-orb-extractor ROS_DISTRO=jazzy make safe-package sudo dpkg -i jazzy_cslam_deb_packages/*.deb
-
Verify dependencies: Check installed packages link against correct SYCL version:
ldd /opt/ros/jazzy/lib/univloc_tracker/univloc_tracker_ros | grep sycl # Should show: libsycl.so.8 => /opt/intel/oneapi/redist/lib/libsycl.so.8
If your system freezes or runs out of memory during build:
Solution: Use the safe build option that automatically limits parallelism:
ROS_DISTRO=jazzy make safe-packageOr manually specify fewer parallel jobs:
ROS_DISTRO=jazzy PARALLEL_JOBS=4 make safe-packageIf builds fail with network errors behind proxy:
Solution: Export proxy environment variables before building:
Comprehensive documentation on this component is available here: dev guide.
Additional documentation is placed under docs folder:
- For enabling imu and odometry data, you can refer to use_odometry.md, use_imu.md.
- For localization mode, saving map or trajectory for evaluation, you can refer to geekplus_doc.md.
- For remapping mode, updating pre-constructed keyframe/landmark map and octree map with manual region input from user, you can refer to remapping_mode.md.
collaborative-slam is licensed under Apache 2.0 License.