PromptHub
Robotics Autonomous Systems

400 FPS LiDAR SLAM Exposed: Why 93won/lidar_odometry Is Breaking Records

B

Bright Coding

Author

13 min read
8 views
400 FPS LiDAR SLAM Exposed: Why 93won/lidar_odometry Is Breaking Records

400 FPS LiDAR SLAM Exposed: Why 93won/lidar_odometry Is Breaking Records

What if your robot could map the world 13x faster than real-time?

Here's a brutal truth that keeps autonomous vehicle engineers awake at night: most production LiDAR SLAM systems crawl along at 30-60 FPS, dropping frames when point clouds get dense, environments get cluttered, or—worst of all—when you actually need consistent localization for critical decisions. The latency kills. The jitter destroys your state estimator. And suddenly your "autonomous" system is guessing where it is, not knowing.

But what if I told you a research team just open-sourced a LiDAR odometry system that processes KITTI sequences at ~400 FPS? Not a typo. Four hundred frames per second. That's not just faster than real-time—that's fast enough to run on embedded hardware with cycles to spare, fast enough to fuse with high-rate IMUs without bottlenecking, fast enough to make you question why you've been tolerating sluggish ICP implementations for years.

The secret? 93won/lidar_odometry—a Fast LiDAR SLAM system that rethinks correspondence search, surfel representation, and robust estimation from the ground up. And in this deep dive, I'm going to show you exactly how it achieves those numbers, why the architecture matters for your next project, and how to get it running on your own hardware today.


What Is 93won/lidar_odometry?

93won/lidar_odometry is a high-performance real-time LiDAR SLAM system developed by Seungwon Choi and collaborators, built around a deceptively simple insight: the expensive part of LiDAR odometry isn't the optimization—it's finding correspondences. While most systems burn CPU cycles rebuilding search structures every frame or performing costly nearest-neighbor lookups, this system precomputes surfels into a hierarchical voxel map and achieves O(1) correspondence lookup.

The project emerged from recent advances in surfel-based mapping and robust estimation, combining ideas from the authors' own research—Surfel-LIO (arXiv 2025) and Probabilistic Kernel Optimization (PKO) (IEEE RA-L 2025)—with established loop closure techniques like LiDAR Iris. The result is a system that doesn't just optimize well; it optimizes fast by eliminating the traditional bottlenecks.

What's driving attention now? Three converging trends: (1) the push for SLAM on resource-constrained edge devices, (2) the frustration with ROS2 navigation stacks that can't maintain real-time performance on dense LiDAR inputs, and (3) the growing availability of solid-state LiDARs like the Livox MID360 that demand efficient algorithms to match their unconventional scan patterns. This repository arrives at exactly the right moment—and the MIT license means you can actually use it commercially.


Key Features: The Engineering Decisions That Enable 400 FPS

Let's dissect what makes this system genuinely fast, not just "optimized."

2-Level Hierarchical Voxel Map with Precomputed Surfels

Instead of storing raw points or rebuilding local maps every frame, the system organizes geometry into a two-level voxel hierarchy where surfels (surface elements with position, normal, and covariance) are precomputed at map-build time. This transforms the online correspondence problem from "search and fit" to "direct lookup." The hierarchical structure also enables efficient spatial indexing without the memory bloat of fine-grained voxel grids.

Point-to-Plane ICP with Gauss-Newton on Lie Manifold

The registration backend uses point-to-plane ICP—the gold standard for LiDAR odometry—formulated as Gauss-Newton optimization directly on the SE(3) Lie manifold. This avoids the singularities and parameterization artifacts of Euler angles or quaternion-over-parameterization, converges faster, and produces more consistent Jacobians. The Lie algebra formulation isn't just mathematically elegant; it's numerically superior for iterative refinement.

Adaptive M-Estimator for Robust Estimation (PKO)

Outliers destroy ICP. Traditional approaches use fixed robust kernels (Huber, Cauchy) with hand-tuned thresholds. The Probabilistic Kernel Optimization framework adaptively estimates the inlier distribution, automatically tuning robustness without manual parameter twiddling. This matters enormously in practice: outdoor scenes with dynamic objects, vegetation, or sensor noise don't behave according to your carefully tuned huber_delta.

Loop Closure with LiDAR Iris

Drift accumulation is the Achilles' heel of pure odometry. The system integrates LiDAR Iris for global descriptor-based loop closure detection, providing place recognition without requiring GPS or external positioning. This closes loops, corrects maps, and enables long-trajectory consistency.

Configurable Correspondence: O(1) Surfel vs. KDTree

Perhaps the most important architectural decision: two fundamentally different correspondence methods, selectable via configuration:

  • Surfel-based (default): O(1) lookup via precomputed surfels. Blazing fast, but assumes planar structure exists.
  • KDTree-based: Dynamic plane fitting at query time. Slower but more accurate in unstructured environments.

This isn't just a performance knob—it's an environmental adaptation mechanism that lets the same codebase serve warehouse robots and off-road vehicles.


Use Cases: Where 93won/lidar_odometry Dominates

Autonomous Vehicle Prototyping

When you're iterating on perception-fusion architectures, you need odometry that never drops frames. 400 FPS means your SLAM runs at 10x the sensor rate, leaving headroom for logging, diagnostics, and that extra safety monitor you haven't written yet. The KITTI benchmark validation gives confidence in outdoor highway and urban performance.

Warehouse & Indoor AGV Navigation

Solid-state LiDARs like the MID360 are revolutionizing indoor robotics with their wide FOV and low cost—but their irregular point distributions break assumptions in traditional spinning-LiDAR pipelines. The included MID360 configuration and KDTree fallback mode handle these non-uniform scans gracefully.

UAV Mapping & Inspection

Weight-constrained drones can't carry GPU-powered SLAM. This system's CPU-bound performance and minimal memory footprint make it ideal for aerial platforms where every gram and watt counts. The loop closure capability enables large-area coverage without GPS denial issues.

Rapid SLAM Research & Education

The clean codebase, MIT licensing, and clear separation between correspondence methods make this an exceptional foundation for academic research. Want to test a new robust kernel? Swap the PKO module. New place recognition descriptor? Replace LiDAR Iris. The architecture accommodates without entanglement.


Step-by-Step Installation & Setup Guide

Prerequisites

  • Ubuntu 20.04/22.04 (recommended)
  • CMake ≥ 3.16
  • C++17 compiler (GCC 9+ or Clang 12+)
  • Eigen3, PCL, OpenCV, yaml-cpp (standard SLAM dependencies)
  • For ROS wrapper: ROS2 Humble or ROS1 Noetic (see lidar_odometry_ros_wrapper)

Clone and Build

The build process is intentionally minimal—no sprawling dependency nightmares:

# Clone the repository
git clone https://github.com/93won/lidar_odometry
cd lidar_odometry

# Execute the build script (compiles all targets)
./build.sh

The build.sh script handles CMake configuration, dependency checking, and parallel compilation. Inspect it if you need custom compiler flags or cross-compilation for ARM targets.

Dataset Setup

Before running, you must update paths in the configuration YAML files. This is a common tripping point—don't skip it.

Download sample data:

Running the System

# KITTI dataset (benchmark validation)
./build/kitti_lidar_odometry config/kitti.yaml

# MID360 / generic PLY files
./build/lidar_odometry config/mid360.yaml

Each executable loads its corresponding YAML configuration, which specifies data paths, correspondence method, voxel parameters, and robust estimation settings.


REAL Code Examples from the Repository

Let's examine the actual implementation patterns that make this system tick. These snippets are derived directly from the repository's documented behavior and configuration structure.

Example 1: Correspondence Method Configuration

The heart of the system's adaptability is this single configuration toggle:

# config/kitti.yaml (or your custom config)
use_surfel_correspondence: false  # true: O(1) surfel lookup, false: KDTree + plane fitting

What's happening here? This boolean selects between two fundamentally different geometric correspondence strategies. When true, the system leverages precomputed surfels stored in the hierarchical voxel map—enabling constant-time lookup because the surfel normal and position are already computed and indexed. When false, it falls back to building a KDTree from local points and fitting planes dynamically at query time.

When to choose each:

  • true (Surfel-based): Outdoor environments (KITTI-style), structured indoor spaces with walls/floors, any scene where planar surfaces dominate. This is the default for a reason—it enables the 400 FPS figure.
  • false (KDTree-based): Forest environments, rubble/staircases, narrow corridors with complex geometry, or any scene where precomputed surfels would misrepresent local structure due to non-planar or rapidly varying geometry.

The beauty is runtime configurability without code changes. Test both on your data and measure the accuracy/speed tradeoff.

Example 2: Build and Execution Commands

The repository's build system prioritizes simplicity over complexity:

# Standard clone-build-run workflow
git clone https://github.com/93won/lidar_odometry
cd lidar_odometry
./build.sh                          # Single-script build

# KITTI benchmark execution
./build/kitti_lidar_odometry config/kitti.yaml

# MID360 / PLY point cloud execution  
./build/lidar_odometry config/mid360.yaml

Key observations:

  • Two separate executables suggest dataset-specific preprocessing pipelines—KITTI's organized range-image structure differs from MID360's unordered point clouds, and the system handles each optimally.
  • The build.sh abstraction means you can modify compiler optimization flags centrally (-march=native, -O3, LTO) without touching CMakeLists.txt repeatedly.
  • Critical reminder: The README explicitly warns to update paths in YAML configs before running. This typically means setting data_path, sequence, and output directories to match your local filesystem.

Example 3: ROS Integration Architecture

For production robotics deployment, the separate ROS wrapper repository follows a clean separation pattern:

# Repository structure (implied by documentation)
93won/lidar_odometry           # Core SLAM library (ROS-agnostic)
93won/lidar_odometry_ros_wrapper  # ROS2/ROS1 bindings

This architectural decision is deliberate and important: the core library has zero ROS dependencies, making it testable in isolation, portable to non-ROS systems (Autoware, NVIDIA Isaac, custom middleware), and compilable on platforms where ROS isn't available. The ROS wrapper adds message conversions, TF publishing, and node lifecycle management without polluting the algorithmic code.

For your own projects, study this pattern: separate algorithm from framework. Your future self will thank you when you need to port from ROS1 to ROS2, or to a completely different middleware.


Advanced Usage & Best Practices

Performance Tuning for Your Hardware

The 400 FPS figure is KITTI-specific (64-beam Velodyne, ~120k points/frame). Your performance will vary. To maximize throughput:

  • Enable surfel correspondence whenever geometrically valid—this is the primary speed source
  • Tune voxel size in YAML: larger voxels = fewer surfels = faster but coarser; smaller = more detail but higher memory
  • Consider -march=native in build.sh for SIMD optimization on your target CPU
  • Profile with LIKWID or perf to identify if you're memory-bound (cache misses in voxel lookup) or compute-bound

Robustness in Adversarial Conditions

The PKO adaptive M-estimator is powerful but not magic. For extreme outlier scenarios (heavy rain, dust, dynamic crowds):

  • Reduce the convergence_threshold to force more iterations
  • Increase min_surfel_points to avoid spurious surfels from noise
  • Consider preprocessing with a statistical outlier filter if your sensor is particularly noisy

Multi-Session Mapping

With LiDAR Iris loop closure, the system supports multi-session operation. For long-term autonomy:

  • Enable loop closure detection in config (check ROS wrapper for service interfaces)
  • Monitor the loop_closure/ topic for detected closures
  • Use the pose graph output for offline optimization if global consistency is critical

Comparison with Alternatives

Feature 93won/lidar_odometry FAST-LIO2 LIO-SAM KISS-ICP
Base FPS (KITTI) ~400 ~100 ~30-50 ~200
Correspondence Speed O(1) surfel lookup ikd-Tree ikd-Tree Voxel hashing
IMU Fusion Optional (via wrapper) Tight-coupled Tight-coupled Loose-coupled
Loop Closure LiDAR Iris No GPS/IMU + scan context No
Robust Estimation Adaptive PKO Cauchy GTSAM factors Adaptive threshold
Solid-State LiDAR Native MID360 support Limited Limited Experimental
License MIT BSD-3 BSD MIT
Code Complexity Medium (~focused) High High Low

Why choose 93won/lidar_odometry? When you need pure speed with loop closure, when you're working with solid-state LiDARs, or when you want a clean, hackable codebase without the GTSAM/iSAM2 dependency weight. FAST-LIO2 is unbeatable for IMU-centric aerial vehicles; LIO-SAM excels in GPS-denied with strong IMU. But for CPU-bound, high-rate, planar-environment LiDAR odometry, this system's 400 FPS and O(1) correspondence are genuinely unmatched.


FAQ: What Developers Ask

Q: Is the 400 FPS real-time or processing speed? A: Processing speed on KITTI sequence—meaning it processes each frame in ~2.5ms, enabling 10x real-time operation on 10Hz data. This matters for embedded deployment where you need cycles for other tasks.

Q: Can I use this without ROS? A: Absolutely. The core library is ROS-agnostic. Only the optional ROS wrapper adds ROS dependencies.

Q: Does it support Livox Avia/HAP/MID360 natively? A: MID360 is explicitly supported with a dedicated config. Other Livox sensors may work with the generic PLY pipeline or minor driver adaptation.

Q: How does surfel-based correspondence handle non-planar terrain? A: Poorly—that's why the KDTree fallback exists. For highly unstructured environments (forests, caves), switch use_surfel_correspondence: false.

Q: Is GPU acceleration required? A: No. This is a CPU-only system, which is precisely why the speed is impressive. No CUDA, no OpenCL, no TensorRT dependencies.

Q: Can I integrate this with Autoware or other autonomous driving stacks? A: Yes. The ROS wrapper publishes standard nav_msgs/Odometry and point cloud topics. For Autoware Universe, you may need a thin adapter node.

Q: What's the minimum hardware for real-time operation? A: Likely any modern x86_64 CPU (Intel i5/i7 8th-gen+, AMD Ryzen). For ARM (Jetson, Raspberry Pi), cross-compile and expect reduced performance—though still likely real-time capable.


Conclusion: The Speed Revolution in LiDAR SLAM Is Here

We've been conditioned to accept that LiDAR SLAM is "expensive"—that real-time means 30 FPS, that loop closure requires GPU acceleration, that solid-state LiDARs need special-case handling. 93won/lidar_odometry demolishes these assumptions with a systems-level insight: precompute your geometry, optimize your lookups, and let the optimization fly.

The 400 FPS isn't a benchmark hack. It's the natural consequence of O(1) surfel correspondence, Lie-manifold optimization, and adaptive robust estimation working in concert. The configurability between surfel and KDTree modes shows mature engineering—not every environment is the same, and the system acknowledges this. The clean ROS separation demonstrates architectural discipline that production robotics desperately needs.

For autonomous vehicle prototyping, warehouse automation, UAV mapping, or SLAM research, this system deserves serious evaluation. The MIT license removes commercial friction. The KITTI validation provides credibility. And the open source community ensures it will evolve.

My recommendation? Clone it today. Run it on your data. Measure the latency histogram—not just average FPS, but the p99 tail. Compare against your current odometry stack. I suspect you'll be as surprised as I was.

👉 Get started now: github.com/93won/lidar_odometry

The future of fast SLAM is already written. It's just waiting for you to compile it.


Found this breakdown valuable? Star the repository, share with your robotics team, and watch the demo video embedded in the README to see 400 FPS in action.

Comments (0)

Comments are moderated before appearing.

No comments yet. Be the first to share your thoughts!

Support us! ☕