LiDAR-driven digital-twin pipeline for structural & environmental monitoring
InfraSpect is a modular ROS 2 system that ingests recorded or live LiDAR data, reconstructs 3-D surface models, and tracks geometric changes over time. It ships with a browser-based dashboard, an interactive Three.js 3-D viewer, and a complete CLI toolchain — all runnable with a single command.
Built on ROS 2 Jazzy · Python 3.12 · Open3D · Three.js
| Capability | Description |
|---|---|
| Bag → live stream | Replays ROS 1/2 bags as standard PointCloud2 streams, transparent to downstream |
| Noise removal & downsampling | Statistical outlier removal, voxel grid, RANSAC ground extraction |
| Scan-to-scan registration | ICP alignment with optional FPFH+RANSAC coarse stage; cumulative transform tracking |
| Surface reconstruction | Poisson mesh from accumulated aligned point clouds; automatic snapshot persistence |
| Geometric feature extraction | Bounding box, floor area, convex volume, roughness, normal distribution, density |
| Versioned state storage | JSON-indexed snapshot catalogue with full provenance |
| Temporal change detection | Cloud-to-cloud displacement analysis with severity classification |
| RViz markers | Colour-coded bounding-box overlays and floating severity labels |
| Web dashboard | Real-time counters, registration chart, feature table, event log, bag upload & playback |
| 3-D model viewer | In-browser PLY mesh viewer with orbit controls, wireframe, and multi-mode colouring |
Rosbag / Sensor
│
▼
┌─────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Module 1 │───▶│ Module 2 │───▶│ Module 3 │───▶│ Module 4 │
│ Ingestion │ │ Preprocess │ │ Registration │ │ Twin Build │
└─────────────┘ └──────────────┘ └──────────────┘ └──────┬───────┘
│
┌─────────────────────────┘
▼
┌──────────────┐ ┌──────────────┐
│ Module 5 │───▶│ Module 6 │
│ Features │ │ Storage │
└──────────────┘ └──────┬───────┘
│
┌────────────────────┘
▼
┌──────────────┐ ┌──────────────┐
│ Module 7 │───▶│ Module 8 │
│ Change Det. │ │ Viz / RViz │
└──────────────┘ └──────────────┘
┌──────────────────────────────────┐
│ Dashboard + 3-D Viewer │
│ http://localhost:3000 │
└──────────────────────────────────┘
| Requirement | Version |
|---|---|
| ROS 2 | Jazzy (or Humble) — desktop install |
| Python | ≥ 3.10 |
| OS | Ubuntu 22.04 / 24.04 |
git clone https://github.com/<you>/InfraSpect.git && cd InfraSpectDownload the Newer College Dataset, convert to ROS 2 format, and drop it under data/:
pip3 install rosbags
rosbags-convert <bag>.bag --dst data/newer_college/bags/run_01/<bag>./run_pipeline.shThis single command installs Python dependencies, builds all nine packages, launches the full 13-node pipeline, plays the bag, and starts the web UI.
| URL | What |
|---|---|
| http://localhost:3000 | Live dashboard |
| http://localhost:3000/viewer | Interactive 3-D twin viewer |
python3 tools/render_snapshot.py --allInfraSpect/
├── src/
│ ├── module1_lidar_ingestion/ Bag replay · bridging · validation · TF · diagnostics
│ ├── module2_preprocessing/ SOR · voxel downsampling · ground removal
│ ├── module3_registration/ ICP alignment · cumulative transforms
│ ├── module4_twin_construction/ Poisson mesh · snapshot persistence
│ ├── module5_feature_engineering/ Geometric feature extraction
│ ├── module6_state_storage/ Versioned state index
│ ├── module7_change_detection/ Cloud-to-cloud displacement · severity
│ ├── module8_visualization/ RViz markers · text summaries
│ └── dashboard/ Flask web UI · Three.js 3-D viewer
├── data/
│ ├── newer_college/bags/ Converted rosbags
│ └── twin_states/ Generated snapshots (.pcd · .ply · .json · .png)
├── tools/
│ └── render_snapshot.py Offline snapshot renderer
├── run_pipeline.sh One-command launcher
└── README.md
Each module is a self-contained ROS 2 ament package with its own config, launch file, tests, and documentation.
| # | Package | Role | Docs |
|---|---|---|---|
| 1 | module1_lidar_ingestion |
Bag playback, frame bridging, validation, TF, diagnostics | README |
| 2 | module2_preprocessing |
Statistical outlier removal, voxel grid, ground plane extraction | README |
| 3 | module3_registration |
ICP scan alignment with optional FPFH+RANSAC coarse stage | README |
| 4 | module4_twin_construction |
Point-cloud accumulation, Poisson surface reconstruction | README |
| 5 | module5_feature_engineering |
Bounding box, area, volume, roughness, density extraction | README |
| 6 | module6_state_storage |
JSON-indexed snapshot catalogue with provenance tracking | README |
| 7 | module7_change_detection |
Cloud-to-cloud displacement analysis, severity classification | README |
| 8 | module8_visualization |
RViz MarkerArray overlays, formatted text reports | README |
| — | dashboard |
Flask web UI, bag control, live monitoring, Three.js 3-D viewer | README |
/os1_cloud_node/points raw bag output
│
▼
/infraspect/lidar/points bridged (frame remapped)
│
▼
/infraspect/lidar/points/validated validated PointCloud2
│
▼
/infraspect/preprocessing/points cleaned + downsampled
│
▼
/infraspect/registration/aligned globally aligned cloud
/infraspect/registration/metrics fitness · RMSE (JSON)
│
▼
/infraspect/twin/update snapshot-ready notification
│
▼
/infraspect/features/extracted geometric features (JSON)
│
▼
/infraspect/state/stored state indexed notification
│
▼
/infraspect/changes/report change report (JSON)
│
▼
/infraspect/visualization/markers RViz MarkerArray
/infraspect/visualization/summary formatted text summary
Every module reads parameters from its own config/params.yaml. Override at launch time:
ros2 launch dashboard full_pipeline.launch.py web_port:=8080Key tunables:
| Parameter | Module | Default | Effect |
|---|---|---|---|
voxel_size |
2 | 0.05 m | Preprocessing grid resolution |
icp_distance |
3 | 0.5 m | ICP max correspondence distance |
min_fitness |
3 | 0.05 | Reject poor scan alignments |
min_scans_per_build |
4 | 15 | Scans accumulated before mesh build |
poisson_depth |
4 | 8 | Octree depth for surface reconstruction |
threshold_medium |
7 | 0.2 m | Boundary between MEDIUM and HIGH severity |
web_port |
Dashboard | 3000 | Web UI port |
Validated against the Newer College Dataset (Oxford Robotics Institute) — Ouster OS-1 64-channel LiDAR scans of historic Oxford buildings and grounds.
The pipeline is sensor-agnostic: any source publishing sensor_msgs/PointCloud2 will work without modification.
source /opt/ros/jazzy/setup.bash
pip3 install open3d scipy flask
colcon build --symlink-install
source install/setup.bash
ros2 launch dashboard full_pipeline.launch.pyMIT