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 的噪声通常进一步分为随机游走和测量噪声,分别对应陀螺仪和加速度计的偏置不稳定性。激光雷达的测距噪声常建模为距离相关的高斯噪声,深度相机则可能包含飞点、多路径和边缘模糊等非高斯成分。
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 做精确同步,但要求时间戳完全一致,实际中更常用近似同步。
四、案例与常见误区
假设一个移动机器人同时使用 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 感知与定位系统的第一步。只有在数据进入融合算法之前把时间戳、坐标系和协方差处理正确,后续的标定、滤波和优化才有意义。