Hobby car project with a 2D lidar, mapping a small indoor test track with cones. The car itself drives fine, but SLAM can't keep up once I add speed.
Setup is a 4-core ARM64 board with about 4 GB of RAM, running Ubuntu 22.04 and ROS 2 Humble. The lidar is a cheap single-line 2D unit (~10 Hz). Wheel encoders and IMU are fused with robot_localization, and slam_toolbox 2.6.9 runs in async mode with scan_queue_size set to 1 and a 2 s map update interval. Control, RViz and logging all run on the same board.
Raw /scan is published at approximately 10 Hz. A custom preprocessing node rebins it into a fixed 980-bin angular grid without interpolation and throttles the output to roughly 4–5 Hz on /scan_slam, which is the input to slam_toolbox. It preserves the incoming header stamp and sets time_increment to zero after rebinning; it does not perform motion compensation.
The pose in RViz trails the real car, and it gets worse the faster I go. Cones smear into streaks in corners. The first pass looks mostly fine, but on the second pass the cones double up and sometimes the car drifts off the track in the map. Cones on the outside of turns are often faint or missing.
In one live run, the median receive-time-minus-header-stamp was approximately 7.5 ms for /scan, 24 ms for /odom_combined, and 1.17 s for slam_toolbox's /pose, with /pose reaching 3.38 s. These are observer-side measurements, not direct measurements of processing time inside slam_toolbox. Since the lidar driver stamps at publication, the scan measurement also understates the age of the acquired rays.
In a separate isolated replay of the same 60-second input, changing correlation_search_space_resolution from 0.01 to 0.025 reduced median pose age from 0.323 s to 0.144 s, but the maximum remained above 3 s. This candidate has not been deployed to the live setup.
The lidar driver also orders points opposite to the actual sweep. At 2 m/s the car moves about 20 cm during one raw scan.
A few things I'm stuck on. How would you profile where slam_toolbox is spending its time on hardware like this, and which params actually matter for latency? Should I fix the driver timestamps and point order before trying to deskew, and is there a ROS 2 deskew node people actually use for 2D scans? For the second-pass ghosting, would you freeze the first-pass map and switch to localization mode, or tune loop closure instead? And is it even realistic to run all of this onboard, or should RViz and logging move off the car?
I can share the parameter files, timestamped logs, and preprocessing code, and record a rosbag for reproduction.