跳转至

架构与时延:模块边界、时间预算与功能安全

本页关注自动驾驶软件框架的核心骨架:如何拆分模块、管控时延、实现功能安全隔离。


1. 软件分层架构

典型自动驾驶软件栈按职责分为以下层次:

┌──────────────────────────────────────────────────────┐
│                   应用层(Application)               │
│  感知 │ 预测 │ 规划 │ 控制 │ 定位 │ 地图匹配          │
├──────────────────────────────────────────────────────┤
│                   中间件层(Middleware)               │
│  消息传递(Topic/Service) │ 参数服务 │ 生命周期管理   │
├──────────────────────────────────────────────────────┤
│                   运行时层(Runtime)                  │
│  调度器 │ 资源管理 │ 时间同步 │ 日志收集              │
├──────────────────────────────────────────────────────┤
│                   硬件抽象层(HAL)                   │
│  传感器驱动 │ 执行器接口 │ GNSS/IMU 驱动             │
└──────────────────────────────────────────────────────┘

架构稳定性

模块边界一旦稳定,接口变更代价极高(跨团队协调、回归测试)。在系统早期投入充足时间定义清晰接口,是长期可维护性的关键。


2. 模块边界设计原则

2.1 接口规范要素

每个模块的接口应明确以下内容:

要素 说明 示例
输入消息 Topic 名称、消息类型、预期频率 /perception/objects, ObjectList, 20 Hz
输出消息 Topic 名称、消息类型、保证频率 /planning/trajectory, Trajectory, 10 Hz
时戳语义 消息时戳含义(感知时刻 vs 发布时刻) 优先使用感知时刻
失效码 模块自我诊断状态的标准编码 0=正常,1=降级,2=失效
版本号 消息格式版本,支持兼容性检测 v1.3.0

2.2 主链路与支撑链路

主链路(实时,高优先级):
  感知 → 融合 → 预测 → 规划 → 控制

支撑链路(准实时/非实时):
  高精地图更新、诊断监控、参数热更新

工具链路(离线/异步):
  日志上传、数据统计、模型评估

3. 端到端时延分析

3.1 时延预算分配

自动驾驶闭环时延从传感器曝光到执行器响应:

环节 预算(城区) 预算(高速) 说明
传感器曝光与读出 30–50 ms 30–50 ms 相机帧率决定
感知推理 30–60 ms 30–60 ms GPU推理时延
多传感器融合 10–20 ms 10–20 ms 时间对齐+融合
预测 10–30 ms 10–30 ms Transformer 推理
规划决策 20–50 ms 20–50 ms 轨迹优化
控制计算 5–10 ms 5–10 ms 高频控制环
通信与执行器 5–15 ms 5–15 ms CAN传输+建压
总计 ~150 ms ~170 ms 高速场景余量更紧

长尾时延的危害

控制系统关注的不是平均时延,而是 P99/P99.9。若 P99 超过 300 ms,高速场景下控制环将出现明显不稳定性。必须监控和控制长尾分布。

3.2 关键路径分析

使用有向无环图(DAG)表示任务依赖:

Camera(0ms) ──┐
LiDAR(0ms)  ──┤─→ 融合(40ms) ─→ 预测(70ms) ─→ 规划(100ms) ─→ 控制(110ms)
Radar(0ms)  ──┘
GNSS/IMU(0ms) ──────────────────────────────────────────────→ 控制(110ms)

关键路径(最长依赖链)决定整体时延下限,优化应优先针对关键路径上的节点。

3.3 时延测量方法

# 在每个模块的入口和出口记录时戳
class ModuleTimer:
    def __init__(self, module_name):
        self.name = module_name

    def on_receive(self, msg):
        self.t_recv = now()
        self.t_sensor = msg.header.timestamp  # 感知时刻

    def on_publish(self, msg):
        t_pub = now()
        latency_proc = t_pub - self.t_recv        # 处理时延
        latency_e2e  = t_pub - self.t_sensor      # 端到端时延
        publish_metric(f"{self.name}_proc_ms", latency_proc * 1000)
        publish_metric(f"{self.name}_e2e_ms",  latency_e2e  * 1000)

4. 实时调度策略

4.1 POSIX 实时调度

Linux 实时调度策略:

策略 说明 适用
SCHED_FIFO 固定优先级,先进先出 感知/控制主线程
SCHED_RR 固定优先级 + 时间片轮转 多传感器并行处理
SCHED_DEADLINE EDF,指定 deadline 和执行预算 精确时间约束任务
SCHED_OTHER 普通分时调度 日志、统计等非实时任务

优先级分配建议:

优先级 90:控制执行(最高实时性需求)
优先级 80:感知主链路
优先级 70:规划
优先级 60:定位更新
优先级 20:日志、统计

4.2 CPU 隔离与绑定

通过 CPU affinity 将关键任务绑定到特定核:

# 隔离 CPU 核 2-7(内核启动参数)
isolcpus=2-7 nohz_full=2-7 rcu_nocbs=2-7

# 将进程绑定到核 2
taskset -cp 2 <pid>

4.3 异步流水线与双缓冲

避免阻塞等待:感知输出直接写入下一模块的输入缓冲区,双缓冲(Ping-Pong Buffer)防止读写冲突:

生产者(感知)       消费者(预测)
写入 Buffer_A ─→  读取 Buffer_B
写入 Buffer_B ─→  读取 Buffer_A
(交替切换,无锁访问)

5. GPU/NPU 任务调度

5.1 多模型并发推理

CUDA Stream 分配策略:
  Stream 0(高优先级):感知主模型(BEV Backbone)
  Stream 1:预测模型
  Stream 2:辅助感知(车道线/可行驶区域)
  Stream 3(低优先级):数据增强/离线推理

多 CUDA Stream 并行可提升 GPU 利用率,但需要注意:

  • 共享显存带宽,并发过多反而降低效率
  • 不同 Stream 之间的同步开销
  • 内存碎片管理

5.2 推理延迟优化

技术 效果 代价
TensorRT/NPU 编译优化 2–5× 加速 需要重新编译,精度可能损失
INT8/FP16 量化 1.5–3× 加速 精度验证成本
批处理(Batching) 提升吞吐,增加时延 适合异步推理场景
动态形状 灵活性强 编译时间长

6. 功能安全架构

6.1 故障检测机制

机制 检测目标 实现方式
心跳超时 模块是否存活 定期发布心跳消息,超时触发告警
输出合理性检查 输出是否异常 速度跳变、坐标跳变、置信度异常
频率监控 发布频率是否正常 统计周期内消息数,偏离阈值告警
看门狗(Watchdog) 整个进程是否冻结 硬件/软件看门狗,超时复位

6.2 故障隔离策略

故障等级分类:
  L1(轻度):单传感器降级,功能受限但可继续
  L2(中度):主链路降级,切换保守策略
  L3(重度):规划或控制失效,触发 TOR
  L4(严重):无法安全运行,触发 MRC

6.3 安全降级决策树

检测到异常
│
├─ 感知模块失效
│   ├─ 单摄像头失效 → 降低该方向感知权重,限速
│   ├─ LiDAR失效 → 切换视觉主导,限速至 60 km/h
│   └─ 主感知失效 → TOR → MRC
│
├─ 规划模块失效(超时/无解)
│   ├─ 连续 1 帧失效 → 使用上周期轨迹延续
│   ├─ 连续 3 帧失效 → 减速保持车道
│   └─ 连续 5 帧失效 → TOR → MRC
│
└─ 控制模块失效
    └─ 立即触发 MRC(最高优先级)

7. 常见工程问题

问题 根因 解决思路
接口频繁变更 需求不稳定,接口未冻结 建立接口 API Review 流程,变更需版本号递增
日志粒度不足 问题复现困难 为每帧数据附加唯一 frame_id,模块间传递
只看平均时延 长尾问题被掩盖 监控 P95/P99,建立自动告警
模块间循环依赖 难以独立测试 强制分层,低层不依赖高层
调度抖动导致不稳定 非实时任务干扰关键任务 CPU隔离 + 优先级调整

8. 关键指标监控看板

建议监控以下核心指标:

指标 说明 告警阈值示例
感知处理时延 P99 感知模块端到端时延 > 80 ms
规划超时率 规划未在预算内完成的比例 > 0.1%
控制环频率 控制指令发布频率 < 90% 目标频率
端到端时延 P99 全链路时延 > 200 ms
系统 CPU 利用率 整体算力消耗 > 85%
GPU 利用率 推理算力使用情况 > 90%(持续超载)