4. 传感器标定与同步

各位同学,大家好。我是你们这门课的老朋友。今天咱们聊聊感知系统里最基础、也最容易被忽视的一环——数据采集与标定。

说实话,我见过太多项目,算法模型调得漂漂亮亮,一上路就翻车。为什么?八成是数据采集阶段就埋了雷。要么时间戳对不上,要么传感器参数是错的。嗯,咱们今天就把这些坑一个个填上。

1.1 传感器数据采集:别让源头脏了

数据采集,说白了就是把物理世界的信号变成数字世界的0和1。听起来简单?我刚开始做的时候也这么想,直到有一次采集了一整天,回来发现相机曝光时间设错了,所有图像全是过曝的……

这里我给大家列几个关键点:

  • 采样率匹配:激光雷达一般是10Hz或20Hz,相机可能是30fps。别让一个传感器等另一个,否则数据流会断档。
  • 数据格式统一:我习惯把所有传感器数据转成ROS bag格式。为什么?因为时间戳、坐标系、数据内容都打包在一起,后期处理省心。
  • 存储带宽:你想想看,一个64线激光雷达每秒产生几百万个点,加上高清图像,存储带宽不够的话,丢帧是必然的。

核心原则:采集时多花一分钟检查,后期调试少花一小时。

1.2 时间同步:所有传感器用同一个“钟”

时间同步,这是感知系统的命门。为什么?因为你的车在动,传感器在动,目标也在动。如果激光雷达说“我在t1时刻看到障碍物”,相机说“我在t2时刻看到同一个障碍物”,而t1和t2差了50毫秒——那这两个数据就根本对不上。

我个人习惯用两种方式:

  1. 硬件同步(PPS/GPS):每个传感器都接GPS的秒脉冲信号。精度能到微秒级。这是最靠谱的方式。
  2. 软件同步(NTP/PTP):通过以太网时间同步协议。精度在毫秒级。适合对同步要求不那么苛刻的场景。

我的经验:如果条件允许,尽量用硬件同步。我曾经在一个项目中只用软件同步,结果车辆高速行驶时,点云和图像偏差了将近半米。后来改成PPS同步,问题立刻解决。

这里给一段简单的代码,演示如何从ROS bag中提取时间戳并检查同步质量:

import rosbag
from datetime import datetime

bag = rosbag.Bag('data.bag')
lidar_times = []
camera_times = []

for topic, msg, t in bag.read_messages(topics=['/lidar/points', '/camera/image']):
    if topic == '/lidar/points':
        lidar_times.append(t.to_sec())
    elif topic == '/camera/image':
        camera_times.append(t.to_sec())

# 检查时间差
for lt, ct in zip(lidar_times[:10], camera_times[:10]):
    diff = abs(lt - ct)
    print(f'时间差: {diff*1000:.2f} ms')
    if diff > 0.05:  # 超过50ms报警
        print('⚠️ 同步异常!')

1.3 内参标定:传感器自己的“体检”

内参,就是传感器内部固有的参数。比如相机的焦距、畸变系数,激光雷达的激光束角度偏移。这些参数出厂时就有,但运输、温度变化、老化都会让它跑偏。

我记得有一次,一个同事死活标定不好相机,后来发现是镜头拧松了半圈。嗯,这种低级错误我也犯过。

常用的内参标定方法:

  • 相机内参:用棋盘格标定板,拍20-30张不同角度的照片,用OpenCV的calibrateCamera()函数搞定。
  • 激光雷达内参:一般用出厂参数,但如果你发现点云有系统性偏差(比如地面不平),可以用反射板做精细标定。

避坑指南:标定相机时,棋盘格一定要平整。我曾经用了一张皱巴巴的打印纸,结果标定出来的畸变参数全是错的,花了三天才找到原因。

1.4 外参标定:让传感器“对齐”世界

外参,描述的是传感器之间的相对位置和姿态。比如激光雷达装在车顶,相机装在挡风玻璃后面,它们看到的同一个物体,坐标是不一样的。外参就是那个“翻译官”。

外参标定有两种主流方式:

方法 精度 适用场景 我的评价
手动测量 厘米级 粗略对齐 简单但不准,适合初调
靶标标定 毫米级 实验室环境 精度高,但操作繁琐
自然场景标定 厘米级 野外/道路 我最喜欢的方式,省事

自然场景标定,说白了就是找一些特征明显的物体(比如电线杆、路牌),让激光雷达和相机同时看到它,然后通过匹配点对来解算外参。我常用的工具是lidar_camera_calibration这个ROS包。

核心公式:
P_camera = R * P_lidar + T
其中R是旋转矩阵,T是平移向量。标定的目标就是求出R和T。

1.5 知识体系总览

下面这张图,是我自己总结的数据采集与标定的完整流程。你把它存下来,以后做项目时对照着看,基本不会漏掉关键步骤。

数据采集与标定知识体系 1. 传感器数据采集 采样率匹配 | 数据格式统一 | 存储带宽保障 2. 时间同步 硬件同步(PPS/GPS) | 软件同步(NTP/PTP) 3. 内参标定 相机内参 | 激光雷达内参 4. 外参标定 手动测量 | 靶标标定 | 自然场景标定 输出:标定后的传感器参数 + 时间对齐的数据流

1.6 本章小结

数据采集与标定,听起来像是体力活,但其实是整个感知系统的地基。地基不稳,上面盖多高的楼都没用。

我个人建议,每次做项目前,先花一天时间把传感器的时间同步和内外参标定搞定。别急着跑算法。你想想看,如果数据本身就有问题,算法再牛也白搭。

好了,这一章就到这里。下一章咱们聊聊点云预处理——怎么把原始点云变成干净、可用的数据。

课后小作业:找一台有激光雷达和相机的设备,采集一段数据,检查时间戳偏差是否在50ms以内。如果超过,想想怎么优化。