Fast, lightweight LiDAR-IMU pipeline for Unitree L2 featuring deskew, on-the-fly feature extraction, a browser-based viewer, and an incremental ikd-Tree map with a scan-to-map pose optimizer.
This README summarizes the project status, milestones, how to build/run, and key CLI flags so you can continue work on another machine quickly.
System packages (Ubuntu/Debian):
sudo apt install -y libeigen3-dev \
libasio-dev \
libwebsocketpp-dev \
libboost-system-dev \
libyaml-cpp-dev \
libpcl-dev
Node (for the viewer):
sudo apt install -y nodejs npm
Optional: Unitree L2 SDK (set USE_UNITREE_SDK=1 to enable; see third_party/unilidar_sdk2).
mkdir -p build && cd build
cmake .. -DUSE_UNITREE_SDK=1
cmake --build . -j
Targets produced:
run_l2,record_l2,stream_lidar_live,deskew_playback,feature_playback,map_playback
-
Logs directory:
log_l2/- IMU CSV:
imu.csvwith header and rows:t,ax,ay,az,gx,gy,gz - LiDAR binary:
lidar.binframes encoded as:- double t0, double t1, uint32 N, followed by N tuples of
(float x, float y, float z, float intensity, double relative_time)
- double t0, double t1, uint32 N, followed by N tuples of
- IMU CSV:
-
Config YAML:
config/unilidar_l2.yaml- Contains extrinsics (
extr.q_il,extr.p_il), ikd-Tree params (ikdt.leaf_size,ikdt.local_win_xyz), deskew params, etc.
- Contains extrinsics (
stream_lidar_live [ws_port] [config_yaml] [deskew=0/1] [features=0/1]
- Streams binary point clouds over WS to the viewer.
- If features=1, colors planar vs non-planar points (RGB payload).
deskew_playback <logs_dir>
- Deskews frames using IMU; can stream over WS if enabled in YAML (
deskew.ws_port).
feature_playback <logs_dir>
- Extracts local planes (PCA) with a per-scan ikd-Tree and can colorize output.
map_playback <logs_dir> <config_yaml> [--iters N] [--k K] [--radius R] [--stride S] [--save-map PATH]
- Builds a persistent ikd-Tree map with on-tree downsampling.
- Uses IMU to seed pose per frame, then refines pose with a Gauss-Newton point-to-plane optimizer.
- Prunes to a sliding local window centered on the current frame using
ikdt.local_win_xyz. - Flags:
--iters: optimizer iterations per scan (default 5)--k: KNN size for plane fitting (default 5)--radius: max KNN radius in meters (default 1.0)--stride: subsampling stride for optimization (default 4)--save-map PATH: export final map as ASCII PLY with x y z intensity
Examples:
# default settings
./build/map_playback ./log_l2 ./config/unilidar_l2.yaml
# tuned and export to PLY
./build/map_playback ./log_l2 ./config/unilidar_l2.yaml \
--iters 4 --k 7 --radius 1.5 --stride 6 \
--save-map ./build/map_pruned.ply
Install deps once:
cd viz
npm install
Run it:
# from repo root
cd viz
node server.js ../log_l2/lidar.bin
# open: http://localhost:8080
Features:
- Color modes: Height, Intensity, or RGB (from stream)
- WS URL via query:
?port=8081or?ws=ws://host:port - Point size control UI
Milestone 1 — Live preprocessing and visualization: COMPLETED
- IMU integrator + deskew wired into live app
- Optional feature extraction with planar coloring
- Viewer supports intensity/height/RGB, configurable WS URL
Milestone 2 — Mapping foundation and optimization: IN PROGRESS
- DONE:
- Persistent ikd-Tree map with on-tree downsampling
- Scan-to-map pose optimizer (Gauss-Newton, point-to-plane, Huber loss)
- IMU-propagated initial pose per frame (compose with extrinsics)
- Local window pruning using
Delete_Point_Boxes - CLI tuning knobs (iters, k, radius, stride) and PLY export
- NEXT:
- Integrate mapping into the live app for real-time operation
- Diagnostics (residual/step logs, trajectory CSV export)
- Optional: colorized PLY exports, adjustable window via CLI
include/fastlio2/— headers (deskew, feature extractor, map manager, optimizer, etc.)src/— implementationsapps/— runnable tools/appsviz/— Node + Three.js viewerthird_party/— ikd-Tree, Unitree SDKconfig/— YAML parameterslog_l2/— sample logs (imu.csv, lidar.bin)
- ikd-Tree first insertion uses
Build, then incrementalAdd_Points. - Deletion in ikd-Tree is lazy; points are flagged and physically cleaned during rebuilds.
- If PCL imported targets aren’t available, CMake falls back to
${PCL_LIBRARIES}.