SS47816/lidar_obstacle_detector

Real-time 3D LiDAR obstacle detection, tracking & trajectory prediction for ROS 1 / ROS 2: ground segmentation, clustering, 2.5D occupancy, optional GPU CenterPoint (TensorRT). ~10 ms/scan on one CPU core.

What it does

This C++ library processes 3D LiDAR scans (the sensor_msgs/PointCloud2 message) to detect and track obstacles (vehicles, pedestrians, walls, etc.) in real time. It works with both ROS 1 and ROS 2, and runs on a single CPU core — no GPU required (though an optional GPU mode exists). It outputs oriented bounding boxes, object IDs, velocities, and occupancy grids that can feed into navigation stacks like Nav2 or Autoware.

Key features

  • Ground segmentation – separates ground points from objects, even on slopes and kerbs (using the Patchwork++ algorithm).
  • Clustering – groups obstacle points into objects.
  • Box fitting – fits oriented bounding boxes around each object.
  • Multi‑object tracking – assigns IDs, estimates velocities, and predicts future positions using a Kalman filter + Hungarian matching.
  • Occupancy grid – builds a 2D grid of free/occupied space and a 3D voxel cloud, ready for costmaps.
  • No training data – the default pipeline is geometric and model‑free; an optional NVIDIA GPU detector can add class labels.
  • Reproducible benchmarks – public results on Argoverse 2 and nuScenes datasets.

How it works (pipeline)

  1. Preprocessing – crops to a region of interest, removes points inside the ego‑vehicle's bounding box, and downsamples (voxel grid).
  2. Ground segmentation – separates ground from non‑ground points. The default fast preset uses Patchwork++ (a state‑of‑the‑art method) plus an elevation‑map refinement to handle slopes.
  3. Clustering – divides non‑ground points into individual objects using one of three methods (height‑aware BEV grid, adaptive Euclidean, or plain Euclidean). Over‑large clusters are split or reported as structures (e.g., walls, vegetation) – they appear in the occupancy grid but not as moving objects.
  4. Box fitting – fits an oriented bounding box (L‑shape, PCA, or axis‑aligned) to each cluster.
  5. Tracking – couples boxes across frames, assigns unique IDs, estimates velocity, and (for moving vehicles) derives heading direction from motion.

Presets

Preset Ground method Clustering Box fitting Tracking Use for
fast (default) Patchwork++ BEV grid (height‑aware) L‑shape Kalman + motion heading most robots and vehicles
accurate Patchwork++ adaptive Euclidean L‑shape Kalman + motion heading best recall, 2–4× the compute
legacy RANSAC Euclidean axis‑aligned Kalman mimics v1 behaviour (without its bugs)

Benchmark highlights (from the README)

On Argoverse 2 (a 32‑beam lidar dataset):

  • fast preset runs in 7.5 ms per scan (~95k points) on one CPU core, and hits a Recall@1m of 0.66 (fraction of objects found within 1 m of a ground‑truth box).
  • accurate raises recall to 0.70 but takes ~32 ms.
  • Tracking is much more stable than the previous v1 version: ID switches drop from 11,822 to 1,725 (fast), and the IDF1 score (identity‑aware F1) improves from 0.20 to 0.73.
  • The percentage of object points wrongly classified as ground drops from 25% to 5%.

Installation & usage

Supports ROS 2 (Humble, Jazzy) and ROS 1 (Noetic). Build with colcon (ROS 2) or catkin (ROS 1). A pixi environment is also provided so you can run without a system ROS install.

Launch example (ROS 2):

ros2 launch lidar_obstacle_detector obstacle_detector.launch.py points:=/velodyne_points

It publishes topics like ~/detections (boxes with track IDs), ~/markers (for RViz), ~/occupancy (grid), and more.

Optional GPU detector

By building with -DLOD_WITH_TENSORRT=ON, you can use NVIDIA’s CUDA‑CenterPoint – a trained neural network that adds class labels (car, pedestrian, etc.) and full heading angles. It runs on an RTX 3090 Ti in ~15 ms per scan. There is also a hybrid mode that combines the geometric detector with CenterPoint, keeping all obstacles including those the network wasn’t trained on.

Parameters

All parameters can be changed live via rqt_reconfigure or ros2 param set. Key ones include:

  • roi_{min,max}_{x,y,z} – region of interest.
  • sensor_height – height of the lidar above ground (used by ground segmentation).
  • cluster_threshold – max gap between points of one object.
  • object_max_length / object_max_width – larger clusters are split or treated as structures.
  • occupancy_min_height / max_height – height band counted as occupied.

Licence & availability

MIT‑licensed, with the vendored Patchwork++ code under BSD‑2‑Clause. The repository includes unit tests, CI for the three ROS versions, and a reproducible benchmark pipeline.

All facts above are taken directly from the project’s README.

Related

  • Project
  • Project
  • Project
  • Project