Skip to content
sparolabPublic

About

SOTA Radar Global Localization (accepted in IROS 2026)

Topics

Resources

Stars

11 stars

Watchers

1 watching

Forks

Latest commit

Β 

History

36 Commits

Folders and files

Repository files navigation

RadLoc: Radar-based 3-DoF Global Localization

Claude Code ready Codex ready CI
pip install radloc
RadLoc SLAM on MulRan KAIST_03 (6.25 km): each radar scan becomes a 40-band RadLoc descriptor; revisits are found and registered by phase correlation, the drifting radar odometry is pulled back onto the roads, and the radar map of the campus comes together

[IROS 2026] RadLoc: Radar-based 3-DoF Global Localization via Fast, Robust,
and Lightweight Spatial Descriptor Across Diverse Environmental Scenarios


A radar sees through rain, fog and dust, and RadLoc lets it recognize where it has been and how it is turned, from a single scan:

  • 🧭 Rotation invariant and tiny: forty floats describe a place, one per range band, averaged over azimuth.
  • πŸ” Two-stage search: a k-d tree over the leading range-weighted bands proposes candidates; the full descriptor re-ranks them.
  • 🎯 3-DoF registration without an initial guess: loops are registered by phase correlation, with no correspondences and nothing to initialize.
  • πŸ” Online loop closing: radar odometry + RadLoc loops in an iSAM2 pose graph, on ROS 1 and ROS 2.
  • πŸ—ΊοΈ Multi-session SLAM: sessions from different runs are aligned into one map (guide).
  • πŸ‘₯ Multi-robot: map merging from a few exchanged keyframes (Commerge).

πŸ’Ύ Datasets

The examples use MulRan KAIST_03 (Navtech CIR204 radar, polar scans and xypose.csv ground truth). The odometry reads scans in the Oxford layout; convert MulRan once:

python applications/slam/tools/mulran_to_oxford.py <MulRan>/KAIST_03/polar <out>/KAIST_03/polar   # Oxford layout

dataset:=mulran (0.0596 m per range bin, also Boreas, the default) or dataset:=oxford (0.0432 m, Oxford Radar RobotCar) sets the range resolution; a wrong value scales the whole trajectory.


πŸ“¦ Installation

pip install radloc                                   # the library (NumPy, SciPy, OpenCV)

Docker

docker compose -f docker/docker-compose.yml build                # ROS 2 Humble (radloc:humble)
docker build -f docker/Dockerfile.ros1 -t radloc:noetic .        # ROS 1 Noetic

Datasets are mounted read-only; see docker/README.md for the paths.

From source

C++ library
cmake -S cpp -B cpp/build -DCMAKE_BUILD_TYPE=Release && cmake --build cpp/build -j8
ctest --test-dir cpp/build                  # descriptor, search and registration checks

In your project, add_subdirectory(RadLoc/cpp) and link radloc::radloc (header-only, OpenCV).

ROS 1 Noetic / ROS 2 Humble

PCL and GTSAM 4.2, then the packages under applications/slam in a catkin or colcon workspace (keep only the ROS version you build). The Dockerfiles list every step.


πŸš€ Run

# ROS 2 Humble
ros2 launch radloc_slam radloc_slam.launch.py sequence_dir:=<out>/KAIST_03 save_directory:=$HOME/kaist03 dataset:=mulran
# ROS 1 Noetic
roslaunch radloc_ros radloc_slam.launch sequence_dir:=<out>/KAIST_03 save_directory:=$HOME/kaist03 dataset:=mulran
# Docker
docker compose -f docker/docker-compose.yml run --rm slam        # SEQUENCE_DIR -> SAVE_DIR

Radar odometry (Yeti: Cen features, ORB matching, motion-distorted RANSAC) gives the motion, the feature cloud and the RadLoc descriptor of every scan; the pose-graph node closes loops with RadLoc, registers them by phase correlation and optimizes with iSAM2. The run is saved as a session (optimized_poses_kitti.txt, odom_poses_kitti.txt, keyframe_times.txt, the .g2o graph, descriptors and scans).

On MulRan KAIST_03 (6.25 km), RadLoc loops bring the radar odometry from 71.7 m to 5.4 m mean error, the same on ROS 1 and ROS 2. Results and the trajectory figure: applications/slam.

Without ROS:

radloc describe <out>/KAIST_03/polar --out kaist03.npy     # one descriptor per scan
radloc loops kaist03.npy --out loops.csv --exclude 100    # loop candidates within the run
import radloc
db = radloc.PlaceDatabase()                       # coarse k-d tree on 20 bands, top 10 re-ranked
for scan in scans:                                # polar PNG paths or (range x azimuth) arrays
    db.add(radloc.compute_descriptor(scan))
matches = db.query(radloc.compute_descriptor(query), limit=len(db) - 100)   # [(index, distance), ...]

🧰 Tools

Multi-session SLAM

LT-SLAM style (LT-mapper), as in Sonar Context and ReFeree: each session keeps its own frame and gets an anchor node; inter-session RadLoc loops, registered by phase correlation, connect the sessions through their anchors. KAIST_03 cut in two halves, each in its own frame: the second half lands within 0.75 m (median) of the first. Results: applications/multi-session-slam.

multi_session_node applications/multi-session-slam/config/kaist03_split.yaml     # sessions_dir/{01,02} -> save_directory

See the multi-session SLAM guide.

Multi-Robot Map Merging

Each robot keeps its RadLoc descriptors; Commerge (IJRR 2026) picks the few keyframes that carry the overlap, and only those are exchanged. On KAIST_03 split into two robots (robot B in a frame turned by 60Β°): 27 of 2,344 keyframes exchanged (1.2 %, 2.6 KB of poses), B's frame recovered within 0.05Β°.

Commerge on MulRan KAIST_03 split into two radar robots, with the RadLoc affinity

See applications/multi-robot-slam.


πŸ€– Run with your agent

Open Claude Code or Codex in an empty folder and paste:

Clone https://github.com/sparolab/RadLoc, read its AGENTS.md, and follow it to build RadLoc and run its SLAM on MulRan KAIST_03 on this machine. Ask me what you need along the way.

The agent follows AGENTS.md: it builds the Docker image, converts the scans, runs the SLAM and checks the result.


Citation

If you use RadLoc in your research, please cite our paper.

See bibtex
@inproceedings{kim2026radloc,
  author    = {Kim, Hogyun and Choi, Jiwon and Lee, Jungwoo and Cho, Younggun},
  title     = {RadLoc: Radar-based 3-DoF Global Localization via Fast, Robust, and Lightweight Spatial Descriptor Across Diverse Environmental Scenarios},
  booktitle = {IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS)},
  year      = {2026}
}

Contributing

Issues and pull requests are welcome.

Acknowledgements

The radar odometry is Yeti by Keenan Burnett, with the feature detector of Sarah H. Cen and Paul Newman. RadLoc builds on ReFeree. Related: SOLiD, Commerge, SKiD-SLAM.

Special Thanks

We sincerely thank Giseop Kim for open-sourcing LT-mapper, whose multi-session design and BetweenFactorWithAnchoring (MIT License) our multi-session SLAM follows.

License

BSD 3-Clause. See LICENSE.

About

SOTA Radar Global Localization (accepted in IROS 2026)

Topics

Resources

Stars

11 stars

Watchers

1 watching

Forks

Packages

Contributors

Languages