
简介Apollo星火自动驾驶比赛项目源码覆盖人行横道、红绿灯、借道绕行、慢速车绕行与施工区域减速等典型赛题并从代码调试、Dreamview可视化回放、赛事编译缓存利用到具体控制逻辑给出完整的参赛实现思路适合备战Apollo赛事或学习自动驾驶行为规划的开发者参考。资源共4个文件包含Markdown实现说明、HTML辅助页面、代码包及相关配置文件压缩包约6KB体量虽小但结构清晰便于快速定位关键模块。已有499人学习下载。通过该资源可了解人行横道场景中如何判断行人通过并构建STOP墙、设置停车时长红绿灯场景下如何配置参数与切换阶段以及绕行和施工区场景的减速避让策略结合源码还可梳理Apollo工程的参数配置与判断流程为后续算法优化提供可落地的代码参照。 Apollo自动驾驶比赛解析这个话题自从我开始带队参加比赛到今年已经连续折腾了三届。从最早只会跑通官方Demo到后来能在仿真赛里稳定拿名次我最大的感受是比赛表面上考的是算法能力实际上考的是对源码的理解深度。Apollo这个开源自动驾驶平台代码量巨大模块划分清晰但如果你只把它当黑盒用跑完比赛就扔那真的浪费了它最值钱的部分。借这篇文章我想把比赛拆开揉碎讲清楚赛题到底在考什么、源码里的关键模块怎么组织、比赛现场哪些细节最终决定了名次。这篇文章适合准备参加Apollo系列赛事的学生队伍也适合第一次接触Apollo源码、想系统学习的工程师。1. 比赛整体设计与赛题拆解1.1 竞赛核心流程与任务拆解每一届Apollo比赛的赛制细节会有调整但整体框架非常稳定官方提供一套高精地图覆盖的仿真环境参赛队伍需要在里面完成从起点到终点的自动驾驶任务。场景里会故意布置一系列难点包括遮挡环境下的行人穿行、连续弯道、窄路会车、信号灯路口左转以及突发障碍物切入。部分场次还会加入泊车功能这种复合场景对感知、规划、控制的协同要求极高。赛制上大部分采用线上仿真后排名的机制。所有队伍在同一套环境里跑同一批场景系统自动评分核心指标包括完成时间、违规次数比如压实线、闯红灯、碰撞以及整车运行的鲁棒性。这里特别要注意评测通常不是跑一次就结束而是多轮连续运行取综合表现这对系统的稳定性提出了远超算法比赛的要求。你精心调好的参数可能在第一轮表现很好第二轮因为某个缓存没有清理或者状态没有重置直接失败。所以我建议参赛队伍把整个比赛当成一个生产环境项目来做而不是当成一次算法大作业。生产环境的思路是先确认数据链路每一环的格式和频率再确认每个模块的容错和降级逻辑最后才轮到调模型和参数。三届比赛下来我见过太多队伍把80%的时间花在调模型上最后却栽在评测环境的基础问题上比如模型推理延迟导致下游拿到的障碍物列表是上一帧的旧数据。1.2 赛题背后的核心技术要求赛题考的不是单项技能而是综合工程能力但仔细拆解下来有三项硬指标直接决定了最终名次。第一项是感知的稳定输出频率。评测系统会实时统计车辆状态并触发事件记录感知模块必须保持稳定帧率。如果感知在某类场景下帧率骤降规划模块输出会同步卡顿车辆可能直接停在路口不动等着超时扣分。这里的核心要求不只是模型的精度指标而是整个感知链路在评测场景中的稳定运行能力。第二项是规划轨迹的平滑性和安全性的平衡。快速完成赛段要求路径不能绕远、速度不能过低但安全性又要求充分考虑避碰约束。这两个目标在EM Planner框架里就是DP和QP两阶段的目标函数权重在起作用。很多队伍能够跑完全程但速度曲线毛刺多车辆频繁加减速最终完成时间被拖得很长。第三项是系统长时间运行下的稳定性。这一点最容易被忽视尤其是支持连续多轮评测的赛制下模块长时间运行可能出现内存增长、循环队列溢出、时间戳混乱等问题。这类问题几乎无法通过调参解决必须回到代码层面做资源管理和状态清理。经历过一次半夜连续评测翻车之后你就会明白这项能力的分量。2. 关键模块与源码架构解析2.1 Apollo源码目录结构与比赛相关模块Apollo源码的目录结构在不同版本间有变动但modules下的模块划分基本稳定。刚接触Apollo的时候对着十几个modules目录发懵是正常反应后来理清了依赖关系发现比赛真正要深入的就那么几个。modules/perception感知模块负责相机、激光雷达、毫米波雷达的数据接入和目标识别是整条链路的起点。modules/prediction预测模块基于感知结果预测障碍物未来轨迹对行人、非机动车的运动意图判断尤其重要。modules/planning规划模块包含参考线处理、路径规划、速度规划是比赛调试的主战场。modules/control控制模块把规划轨迹转化为油门、刹车、转向指令常用LQR和MPC两种控制器。modules/routing路由模块基于高精地图完成全局路径搜索为规划模块提供参考线。modules/localization定位模块仿真中通常表现稳定但车辆参数改动后要同步检查定位输出。modules/map高精地图的加载和查询比赛里一般不用改但要理解参考线的生成机制。理解目录结构的关键在于梳理模块间依赖关系。Apollo的模块间通信基于Cyber RT框架模块通过话题发布和订阅来传递消息。看源码的时候本质上是在做一件朴素的工程事理清谁发布什么话题、谁订阅什么话题、消息类型和频率是多少。这份调用链图谱比任何教程都有用比赛里出问题的时候你就是靠这张图谱快速定位到底是哪个环节断了。2.2 感知模块的源码逻辑拆解感知模块是比赛中的重点投入方向因为后续的预测、规划、控制全部依赖感知输出的障碍物列表、车道线信息和信号灯结果。感知一旦出错后面链路再完美也白搭。以激光雷达点云目标检测为例当前Apollo常见的主推方案是CenterPoint。它的推理过程在源码里被封装成一系列组件预处理把原始点云转成体素网格模型做中心点检测和框回归后处理解析出可信度最高的3D边框。相比传统的基于Anchor的检测方案CenterPoint在精度和速度上都有优势也是目前自动驾驶点云感知的主流范式之一。但是CenterPoint在比赛环境里的落地有几个容易踩的坑。最典型的两个体素分辨率与输入范围的权衡以及GPU资源管理。体素尺寸越小模型看得越细但计算量成倍增长显存占用直接上去。按照我实测下来的经验常见配置是单帧点云检测范围控制在70到80米、体素分辨率0.1米左右推理频率可以达到30Hz上下显存占用在3到4GB之间。如果你能接受感知距离略短比如限制在50米体素分辨率放到0.2米显存能压到2GB以内帧率可以拉到40Hz以上。具体怎么选取决于评测场景的复杂度和你的硬件条件。相机图像回灌是比赛中很实用的一项调试技巧。简单说就是把采集好的相机图像按原始时间戳重新注入感知模块配合激光点云和毫米波雷达数据回放在离线状态下复现仿真或实车的现场。这样你可以反复调试同一个复杂场景不需要每次都重新跑车。回灌调试有几个关键点时间戳必须原样保留否则感知输出目标位置会与自车位置错位相机内外参要与采集时完全一致回灌过程中要同步回放定位信息否则传感器融合会乱。2.3 规划与控制模块的联动机制规划模块在Apollo源码中是一个庞大的目录核心是EM Planner。EM Planner的思路是把路径规划和速度规划交替迭代先基于静态信息生成路径候选再基于动态障碍物和交通规则优化速度然后把速度结果反馈回来修正路径循环往复让路径和速度逐步收敛到可行解。这个机制里有个重要的基础概念叫参考线。规划模块只在参考线附近一定范围内做决策不会全局搜索。比赛调试中我要求队员做的第一件事就是直道加转向路段的参考线检查。如果参考线抖动或者不连续后面规划出的轨迹不可能平滑车辆会表现出明显的蛇形行驶。参考线问题很多时候不是规划参数造成的而是地图数据的曲率采样有毛刺。控制模块接在规划模块后面主要做轨迹跟踪。Apollo支持LQR和MPC两种控制器。LQR参数少、调试简单适合起步阶段先把整车跑稳MPC显式处理约束能应对紧急避障这类极限场景但参数多调不好就会出现控制抖动。我的建议是先用LQR把整条赛道跑通再根据赛道特点决定要不要切换MPC。规划和控制之间的联调最常见的问题出在时间戳和状态同步上。规划的轨迹点带有时间戳控制模块必须按时间戳顺序跟踪。如果规划输出频率不稳定控制模块就会出现位置和速度错位表现就是车辆在弯道里频繁修方向。排查思路是先看Cyber工具里各话题的消息频率确认正常后再回到规划代码里查轨迹生成逻辑。3. 实操过程从源码到赛级方案3.1 环境搭建与仿真器上手环境搭建是比赛的第一步也是很多队伍第一次崩溃的地方。Apollo基于Docker容器运行环境依赖基本封装好了真正麻烦的是硬件资源。官方推荐配置是16GB内存加6GB以上显存的GPU我的实际经验是显存8GB起步才够用感知模型跑起来才不束手束脚。如果你的机器只有4GB显存那就要在感知配置上做减法同时关掉不必要的可视化辅助功能。仿真器上手我推荐一个顺序先跑通官方Demo场景再翻源码然后从最小改动开始调试。千万别一上来就改一堆代码否则出了问题根本定位不到是哪一处改动引起的。我自己的做法是先在原版代码上完整运行一次评测记录日志和评分接着只修改一个参数比如把规划速度上限从10m/s改到12m/s再跑一次对比日志差异。通过这种一次只改一个变量的方式你会逐渐建立起对系统行为的直觉后期调参效率反而更高。3.2 一组可以直接落地的调参流程我总结了一套比赛调参的顺序流程从零基础到稳定完赛大概分四步。第一步确认感知输出正常。在可视化工具里观察感知模块输出的障碍物框确保评测场景的主要路线上框体稳定不跳变。如果感知输出跳动先检查相机标定和激光雷达外参再检查模型输入分辨率最后才轮到模型本身。第二步确认规划无严重异常。先跑一段直线赛道观察规划轨迹是否平滑、目标速度是否在合理区间。然后再加入弯道和障碍物场景逐步观察轨迹反应。如果轨迹剧烈震荡优先检查参考线质量和速度规划的约束设置。第三步控制参数粗调。用LQR控制器先跑通赛道如果车辆出现明显震荡优先降低控制增益不要一上来就追求激进的控制响应。震荡消除后再逐步提升控制精度目标是让实际行驶轨迹和规划轨迹的横向偏差稳定在0.3米以内。第四步综合赛道联合调优。选择一段3公里左右的综合道路跑5轮连续评测记录每轮的完成时间和违规事件数。根据违规类型回溯模块闯红灯重点查信号灯感知和决策逻辑压实线查参考线偏移或控制偏差超时未完成查某环节的延迟堆积。这套流程是我带队拿名次的核心方法论它的好处是把复杂系统拆成可验证的小环节任何问题都能快速定位到模块层。3.3 必须吃透的3个关键数据结构与图像回灌调试法源码层面有三个数据结构比赛调试中绕不开。第一个是PerceptionObstacles感知模块输出的障碍物列表包含目标的位置、速度、朝向、类型、置信度等信息。规划模块通过订阅这个话题获取周围环境信息。调试时经常需要手动打印这个结构的字段确认感知是否输出正确的障碍物属性尤其要留意类型字段把行人识别成车辆会导致预测行为完全不同。第二个是TrajectoryPoint规划模块输出的轨迹点。每个轨迹点包含时间戳、位置、速度、加速度、曲率等字段控制模块按这个序列做跟踪。如果车辆在某类弯道表现不佳先检查TrajectoryPoint的曲率字段看规划轨迹是否在弯道附近出现了不合理的曲率跳变。曲率跳变会引起控制模块的转向突变车辆姿态一下就失控了。第三个是Chassis车辆底盘状态信息包含车速、转向角、加速度等反馈量。控制模块依赖这个信息形成闭环。如果Chassis数据出现跳变或者延迟控制模块就无法准确判断当前状态直接表现就是控制不稳定。比赛里如果出现奇怪的震荡问题先拉出来看一眼Chassis数据的时间戳和数值范围排查效率会高很多。图像回灌调试法我在前面感知部分已经提过这里补充一下实操细节。回灌的实质是把采集好的传感器数据按时间戳重新注入感知模块模拟实时数据流。用的时候需要注意数据包的发布时间要平滑过渡不能突然一下涌进几十帧否则会因为队列积压让感知模块直接崩溃。正确做法是先按照原始时间间隔逐步放出数据等模块稳定后再加快放出速率让整个链路先进入稳态再开始测试。4. 常见问题与排查技巧4.1 仿真与实车表现不一致怎么排查仿真里跑得好好的一上实车就翻车这种情况在比赛中非常常见。根源通常在感知数据的质量差异仿真环境里的传感器数据干净、无噪声、标定准确实车数据有光照变化、雨雾噪声、震动干扰。感知模型如果过拟合了仿真数据到实车上就会露馅。排查思路是按数据链路逐层检查。先看感知模块输出的障碍物列表是否稳定如果仿真里检测率超过95%实车只有70%那你真正需要做的是数据增强和模型鲁棒性训练而不是重新调规划参数。接着检查定位数据实车的GPS和IMU延迟漂移比仿真大很多如果不调整多传感器融合的权重规划模块拿到的自车位置会持续偏移。最后检查控制参数实车平台的转向延迟和踏板响应都会影响控制效果必要时候针对实车重新做系统辨识。4.2 延迟超时和GPU占用的典型原因与优化手段比赛过程中最让人崩溃的问题是模块延迟越跑越大最终导致评测超时。这个问题有三个典型原因每个都值得单独排查。第一个是感知推理延迟过高。CenterPoint这类点云模型如果输入帧率过高处理队列会积压导致感知输出频率低于规划订阅频率。解决手段包括限制输入点云密度、降低体素分辨率、缩小检测范围、开启半精度推理。这里要注意降低体素分辨率这种手段不是拍脑袋定的要结合你的GPU去实测找到帧率和精度都可以接受的点。第二个是日志和可视化工具的开销。Apollo的可视化工具后台运行会持续消耗CPU和GPU资源。评测时建议关闭不必要的流可视化把日志等级从DEBUG调整为INFO这个操作能明显降低系统负载。很多队伍在评测的时候还开着各种调试窗口结果评分下降还找不到原因。第三个是内存泄漏和资源未释放。连续多轮评测时某些模块的循环队列会无限增长。比如消息缓存队列如果没有设置上限低频率的订阅消息会不断累积内存最终拖垮整个系统。检查Cyber里的队列配置和感知模块的缓存策略是非常值得投入时间的环节。关于GPU占用我再多说一句。CenterPoint推理的GPU占用和体素化参数强相关不同配置下可以从1.5GB到4GB波动。比赛场景如果比较简单完全可以压缩检测范围只保留前方60米、左右各40米的核心区域这样不仅降低显存占用还能减少误检。GPU占用稳定后评测系统的整体帧率才会稳定最终成绩才有保障。4.3 团队协作与数据处理流水线的经验比赛基本是团队作战成员分工和协作方式直接影响迭代速度。我的建议是按模块分工但每个人都要能跑通全链路。具体做法是队长负责整体架构、任务拆解和进度管理感知组负责相机、激光雷达相关的模型调试规划控制组负责决策轨迹和控制调优。这样分工的好处是各模块有明确负责人但联调时大家都有全局概念不会出现各管一段、互不理解的局面。团队代码管理要严格。Apollo源码版本更新频繁不同模块之间可能有兼容问题。我们的做法是固定在一个Apollo版本上把团队所有改动打patch统一管理每次评测前在干净环境里重新构建镜像确保评测结果不因为本机残留配置产生偏差。分支策略上至少分为develop分支和stable分支凡是往stable合入的代码必须通过全链路回归。数据处理这块建议引入自动化流水线。比赛周期内会产生大量场景数据、模型日志、评测结果靠人工整理效率太低。可以借助工作流调度工具把数据采集、预处理、回灌测试、结果统计串成一条流水线每次修改代码后自动跑一轮回归把数小时的手工操作压缩到十几分钟。实测下来这套自动化方案能让团队每天多出两三轮有效迭代在比赛后期这个差距非常致命。不要觉得搭建流水线花时间这部分时间会在后面成倍省回来。我自己带队这几年的体会是自动驾驶比赛最终比的是理解和控制复杂系统的能力而不是某个单独算法的精度。你不需要成为每个模块的专家但必须对全链路的数据流、消息流有一个准确的心智模型。遇到问题不要慌先回到数据链路去排查多数问题的根源都在某个模块的边界条件上。最后分享一个我们沿用至今的小技巧比赛前一周强制组织一次无文档排障演练由队长随机埋几个隐蔽问题队员只允许通过日志和调试工具排查。这个演练带来的成长速度比闷头刷代码快得多。本文还有配套的精品资源点击获取