第3章:Apollo系统架构概览
各位同学,今天我们来聊聊Apollo 8.0和9.0的软件栈。说实话,我刚接触Apollo时也被它的架构吓了一跳——模块太多了。但别担心,我会用最直白的方式帮你理清楚。
3.1 整体软件栈:从底层到上层
Apollo的软件栈,说白了就是一套分层设计的系统。我习惯把它想象成一栋楼:
- 底层(RTOS/Linux):负责硬件调度,跑的是Ubuntu + 实时内核补丁
- 中间层(Cyber RT):Apollo自研的通信框架,替代了ROS 1的节点通信
- 应用层:感知、规划、控制、定位等模块
嗯,这里要注意:Apollo 8.0开始全面拥抱Cyber RT,不再依赖ROS 1了。为什么?因为ROS 1的实时性不够,你想想看,自动驾驶车辆在高速上跑,消息延迟几十毫秒可能就出大事了。
核心要点:Cyber RT是Apollo的通信基石,它提供了发布/订阅、服务调用、任务调度等能力。我个人习惯把Cyber RT看作“自动驾驶版ROS 2”,虽然它比ROS 2更早诞生。
3.2 模块划分:五大核心模块
Apollo 8.0/9.0的模块划分非常清晰。我把它总结为“感知-定位-规划-控制-人机交互”五件套。下面这张图能帮你快速建立整体认知:
这张图展示了数据流动的方向:感知模块先拿到传感器数据,定位模块告诉你“我在哪”,规划模块决定“我要去哪”,控制模块负责“怎么去”。整个过程都跑在Cyber RT之上。
3.3 感知模块:车辆的眼睛
感知模块负责处理摄像头、激光雷达、毫米波雷达的数据。Apollo 8.0引入了基于Transformer的检测模型,9.0又做了进一步优化。
我记得有一次在测试中,激光雷达检测到了前方障碍物,但摄像头因为逆光没识别出来。这时候Apollo的融合算法就起作用了——它把两种传感器的结果做了加权融合,最终正确判断了障碍物位置。
避坑指南:我曾经在集成时发现感知模块CPU占用率飙到90%以上。后来排查发现是点云预处理线程数设置太多,导致上下文切换开销过大。建议根据实际CPU核心数调整lidar_preprocessor_num_threads参数。
3.4 定位模块:知道自己在哪里
定位模块融合了GPS、IMU、激光雷达点云匹配(NDT算法)和视觉里程计。Apollo 9.0的定位精度在开放道路上能达到厘米级。
这里有个关键点:GPS信号丢失时怎么办?Apollo的解决方案是“多传感器融合定位”——即使GPS失效,依靠IMU和激光雷达的NDT匹配,车辆依然能保持定位。我在隧道测试中验证过,定位误差在10秒内不超过20厘米。
3.5 规划模块:决策与路径
规划模块分为三层:
- 路由(Routing):全局路径规划,类似导航软件
- 决策(Decision):处理交通规则、障碍物行为预测
- 轨迹规划(Trajectory Planning):生成平滑的行驶轨迹
Apollo 8.0引入了“场景引擎”的概念,把不同驾驶场景(如十字路口、高速汇入)封装成独立的决策逻辑。说白了,就是让车辆知道“在什么场景下该做什么事”。
注意:规划模块的输出是轨迹点序列,每个点包含位置、速度、加速度、时间戳。控制模块必须严格按这个轨迹执行。如果规划频率(默认10Hz)和控制频率(默认50Hz)不匹配,会导致车辆抖动。我建议在控制模块中做轨迹插值,把10Hz的轨迹点插值到50Hz。
3.6 控制模块:执行与反馈
控制模块接收规划轨迹,输出油门、刹车、转向指令。Apollo默认使用LQR(线性二次型调节器)和MPC(模型预测控制)两种算法。
我个人更推荐MPC,因为它能处理约束条件(比如最大转向角、加速度限制)。但MPC计算量大,对硬件要求高。如果你用的是工控机,建议先用LQR调通,再升级到MPC。
3.7 模块间通信:Cyber RT的Channel机制
模块之间通过Cyber RT的Channel通信。每个Channel有一个名称和数据类型。比如:
// 感知模块发布障碍物信息
channel: /apollo/perception/obstacles
type: PerceptionObstacles
// 规划模块发布轨迹
channel: /apollo/planning/trajectory
type: ADCTrajectory
// 控制模块发布控制指令
channel: /apollo/control/command
type: ControlCommand
你可以在Cyber RT的Monitor工具中实时查看这些Channel的数据流。我调试时经常用cyber_monitor命令,它能显示每个Channel的发布频率、数据大小、延迟等信息。
3.8 总结:一张表看懂模块职责
| 模块 | 输入 | 输出 | 关键算法 |
|---|---|---|---|
| 感知 | 摄像头图像、激光雷达点云、雷达数据 | 障碍物列表、车道线、交通标志 | YOLO、PointPillars、Transformer |
| 定位 | GPS、IMU、点云、图像 | 车辆位姿(x, y, z, roll, pitch, yaw) | NDT匹配、EKF融合 |
| 规划 | 障碍物信息、定位结果、地图数据 | 轨迹点序列 | A*、Dijkstra、QP优化 |
| 控制 | 规划轨迹、车辆状态 | 油门/刹车/转向指令 | LQR、MPC、PID |
好了,这一章的内容就到这里。记住:理解Apollo的架构,关键是把握模块间的数据流和依赖关系。下一章我们会深入Cyber RT的通信机制,到时候手把手教你写一个简单的发布/订阅程序。