Library / SDK
gaoxiang12/lightning-lm avatar
gaoxiang12/lightning-lm

lightning-lm: lidar mapping and localization with efficient CPU use

Lidar Localization and Mapping

1,675 stars343 forksC++License varies

At a glance

What is it?
Lightning-LM is a ROS 2 SLAM and localization module that keeps mapping, loop closure and localization in a single process, with the state vector cut from 23 to 12 dimensions in the 2026.4.2 release. Offline and online are the same code with a different entry point, and GPS geoinformation is still marked TODO.
Who is it for?
Consider lightning-lm if you run ROS 2 on Ubuntu and want CPU-based mapping and localization, with online localization reported at 0.8 cores and mapping at 1.2 cores on a 32-line LiDAR. Do not adopt it expecting georeferenced output or fused vehicle odometry, because GPS association and odometry input are listed as TODO rather than implemented.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two features are on the list, and they are not done

The feature list uses status markers, and two of the thirteen entries carry TODO rather than done: GPS geoinformation association and vehicle odometry input.

That is worth internalising before you read the rest, because the rest is genuinely complete. Done items include full 3D lidar SLAM with the AA-FasterLIO front-end, real-time loop closure detection with back-end correction, smooth high-precision 3D lidar localization, dynamic loading of map partitions for large-scale scenes, a 100Hz high-frequency IMU smooth output, a lightweight optimisation library named miao, and both offline and online verification schemes.

The distinction matters for two different projects. If you need your pose tied to a geographic frame, this module will not give it to you. If you have vehicle odometry from a wheel encoder or a separate estimator and want it fused, there is no input path for it yet.

Everything else on the list is a building block you would otherwise write yourself, which is what makes the two gaps conspicuous rather than fatal.

The state vector went from 23 dimensions to 12

The 2026.4.2 entry contains the most consequential line in the update log, and it is a design change rather than a fix.

The structure and dimensions of the state variables were adjusted, so that `ba`, `grav`, `offset_R` and `offset_t` no longer need to be estimated online, reducing the state vector to 12 dimensions from 23. Fewer dimensions means fewer Jacobians, a smaller covariance matrix and less to go wrong numerically in an extended state Kalman filter, which is where those quantities live.

The same release added a correction scale for laser localization so that localization is based on LIO prediction, explicitly to prevent large laser jumps. It also switched localization to using LIO keyframes for map-to-map registration, adjusted the ESKF interface to accommodate point-to-point ICP since that has different dimensions from point-plane ICP, and added point-to-point ICP error to the LaserMapping module with multithreaded acceleration.

The Kalman filter work is listed separately and is the kind of detail that only matters when something has gone wrong: symmetrization of the P matrix, protection of minimum values, and a set of tricks added to the ESKF module.

The release also reports significantly improved stability for mapping and localization, adapted to multi-floor data raised in issues and to data provided by Deep Robotics, with tuned parameters for several Deep Robotics datasets.

A height constraint you must know when to switch off

The 2025.11.13 entry added a global height constraint configured in `loop_closing.with_height`, and the README is unusually clear about when to leave it alone.

If it is set true, lightning-lm keeps the output map at the same height to avoid Z-axis drift in large scenes. It should not be set if you are using lightning-lm in scenes that have multi-floor or stairs structures.

That is a configuration flag with a genuine footgun. In a single-floor building, drift correction is what you want. In a multi-floor building, the same constraint is exactly wrong, because the floors are supposed to differ in height, and forcing them onto one plane corrupts the map. The 2026.4.2 release subsequently added adaptation to multi-floor data, and a related option makes localization use a fixed map height when one was set during mapping, disabled by default.

Two other configuration entries from the same period follow the same pattern. The `try_self_extrap` option in the localization module is disabled by default, because when disabled the localization module does not use its own extrapolated pose, and the reasoning given is that the localization interval is large and its extrapolated pose can be inaccurate when the vehicle moves significantly.

A configuration file for Livox was added too, since that hardware is widely used.

One core, and the two ways to run it

The performance claim is stated concretely enough to check against your own hardware: all the listed features can run using less than one CPU core on the pure CPU side, with online localization at 0.8 cores and mapping at 1.2 cores on a 32-line LiDAR without UI.

Note the arithmetic that implies. Mapping at 1.2 cores is above one core, so the less-than-one-core statement describes the CPU side of a multi-threaded pipeline rather than a strict single-core guarantee for every mode. The 0.8 figure for online localization is the one to hold on to, since that is the mode running on a robot.

The run modes are the same binaries with different entry points, which keeps the configuration surface small. Offline programs suit scenarios with recorded data packets, for quickly obtaining mapping or localization results. Online programs suit scenarios with actual sensors, for real-time results.

bash
ros2 run lightning run_slam_offline --input_bag ~/data/NCLT/20130110/20130110.db3 --config ./config/default_nclt.yaml

To use the online version, change the offline part to online, which gives `run_slam_online`.

bash
ros2 run lightning run_slam_online --config ./config/default_nclt.yaml

The package name in the ROS 2 namespace is lightning.

Ubuntu 22.04, ROS 2 Humble, and colcon

The build environment is specific. Ubuntu 22.04 or higher; Ubuntu 20.04 should also work but is not tested.

The dependencies are a ROS 2 stack plus a rendering and logging set: ros2 humble or above, Pangolin for visualization, which the README points at under thirdparty, OpenCV, PCL, yaml-cpp, glog, gflags and pcl_conversions.

On Ubuntu 22.04 there is a script for the system dependencies.

bash
./scripts/install_dep.sh

The package is a CMake project built with colcon, since package.xml and CMakeLists.txt sit at the root alongside cmake/, src/, config/, srv/, scripts/, doc/, docker/, thirdparty/ and pcd/.

bash
colcon build

After building, you source the generated setup script to use it.

bash
source install/setup.bash

The presence of srv/ means the package exposes ROS 2 services, which is worth knowing if you intend to drive mapping or localization from another node rather than only from the command line. A Dockerfile exists under docker/, and a .clang-format at the root means formatting is enforced rather than argued about.

A Chinese version of the README exists alongside the English one, and the main language detected for the repository is C++.

Datasets you can use directly, and the ones you must convert

Testing guidance is concrete, which saves a lot of setup time.

The project publishes converted datasets on OneDrive and BaiduYun, with an extraction code given for the BaiduYun link. You can use those directly. If you want the original datasets instead, you need to convert them to the ros2 db3 format yourself.

The original sources it targets are the NCLT dataset from the University of Michigan, the UrbanLoco dataset, and the VBR dataset. The examples section shows mapping and localization runs on the VBR campus dataset, localization on NCLT, data from a Deep Robotics quadruped robot, and a tilted mounting demo.

The dataset names recur in the update log, which tells you what is actually being tested. VBR gets a specific fix: MapIncremental is now called at the keyframe level to improve LIO robustness, with no drift on the VBR dataset. VBR also has abnormal timestamp issues, so timestamp checks were added. Deep Robotics quadruped data with RoboSense lidar type=4 was adapted to in the 2026.3.20 release. Tilted mounting has its own demo, which is a real installation condition that breaks many lidars.

The 2026.3.20 entry also fixes several issues that could cause segmentation faults and one in the loop closure detection module, issue #88, so treat an older checkout with suspicion on complex data.

Editorial conclusion

Consider lightning-lm if you run ROS 2 on Ubuntu and want CPU-based mapping and localization, with online localization reported at 0.8 cores and mapping at 1.2 cores on a 32-line LiDAR. Do not adopt it expecting georeferenced output or fused vehicle odometry, because GPS association and odometry input are listed as TODO rather than implemented. Before you build, install the dependencies with./scripts/install_dep.sh on Ubuntu 22.04, then build with colcon build and source install/setup.bash, and check loop_closing.with_height before running it on multi-floor data, where the global height constraint must stay off.

Frequently asked questions

What are the build requirements for lightning-lm?

Ubuntu 22.04 or higher, with Ubuntu 20.04 untested. Dependencies are ros2 humble or above, Pangolin, OpenCV, PCL, yaml-cpp, glog, gflags and pcl_conversions. Run ./scripts/install_dep.sh on Ubuntu 22.04, then colcon build and source install/setup.bash.

Does lightning-lm support GPS and vehicle odometry input?

Not yet. Both GPS geoinformation association and vehicle odometry input are listed as optional and marked TODO rather than done in the feature list.

How do I run lightning-lm on a recorded bag?

Use the offline entry point: `ros2 run lightning run_slam_offline --input_bag ~/data/NCLT/20130110/20130110.db3 --config ./config/default_nclt.yaml`. Switching offline for online in the command name gives the online program.

What does the loop_closing.with_height option do?

When set to true, lightning-lm keeps the output map at the same height to avoid Z-axis drift in large scenes. The README says not to set it in scenes with multi-floor or stairs structures.

How much CPU does lightning-lm use?

The README states all features can run using less than one CPU core on the pure CPU side, citing online localization at 0.8 cores and mapping at 1.2 cores with a 32-line LiDAR and no UI.

Official sources

  1. gaoxiang12/lightning-lm on GitHub
  2. Issues
  3. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gaoxiang12-lightning-lm.svg)](https://hysenlabs.com/projects/gaoxiang12-lightning-lm)

Was this useful?