If your robot runs multiple 2D LiDARs and you need a single, unified scan for SLAM, obstacle avoidance, or any downstream algorithm → this is the tool you’ve been looking for.
Most solutions make you pay for it: PCL dependencies, intermediate PointCloud2 conversions, compile-time caps on how many sensors you can even plug in. It’s messy, it’s slow, and it shouldn’t be this hard.
So I built a better one.
What is it?
A composable ROS2 node that subscribes to as many LaserScan topics as you want, synchronizes them in time, transforms each one via TF2, and publishes a single merged LaserScan → with zero intermediate point cloud conversion and zero PCL dependency.
What makes it actually good:
Unlimited LiDAR inputs → no compile-time cap, ever
Parallel ray projection via a persistent C++20 thread pool → no per-callback overhead
Direct polar-to-bin projection → no PointCloud2, no PCL, no bloat
Per-topic QoS → mix reliable and best-effort publishers freely
Two-pass sync safety → no silent data loss on partial sync failures
ROS2 compatibility → works out of the box, no code changes needed:
This looks like something that would be excellent to have as a released package that could be distributed by the buildfarm. Is that something you are looking into doing?
I have a similar node that merges any mix of pointclouds, laserscans, deskewing wrt multiple lidars on an articulated platform, performs pre-processing using both CUDA and CPU with a 45ms latency.
I’ve never tried a two lidar setup, but can common slam stacks really not process multiple lidars relayed to the same topic as input? Each should just get transformed into their respective header frames and projected properly unless there is some other assumption that this messes with.
Processing each one separately from its point of origin sequentially ought to get far more accurate when the sensors are placed further and further away from one another too, given that scans will be traced from the scan origin to the detected point, and if merged to a single average-ish origin it can start projecting unscanned areas as potentially clear. Though for AMCL it wouldn’t really matter I suppose.
Some common frameworks for SLAM (e.g. slam_toolbox) and localization (e.g., Nav2 amcl) expect a single scan, so those are the main use cases this is targeting.
Your concerns are completely valid though. It’s a real trade-off, especially as sensor separation increases.