3. 传感器数据基础

在 ROS2 系统中,传感器是机器人感知外部世界的入口。无论是激光雷达、深度相机、IMU、GNSS 还是轮式编码器,它们输出的数据最终都要经过驱动节点封装为 ROS2 消息,再通过中间件传输给感知、定位、规划等模块。理解传感器数据的类型、格式、采样率、精度、噪声模型以及时间同步机制,是后续做数据融合、标定和系统调优的基础。

一、常见传感器类型与数据格式

ROS2 中传感器数据通常以标准消息类型发布。下表列出常见传感器及其典型消息格式和关键字段:

传感器 典型消息类型 关键字段 数据维度
2D 激光雷达 sensor_msgs/LaserScan ranges、angle_min、angle_increment 一维距离数组
3D 激光雷达 sensor_msgs/PointCloud2 fields、data、point_step 三维点云
深度相机 sensor_msgs/Image + CameraInfo encoding、data、K、D 二维深度/彩色图
IMU sensor_msgs/Imu angular_velocity、linear_acceleration、orientation 三轴角速度/加速度/姿态
GNSS sensor_msgs/NavSatFix latitude、longitude、altitude、status 经纬高 + 协方差
轮式编码器 nav_msgs/Odometry pose、twist、covariance 位姿 + 速度

这些消息都带有 header 字段,其中 stamp 表示数据采集时刻,frame_id 表示传感器坐标系。正确填写这两个字段,是后续做时间同步和坐标变换的前提。

二、采样率、精度与噪声模型

采样率决定单位时间内传感器输出多少帧数据。例如激光雷达常见 10 Hz,IMU 可达 100~1000 Hz,相机通常 30 Hz。采样率越高,系统对动态环境的响应越快,但也会增加 CPU、带宽和存储压力。在 ROS2 中,采样率通常由驱动节点参数控制,例如:

# 以 IMU 驱动为例
ros2 param set /imu_node publish_rate 200.0
ros2 param set /imu_node frame_id "imu_link"

精度描述测量值与真实值的接近程度,常用分辨率、均方根误差或协方差表示。噪声模型则描述测量误差的统计特性。工程上最常用的是高斯白噪声模型:

z(t) = x(t) + n(t)
n(t) ~ N(0, σ²)

其中 z(t) 是测量值,x(t) 是真实值,n(t) 是零均值高斯噪声。IMU 的噪声通常进一步分为随机游走和测量噪声,分别对应陀螺仪和加速度计的偏置不稳定性。激光雷达的测距噪声常建模为距离相关的高斯噪声,深度相机则可能包含飞点、多路径和边缘模糊等非高斯成分。

在 ROS2 中,很多传感器消息都带有协方差字段,例如 Imu.angular_velocity_covariance、NavSatFix.position_covariance。这些协方差不是装饰,而是滤波器(如 EKF、UKF)计算权重的重要输入。标定噪声参数时,应尽量让协方差与真实误差统计一致。

三、时间同步概念

多传感器系统中,不同传感器有各自的时钟和采样时刻。如果直接拿时间戳不一致的数据做融合,会引入运动畸变和错误关联。ROS2 提供两种时间源:系统时间和仿真时间。使用仿真时间时,需要设置 use_sim_time 参数:

ros2 param set /lidar_node use_sim_time true
ros2 param set /imu_node use_sim_time true

时间同步分为硬同步和软同步。硬同步通过硬件触发信号让多个传感器在同一时刻曝光或采样;软同步则在软件层根据时间戳对齐数据。ROS2 中常用 message_filters 做近似时间同步:

import message_filters
from sensor_msgs.msg import Image, CameraInfo

image_sub = message_filters.Subscriber(self, Image, '/camera/image')
info_sub = message_filters.Subscriber(self, CameraInfo, '/camera/info')

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

其中 slop 表示允许的最大时间差。若两帧时间差超过该值,则不会触发回调。对于 IMU 和激光雷达融合,常使用 TimeSynchronizer 做精确同步,但要求时间戳完全一致,实际中更常用近似同步。

ROS2 多传感器数据流与时间同步 激光雷达 10 Hz / PointCloud2 IMU 200 Hz / Imu 深度相机 30 Hz / Image GNSS 5 Hz / NavSatFix lidar_driver stamp + frame_id imu_driver covariance 填充 camera_driver CameraInfo 标定 gnss_driver status + 协方差 ROS2 中间件(DDS) 话题发布 / 订阅 · QoS 策略 · 时间戳传递 message_filters ApproximateTimeSynchronizer EKF / UKF 融合 协方差加权 · 状态估计 t_lidar t_imu t_cam t_gnss

四、案例与常见误区

假设一个移动机器人同时使用 10 Hz 激光雷达和 200 Hz IMU 做定位。若直接以激光雷达帧为基准,把最近一帧 IMU 数据与之关联,而不检查时间差,当机器人以 1 m/s 运动时,50 ms 的时间偏差会带来约 5 cm 的位置误差。若机器人快速转弯,角速度 90°/s,50 ms 偏差则对应约 4.5° 的姿态误差,足以导致点云匹配失败。

常见误区一:忽略 frame_id,导致 TF 树断裂。常见误区二:所有传感器都使用系统时间,但仿真环境中未设置 use_sim_time,造成时间戳跳变。常见误区三:把协方差全部填零,滤波器无法正确分配权重。常见误区四:认为采样率越高越好,忽略 CPU 和带宽瓶颈。

复盘时,建议按以下清单逐项检查:

  • 每个传感器消息的 header.stamp 是否来自真实采集时刻,而非回调时刻。
  • header.frame_id 是否与 URDF/TF 中的坐标系名称一致。
  • 多传感器融合前是否经过 message_filters 同步,slop 是否合理。
  • 协方差字段是否根据标定结果填写,而非全零或随意赋值。
  • 仿真环境下所有节点是否统一设置 use_sim_time。
  • 采样率是否与下游算法匹配,是否存在不必要的降采样或丢帧。

掌握传感器数据类型、采样率、精度、噪声模型和时间同步,是构建可靠 ROS2 感知与定位系统的第一步。只有在数据进入融合算法之前把时间戳、坐标系和协方差处理正确,后续的标定、滤波和优化才有意义。