Skip to content

Latest commit

 

History

1,237 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

lidarslam_ros2

CI License: BSD-2-Clause ROS 2: Humble | Jazzy GitHub stars

Turn a rosbag into a map you can actually drive on.

ROS 2 LiDAR SLAM that outputs an Autoware-compatible map bundle — pointcloud_map/, map_projector_info.yaml, and auto-generated lanelet2. Frontend is RKO-LIO (MIT), backend is graph_based_slam (BSD-2). No GPL components on the default workflow.

Point cloud map built by this stack (Shinjuku demo bag)

Shinjuku point cloud map built from a demo rosbag with this stack — start at the Quickstart. develop is the default branch; current release candidate notes: v0.9.1. 日本語クイックスタート.

Quickstart

Choose your shortest path

Goal Start here Safety and cost boundary
See a verified map, no build Default if unsure: Docker demo Stable v0.9.0-humble; needs Docker; host writes stay in ./lidarslam_output.
Map my own rosbag Own-bag route: lidarslam-map doctor /path/to/rosbag2 Read-only diagnosis first; then lidarslam-map start /path/to/rosbag2 writes a new output.
Build the current candidate or contribute Source quickstart: bash scripts/source_quickstart.sh --dry-run Candidate v0.9.1; needs ROS 2, 8 GiB, and roughly 30 minutes.

Try it with Docker (one command, no build)

docker run --rm -e LIDARSLAM_HOST_UID="$(id -u)" -e LIDARSLAM_HOST_GID="$(id -g)" \
  -v "$PWD/lidarslam_output:/lidarslam_ws/output" \
  ghcr.io/rsasaki0109/lidar_slam_ros2:v0.9.0-humble

Use the latest published stable image (v0.9.0-humble) for the 517 MB MID-360 demo; it writes lidarslam_output/mid360_demo/ and returns ownership via UID/GID. The v0.9.1 release candidate is not published yet; use the source quickstart for that candidate. See Getting Started for other platforms.

Map your own bag (one command after install)

lidarslam-map start /path/to/rosbag2

Not sure where to begin? Run lidarslam-map with no arguments in a terminal; its safe home offers an installation check, the demo, your own bag, or previous sessions. Before finding a bag, run lidarslam-map doctor; it uses no network, writes no files, and prints one recovery action for each missing requirement. start checks sensor setup before writing. See supported inputs and recovery.

Build + verified demo from source (one helper)

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone --recursive https://github.com/rsasaki0109/lidar_slam_ros2.git
cd lidar_slam_ros2
bash scripts/source_quickstart.sh

The helper detects Humble/Jazzy, verifies the exact maintained six-package inventory, installs repository-only dependencies, builds only that list, and runs the verified demo. Use --dry-run or --build-only. Completion prints an absolute lidarslam-map path that auto-activates this build in a fresh terminal—no remembered source install/setup.bash. ROS 2 must be installed. Allow 8 GiB and roughly 30 minutes; see Getting Started and Operator workflows for contracts and contributor tests. Before handoff, run the read-only offline package audit: python3 scripts/check_first_map_verification_package.py --json and continue only on READY.

Use your own bag

For an Ouster, Velodyne, RoboSense, simulated, or another compatible PointCloud2 bag, do not edit this package's launch files or YAML first; run lidarslam-map doctor /path/to/rosbag2, then start detects the inputs, builds a verified map, and opens it. The guided path checks topics, frames, fields, timestamps, a maintained profile, and calibration; unsafe inputs stop with a stable reason code and one next action, while detection alone is not a verified vendor-support or accuracy claim. PointCloud2+Imu, PointCloud2+NavSatFix, and VelodyneScan+Applanix GSOF49 are the maintained input combinations.

lidarslam-map start /path/to/rosbag2

With Docker but no ROS installation, run the same high-level workflow from this checkout; the bag is mounted read-only and all output returns to your user:

bash scripts/docker_map_bag.sh /absolute/path/to/rosbag2

See Docker Own-Bag Map for dry-run, Jazzy, calibration, immutable-image, and private no-write JSON-plan options.

For RKO-LIO profiles, --editable retains deterministic replay input for later loop fixes. A successful run writes Autoware artifacts; lidarslam-map view "$PWD/output/my_map" provides offline 3D review and source-preserving edit plans that lidarslam-map edit applies without extra replay paths. Reopen runs with lidarslam-map sessions, compare two with lidarslam-map compare day1 day2, create a private-by-default issue ZIP with lidarslam-map support day1, prepare a verified first-map report with lidarslam-map support day1 --first-map, or merge visits with lidarslam-map merge day1 day2 --output-dir site_project. For fixed Docker/source output, use lidarslam-map report /path/to/output/mid360_demo --json when the reviewed candidate CLI is installed; the stable-image fallback and attachment boundary are in the first-map validation guide. Automation can use lidarslam-map run; direct launches and filtering are in Operator workflows.

Autoware map loaders rendering a pointcloud_map authored by this stack

Why lidarslam_ros2

Most LiDAR SLAM stacks stop at a trajectory and a point cloud. This one ships the artifacts you need downstream:

  • Autoware-compatible outputpointcloud_map/ + map_projector_info.yaml open directly in Autoware map loaders; verify_autoware_map.py prints map_verify: PASS on every saved bundle.
  • lanelet2 auto-generation — drivable lanelets from the SLAM trajectory, validated for multi-segment Autoware routing.
  • Surveyed ground truth — releases are gated in CI by per-dataset APE thresholds, including total-station checkpoints on a Livox MID-360 (accuracy).
  • Loop closure, GPL-free — opt-in built-in Scan Context, BEV / SOLiD / STD/BTC-style Triangle descriptors, and 3D-BBS verification.
  • Tunnel / fog degeneracy presets — opt-in radar fusion and gravity alignment map a ~500 m self-similar tunnel end-to-end (result, guide).
  • Deterministic offline mapping — backend and frontend offline runners produce byte-identical trajectories, loop edges, and submaps under the release gate.
  • Globally refined, quality-gated maps — clean-room plane bundle adjustment refines submap poses under holdout-validated quality thresholds (evidence).
  • GNSS and camera output — optional georeferencing plus calibration-aware, occlusion-resistant camera colouring.
flowchart LR
    bag(["rosbag2"]) --> rko["RKO-LIO<br/>LiDAR-inertial odometry"]
    rko --> gbs["graph_based_slam<br/>loop closure + graph optimization"]
    gbs --> bundle["Autoware map bundle<br/>pointcloud_map · lanelet2 · projector info"]
Loading

Camera-coloured point-cloud maps

The pipeline registers LiDAR scans with the corrected trajectory, then projects synchronized camera pixels onto that geometry. This RTK-SLAM Construction Hall 1 result follows the full estimated 60 m walking loop.

Camera-coloured SLAM point-cloud map and its estimated trajectory (MP4 · GIF)

K4 has 4.91 M points, 76.66% colour coverage, and 11/11 profile checks passing. Pose-aware dynamic cleaning before K3's camera fusion improves held-out RGB median from 41.17 to 40.54 and planar roughness median from 7.23 to 6.40. See the release-readiness record for paired K3/K4 evidence and limits. The sequence is from RTK-SLAM (CC-BY 4.0); its total-station checkpoints also drive the accuracy gate.

If graph optimization outputs sparse keyframes, the coloured-map pipeline can propagate their corrections onto the dense SLAM pose stream automatically:

python3 tools/colored_map/colored_map_pipeline.py \
  <bag> output/<run>/traj_corrected.tum output/<run>/colored_map \
  --raw-traj output/<run>/traj_raw.tum \
  --extrinsic configs/gaussian_splatting/<lidar_camera_extrinsic>.yaml

The pipeline caches dense_corrected_trajectory.tum and rebuilds stale downstream artifacts; use --force-trajectory for an explicit refresh. Moving rigs can add --refine-spatiotemporal-calibration; see the held-out-gated design and RTK-SLAM result.

Cross-repository SLAM benchmark

public_suite_v1.yaml connects Localization Zoo trajectories to trajectory, geometry, real-RGB, runtime, and memory gates, with frozen OFF/ON candidate promotion across MID-360, HILTI, and RTK-SLAM surveyed references. Commands, replay, and adoption records: Benchmarking and release gate.

Open-source benchmark results

On the same HILTI 2022 exp04 LiDAR/IMU input and CPU-only host, the competitive profile recorded 34.7% lower median APE RMSE than GLIM over three completed historical runs:

System Median APE RMSE Median processing RTF Maximum peak RSS
lidarslam_ros2 0.0565 m 0.993 586.83 MB
GLIM CPU 0.0866 m 0.244 690.88 MB

This is a scoped HILTI exp04 trajectory-accuracy and peak-memory win; GLIM wins runtime. It is not an overall-SOTA claim. Normal development needs only one new run:

python3 scripts/run_ours_competitive_benchmark.py \
  --bag <hilti-exp04-ros2-bag> \
  --reference-tum <common-six-checkpoints.tum> \
  --reference-meta <common-six-checkpoints.json> \
  --rko-param configs/hilti2022/rko_lio_hilti2022_pandar_competitive_v2.yaml \
  --lidarslam-param configs/hilti2022/lidarslam_competitive_v2.yaml \
  --output output/hilti_exp04_ours_n1 --runs 1

The GLIM CPU counterpart is:

python3 scripts/run_glim_benchmark.py \
  --bag <hilti-exp04-ros2-bag> \
  --output output/hilti_exp04_glim_n1 --runs 1

Exact scoring rules, revisions, checkpoint policy, and map-quality limitations are in Comparison.

In a separate n=1 development measurement, task-local correspondence reduction kept the 1,258-pose frontend trajectory byte-identical while mean ICP time moved from 21.60 ms to 20.92 ms and frontend wall time from 47.51 s to 46.55 s. These timing deltas are directional optimization evidence; see the SOTA product development plan.

Tunnel and fog mapping without degeneracy collapse

On the ~500 m self-similar Fyllingsdalen tunnel from the NTNU LiDAR degeneracy datasets, the plain frontend covers 98.7 m before along-axis degeneracy freezes it. The opt-in presets (radar ego-velocity fusion + sliding-window gravity alignment) map the whole tunnel — reach 504.5 m, transverse RMS 1.34 m, end-height −4.7 m (−33 m without gravity alignment) — and cut fog clutter-lock drift 35.6 → 9.6 m, with defaults unchanged (a MID-360 driving holdout stays byte-identical). Symptom table: Degeneracy Resilience Guide; evidence: research note.

NTNU tunnel SLAM map: top view and gravity-alignment before/after side view

Accuracy

Current numbers from the release-gate profiles (scripts/release_profiles.yaml). The pre-release gate rejects missing evidence and regressions in every blocking profile.

Dataset Sensor Reference APE RMSE Gate (pass)
NTU VIRAL tnp_01 (outdoor, ~580 s) Ouster OS1-16 + VN-100 Leica prism ground truth 0.95 m (best 0.87) ≤ 1.00 m
RTK-SLAM Construction Hall 2 (indoor, ~600 s) Livox MID-360 total-station checkpoints¹ 0.086 m (median 0.064, 16/16) ≤ 0.30 m
RTK-SLAM Construction Hall 1 (indoor, ~741 s) Livox MID-360 total-station checkpoints¹ 0.321 m (median 0.163, 16/16) ≤ 0.55 m
RTK-SLAM Stadtgarten 2 (outdoor park, ~876 s) Livox MID-360 total-station checkpoints¹ 0.426 m (median 0.264, 19/19) report-only²
RTK-SLAM Stadtgarten 1 (outdoor park, ~1 km loop) Livox MID-360 total-station checkpoints¹ 0.838 m (median 0.511, 36/36) report-only²
Newer College Maths-Hard (~320 m loop) Ouster OS0-128 ICP registration to survey-grade map candidate evidence required locally ≤ 0.10 m

¹ Surveyed checkpoints from the public RTK-SLAM dataset (CC-BY 4.0), scored like its published baselines (dense odometry trajectory). ² Outdoor profiles soak as report-only before graduating; the former GLIM cross-validation gate is also report-only since v0.5. Methodology and caveats: docs/comparison.md.

Reproduce locally:

python3 scripts/download_rtk_slam_dataset.py --sequence construction_seq2 --eval-assets
python3 scripts/run_rtk_slam_accuracy_suite.py

Details and optional MID-360 / production-bundle gates: docs/benchmarking.md.

Docs

Preview the doc site locally: python3 -m mkdocs serve.

Support and license

ROS 2 distro Ubuntu Scope
Humble 22.04 default workflow build + package tests in CI
Jazzy 24.04 default workflow build + package tests in CI; Autoware dogfood exercised locally

graph_based_slam is BSD-2-Clause; RKO-LIO, DLIO, and the optional vendored 3D-BBS are MIT; FAST_GICP is BSD-3-Clause; built-in Scan Context is local. GPL-only components (Thirdparty/lio-sam, Thirdparty/3d_bbs) are excluded via COLCON_IGNORE.

Quality gates

bash scripts/run_default_ci_checks.sh
bash scripts/run_release_readiness_checks.sh --fail-on-profiles
python3 scripts/check_v1_readiness.py
python3 scripts/check_ndt_omp_release_readiness.py --offline

Reference commands and parameter pointers live in docs/workflows.md.

If this project saves you mapping time, a ⭐ helps others find it.

About

ROS 2 LiDAR SLAM for pointcloud-map authoring, benchmarking, and Autoware-compatible map workflows.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

846 stars

Watchers

12 watching

Forks

Releases

Packages

Used by

Contributors

Languages