# SuperOdom couples a LiDAR estimator and an IMU estimator to each other

> SuperOdom is a slim build of Super Odometry, a ROS 2 Humble package for LiDAR-only or LiDAR-inertial odometry with Livox, Velodyne and Ouster sensors. Its two estimators are wired to each other, with the LiDAR constraining the IMU bias and the IMU supplying the initial guess for ICP, and the interesting engineering is in the degeneracy and uncertainty reporting rather than in the pose graph.

**superxslam/SuperOdom** — A highly robust and accurate LiDAR-only,  LiDAR-inertial odometry

- Repository: https://github.com/superxslam/SuperOdom
- Website: https://superodometry.com
- Stars: 1,196 · Forks: 155
- Language: C++
- License: GPL-3.0
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/superxslam-superodom

## Each estimator corrects the other

The README describes the arrangement in a way that is easy to misread, so it is worth restating. This is a slim version of Super Odometry, containing the LiDAR Odometry component and the IMU Odometry component, and the LiDAR odometry only provides pose constraints to the IMU odometry modules to estimate the bias of IMU. In return, the IMU Odometry module offers pose predictions to the LiDAR Odometry module, serving as an initial guess for ICP optimization.

So it is a loop, and each side is weaker alone. The IMU integrates cleanly over short intervals but drifts, and the bias in that drift is what the LiDAR side can observe, because a LiDAR registration residual will not agree with a badly biased inertial propagation. The LiDAR side is slower, because registering a scan takes time, and a fast inter-frame motion estimate lets the registration converge from a much better starting point than the previous pose would give.

What is notable is that this is not a filter fusing two measurements of the same state. The IMU is not treated as another observation of the pose, it is treated as a predictor of where the next scan starts, and the LiDAR is treated as a constraint on the IMU's parameters rather than as a pose measurement in a shared filter. GTSAM and Ceres are both in the dependency list, which is consistent with a factor graph formulation over states and biases rather than an extended Kalman filter.

The primary language is C++, the default branch is ros2, and the licence is GPL 3.0.

## LiDAR-only mode is one empty line in a config file

The 2025/06 release added support for both LiDAR-only and LiDAR-inertial odometry, and the way you choose between them is unusually cheap.

For LiDAR-only use, you leave the imu_topic unset or empty in your super_odometry/config/$(YOUR_LIDAR_SENSOR).yaml, or remove the IMU topic, and the odometry pipeline will run in LiDAR-only mode automatically.

```yaml
imu_topic: ""    # leave empty for LiDAR-only mode
```

No separate binary, no separate launch file, no compile time flag. The pipeline detects the absence of the IMU topic and changes what it does, which means a deployment can start as a LiDAR-only system and gain the inertial side when the IMU arrives.

The cost of that convenience is that the two modes are not equally strong, and the feature list says so. LiDAR-inertial fusion is listed as a separate capability from LiDAR-only support, and the two estimators feed each other as described earlier. In LiDAR-only mode there is no IMU bias to estimate and no inertial prediction to seed the registration, so the LiDAR estimator carries the whole load on its own.

That matters for the platforms the project says it has been widely tested on, which are equipped with Livox, Velodyne and Ouster LiDAR. Sensor family is not a detail here, because the registration and the degeneracy analysis both depend on the scan pattern, and the configuration file is named after the sensor.

## The interesting outputs are the warnings, not the poses

Two of the key features have nothing to do with producing a trajectory.

The first is degeneracy awareness, described as robust detection of environmental degeneracy, and the README emphasises it as 6 DOF degeneracy uncertainty detection. A corridor, a tunnel, an open car park and a forest floor all produce LiDAR observations that constrain some directions and not others, and a system that reports a confident pose in a corridor is worse than one that reports an uncertain one, because the robot or the vehicle will act on it.

The second is alignment risk prediction for ICP algorithms. ICP is a local method, and local methods fail locally. Predicting that the alignment is at risk before the estimate goes wrong is a different kind of output from the pose itself, and the README pairs it with visualisation in both RVIZ and Rerun.

A separate component exists because of this. The 2025/08 news entry records the release of SuperLoc code to achieve online degeneracy detection, and the table of contents points at a separate document for localization mode configuration, doc/LOCALIZATION.md.

The key features list also includes dual-mode operation, supporting both localization and mapping modes. Those are different problems, because a mapping system can accumulate drift and smooth it over a trajectory, while a localization system is being told where it is and must not move. The repository topics reflect the same emphasis, with resilient-slam, uncertainty-estimation and sensor-fusion among them, and the project home is superodometry.com.

## The build is a stack of pinned C++ dependencies

The installation section lists the system requirements, and they are the heavy ones: ROS2 Humble, PCL, Eigen, Sophus, GTSAM at 4.0.2 or 4.1, and Ceres Solver at 2.1.0. The README strongly recommends checking the Docker files instead and running the code through the container, and that is the sane advice for anything but a machine you are about to spend an evening on.

The dependency instructions pin specific commits, which is the detail that makes a reproducible build possible at all.

```bash
git clone http://github.com/strasdat/Sophus.git
cd Sophus && git checkout 97e7161
mkdir build && cd build
cmake .. -DBUILD_TESTS=OFF
make -j8 && sudo make install
```

GTSAM gets the same treatment, with the checkout 4abef92 and two CMake switches that are worth reading rather than copying blindly.

```bash
git clone https://github.com/borglab/gtsam.git
cd gtsam && git checkout 4abef92
mkdir build && cd build
cmake \
  -DGTSAM_USE_SYSTEM_EIGEN=ON \
  -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF \
  ..
make -j6 && sudo make install
```

Using the system Eigen avoids building a second copy of it, and turning off the native march tuning is what makes the result portable between machines. Ceres follows the same pattern with the commit f68321e7de8929fbcdb95dd42877531e64f72f66, and Rerun is a single pip install of rerun-sdk, since it is a visualisation library rather than a compiled dependency.

## Docker means a ROS 2 workspace with two other repos beside it

The container route is not a single image with everything inside. The image is built from the ros2_humble_docker directory, and the workspace inside it needs three repositories side by side.

```bash
cd ros2_humble_docker
docker build -t superodom-ros2:latest .
```

The workspace structure is fixed, and the README insists on maintaining it exactly.

```bash
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
git clone https://github.com/superxslam/SuperOdom
```

```
ros2_ws/src
├── SuperOdom
├── livox_ros_driver2
└── rviz_2d_overlay_plugins
```

The two extra repositories are the Livox ROS driver 2 and the rviz_2d_overlay_plugins, and both have to be cloned into the same src directory, which tells you the driver and the overlay visualisation are not optional extras but part of the supported configuration.

Running the container needs the display shared with Docker first, and the paths for the project and the dataset set in container_run.sh.

```bash
# Allow Docker GUI access
xhost +local:docker
```

```bash
PROJECT_DIR="/path/to/your/superodom"
DATASET_DIR="/path/to/your/dataset"
```

Then the container is started and the workspace is built inside it, and the order matters, because the Livox driver has to be built before the workspace itself.

```bash
cd ~/ros2_ws/src/livox_ros_driver2
./build.sh humble 
cd ~/ros2_ws
colcon build
```

NVIDIA Container Toolkit is a prerequisite for the GPU work, and the container itself is reached with docker exec when you need a shell inside it.

## Demo datasets for three sensor families, and a licence to think about

To launch SuperOdometry, the project provides demo datasets for the Livox-mid360, the VLP-16 and the OS1-128 sensor, with a download link to a shared drive. That list is the same three families the feature list names as compatible, Livox, Velodyne and Ouster, and it is also the set of sensors the project says it has been widely tested on.

There is a specific conversion note for Velodyne. To convert a Velodyne packet message into a sensor_msgs/PointCloud2 message, the README points at a tutorial in the ICCV2023_SLAM_Challenge repository, and the ROS 2 workspace structure in the previous section, with livox_ros_driver2 beside SuperOdom, is what makes the Livox path work.

The release record is short. There is one listed release, v1.0 from 2025-04-25, and the news list carries the three changes since, which are the LiDAR-only and LiDAR-inertial release in 2025/06, the SuperLoc code in 2025/08, and an adaptation for a humanoid robot in 2025/10, which is on a separate branch called humanoid_ros2. The last push was on 2026-07-23, and the project is not archived.

The licence is GPL 3.0, with the badge and the file in the repository root. For a robotics package that is a normal choice, since the software is deployed on the robot and the licence obligations attach to redistribution of the software rather than to the output of the odometry. The acknowledgements section is worth reading, since a package assembled from Sophus, GTSAM, Ceres, PCL and Eigen inherits terms from all of them.

One thing the README does not document is a rollback or a release history beyond that single tag, so a team that wants a repeatable build for the field should pin a commit and the matching sensor configuration rather than rely on a version number.

## Conclusion

SuperOdom fits a robotics team running ROS 2 Humble on Livox, Velodyne or Ouster hardware that needs pose estimates with an uncertainty signal. It is the wrong choice if your platform is not one of the tested sensor families, or if you need the full Super Odometry stack rather than the odometry components, since this repository is deliberately the slim subset. Verify first which branch and which sensor config you need, and read the localization mode document, because the switch between mapping and localization changes what the system believes about the world.

## FAQ

### How do I run SuperOdom in LiDAR-only mode?

Leave the imu_topic unset or empty in your super_odometry/config/$(YOUR_LIDAR_SENSOR).yaml, or remove the IMU topic, and the odometry pipeline runs in LiDAR-only mode automatically. The README gives imu_topic: "" as the example.

### Which LiDAR sensors does SuperOdom support?

It is compatible with Livox, Velodyne and Ouster sensors, and the project says it has been widely tested on platforms equipped with those three families. Demo datasets are provided for the Livox-mid360, the VLP-16 and the OS1-128.

### What does SuperOdom need to build?

ROS2 Humble, PCL, Eigen, Sophus, GTSAM at 4.0.2 or 4.1 and Ceres Solver at 2.1.0, with the build instructions pinning specific commits for Sophus, GTSAM and Ceres. Rerun, used for visualisation, is installed with pip install rerun-sdk.

### How do I run SuperOdom with Docker?

Build the image from the ros2_humble_docker directory with docker build -t superodom-ros2:latest ., share the display with xhost +local:docker, set PROJECT_DIR and DATASET_DIR in container_run.sh, then start the container with ./container_run.sh. Inside it, build livox_ros_driver2 first with ./build.sh humble and then run colcon build in the workspace.

### What does the SuperOdom repository include?

The repository is a slim version of Super Odometry with the LiDAR Odometry and IMU Odometry components, laid out as super_odometry/, super_odometry_msgs/, ros2_humble_docker/, script/ and doc/. It is GPL 3.0 licensed, the last push was on 2026-07-23, and the listed release is v1.0 from 2025-04-25.

## Sources

- [License: GPL-3.0](https://github.com/superxslam/SuperOdom/blob/ros2/LICENSE)
- [Project website](https://superodometry.com)
- [README](https://github.com/superxslam/SuperOdom/blob/ros2/README.md)
- [Releases](https://github.com/superxslam/SuperOdom/releases)
- [superxslam/SuperOdom on GitHub](https://github.com/superxslam/SuperOdom)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/superxslam-superodom
