lidar_slam_ros2
ROS 2 LiDAR SLAM for pointcloud-map authoring, benchmarking, and Autoware-compatible map workflows.
git clone https://github.com/rsasaki0109/lidar_slam_ros2.gitrsasaki0109/lidar_slam_ros2lidarslam_ros2
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.
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.0.
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 output —
pointcloud_map/+map_projector_info.yamlopen directly in Autoware map loaders;verify_autoware_map.pyprintsmap_verify: PASSon 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 —
graph_slam_offline_runner(backend, recorded odometry bag) andscan_matcher_offline_runner(frontend, raw bag) produce byte-identical trajectories, loop edges and submaps; the release gate enforces both. - Globally refined, quality-gated maps — clean-room plane bundle adjustment refines submap poses under holdout-validated quality thresholds (evidence).
- GNSS georeferencing — optional GNSS constraints and projector metadata for real-world coordinates.
- Camera-coloured point-cloud maps — synchronized images are projected onto registered LiDAR scans with calibration-aware, occlusion-resistant 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
Quickstart
Start with Getting Started. The Product Contract defines the maintained surface; see Distribution for installed names and binary-release limits.
Try it with Docker (one command, no build)
mkdir -p "$PWD/lidarslam_output" 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:humble
This runs the 517 MB MID-360 demo with periodic progress and writes lidarslam_output/mid360_demo/.
UID/GID returns it to the Linux user; see Getting Started for other platforms.
Build from source
cd ~/ros2_ws/src git clone --recursive https://github.com/rsasaki0109/lidar_slam_ros2.git cd .. rosdep install --from-paths src --ignore-src -r -y colcon build --symlink-install --cmake-args -DCMAKE_BUILD_TYPE=Release source install/setup.bash
If you cloned without --recursive: git -C src/lidar_slam_ros2 submodule update --init --recursive.
Then run one public dataset end to end — NTU VIRAL tnp_01 (~580 s outdoor bag)
through RKO-LIO + graph_based_slam into an Autoware-loadable map:
cd src/lidar_slam_ros2 bash scripts/download_ntu_viral_tnp01.sh bash scripts/run_autoware_quickstart.sh python3 scripts/verify_autoware_map.py output/.../pointcloud_map
Use your own bag
lidarslam-map run /path/to/rosbag2 --output-dir "$PWD/output/my_map"
One command turns the bag into a complete Autoware map bundle:
pointcloud_map/ tiles, map_projector_info.yaml, and a lanelet2_map.osm
generated from the loop-closed trajectory.
Direct launch commands, required topics, GNSS / IMU pre-integration, and dynamic-object filtering are in docs/workflows.md.
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.
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.
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.
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.154 m (median 0.061) | ≤ 0.30 m |
| RTK-SLAM Construction Hall 1 (indoor, ~741 s) | Livox MID-360 | total-station checkpoints¹ | 0.403 m (median 0.263) | ≤ 0.55 m |
| RTK-SLAM Stadtgarten 2 (outdoor park, ~876 s) | Livox MID-360 | total-station checkpoints¹ | 0.835 m (median 0.327) | report-only² |
| RTK-SLAM Stadtgarten 1 (outdoor park, ~1 km loop) | Livox MID-360 | total-station checkpoints¹ | 1.666 m (median 1.511) | report-only² |
Newer College math-hard (~320 m loop) |
Ouster OS0-128 | prism ground truth | reported separately | ≤ 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:
bash scripts/run_rko_lio_graph_benchmark.sh bash scripts/run_release_readiness_checks.sh --fail-on-profiles
Details and optional MID-360 / production-bundle gates: docs/benchmarking.md.
Degeneracy resilience (fog / tunnels)
Opt-in radar/intensity gates recover fog "clutter-lock" (drift 35.6 → 11.2 m) and self-similar tunnels (reach 98.7 m → ~500 m): docs/degeneracy-guide.md.
Docs
- Getting started: Getting Started · Distribution · Autoware quickstart · Operator workflows · Autoware Foxglove
- Pipelines: Autoware-compatible map authoring
- Benchmarking: Benchmarking and release gate · Comparison
- Project: Product contract · v1.0 readiness · Independent first-map validation · v0.9.0 RC notes · v0.9 roadmap · Contributing · Support · Security · Governance · Changelog · Releasing
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.
more like this
editing-traces
Real world text editing traces for benchmarking CRDT and Rope data structures
CenterNet3D-PyTorch
Unofficial PyTorch implementation of the paper: "CenterNet3D: An Anchor free Object Detector for Autonomous Driving"



