Skip to content

About

Offline LiDAR odometry that runs directly on a folder of .pcd scans — no ROS required. A fork of direct_lidar_odometry with the ROS runtime stripped out, using PCL, Eigen3, and nano-GICP to register point clouds and output per-frame poses and a merged local map.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

 
 

Repository files navigation

Direct LiDAR Odometry — offline sequence runner

This repository is an offline, non-ROS runner derived from vectr-ucla/direct_lidar_odometry. The odometry defaults and IMU behavior track upstream v1.4.3, while YAML input, stable output files, and sequence evaluation support rapid offline experiments.

Build and test

Required packages are CMake, Eigen3, PCL (common, filters, I/O, registration, and surface), Boost filesystem/system, yaml-cpp, OpenMP, and Python 3 with NumPy for the evaluator.

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
ctest --test-dir build --output-on-failure

The build uses the PCL installation discovered at configure time. Do not reuse a checked-in or copied build directory from a different host/PCL version.

Run an offline sequence

Every PCD filename stem must be its finite numeric timestamp in seconds. Files are sorted numerically and duplicate timestamps are rejected.

./build/direct_lidar_odometry_offline \
  --config config/uturn_frf.yaml

Command-line input/output overrides make one profile reusable:

./build/direct_lidar_odometry_offline \
  --config config/upstream.yaml \
  --lidar-dir /path/to/timestamped_pcds \
  --imu-file /path/to/imu.csv \
  --output-dir result/experiment

Use --max-scans N for a prefix smoke test. Configuration is strict: unknown keys, invalid values, missing required paths, non-numeric PCD names, and non-monotonic IMU data fail with an error instead of silently changing behavior. When IMU is enabled, offline.input.maxImuGap also enforces end coverage and a maximum internal sampling gap before any scans are processed.

Two profiles are included:

  • config/upstream.yaml: exact upstream v1.4.3 algorithm defaults, with IMU enabled and offline paths left for the caller.
  • config/uturn_frf.yaml: the supplied lidar_frf_at128 sequence, using upstream algorithm defaults and LiDAR-only mode. IMU is intentionally off because the dataset does not provide a verified IMU-to-LiDAR extrinsic.

IMU contract

IMU support matches upstream DLO semantics. The measurements must already be expressed in the LiDAR frame. The first configured calibration interval (default: 3 seconds) estimates gyroscope bias and mean gravity; LiDAR frames in that interval are recorded as skipped. Gravity alignment is optional. After calibration, integrated angular velocity provides a rotation-only prior for scan-to-scan GICP.

This is not tightly coupled LIO: it does not estimate IMU extrinsics, predict translation, or deskew individual points.

Set dlo.imu: false for a fully supported LiDAR-only run.

Outputs

The configured output directory contains:

  • local_pose.txt: accepted poses as frame_id filename tx ty tz qx qy qz qw.
  • frames.csv: one row per input, including accepted/skipped/rejected status, reason, keyframe flag, and odometry-core latency.
  • run_summary.json: counts, keyframes, mean core latency, and loop wall time.
  • local_map_keyframes.pcd: merged keyframe map when saveMap is true.
  • keyframes/<index>.pcd: transformed keyframe clouds when saveKeyframes is true.

Frame IDs are original input indices. This keeps poses and diagnostics traceable even when calibration skips or load/validation failures occur.

Evaluate against INS

The evaluator synchronizes each accepted pose to the nearest INS sample, converts WGS84 positions to local ENU, and applies rigid SE(3) alignment without scale fitting.

python3 tools/evaluate_trajectory.py \
  --poses result/uturn_frf/local_pose.txt \
  --ins /path/to/ins.txt \
  --output result/uturn_frf/evaluation.json

It reports 3D ATE RMSE/median/max and signed path-length error. See docs/upstream-parity.md for the restored behaviors, intentional offline differences, and regression procedure.

About

Offline LiDAR odometry that runs directly on a folder of .pcd scans — no ROS required. A fork of direct_lidar_odometry with the ROS runtime stripped out, using PCL, Eigen3, and nano-GICP to register point clouds and output per-frame poses and a merged local map.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages