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:
- KITTI Sequence 07: Google Drive
- MID360 Dataset: Google Drive
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.shabstraction 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=nativein 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_thresholdto force more iterations - Increase
min_surfel_pointsto 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.