Skip to content

About

SOTA SONAR Global Descriptor in Underwater SONAR Place Recognition (accepted in ICRA'23)

Resources

Stars

61 stars

Watchers

3 watching

Forks

Latest commit

Β 

History

40 Commits

Folders and files

Repository files navigation

Sonar Context: Imaging Sonar Place Recognition and Localization

Claude Code ready Codex ready CI
pip install sonar-context
Sonar Context SLAM on Aracati 2017: each forward-looking sonar keyframe gets a Sonar Context; revisits are found from it, verified by dense correlation and closed in a pose graph over DISO's sonar odometry, and the sonar mosaic of the marina comes together

[ICRA 2023] Robust Imaging Sonar-based Place Recognition and Localization in Underwater Environments


Underwater there is no GPS and little light; a forward-looking imaging sonar sees 50 m ahead through murky water, but its images are noisy and change with the viewpoint. Sonar Context turns one sonar image into a small, robust place descriptor, so the robot knows it has been here before:

  • 🌊 Sonar Context: the polar sonar image pooled into patches (range rings Γ— bearing sectors), plus a polar key (one value per ring) that does not change with the heading.
  • πŸ” Coarse to fine: the polar key finds candidates in a k-d tree; the Sonar Context compares them over every bearing shift (a rotation) and range shift.
  • ⚑ Lightweight: NumPy or C++17 with Eigen, no GPU and no training.
  • πŸ” Online loop closing: DISO sonar odometry + Sonar Context loops, verified by dense phase correlation, in an iSAM2 pose graph, on ROS 1 and ROS 2.
  • πŸ—ΊοΈ Multi-session SLAM: sessions recorded apart are aligned into one map, LT-SLAM style (guide).
  • πŸ‘₯ Multi-robot: map merging from a few exchanged keyframes (Commerge).

πŸ’Ύ Datasets

The examples use Aracati 2017 (an ROV with a BlueView P900-130 in a marina): the bag (/son, /pose_gt, /cmd_vel) for the SLAM and the polar images (polar_image.zip, stored beams Γ— range: layout="beam_range") for the library. DISO's Aracati2017_DISO (a submodule) adds the dead-reckoning prior. Also: HoloOcean simulation (Google Drive); KRISO data is not public.


πŸ“¦ Installation

pip install sonar-context                 # the library (NumPy, SciPy, Pillow)

Docker

git clone --recursive https://github.com/sparolab/sonar_context.git && cd sonar_context
docker build -f docker/Dockerfile.slam -t sonar-context-slam:noetic .          # ROS 1: DISO + SLAM
docker build -f docker/Dockerfile.slam-ros2 -t sonar-context-slam:humble .     # ROS 2: SLAM

From source

C++ library
sudo apt install libeigen3-dev
cmake -S cpp -B cpp/build && cmake --build cpp/build -j && ctest --test-dir cpp/build

In your project, add_subdirectory(sonar_context/cpp) and link sonar_context::sonar_context. Same distances and shifts as Python (checked in CI).

ROS 1 Noetic / ROS 2 Humble

GTSAM and OpenCV, then applications/slam in a catkin or colcon workspace (keep only the ROS version you build; ROS 1 also needs DISO's dependencies). The Dockerfiles list every step.


πŸš€ Run

# ROS 1: the bag + DISO + Sonar Context SLAM (record:= also writes a bag for ROS 2)
docker run --rm -v <Aracati>:/data:ro -v $PWD/out:/out sonar-context-slam:noetic \
    roslaunch sonar_context_slam aracati2017.launch bag:=/data/ARACATI_2017_8bits_full.bag save_dir:=/out/slam record:=/out/aracati_diso.bag
# ROS 2: the same SLAM on the recorded DISO poses (rosbags-convert the bag first)
docker run --rm -v $PWD/out:/out sonar-context-slam:humble \
    ros2 launch sonar_context_slam aracati2017.launch.py bag:=/out/aracati_diso_ros2 save_dir:=/out/slam_ros2
# Your own odometry: set pose_topic (PoseStamped or Odometry), image_topic and image_layout

Keyframes every 1 m; Sonar Context proposes revisits; each is verified by dense phase correlation of the two sonar frames and closed with iSAM2. On Aracati 2017 (620 m in a marina), the loops bring DISO's sonar odometry from 4.54 m to 1.91 m APE against the DGPS ground truth. Results: applications/slam.

Without ROS:

import sonar_context as sc
desc = sc.sonar_context(image, patch=(4, 4))             # rows = range bins, columns = beams
dist, shift = sc.column_distance(desc_a, desc_b)         # 1 - similarity, best bearing shift
m = sc.SonarContextManager(col_threshold=0.2, exclude_recent=30)
loop = m.update(image)                                   # Loop(query, match, distance, column_shift, ...) or None
sonar-context describe polar_image.zip --layout beam_range --out seq.npz      # descriptors of a sequence
sonar-context loops seq.npz --out loops.csv --poses poses.txt               # online loop detection
sonar-context affinity a.npz b.npz --out affinity.npy                       # two sessions, for Commerge

🧰 Tools

Multi-session SLAM

LT-SLAM style (LT-mapper), as in RadLoc and ReFeree: sessions saved by the SLAM keep their own frames and get one anchor node each; inter-session Sonar Context loops, verified by dense correlation, connect them through the anchors. Aracati 2017 split in two sessions, each in its own frame, comes together at 2.52 m APE. Results: applications/multi-session-slam.

sonar_context_align_sessions session_a/ session_b/ merged/ --threshold 0.25

See the multi-session SLAM guide.

Multi-Robot Map Merging

Each robot keeps its Sonar Contexts; Commerge (IJRR 2026) picks the few keyframes that carry the overlap, and only those are exchanged: on Aracati split into two robots, 4.5 % of the keyframes (2.6 KB of poses) merge the maps within 1.3 m.

Commerge on Aracati 2017 split into two sonar robots

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/sonar_context, read its AGENTS.md, and follow it to build Sonar Context and run its SLAM on Aracati 2017 on this machine. Ask me what you need along the way.

The agent follows AGENTS.md: it builds the Docker images, runs the SLAM on the bag and checks the result.


Citation

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

See bibtex
@inproceedings{kim2023robust,
  title={Robust Imaging Sonar-based Place Recognition and Localization in Underwater Environments},
  author={Kim, Hogyun and Kang, Gilhwan and Jeong, Seokhwan and Ma, Seungjun and Cho, Younggun},
  booktitle={2023 IEEE International Conference on Robotics and Automation (ICRA)},
  pages={1083--1089},
  year={2023},
  organization={IEEE}
}

Contributing

Issues and pull requests are welcome.

Acknowledgements

Sonar Context builds on Scan Context (Kim and Kim, IROS 2018). The SLAM uses DISO (Xu et al., ICRA 2024, GPLv3, a submodule) for odometry and GTSAM. Data: Aracati 2017 (dos Santos et al., RA-L 2022) and HoloOcean (Potokar et al., ICRA 2022); multi-session underwater SLAM: Jang et al., ICRA 2021. Related: SOLiD, Commerge, ReFeree, RadLoc.

Special Thanks

We sincerely thank Giseop Kim for open-sourcing Scan Context, which Sonar Context builds on, and LT-mapper, whose multi-session design our multi-session SLAM follows.

License

BSD 3-Clause for academic use; for any commercial purpose, please contact the authors (hg.kim@inha.edu). DISO (thirdparty/DISO) is GPLv3 and is not part of this license.

About

SOTA SONAR Global Descriptor in Underwater SONAR Place Recognition (accepted in ICRA'23)

Resources

Stars

61 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages