一台移动机器人上,激光雷达话题发布频率标称 10Hz,实测在 6~12Hz 之间抖,导航偶发丢定位。不是雷达问题,是 ROS2 定时器回调被 executor 拖住了。
1. 先确认抖动来自发布端还是订阅端。ros2 topic hz 看的是订阅端收到的频率,发布端自己的时间戳才说明问题。在发布回调里打时间戳,算相邻两次发布的间隔——我们实测发布间隔本身就在 80~160ms 之间抖,问题在发布端。
2. SingleThreadedExecutor 是最常见的坑。一个 executor 里塞了订阅、定时器、服务三个回调,订阅回调一耗时,定时器就被拖后。把高频话题发布拆到独立的 executor,或者换 MultiThreadedExecutor + CallbackGroup 隔离,频率立刻稳下来。
3. 定时器回调里别做重活。发布回调里做点云预处理、写日志、调服务,都会拖慢下一次触发。回调里只做“取数+发布”,重活扔给单独的线程或节点。我们把点云滤波移出回调后,发布间隔标准差从 28ms 降到 4ms。
4. 检查 DDS 层面的 QoS。发布端 BEST_EFFORT、订阅端 RELIABLE 这种不匹配组合,丢包会被误读成频率抖动。ros2 topic info -v 对一下两边的 QoS,reliability 和 durability 先对齐再谈频率。
最后发布频率稳定在 10Hz ±0.3Hz,导航丢定位消失。
你们 ROS2 节点里,定时器和订阅回调一般怎么隔离?是 CallbackGroup 还是直接拆节点?