Skip to content

SaxionMechatronics/ar_slam

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ar_slam: GPS-Denied Localization with ArUco Markers and Multi-Camera VIO

A ROS 2 package for drift-free localization in warehouse environments and other GPS-denied spaces. The system combines Odometry data with ArUco/AprilTag marker detection to produce a globally consistent map to odom transform without any active infrastructure (no UWB anchors, no Wi-Fi fingerprinting, no surveying).

The following video is a demo of how this package was used for drone localization in a warehouse. The green path is multi-fisheye-camera VIO output and blue path is the drift-corrected path using AR markers. Upon seeing any of the markers, it does a full history correction using iSAM2 aglorithm from GTSAM library.

Demo


Why This Package?

  • It provides a marker mapping tool based on data recorded from a smart phone, through optimizing a pose-landmark factor graph. This can be an alternative to use of surveying equipment for marker mapping.
  • Modular camera configuration where you can add any number of cameras that are on your robot. The condition is that there should be a single central IMU on the robot and each camera should have a Kalibr-style camera-IMU calibration config (.yaml) file.
  • Support for quad-camera omni-directional setups similar to OmniNxt.

Installation

The system runs inside the D²SLAM Docker container, which bundles all required dependencies (ROS 2 Humble, GTSAM, OpenCV-CUDA, TensorRT, ONNX Runtime, etc.).

1. Clone ar_slam and D²SLAM

cd /path/to/your/workspace
git clone https://github.com/SaxionMechatronics/ar_slam.git
git clone https://github.com/SaxionMechatronics/D2SLAM.git
cd D2SLAM
git checkout ROS2

2. Build the Docker image

cd D2SLAM
docker build -f docker/Dockerfile.ros2_humble -t d2slam:ros2-humble .

The OpenCV CUDA build step might take several minutes.

3. Run the container and volume both D²SLAM and this repo

The container needs two source trees mounted into the same ROS 2 workspace:

xhost +local:docker

docker run -it --rm --runtime=nvidia --gpus all --net=host \
  -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix \
  -v /path/to/D2SLAM:/d2slam_ws/src/d2slam \
  -v /path/to/ar_slam:/d2slam_ws/src/ar_slam \
  -v /path/to/data:/data \
  d2slam:ros2-humble bash

Replace /path/to/D2SLAM, /path/to/ar_slam, and /path/to/data with your actual paths. The ar_slam package is volumed into the same src/ tree so both packages are built together.

4. Install Python dependencies

pip install -r /d2slam_ws/src/ar_slam/requirements.txt

5. Build the workspace

source /opt/ros/humble/setup.bash
cd /d2slam_ws
colcon build --symlink-install --parallel-workers 6 --cmake-args -DCMAKE_BUILD_TYPE=Release
source install/setup.bash

Preparation Phase

Step 1: Print and place markers

Print AprilTag 25H9 (any dictionary supported by opencv's aruco module) markers, measure the physical size of them, and stick them around the environment at arbitrary positions and heights. No surveying or precise placement is required; the mapper will compute their 3D positions automatically.

  • Dictionary: DICT_APRILTAG_25H9
  • Recommended physical size: 25 cm (side length; adjustable in ar_mapper.yaml)
  • Print source: AprilTag 25H9 PDF generator or generate with OpenCV

Place markers, making sure they will be visible from the robot's cameras.

Step 2: Record the environment with a smart phone

Currently, the package supports the data recorded by Record3D iOS app (tested on an iPhone 16 Pro Max) to scan the environment.

  • Settings used:

    Record3D settings
  • Walk the environment in closed loops, visiting each marker multiple times without consecutive order, from different angles and distances.

  • Slow, deliberate movement gives better pose data

  • Export the recording from the Record3D app in .r3d format and transfer the file into the data/ folder of this package:

Step 3: Run the offline mapper (pose-landmark optimization)

The ar_mapper node processes the recording, detects AprilTag markers in each frame, and runs a full pose-landmark factor graph optimisation with GTSAM (Levenberg–Marquardt). Every marker observation from every frame becomes a factor; the optimizer jointly estimates all camera poses and all 3D marker positions, averaging out sensor noise across all the loops you walked.

# Configure the paths in config/ar_mapper.yaml, then:
ros2 launch ar_slam ar_mapper.launch.py

Key parameters (config/ar_mapper.yaml):

Parameter Default Description
recording data/recording.r3d Path to the .r3d file (or pre-extracted directory)
aruco_dict DICT_APRILTAG_36H11 Marker dictionary — must match printed tags
marker_size 0.25 Physical side length in metres
freq_hz 1.0 Temporal sub-sampling of the 60 fps stream
markers_csv_out markers_optimized.csv Output landmark map path

The node publishes a live RViz2 visualization of the optimised marker positions and the reconstruction trajectory. On completion it writes markers_optimized.csv; this is the only file that will be used for online marker-based optimization on the robot.

Upon launching the marker mapper, the results will be displayed in RVIZ similar to the following image. The optimized positions of markers will be saved to markers_optimized.csv. Note that the pose of all markers will subtracted from pose of a marker of choice (id=0 by default). Thus, be careful about how you intend to define the origin of map coordinate system defined by these markers. In our drone localization case, we needed z axis upwards, thus the marker 0 is placed horizontally.

rviz pose marker graph


Robot Deployment Phase

You can use any source of odometry that suits your robot. For our aerial robot, we used D²VINS, which can give us visual-inertial odometry estimation, combining 4 fish-eye cameras.

Step 4: Run D²VINS + ar_localizer on the robot

The ar_localizer node subscribes to the live quadcam image stream and the VIO odometry from D²VINS. It detects AprilTag markers in all four camera sub-images simultaneously, adds marker-pose factors into an online GTSAM iSAM2 factor graph, and publishes a corrected map to odom TF that compensates for VIO drift.

# Terminal 1 — VIO odometry (inside Docker, see Installation section)
ros2 launch d2vins quadcam.launch.py

# Terminal 2 — AR localizer
ros2 launch ar_slam ar_localizer.launch.py

# Terminal 3 — sensor data
ros2 bag play /data/your_sequence.bag

Key parameters (config/ar_localizer.yaml):

Parameter Default Description
landmark_csv markers_optimized.csv Map produced by ar_mapper (Step 3)
camera0 ... An entry for introducing a camera input. You can have multiple camera entries (camera1, camera2, ...). For this entry, you can specify the topic for the camera, the type of the camera (quadcam fisheye, or mono camera), the calibration file for that camera chain, and etc. Note that for quad-cameras used in our implementation, we used the calibration tools provided by OmniNxt.
odom_topic /odom Odometry input

License

See LICENSE for details.

About

A ROS2 package for drift-free localization by fusing Odometry and AR marker detection.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages