# rainbroken/lio architecture

> Architecture diagram of the GitHub repository rainbroken/lio, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/rainbroken/lio
- Repository: https://github.com/rainbroken/lio

## Overview

IteraLIO is a ROS 2 LiDAR–inertial odometry and mapping system. Its central workflow accepts sensor measurements, synchronizes and prepares scans, estimates motion by scan-to-map correction, updates local and global maps, and publishes odometry and map outputs. Optional backend keyframes and loop verification support pose-graph correction; evaluation records and run-comparison tools provide a separate analysis branch. The main pipeline and selected backend/loop internals are sampled; links for other subsystems follow the documented capabilities and repository layout, so uncertain internal call paths are omitted.

Main entry points: [`src/itera_lio/src/system/lio_pipeline.cpp`](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/system/lio_pipeline.cpp) (LIO pipeline), [`src/itera_lio/src/itera_lio_node.cpp`](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/itera_lio_node.cpp) (ROS node), [`src/itera_lio/src/ros/input_adapter.cpp`](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/ros/input_adapter.cpp) (ROS input adapter), [`tools/compare_lio_runs.py`](https://github.com/rainbroken/lio/blob/main/tools/compare_lio_runs.py) (Run comparison)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ros["ROS input/output"]
  node_livox["Livox adapter"]
  node_ros_adapter["ROS input adapter<br/>[input_adapter.cpp]"]
  node_sync["Measurement synchronizer"]
  node_parser["LiDAR parser<br/>[lidar_parser.cpp]"]
  node_node["ROS node<br/>[itera_lio_node.cpp]"]
  node_output_pub["Output publisher"]
end

subgraph group_odometry["Odometry frontend"]
  node_pipeline["LIO pipeline<br/>[lio_pipeline.cpp]"]
  node_processor["LIO processor<br/>[lio_processor.cpp]"]
  node_eskf["Iterated ESKF<br/>[iterated_eskf.cpp]"]
  node_lidar_update["LiDAR correction<br/>[lidar_update.cpp]"]
  node_deskewer["Scan deskewer<br/>[deskewer.cpp]"]
  node_scan_map["Scan-to-map registration<br/>[scan_to_map.cpp]"]
end

subgraph group_mapping["Mapping"]
  node_local_map[("Local map store<br/>[ikd_map.cpp]")]
  node_local_manager["Local map manager"]
  node_global_map[("Global map archive<br/>[global_map.cpp]")]
  node_color_map[("Colored map")]
  node_pcd["PCD writer<br/>[pcd_writer.cpp]"]
end

subgraph group_backend["Backend and loops"]
  node_backend["Backend manager"]
  node_pose_graph["Pose graph optimizer"]
  node_loop["Loop closure manager"]
  node_cloud_store[("Keyframe cloud store")]
end

subgraph group_evaluation["Evaluation"]
  node_evaluation["Evaluation logger"]
  node_compare["Run comparison"]
  node_run_records["Run records"]
  node_comparison["Comparison report"]
end

node_lidar(("LiDAR and IMU"))
node_user(("ROS user"))

node_lidar -.->|"publishes scans"| node_livox
node_livox -.->|"adapts messages"| node_ros_adapter
node_lidar -->|"sends measurements"| node_ros_adapter
node_ros_adapter -->|"buffers measurements"| node_sync
node_sync -->|"supplies scans"| node_parser
node_node -->|"receives input"| node_ros_adapter
node_node -->|"processes frames"| node_processor
node_processor -->|"runs odometry"| node_pipeline
node_pipeline -->|"prepares scan"| node_deskewer
node_pipeline -->|"registers scan"| node_scan_map
node_pipeline -->|"corrects state"| node_lidar_update
node_lidar_update -->|"updates estimate"| node_eskf
node_scan_map -->|"queries map"| node_local_map
node_pipeline -->|"updates window"| node_local_manager
node_local_manager -->|"prunes points"| node_local_map
node_pipeline -->|"archives points"| node_global_map
node_pipeline -->|"adds keyframes"| node_backend
node_pipeline -->|"submits keyframes"| node_loop
node_loop -->|"stores clouds"| node_cloud_store
node_backend -->|"optimizes graph"| node_pose_graph
node_pipeline -.->|"optional coloring"| node_color_map
node_node -->|"publishes results"| node_output_pub
node_output_pub -->|"emits ROS outputs"| node_user
node_pipeline -.->|"exports map"| node_pcd
node_node -->|"records run"| node_evaluation
node_evaluation -->|"writes metrics"| node_run_records
node_user -->|"selects runs"| node_compare
node_run_records -->|"reads records"| node_compare
node_compare -->|"writes report"| node_comparison

click node_livox "https://github.com/rainbroken/lio/blob/main/src/interfaces/src/livox_to_pointcloud2_node.cpp"
click node_ros_adapter "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/ros/input_adapter.cpp"
click node_sync "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/sensor/measurement_synchronizer.cpp"
click node_parser "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/sensor/lidar_parser.cpp"
click node_node "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/itera_lio_node.cpp"
click node_pipeline "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/system/lio_pipeline.cpp"
click node_processor "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/system/lio_processor.cpp"
click node_eskf "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/estimator/iterated_eskf.cpp"
click node_lidar_update "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/estimator/lidar_update.cpp"
click node_deskewer "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/deskewer.cpp"
click node_scan_map "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/scan_to_map.cpp"
click node_local_map "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/ikd_map.cpp"
click node_local_manager "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/local_map_manager.cpp"
click node_global_map "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/global_map.cpp"
click node_color_map "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/mapping/color/colored_global_map.cpp"
click node_backend "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/backend/backend_manager.cpp"
click node_pose_graph "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/backend/pose_graph_optimizer.cpp"
click node_loop "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/loop/loop_closure_manager.cpp"
click node_cloud_store "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/loop/keyframe_cloud_store.cpp"
click node_output_pub "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/ros/publishers/output_publisher.cpp"
click node_pcd "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/output/pcd_writer.cpp"
click node_evaluation "https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/output/evaluation_logger.cpp"
click node_compare "https://github.com/rainbroken/lio/blob/main/tools/compare_lio_runs.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_livox,node_ros_adapter,node_sync,node_parser,node_node,node_output_pub,node_user toneBlue
class node_pipeline,node_processor,node_eskf,node_lidar_update,node_deskewer,node_scan_map toneAmber
class node_local_map,node_local_manager,node_global_map,node_color_map,node_pcd toneMint
class node_backend,node_pose_graph,node_loop,node_cloud_store toneRose
class node_evaluation,node_compare,node_run_records,node_comparison,node_lidar toneIndigo
```

## Components

### ROS input/output

- [Livox adapter](https://github.com/rainbroken/lio/blob/main/src/interfaces/src/livox_to_pointcloud2_node.cpp): `src/interfaces/src/livox_to_pointcloud2_node.cpp`
- [ROS input adapter](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/ros/input_adapter.cpp): `src/itera_lio/src/ros/input_adapter.cpp`
- [Measurement synchronizer](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/sensor/measurement_synchronizer.cpp): `src/itera_lio/src/sensor/measurement_synchronizer.cpp`
- [LiDAR parser](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/sensor/lidar_parser.cpp): `src/itera_lio/src/sensor/lidar_parser.cpp`
- [ROS node](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/itera_lio_node.cpp): `src/itera_lio/src/itera_lio_node.cpp`
- [Output publisher](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/ros/publishers/output_publisher.cpp): `src/itera_lio/src/ros/publishers/output_publisher.cpp`

### Odometry frontend

- [LIO pipeline](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/system/lio_pipeline.cpp): `src/itera_lio/src/system/lio_pipeline.cpp`
- [LIO processor](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/system/lio_processor.cpp): `src/itera_lio/src/system/lio_processor.cpp`
- [Iterated ESKF](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/estimator/iterated_eskf.cpp): `src/itera_lio/src/estimator/iterated_eskf.cpp`
- [LiDAR correction](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/estimator/lidar_update.cpp): `src/itera_lio/src/estimator/lidar_update.cpp`
- [Scan deskewer](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/deskewer.cpp): `src/itera_lio/src/frontend/deskewer.cpp`
- [Scan-to-map registration](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/scan_to_map.cpp): `src/itera_lio/src/frontend/scan_to_map.cpp`

### Mapping

- [Local map store](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/ikd_map.cpp): `src/itera_lio/src/frontend/ikd_map.cpp`
- [Local map manager](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/local_map_manager.cpp): `src/itera_lio/src/frontend/local_map_manager.cpp`
- [Global map archive](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/frontend/global_map.cpp): `src/itera_lio/src/frontend/global_map.cpp`
- [Colored map](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/mapping/color/colored_global_map.cpp): `src/itera_lio/src/mapping/color/colored_global_map.cpp`
- [PCD writer](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/output/pcd_writer.cpp): `src/itera_lio/src/output/pcd_writer.cpp`

### Backend and loops

- [Backend manager](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/backend/backend_manager.cpp): `src/itera_lio/src/backend/backend_manager.cpp`
- [Pose graph optimizer](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/backend/pose_graph_optimizer.cpp): `src/itera_lio/src/backend/pose_graph_optimizer.cpp`
- [Loop closure manager](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/loop/loop_closure_manager.cpp): `src/itera_lio/src/loop/loop_closure_manager.cpp`
- [Keyframe cloud store](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/loop/keyframe_cloud_store.cpp): `src/itera_lio/src/loop/keyframe_cloud_store.cpp`

### Evaluation

- [Evaluation logger](https://github.com/rainbroken/lio/blob/main/src/itera_lio/src/output/evaluation_logger.cpp): `src/itera_lio/src/output/evaluation_logger.cpp`
- [Run comparison](https://github.com/rainbroken/lio/blob/main/tools/compare_lio_runs.py): `tools/compare_lio_runs.py`
- **Run records**
- **Comparison report**

### Other components

- **LiDAR and IMU**
- **ROS user**

## Connections

- LiDAR and IMU → Livox adapter: publishes scans
- Livox adapter → ROS input adapter: adapts messages
- LiDAR and IMU → ROS input adapter: sends measurements
- ROS input adapter → Measurement synchronizer: buffers measurements
- Measurement synchronizer → LiDAR parser: supplies scans
- ROS node → ROS input adapter: receives input
- ROS node → LIO processor: processes frames
- LIO processor → LIO pipeline: runs odometry
- LIO pipeline → Scan deskewer: prepares scan
- LIO pipeline → Scan-to-map registration: registers scan
- LIO pipeline → LiDAR correction: corrects state
- LiDAR correction → Iterated ESKF: updates estimate
- Scan-to-map registration → Local map store: queries map
- LIO pipeline → Local map manager: updates window
- Local map manager → Local map store: prunes points
- LIO pipeline → Global map archive: archives points
- LIO pipeline → Backend manager: adds keyframes
- LIO pipeline → Loop closure manager: submits keyframes
- Loop closure manager → Keyframe cloud store: stores clouds
- Backend manager → Pose graph optimizer: optimizes graph
- LIO pipeline → Colored map: optional coloring
- ROS node → Output publisher: publishes results
- Output publisher → ROS user: emits ROS outputs
- LIO pipeline → PCD writer: exports map
- ROS node → Evaluation logger: records run
- Evaluation logger → Run records: writes metrics
- ROS user → Run comparison: selects runs
- Run records → Run comparison: reads records
- Run comparison → Comparison report: writes report
