4. 数据采集与同步

在无人机多传感器融合系统中,深度相机与雷达的数据采集与同步是决定后续融合精度的第一道关口。若时间戳错位、触发不同步或数据格式不统一,即使标定再精确、算法再先进,融合结果也会出现重影、拖尾或深度空洞。本节围绕 ROS/ROS2 采集框架、时间同步机制、硬件触发方式、数据格式与预处理,以及常见采集问题展开,帮助读者建立可落地的采集链路。

一、核心原理:为什么同步比采集本身更关键

深度相机输出的是图像帧(RGB、深度、IR),雷达输出的是点云或扫描线。两者物理机制不同:相机以固定帧率曝光,雷达以旋转或固态扫描方式逐点测距。若各自独立运行,同一时刻的“环境快照”并不一致。无人机运动时,平台位移和姿态变化会直接放大时间偏差带来的空间误差。

时间同步的目标是让不同传感器数据在同一时间基准下对齐。ROS 中常用两种时间源:ROS_TIME(仿真或外部时钟)与 系统时间。ROS2 则通过 use_sim_time 参数和 /clock 话题统一时间。同步精度通常要求达到毫秒级,高动态场景甚至需要微秒级。

同步误差 1 ms,在 10 m/s 飞行速度下对应约 1 cm 的空间错位;若姿态角速度达到 30°/s,还会引入额外的角度偏差。因此采集阶段必须把时间戳精度当作硬指标。

二、方法流程:从驱动到融合的采集链路

一个典型的 ROS/ROS2 采集链路包含:传感器驱动节点、时间同步节点、数据缓存与预处理节点、融合节点。推荐流程如下:

  1. 启动相机与雷达驱动,确认各自话题频率与时间戳来源。
  2. 使用 message_filters 的 ApproximateTime 或 ExactTime 策略对齐图像与点云。
  3. 若支持硬件触发,配置触发源与触发信号线,使相机曝光与雷达扫描起始沿对齐。
  4. 对对齐后的数据做去畸变、降采样、ROI 裁剪、无效值剔除等预处理。
  5. 将预处理结果写入统一坐标系,并发布同步后的融合输入话题。

下面是一个 ROS2 中使用 message_filters 做近似时间同步的示例:

import message_filters
from sensor_msgs.msg import Image, PointCloud2

sub_img = message_filters.Subscriber(self, Image, '/camera/depth/image_raw')
sub_pcl = message_filters.Subscriber(self, PointCloud2, '/lidar/points')

sync = message_filters.ApproximateTimeSynchronizer(
    [sub_img, sub_pcl], queue_size=10, slop=0.05)
sync.registerCallback(self.callback)

其中 slop=0.05 表示允许 50 ms 的时间偏差。若传感器支持硬触发,应优先使用 ExactTime,将 slop 设为 0 或极小值。

三、硬件触发与时间同步机制

硬件触发是解决同步问题的根本手段。常见方案包括:

  • 相机触发雷达:相机曝光信号输出到雷达的触发输入,雷达在曝光瞬间开始扫描。
  • 雷达触发相机:雷达每圈起始脉冲触发相机曝光,适合机械式激光雷达。
  • 外部同步器:使用 FPGA 或专用同步盒产生统一 PPS/触发信号,同时驱动相机与雷达。
  • PTP/gPTP:在网络层实现亚微秒级时钟同步,适合以太网接口的雷达与相机。

在 ROS2 中,硬件触发通常配合 use_sim_time=false 和驱动层时间戳重写。若驱动不支持硬触发,则只能依赖软件时间同步,此时需注意队列长度与 slop 的权衡:队列过小会丢帧,slop 过大会引入错误匹配。

四、数据格式与预处理

深度相机常见格式为 sensor_msgs/Image(16UC1 深度、8UC3 RGB),雷达常见格式为 sensor_msgs/PointCloud2。预处理的目标是统一分辨率、坐标系和无效值表示。

处理项相机侧雷达侧目的
去畸变使用内参矩阵通常不需要消除镜头畸变
降采样图像缩放体素滤波降低计算量
无效值深度 0 或 NaN距离超限点避免污染融合
ROI 裁剪裁剪感兴趣区域角度/距离滤波聚焦有效区域
坐标变换光学坐标系雷达坐标系统一到机体坐标系

预处理代码示例(Python + OpenCV):

depth = bridge.imgmsg_to_cv2(msg, desired_encoding='16UC1')
depth = cv2.undistort(depth, K, D)
depth[depth == 0] = np.nan
depth = cv2.resize(depth, (320, 240), interpolation=cv2.INTER_NEAREST)

五、常见采集问题与排障

实际飞行中,采集问题往往表现为“数据看起来有,但融合效果差”。以下是高频问题与排查方向:

  • 时间戳跳变:检查是否混用 ROS_TIME 与系统时间,或驱动是否在每帧重新打时间戳。
  • 丢帧与队列溢出:查看 queue_size 与话题频率,必要时增大队列或降低分辨率。
  • 同步失败:确认 slop 是否过小、传感器频率是否差异过大,或硬件触发线是否接反。
  • 深度空洞:检查曝光时间、环境光、反射率,以及是否与雷达视场重叠不足。
  • 点云与图像错位:优先检查外参标定与时间同步,再检查坐标系变换方向。
不要用“先采集后对齐”替代硬件同步。后处理只能补偿固定延迟,无法修复随机抖动。若无人机平台振动大,建议在采集阶段就启用硬触发并记录触发时刻的 IMU 数据,便于后续做运动补偿。

六、案例:室内无人机巡检采集配置

某室内巡检无人机搭载 RealSense D435i 与 Livox Mid-360。初始方案使用软件同步,飞行速度 1.5 m/s 时点云与深度图出现约 3 cm 错位。改为 Livox 的 PPS 输出触发相机曝光后,错位降至 5 mm 以内。同时将深度图降采样至 320×240,点云体素滤波 0.05 m,融合节点 CPU 占用从 85% 降至 42%。

该案例说明:硬件触发解决时间对齐,预处理解决计算负载,两者缺一不可。采集阶段的目标不是“拿到最多数据”,而是“拿到最一致、最干净、最可对齐的数据”。

深度相机与雷达采集同步链路 深度相机 RGB / Depth / IR 激光雷达 PointCloud2 硬件触发 / PPS 同步信号 相机驱动节点 时间戳重写 雷达驱动节点 时间戳重写 message_filters 时间同步 ApproximateTime / ExactTime 图像预处理 去畸变 / 降采样 / 无效值 点云预处理 体素滤波 / 距离滤波 / ROI 融合输入:统一时间基准 + 统一坐标系 同步后的深度图与点云 时间轴: t0 t1 t2 t3

总结来看,采集与同步不是简单的“开驱动、录包”,而是一条从硬件触发、驱动时间戳、软件同步、预处理到统一坐标系的完整链路。只有把每个环节的误差控制在可接受范围内,后续的深度融合才有可靠的数据基础。