数据中缺少 IMU 与 LiDAR 外参时必须用 --config 传入含 extrinsic_imu2base_quat_xyzw_xyz 和 extrinsic_lidar2base_quat_xyzw_xyz 的配置文件;用 -v 可视化需额外安装 rerun-sdk>=0.31;ROS 话题与坐标系自动检测仍是实验性功能,失败时需手动指定 imu_topic、lidar_topic 和 base_frame
rko_lio
PRBonnMIT活跃维护一个不依赖传感器专门建模的鲁棒 LiDAR-惯性里程计,直接融合激光雷达与 IMU 数据估计位姿并建图,适合机器人 SLAM 场景。
A Robust Approach for LiDAR-Inertial Odometry Without Sensor-Specific Modelling
pip install "rko_lio[all]"
rko_lio -v /path/to/dataREADME 未说明显存、CPU 或 GPU 型号要求
无需针对特定传感器建模的鲁棒 LiDAR-惯性里程计,支持 ROS1/ROS2 rosbag 直接跑
一个不依赖传感器专门建模的鲁棒 LiDAR-惯性里程计,直接融合激光雷达与 IMU 数据估计位姿并建图,适合机器人 SLAM 场景。
核心能力
- 从 rosbag 自动读取 IMU 与 LiDAR 外参
- 提供 pip 安装的 Python CLI 与 ROS 包两种用法
- 支持 ROS1 和 ROS2 bag 数据加载
- 用 rerun 可视化里程计结果
- 支持 Humble 到 Rolling 多个 ROS 发行版
容易踩的坑
- v0.4.0最新正式版2026-09-01 · 2026-09-01 16:24 UTC
What's Changed
Well. A lot.
The most important is that there have been significant performance improvements made in this release, especially focusing on single-threaded performance. In fact, the defaults for
max_num_threadshas been changed to 1 from the earlier 0 (use all available) on the ROS side of things.More details of the improvements are covered in PRs #157 to #172. I'll just repeat the image i had in #170, which should give a quick idea of the kind of improvements we're talking about, for single threaded:
The next main thing is better online ros node behavior.
Failure recovery, or more precisely failure resetting, behaviors for the online ROS nodes. Earlier a registration error meant a kill. Now, odometry resets to a new identity frame and proceeds anew. Additionally, frame timing errors of 1s or more no longer mean an unrecoverable error. Instead registration is still attempted using the imu for an initial guess even on long gaps. Thanks to @Dhagash4 for this one in #174.
And then, a quick summary of all the relevant PRs that make up this release:
- core, perf: improve closest neighbour search by early pruning voxels by @mehermvr in https://github.com/PRBonn/rko_lio/pull/157
- core, cleanup: linear system build cleanup, and voxel map op unification by @mehermvr in https://github.com/PRBonn/rko_lio/pull/158
- core, perf: reducing scan copies by @mehermvr in https://github.com/PRBonn/rko_lio/pull/159
- all: floating point type is now configurable to float or double by @mehermvr in https://github.com/PRBonn/rko_lio/pull/160
- core: better icp convergence criterion, function tolerance by @mehermvr in https://github.com/PRBonn/rko_lio/pull/161
- chore: enforce formatters and linters, cut CI duplication by @mehermvr in https://github.com/PRBonn/rko_lio/pull/162
- core: switch icp to right perturbation by @mehermvr in https://github.com/PRBonn/rko_lio/pull/163
- core: quantise the voxel map to int8 offsets with fixed-size inline blocks by @mehermvr in https://github.com/PRBonn/rko_lio/pull/170
- core, ros: consistent naming, and make the voxel map's state private by @mehermvr in https://github.com/PRBonn/rko_lio/pull/171
- core: deskew without a per-point SE3 exp by @mehermvr in https://github.com/PRBonn/rko_lio/pull/172
- core: timestamp struct handling cleanup, min max compute once by @mehermvr in https://github.com/PRBonn/rko_lio/pull/175
- core: extrapolate the motion prior across a lidar gap instead of thro… by @Dhagash4 in https://github.com/PRBonn/rko_lio/pull/174
- ros: drop the oldest frame on the online node instead of the latest scan by @mehermvr in https://github.com/PRBonn/rko_lio/pull/155
- core, ros: remove nlohmann_json as a dep, dump config as yaml instead by @mehermvr in https://github.com/PRBonn/rko_lio/pull/177
- chore: dependency management using renovate and not dependabot by @mehermvr in https://github.com/PRBonn/rko_lio/pull/178
- core, ci: bump clang tidy to latest, clean up linter warnings by @mehermvr in https://github.com/PRBonn/rko_lio/pull/179
- core: switch to an spdlog sink instead of cout/cerr for core logs by @mehermvr in https://github.com/PRBonn/rko_lio/pull/180
- python: finally drop helipr by @mehermvr in https://github.com/PRBonn/rko_lio/pull/181
- core: use typed exceptions and clean up error handling by @mehermvr in https://github.com/PRBonn/rko_lio/pull/182
- core, ros: reset odometry on fatal registration error by @mehermvr in https://github.com/PRBonn/rko_lio/pull/183
- Bump version 0.4.0 by @mehermvr in https://github.com/PRBonn/rko_lio/pull/184
New Contributors
- @Dhagash4 made their first contribution in https://github.com/PRBonn/rko_lio/pull/174
Full Changelog: https://github.com/PRBonn/rko_lio/compare/v0.3.2...v0.4.0
- v0.3.22026-07-28 · 2026-07-28 14:20 UTC
查看更新说明
Minor release to pick up QoL features that just landed.
In python, a cleanup of the rerun-based viz and a fix of the trajectory visualization (which regressed at some point with a rerun api change). The blueprint file is also no longer vendored in the package, but rather built on the fly. Cleaner.
In ROS, a major qol feature I've been wanting for a while and harnessing the power of vibe coding, I present autodetection of lauch topics and frames. No longer do you need to specify the imu and lidar topics when you have just one of those on your system, and even the base frame is auto picked up based on the usual names. Of course you can still override flags as before to suit your needs. This is currently flagged experimental as I didn't test it extensively, but I expect there to be no issues.
What's Changed
- py: refactor of everything rerun by @mehermvr in https://github.com/PRBonn/rko_lio/pull/151
- ros, launch: autodetect topics and frames similar to the python side by @mehermvr in https://github.com/PRBonn/rko_lio/pull/152
- Bump version 0.3.2 by @mehermvr in https://github.com/PRBonn/rko_lio/pull/153
Full Changelog: https://github.com/PRBonn/rko_lio/compare/v0.3.1...v0.3.2
- v0.3.12026-07-16 · 2026-07-16 17:53 UTC
查看更新说明
Minor patch to pick up changes for a ros rolling api change fix. python release will have the [all] install option not installing open3d anymore. speedup, yay.
What's Changed
- build(deps): bump actions/checkout from 6 to 7 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/144
- build(deps): bump pypa/cibuildwheel from 3.4.0 to 4.1.0 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/145
- build(deps-dev): update rerun-sdk requirement from <0.32,>=0.31 to >=0.31,<0.34 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/146
- build(deps): update typer requirement from <0.25,>=0.19 to >=0.19,<0.27 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/147
- py: improve raw dataloader and remove open3d as a dep by @mehermvr in https://github.com/PRBonn/rko_lio/pull/148
- ros: fix rolling compat break, plus a bunch of deprecation warnings by @mehermvr in https://github.com/PRBonn/rko_lio/pull/149
- Bump version 0.3.1 by @mehermvr in https://github.com/PRBonn/rko_lio/pull/150
Full Changelog: https://github.com/PRBonn/rko_lio/compare/v0.3.0...v0.3.1
- v0.3.02026-06-16 · 2026-06-16 15:54 UTC
查看更新说明
a long overdue release, packaging a bunch of performance and ux improvements. its been a pre-release for a while, and i've also been testing master's state extensively, both python and ros, so hopefully this goes smoothly.
i think i'm slowly approaching a 1.0 release with this project (in principle, as i'll just stick with zero versioning). theres a few last things i'd want to work on here at some point, but hopefully soon
What's Changed
- Some code refactoring and execution time improvement. by @l00p3 in https://github.com/PRBonn/rko_lio/pull/93
- core: orientation linear system simplifications. Move util classes to util by @mehermvr in https://github.com/PRBonn/rko_lio/pull/94
- Bump actions/upload-artifact from 5 to 6 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/99
- Bump actions/download-artifact from 6 to 7 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/98
- Update typer requirement from <0.21,>=0.19 to >=0.19,<0.22 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/97
- Bump pypa/cibuildwheel from 3.3.0 to 3.3.1 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/103
- python: simplify the base config classes to be dataclasses by @mehermvr in https://github.com/PRBonn/rko_lio/pull/106
- Docs: add supplementary material for ral by @mehermvr in https://github.com/PRBonn/rko_lio/pull/107
- ros: add deskewed scan topic as a config, change default topic names to relative by @mehermvr in https://github.com/PRBonn/rko_lio/pull/108
- Revert "python: simplify the base config classes to be dataclasses" by @mehermvr in https://github.com/PRBonn/rko_lio/pull/109
- core: error out if keypoints is too small as thats likely a data error by @mehermvr in https://github.com/PRBonn/rko_lio/pull/110
- Update typer requirement from <0.22,>=0.19 to >=0.19,<0.24 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/111
- Update typer requirement from <0.24,>=0.19 to >=0.19,<0.25 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/112
- Python: Simplify pipeline, config, add a sequencer class by @mehermvr in https://github.com/PRBonn/rko_lio/pull/113
- Bump actions/download-artifact from 7 to 8 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/114
- Bump actions/upload-artifact from 6 to 7 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/115
- Fix rosbag typestore initialization by @ExpectedArgument in https://github.com/PRBonn/rko_lio/pull/117
- Docs/minor readme update by @mehermvr in https://github.com/PRBonn/rko_lio/pull/118
- Python/simplifications by @mehermvr in https://github.com/PRBonn/rko_lio/pull/119
- Bump pypa/cibuildwheel from 3.3.1 to 3.4.0 by @dependabot[bot] in https://github.com/PRBonn/rko_lio/pull/120
- Add Catch2 tests for core functionalities and related updates by @mehermvr in https://github.com/PRBonn/rko_lio/pull/123
- core: simplifications, again by @mehermvr in https://github.com/PRBonn/rko_lio/pull/124
- ros, feat: odometry at imu rate by @mehermvr in https://github.com/PRBonn/rko_lio/pull/125
- docs: overhaul by @mehermvr in https://github.com/PRBonn/rko_lio/pull/126
- ros: offline node exits once lidar buffer has been emptied by @mehermvr in https://github.com/PRBonn/rko_lio/pull/127
- Bump FetchContent dependencies by @mehermvr in https://github.com/PRBonn/rko_lio/pull/128
- core: drop Bonxai for tsl::robin_map by @mehermvr in https://github.com/PRBonn/rko_lio/pull/130
- ros (+ core): Installable and therefore reusable libs by @mehermvr in https://github.com/PRBonn/rko_lio/pull/131
- core: time in nanoseconds by @mehermvr in https://github.com/PRBonn/rko_lio/pull/132
- py: relocate rerun viz initialization to prevent spurious rerun launches by @mehermvr in https://github.com/PRBonn/rko_lio/pull/134
- Reject empty input vectors instead of dereferencing end() by @gistrec in https://github.com/PRBonn/rko_lio/pull/135
- core, python, ros: a series of simplifications by @mehermvr in
- v0.2.02025-12-02 · 2025-12-02 08:18 UTC
查看更新说明
What's Changed
- Core/move logging to wrappers by @mehermvr in https://github.com/PRBonn/rko_lio/pull/68
- Folder reorganisation and docs update by @mehermvr in https://github.com/PRBonn/rko_lio/pull/69
- More CLI options, profiles stats has variance, dumping deskewed scans by @mehermvr in https://github.com/PRBonn/rko_lio/pull/73
- core: Configurable lidar timestamp processing by @mehermvr in https://github.com/PRBonn/rko_lio/pull/74
- Bump FetchContent TBB dependency by @mehermvr in https://github.com/PRBonn/rko_lio/pull/75
- Fix: core - proper second frame pose if initialization off by @mehermvr in https://github.com/PRBonn/rko_lio/pull/77
- Rename published_deskewed_cloud to publish_deskewed_scan by @anthonytec2 in https://github.com/PRBonn/rko_lio/pull/81
- Remove pytest as optional dep by @mehermvr in https://github.com/PRBonn/rko_lio/pull/83
- python: remove unintentional additional scan viz by @mehermvr in https://github.com/PRBonn/rko_lio/pull/85
- chore: trigger workflows conditionally based on file changes by @mehermvr in https://github.com/PRBonn/rko_lio/pull/86
- core: minimize TimestampProcessingConfig by @mehermvr in https://github.com/PRBonn/rko_lio/pull/87
- Bump FetchContent Eigen version by @mehermvr in https://github.com/PRBonn/rko_lio/pull/88
- Fix (core): log proper pose for the first frame if init. phase is on by @mehermvr in https://github.com/PRBonn/rko_lio/pull/89
- Bump version to 0.2.0 by @mehermvr in https://github.com/PRBonn/rko_lio/pull/92
New Contributors
- @anthonytec2 made their first contribution in https://github.com/PRBonn/rko_lio/pull/81
Full Changelog: https://github.com/PRBonn/rko_lio/compare/v0.1.7...v0.2.0
Stay tuned for the next
episoderelease ofDragon--rko_lio for some more significant changes to the core library, including but not limited to performance tuning.
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
Quick Start
Following is for the python version, see ROS for that.
Assuming you have a rosbag (ros1/ros2) which contains a TF tree, you can run RKO-LIO through
pip install "rko_lio[all]"
# or
pip install rko_lio rosbags "rerun-sdk>=0.31"
# data path should be a directory with *.bag files (ROS1) or a metadata.yaml (ROS2)
rko_lio -v /path/to/data
Why pip install those three packages?
rko_lio-> the odometry packagerosbags-> required for the rosbag dataloader. Both ros1 and ros2 bags are supported!rerun-sdk-> required for the optional visualizer (-vflag)
pip install "rko_lio[all]" fetches the other optional dependencies as well.
Check further options for the CLI through rko_lio --help.
To dump a default config you can edit and pass with --config, run rko_lio --dump_config.
More details are available in the Python docs.
Extrinsics and convention
Please note that the system needs the extrinsic to be specified between IMU and LiDAR. Either your data includes this in some format, and then the dataloaders try to automatically read it, or otherwise you can specify it in a config file (required if it's missing in the data). Pass the config file with
rko_lio --config config_file.yaml
This file needs two keys: extrinsic_imu2base_quat_xyzw_xyz and extrinsic_lidar2base_quat_xyzw_xyz, which must each
be a list. For example: [0,0,0,1,0,0,0] for identity. Both keys are required.
Throughout this package, I refer to transformations using transform_<from-frame>2<to-frame>. By this, I mean a
transformation that converts a vector expressed in the <from-frame> coordinate system to the <to-frame> coordinate
system. Mathematically, this translates to:
$$ \mathbf{v}^{\mathrm{to}} = {}^{\mathrm{to}}\mathbf{T}_{\mathrm{from}} \mathbf{v}^{\mathrm{from}} $$
The superscript on the vector indicates the frame in which the vector is expressed, and
$^{ \mathrm{to} }\mathbf{T}_{\mathrm{from}}$ corresponds to transform_<from-frame>_to_<to-frame>.
ROS
Supported distros: Humble, Jazzy, Kilted, Lyrical, Rolling.
sudo apt install ros-$ROS_DISTRO-rko-lio
Or if you'd like to build from source, clone the repo into your colcon workspace and
rosdep install --from-paths src --ignore-src -r -y
colcon build --packages-select rko_lio # --symlink-install --event-handlers console_direct+
In case you cannot system install the necessary dependencies through rosdep, you can also build the dependencies while building RKO-LIO
colcon build --packages-select rko_lio --cmake-args -DRKO_LIO_FETCH_CONTENT_DEPS=ON
A launch file is provided:
ros2 launch rko_lio odometry.launch.py
The topics and frames are autodetected (experimental). To set them yourself instead:
ros2 launch rko_lio odometry.launch.py autodetect:=false \
imu_topic:=<topic> lidar_topic:=<topic> base_frame:=base_link
Those three are then the minimum you need to specify. You can specify them and other options all at once in a config
file passed with config_file:=file.yaml.
Check further launch configuration options through ros2 launch rko_lio odometry.launch.py -s
More details are available in the ROS docs.
The same note above about extrinsics applies here as well. Though you probably have a well defined TF tree and need not concern yourself with this (I hope).
Citation
If you found this work useful, please consider leaving a star :star: on this repository and citing our paper (RA-L | arXiv):
@article{malladi2026ral,
author = {M.V.R. Malladi and T. Guadagnino and L. Lobefaro and C. Stachniss},
title = {A Robust Approach for LiDAR-Inertial Odometry Without Sensor-Specific Modeling},
journal = {IEEE Robotics and Automation Letters},
year = {2026},
volume = {11},
number = {6},
pages = {7420--7427},
doi = {10.1109/LRA.2026.3685966},
}
The paper supplementary material page collects extra figures and explanations pertaining to the same paper.
You can check out the branch ral_submission for the version of the code used for submission to RA-L. Please note that
that branch is meant to be an as-is reproduction of the code used during submission and is not supported. The master
and release versions are vastly improved, supported, and are the recommended way to use this system.
Contributing
My goal with this project is to have a simple LiDAR-Inertial odometry system that can work with minimal friction, in the lines of "it just works". I gladly welcome any contribution or feedback you think would help in this direction. Performance improvements or bug fixes are of course always appreciated.
Thanks to the following contributors
Acknowledgements
This package is inspired by and would not be possible without the work of KISS-ICP and Kinematic-ICP. Additionally, we use and rely heavily on, either in the package itself or during development, PlotJuggler, Rerun, and of course ROS itself.
A special mention goes out to Rerun for providing an extremely easy-to-use but highly performative visualization system. Without this, I probably would not have made a python interface at all.
License
This project is free software made available under the MIT license. For details, see the LICENSE file.