共计 1499 个字符,预计需要花费 4 分钟才能阅读完成。
一、背景与痛点
在开发 Apollo 自动驾驶小车时,我们遇到了两个主要问题:

- 传感器时钟同步问题 :
- 使用了多种异构传感器(激光雷达、摄像头、IMU 等)
- 各传感器时钟源不同,数据时间戳不一致
-
导致感知融合时出现数据对齐误差
-
规划模块实时性不足 :
- 复杂场景下规划算法计算量激增
- 导致控制指令输出延迟
- 在高速场景下可能引发安全问题
二、总体架构设计
2.1 硬件架构
- 传感层 :
- 16 线激光雷达(20Hz 扫描频率)
- 全局快门摄像头(60fps,HDR 支持)
-
6 轴 IMU(200Hz 采样率)
-
计算单元 :
- 主控:NVIDIA Xavier NX(ARM Cortex-A57+Volta GPU)
- 协处理器:Artix-7 FPGA(用于传感器预处理)
- CAN 总线接口(500kbps 速率)
2.2 软件架构
基于 Apollo Cyber RT 框架的分层设计:
- 感知层 :
- 传感器驱动模块
- 多源数据融合
-
障碍物检测与跟踪
-
决策层 :
- 场景理解
- 行为决策
-
运动规划
-
控制层 :
- 线控接口
- PID 控制器
- 安全监控
三、关键优化方案
3.1 传感器数据同步
采用 DDS 通信的 QoS 配置优化(ROS 2 示例):
// 创建同步订阅者
auto qos = rclcpp::QoS(rclcpp::KeepLast(10));
qos.best_effort();
qos.durability_volatile();
// 激光雷达订阅
lidar_sub_ = create_subscription<sensor_msgs::msg::PointCloud2>(
"/lidar", qos,
[this](const sensor_msgs::msg::PointCloud2::SharedPtr msg) {
// 时间对齐处理
auto aligned_data = time_aligner_.process(msg);
});
3.2 规划算法优化
实现计算量分级策略的线程池:
// 创建优先级线程池
ThreadPool pool(4); // 4 个 worker 线程
// 提交不同优先级的任务
pool.enqueue([] {// 高优先级:碰撞检测}, Priority::High);
pool.enqueue([] {// 低优先级:路径平滑}, Priority::Low);
3.3 ARM NEON 指令优化
点云降采样加速示例:
void downsample(const float* input, float* output) {float32x4_t voxel_size = vdupq_n_f32(0.1f);
for (int i = 0; i < n; i += 4) {float32x4_t points = vld1q_f32(input + i);
float32x4_t quantized = vmulq_f32(vcvtq_f32_s32(vcvtq_s32_f32(points)),
voxel_size);
vst1q_f32(output + i, quantized);
}
}
四、性能对比
| 优化项 | 优化前延迟 | 优化后延迟 |
|---|---|---|
| 传感器数据同步 | 32ms | 8ms |
| 规划模块 | 56ms | 22ms |
| 端到端延迟 | 120ms | 65ms |
五、避坑指南
- FPGA 加速注意事项 :
- DMA 传输必须保证 64 字节对齐
-
使用 AXI-Stream 接口避免阻塞
-
CAN 总线优化 :
- 将控制指令分多个 CAN ID 发送
-
启用硬件时间戳功能
-
功能安全设计 :
- 关键模块采用 ASIL- D 隔离
- 实现心跳监测和 watchdog
六、动手实践建议
推荐使用 Gazebo 仿真验证控制延迟:
- 安装 Apollo 仿真环境
- 录制传感器数据包
- 修改控制频率参数
- 使用 rqt_plot 观察延迟变化
通过上述优化,我们的 Apollo 小车在测试场实现了 50km/ h 下的稳定自动驾驶。建议读者在实际项目中重点关注时间同步和计算资源分配这两个核心问题。
正文完
