感知:自动驾驶的第一道关
如果把人开车的过程拆开,第一件事永远不是打方向,而是看清楚。自动驾驶的感知模块承担的就是这一步:把相机图像、激光雷达点云、毫米波雷达回波这些原始信号,转换成车辆周围可被下游使用的结构化描述——哪里有车、哪里有人、哪里是路沿、哪里还能走。
这一步之所以难,是因为真实道路既不干净也不封闭。逆光、雨雾、夜间低照度会削弱相机;粉尘与大雨会散射激光雷达的激光束;金属护栏、隧道壁会产生多径反射干扰毫米波雷达。任何单一传感器都有明确的失效场景,这正是多传感器融合存在的理由:让不同物理原理的传感器在被测量对象上互相补位,而不是互相替代。
感知的目标不是看得最远或看得最清,而是在尽可能多的场景下都不出现致命的漏检与误检。冗余的价值,恰恰体现在某种传感器失效的那几百毫秒。
- 传感器互补相机擅长语义与色彩,激光雷达擅长精确几何,毫米波雷达擅长测距测速且不受光照影响。
- 时空对齐融合的前提是把多路数据对齐到同一时间戳与同一坐标系,标定误差会直接传导为融合误差。
- BEV 视角把多路相机与雷达统一到车辆俯视平面,是近年主流感知架构的公共底座。
- Occupancy用三维体素表达每个空间是否被占据,覆盖传统目标框难以描述的不规则障碍物。
三种传感器的能力与短板
工程上做传感器选型,本质上是在成本、可靠性与算力之间做权衡。三种主流传感器各有一条清晰的能力边界:相机提供稠密的语义纹理,却没有直接的深度;激光雷达提供高精度三维几何,但受天气与成本制约;毫米波雷达能直接测出相对速度,却缺少足够的横向分辨率。
| 传感器 | 核心优势 | 主要短板 | 典型角色 |
|---|---|---|---|
| 相机 | 分辨率高、语义丰富、成本低 | 受光照与天气影响大,深度需估算 | 识别车道线、交通标志、红绿灯与目标类别 |
| 激光雷达 | 三维几何精度高,可直接获得距离 | 雨雾粉尘下衰减,成本与数据量大 | 提供精确的障碍物轮廓与可通行空间 |
| 毫米波雷达 | 直接测距测速,全天候稳定 | 角分辨率低,静止目标易混淆 | 提供远距离的速度与距离冗余 |
需要注意的是,三者的融合不是简单相加。当相机说前方是空车道、激光雷达却扫到一个轮廓时,系统需要有明确的仲裁逻辑;当雷达报出 60 km/h 的相对速度而视觉没有对应目标时,也要判断这是真实来车还是护栏多径。这些冲突处理规则,往往比单个模型的精度更能决定最终的感知质量。
多传感器融合:标定与时空对齐
融合的第一道门槛不是算法,而是对齐。不同传感器的采样频率、曝光时刻、安装位置都不一样:相机通常每秒 30 帧,激光雷达 10 到 20 帧,雷达可达 50 帧以上。如果不做时间同步,一辆以 120 km/h 行驶的车在两次采样之间就已经前进了半米多,融合结果会出现明显的重影。
空间对齐则依赖标定:内参描述相机自身的成像几何,外参描述各传感器相对车辆坐标系的位置与姿态。标定误差会在投影链路上被逐级放大,因此量产车通常需要在出厂、维修后乃至行驶中做在线标定与漂移监测。下面这段伪代码给出了一个最小可读的融合流程:
# 多传感器融合:先按时间戳对齐,再统一到车辆坐标系
def fuse_frame(cam_list, lidar_ts, radar_list):
# 1) 时间对齐:为每路传感器找最接近激光雷达帧的时刻
t_ref = lidar_ts
cam_synced = [nearest(cam.frame, t_ref) for cam in cam_list]
radar_synced = [nearest(rad.frame, t_ref) for rad in radar_list]
# 2) 空间对齐:相机像素 → 相机坐标系 → 车辆坐标系
points = []
for cam in cam_synced:
uvd = back_project(cam.pixels, cam.intrinsics) # 像素 + 深度分布
xyz_cam = deproject(uvd, cam.intrinsics) # 相机坐标系下的三维点
xyz_ego = cam.extrinsics @ xyz_cam # 外参把点变换到车辆坐标系
points.append(xyz_ego)
# 3) 雷达目标同样投影到车辆坐标系,与视觉、激光结果做关联
for rad in radar_synced:
points.append(rad.extrinsics @ rad.targets)
# 4) 按空间重叠度合并同一目标,重叠不足则保留为独立观测
return merge_by_iou(points, iou_thr=0.5)
这段逻辑里最容易被低估的是 nearest 这个时间对齐函数:它实际处理的是插值、丢帧与传感器时间戳漂移。真实系统里,时间对齐失败往往是看起来很正常、却偶发一次误刹的根因。
BEV 视角:把多路输入画进同一张图
传统的图像检测结果停留在像素坐标里,而规划模块需要的是车辆坐标系下的位置。为了弥合这道鸿沟,近年的主流做法是把所有传感器统一到一张鸟瞰特征图(BEV)上:以自车为中心向四周铺开若干格子,每个格子记录该处是否存在目标、是什么类别、朝哪个方向。
BEV 的价值在于统一:无论信息来自前视相机、环视相机还是激光雷达,最终都落到同一个俯视平面上,下游的检测头、预测模块与占用栅格网络因此可以共享同一套空间表示。典型的处理链路如下:
图像特征(N 路相机)
│ 内外参 + 深度分布
▼
视锥投影 → 三维空间采样
│
▼
BEV 特征图(H × W × C)
│ BEV Encoder + 时序融合
▼
检测头 → 三维目标框 / 语义 / 占用栅格
需要提醒的是,BEV 并不是免费的。把图像特征抬升到三维空间需要深度估计或多视角几何,这一步一旦在标定或深度上出错,就会表现为错误的高度估计与目标框漂移。因此 BEV 方案的质量,很大程度上取决于标定精度与深度监督信号的可靠性。
目标检测与 Occupancy 网络
有了统一的 BEV 表示之后,感知输出通常分成两类任务。一类是目标检测,为感兴趣的物体回归出一个带朝向的三维框;另一类是占用预测,直接判断三维空间中的每个体素是否被占据。二者的分工可以这样理解:
- 三维目标检测输出框的中心、尺寸、朝向与类别,适合车辆、行人、骑行者这类有明确几何形状、需要跟踪与预测轨迹的对象。
- Occupancy 网络输出稠密的体素占用与语义,适合异形障碍物、掉落货物、施工围挡这类无法用标准框描述的对象。
- 时序融合把连续多帧的 BEV 特征对齐叠加,可以在目标被短暂遮挡时维持稳定输出,也能估计速度。
- 不确定性建模为每个检测结果给出置信度或分布,让下游规划知道哪些目标可以信任、哪些需要保守对待。
过去感知只做三维框,遇到形状不规则的障碍物时只能靠漏检来暴露问题。Occupancy 的流行,本质上是承认了世界不都是长方体,用更稠密、更诚实的表示去覆盖长尾场景。
数据闭环与 Corner Case
感知模型的能力上限,往往不是网络结构决定的,而是数据决定的。量产系统都会建立数据闭环:车端记录触发事件(急刹、接管、低置信度)的片段,回传到云端做标注与难例挖掘,再进入训练集迭代模型,最后通过 OTA 下发回车辆。
这条闭环的关键在于触发条件的设计。只记录事故片段会让数据分布极度偏斜,因此工程上更常见的做法是按场景维度做均衡采样:夜间、雨雪、隧道、施工区、异形车辆各保留一定比例,同时用自动标注与主动学习降低标注成本。极端场景从来不缺,缺的是发现它、标注它、并把它稳定复现出来的工程能力。
感知评测与常见工程坑
评测感知系统不能只看 mAP 一个数字。面向安全的设计更关心漏检率,尤其是行人与两轮车;也关心误检带来的误刹,以及精度在不同距离区间上的衰减。一个常见误区是用单帧离线指标代表系统能力,却忽略了时序稳定性与触发逻辑。
工程上高频出现的几个坑值得提前避开:
- 标定漂移未监控:外参随温度、碰撞、维修变化,导致融合结果缓慢劣化且不易察觉。
- 只看平均精度:忽略长尾场景的漏检,而安全恰恰由尾部决定。
- 训练与部署预处理不一致:归一化、裁剪、颜色空间在两端不同,模型在车上表现与离线不符。
- 忽视标注噪声:多传感器标注一致性差时,模型学到的是一套自相矛盾的标签。
感知做得越扎实,后面的预测与规划就越像一道工程题;感知漏洞越多,再聪明的决策也只能在不确定中冒险。
下一篇我们会把视角从感知再往后推一步,讨论端到端自动驾驶与车路协同,是如何重新组织这条从传感器到执行器的流水线的。