You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ROS Melodic下message_filters.ApproximateTimeSynchronizer无法触发回调问题

解决ROS Melodic中Ouster激光雷达与相机数据同步问题

一、先修复代码的基础错误

你的代码存在两个关键语法/逻辑问题,会直接导致回调无法触发:

  1. 回调函数无缩进:callback函数定义后的代码块没有缩进,Python会识别为函数体为空,即使触发同步也不会执行任何操作。
  2. 节点初始化顺序错误:rospy.init_node('sync_node')应该放在所有订阅器创建之前,ROS订阅器需要依赖已初始化的节点才能正常工作。

修复后的代码示例:

import rospy
import message_filters
from sensor_msgs.msg import Image, CameraInfo, PointCloud2

def callback(image_msg, camera_info_msg, lidar_msg):
    # Process synchronized data here
    rospy.loginfo("Received synchronized data!")
    # 可添加时间戳打印用于调试
    rospy.loginfo(f"Image timestamp: {image_msg.header.stamp}")
    rospy.loginfo(f"Lidar timestamp: {lidar_msg.header.stamp}")

if __name__ == "__main__":
    rospy.init_node('sync_node')
    
    # 初始化订阅器(必须在节点初始化之后)
    image_sub = message_filters.Subscriber('/cv_camera/image_raw', Image)
    info_sub = message_filters.Subscriber('/cv_camera/camera_info', CameraInfo)
    lidar_sub = message_filters.Subscriber('/ouster/points', PointCloud2)
    
    # 初始化近似时间同步器
    ts = message_filters.ApproximateTimeSynchronizer(
        [image_sub, info_sub, lidar_sub], 
        queue_size=10, 
        slop=0.1  # 允许的时间差(秒),可根据实际情况调整
    )
    ts.registerCallback(callback)
    
    rospy.spin()

二、解决Ouster点云无时间戳的核心问题

ouster/points没有时间戳是同步失败的根本原因——ApproximateTimeSynchronizer完全依赖消息头中的stamp字段进行时间匹配,解决方法如下:

1. 配置Ouster ROS驱动生成时间戳

Ouster的ouster_ros驱动默认支持生成时间戳,需检查launch文件配置:

  • 打开Ouster的启动launch文件(如os1.launch),添加或确认以下参数:
<!-- 使用系统时间作为点云时间戳(无硬件同步时用) -->
<param name="os1/use_system_time" value="true" />
<!-- 若有硬件同步(PPS/NMEA),启用以下参数 -->
<param name="os1/use_pps" value="true" />
<param name="os1/use_nmea" value="true" />

重启驱动后,再次用rostopic echo /ouster/points/header/stamp验证时间戳是否生成。

2. 手动为点云补全时间戳(临时方案)

如果驱动无法自动生成时间戳,可创建一个中转节点为点云添加系统时间:

import rospy
from sensor_msgs.msg import PointCloud2

def lidar_callback(msg):
    msg.header.stamp = rospy.Time.now()
    pub.publish(msg)

if __name__ == "__main__":
    rospy.init_node('lidar_timestamp_adder')
    sub = rospy.Subscriber('/ouster/points', PointCloud2, lidar_callback)
    pub = rospy.Publisher('/ouster/points_with_stamp', PointCloud2, queue_size=10)
    rospy.spin()

之后在同步节点中订阅/ouster/points_with_stamp话题即可。

三、验证与调试

  1. 确认所有话题时间戳正常:
    • 执行rostopic echo /cv_camera/image_raw/header/stamp查看相机图像时间戳。
    • 执行rostopic echo /ouster/points/header/stamp确认激光雷达点云时间戳存在。
  2. 调整同步时间差阈值:
    若相机与激光雷达时间差较大,可增大ApproximateTimeSynchronizer的slop参数(如从0.1改为0.5秒),但不宜过大,避免匹配无关数据。
  3. 尝试严格时间同步(可选):
    若通过硬件同步保证了相机与激光雷达时间严格对齐,可替换为严格时间同步器:
    ts = message_filters.TimeSynchronizer([image_sub, info_sub, lidar_sub], queue_size=10)
    

内容的提问来源于stack exchange,提问作者Rupika raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 08:15:17