开篇先把结论放在这里:自动驾驶系统的验证,光靠真车路测是走不到量产那一步的。这两年被反复讨论的Harness Engineering和Loop Engineering,本质上回答的是同一个问题——在开放、无边界的真实世界里,凭什么证明你的系统是安全的。前者负责造出一套能和被测系统交手、还能说谎骗它出错的"试验台架",后者负责让真实世界无穷尽的新问题不断流回这套台架,驱动系统持续变好。一个提供"可信的考题",一个提供"源源不断的新考题",合在一起才撑起了自动驾驶从研发到量产的安全闭环。
这篇文章算是这个系列的第三篇,面向自动驾驶测试工程师、仿真平台开发团队、感知算法组和整车安全验证人员。我会把这两个概念的来龙去脉、落地做法和我在实际项目里踩过的坑一起说清楚。
1. 为什么一套工程方法解决不了验证问题
先讲一个扎心的现实:自动驾驶测试根本测不完。随便一段城市道路,雨天、逆光、外卖车乱窜、前车突然掉头,组合出来的场景数量级远远超过任何团队的测试预算。靠真车去跑,一年跑几百万公里也只是九牛一毛,而且大部分时间是平淡无聊的重复路况,真正要命的极端场景一年也碰不到几次。
1.1 验证不可穷尽,怎么办
传统汽车的安全验证建立在"物理规律可穷举"的思路之上——零部件级别、系统级别、整车级别的测试规范是几十年沉淀下来的,边界明确。但自动驾驶把问题从机械与电子拉到了感知和决策,算法的行为空间巨大,外部环境又几乎不可预测。这时候你会发现:测试的难点不再是"跑得多不多",而是"考得准不准"——你有没有那种能精准把系统逼到极限的考题。
考题从哪来?两个源头:一是靠工程师设计出来,二是从真实世界里捞出来。Harness Engineering解决"怎么设计考题、怎么让考题与系统过招";Loop Engineering解决"怎么从真实世界自动、高效地捞出考题并送回测试环境"。二者不是两个独立方向,而是同一件事的输入端和回流端。
1.2 Harness与Loop的分工协作
如果把被测的自动驾驶系统比作一名考生,Harness就是整套考场设施:光线、噪声、路况、意外事件都可以被安排和控制,考生的每次反应都被记录下来评分。Loop Engineering则是"考题更新机制":每次真实考试(路测或用户运营)中发现的错题、新题型,会被整理成新的标准题收入题库,下次再用来考新版考生。
在开发节奏上,这两个概念对应两条贯穿始终的线索。Harness是验证能力的底座,它决定你能把系统置于多真实、多苛刻的环境里;Loop是迭代速度的引擎,它决定你发现问题的速度有多快、修复一次的能力提升能多快被再次确认。这两条线索交织在开发流程里,缺一条都不行。
1.3 为什么现在才开始被当成工程来做
早期大家靠堆里程、堆人工标注,属于"野蛮生长"。直到行业发现连续好几年都翻不过某个事故率门槛,才意识到验证不单纯是钱的问题,而是得把场景当作一种工程资产来管理。Harness和Loop正是在这个背景下被提纯出来的方法论,它们把原来零散的仿真脚本、路测日志人工回放、用例维护等杂活儿,整理成了一套可以规模化、可量化评估的工程体系。
2. Harness Engineering到底在工程里做什么
有很多人第一次听到这个词会误以为它就是写仿真场景,远不止。Harness的本质是围绕被测系统构建一整层可控、可观测、可复现的"世界接口"。被测系统不仅包括决策算法,还包括传感器融合、规划控制、执行器,甚至驾驶员或远程接管模块。Harness要把这些东西统统包在一个容器里,让外部信号可以自由注入。
2.1 Harness的五个关键部分
一个完整的自动驾驶测试Harness,我习惯拆成五块:
- 环境仿真层:路面、车道线、交通标志、天气、光照、建筑、动态障碍物,这是给感知系统看的"世界"。
- 传感器物理层:摄像头图像渲染、激光雷达点云、毫米波雷达反射,都是基于物理模型对世界进行采样。
- 车辆动态层:整车动力学模型,模拟油门刹车转向输入下车辆的真实响应,也包括轮胎附着力等极限工况。
- 被测系统接口层:把感知、决策、规划的输入输出接口替换或者注入到Harness里,从软件在环一直做到硬件在环。
- 观测与评分层:不仅记录系统输出,还要在场景运行过程中测量各种安全指标,比如最小碰撞时间、横向偏移、风险场雷达图等。
这五层里,前三层构建"虚拟世界",第四层决定测试的保真度等级,第五层是决定场景能不能自动判分的裁判体系。多数团队初期只做第一层和第五层,等需要验证真实域控制器的时候才补齐中间两层,这也是一条比较现实的演进路线。
2.2 保真度没那么玄,关键是够用
我见过有人为了追求仿真画面极度逼真,显卡烧了好几万,结果决策模块根本用不到那么高分辨率的纹理。保真度应该按被测对象来定:如果被测的是感知模型,那你需要足够真实的传感器采样,包括光照、遮挡、材质反射,图像还得有适当的噪声和伪影;如果被测的是决策规划模块,输入往往已经是理想化或者经过前融合后的目标列表,这时环境仿真的核心是交通参与者的行为逻辑,而不是像素级画面。
所以Harness工程的第一步永远是明确"被测对象是什么、它的输入输出接口长什么样"。是测摄像头算法、测融合模块、测规划器,还是测整车控制器?对象不同,世界层的精细程度天差地别,盲目堆高保真度只会拖慢测试速度、提高成本,还得不到更有效的验证结论。
这里还要提醒一点:Harness的"真实性"是相对于被测系统的,不是相对于人眼的。车载摄像头看到的世界和人类看到的并不完全相同,传感器仿真要模拟的是器件响应而不仅是场景观感。这个认知直接决定团队应该把仿真资源投在哪里。
2.3 场景设计:从Roadscape到Corner Case
场景是Harness的灵魂。业内普遍会把场景按难度和价值分成几档,我在实践中一般这样划分:
| 场景类型 | 描述 | 价值 | 在Harness中的状态 |
|---|---|---|---|
| 基础合规场景 | 车道保持、前车加减速、跟停跟起 | 验证系统不出"低级错误" | 常驻回归集 |
| 法规标准场景 | 法规和安全评价里明确定义的工况 | 满足准入预审要求 | 强制必跑 |
| 边缘参数场景 | 在合法边界附近微调,如曲率略大、速度略高 | 摸系统能力边界 | 定期扩充 |
| 对抗性场景 | 刻意构造的遮挡、突变、误导 | 暴露系统性缺陷 | 持续生成 |
| 真实路采挖掘场景 | 从路测日志里复现的罕见事件 | 与真实分布对齐 | Loop回流进入 |
场景并不仅仅是"地图里的一个交通环境",它是一组带参数的状态机:起点、路网、交通流密度、参与者意图、天气、被测车辆初始姿态。这组状态机必须支持参数化和批量生成,否则就没法和Loop Engineering对接。写死一条轨迹的场景是死的,不好用。
2.4 一版能用的Harness怎么落地
以我做过的一个项目为例,仿真侧要支持"15分钟跑完1000个场景"的批量测试,团队踩了很多坑后形成了一套还比较稳定的搭建路径:
- 第一步,把被测系统的输入接口抽象出来,用协议描述文件定义好每类消息的格式。这一步决定了后面所有工具能不能顺利对接。
- 第二步,用开源的物理引擎加上自研的动力学插件,跑通"车辆按控制指令运动"的闭环。
- 第三步,接到一款开源交通流模拟器,生成交通参与者的背景行为,再把有人驾驶的车辆替换成可注入轨迹的测试车。
- 第四步,实现对感知输出的无损注入,在仿真中产生的目标列表直接作为决策模块的输入,这样不依赖相机反向投影,速度能提升不少。
- 第五步,写一个场景运行管理器,统一调度场景加载、参数解析、事件触发与指标采集,保证批量跑的时候不出乱子。
这套流程走下来,大概一个季度能让一个五六人的团队具备基本的批量仿真能力。保真度此时够用不代表永远够用,后面真车数据回灌的时候,传感器仿真会被迫升级,正好树挪死人挪活,一步一步来。
3. Loop Engineering的本质:让数据自己长成考题
关于数据闭环,圈内最常见的一种说法是"数据回灌、场景挖掘、再训练",听起来不算复杂,实际操作里牵涉到的工程环节很多时候比Harness还多。Loop Engineering要成立的三个前提缺一不可:能采到数据、能自动发现问题、能把这个发现变成一个可在Harness里反复重放的场景。做不到第三条,前面采再多数据也只是一堆硬盘里的日志,离考题还很远。
3.1 一条完整的闭环链路长什么样
我把数据闭环拆成六个环节,任何一个环节掉了链子,整个环就会卡住:
数据采集:车端或者影子模式下,采集原始传感器数据、自车状态、高精地图匹配结果、模型推理输出。这里要关注采什么样的数据,不用全采,只有触发条件或随机采样加上定向采样两种策略配合,才不至于存储成本失控。
问题发现:通过离线规则检测、安全指标超阈值、驾驶员干预检测或模型不确定性打分,把可疑片段挑出来。很多情况下问题不一定真实发生,只是模型"差点出错",这就要靠影子模式在后台并行运行理想版模型来做差异识别。
场景结构化:把一段原始日志切片成标准的场景文件,提取出车道几何、信号灯相位、参与者轨迹、天气光照参数。这个环节最难,因为原日志里只有感知输出或者原始点云,需要依赖高精地图匹配和轨迹后处理来重建全局坐标系下的完整画面。
库管理与参数化:存入场景库并打上标签,按场景类型、风险级别、覆盖度分组。这里定期要做去重和相似度聚类,避免一千个几乎相同的场景把场景库撑爆。
重仿真与标注:在Harness中重新运行结构化场景,让被测系统的更新版本面对当年"考砸"的题目。如果发现新版系统依然处理不好,标注人员介入,补充语义标注后交给算法团队。
回归与部署:修复后的模型重新跑全量场景集,确认不仅解决了旧问题,也没有引发新问题。达到发布标准后走向量产,然后在道路上面对新情况的检验,整个环重新转起来。
这个环从一头到另一头,快则一两周,慢则按月算,圈里最怕的是某个环节手工化太重,导致整条链路只能靠人肉接力。
3.2 怎么从海量日志里捞真正的Corner Case
说句实在话,海量里程里绝大多数片段都是没价值的重复。捞场景常用三层筛法,一层比一层挑得细。
第一层是规则筛选,设置硬性触发条件,比如急刹超过0.6g、近距离切入、横穿目标出现、接管事件、碰撞预警触发。这些规则简单,能快速把几万条日志缩到几百段。
第二层是安全指标筛选,结合后处理重建轨迹,用全局视角算最小距离、反应时间、预测偏差,把"看似平稳但其实系统测距很晚"的片段捞出来。我见过很多危险场景表面不紧急,但是系统的预留时间已经低于安全基线,这层筛选最能发现早期隐患。
第三层是分布异识,用无监督聚类或者学习型编码器把日志里的场景片段向量化,和场景库里已有的覆盖域比较,只把落在低密度区域的片段保留下来。这一层能发现人类工程师根本想不到的怪异场景,比如某处十字路口特有一个让系统困惑的遮挡结构。
这三层筛出来的片段量能压缩到原始日志的万分之一到千分之一,完全在人工处理能力之内。不过要想让第三层有价值,前提是前面的日志采集别做太多修剪,原始存储保留够久,不然真等发现某种奇异事故模式时,回头发现相关日志早被覆盖了,那才是欲哭无泪。
3.3 从回放日志到可批量利用的仿真场景
把一段传感器日志转成仿真场景,行业里的做法有两种,各有取舍。
第一种叫场景重建,就是用后处理算法在仿真环境中重建出和日志一致的交通环境。优点是最贴近真实,但是对地图偏移、物体轨迹平滑都极其敏感,稍微歪一点就会让感知模型"看到"世界上位置对不齐的车,产生假目标。这类偏差我见过太多,轻则白跑一遍,重则误导算法团队判断"模型有严重撞人倾向",其实完全是场景重建的质量问题。
第二种叫轨迹抽象,把日志里的参与者轨迹提取出来,去掉细节纹理只保留运动学约束,再重新植入一张高保真地图中。优点是稳定,适合大批量回归;缺点是丢失了传感器层面的真实感,如果被测包含相机模型,一些视觉信息没法复原,测试效果会打折。
我的经验是,针对感知系统的问题用场景重建,针对规划决策的问题用轨迹抽象,两者在同一个场景库中并存,标签里注明来源类型。这样既保证冒烟快,也保证有能打的硬仗。
3.4 回归评测门禁,别让闭环变成拍脑袋
所有回灌的场景最后总要过一道门槛:到底能不能发布新版本。我们一般会把回归评测分成三级,严进严出:
第一级是"必过集",自动驾驶系统发布必须通过的基础安全场景,包含法规场景和高频碰撞场景,主要用来守护安全底线,底线被突破直接打回。
第二级是"能力集",从场景库里随机抽取一个覆盖率均衡的子集,包含过往修复过的所有Corner Case,主要用来防止问题反复,新版本普遍会比旧版本评分高出一点才放行。
第三级是"怪物集",最难的对抗性场景,尽可能逼近已知系统弱点,这一级的通过率门槛不放在每次发布之间,而是放在大版本迭代上。从工程角度看,将门槛比例定死比放开更易管理,用数据说话每次都有人争,用情绪打分则永远定不下来。
第二级的随机抽取要避免主观挑题,保证每次评分样本的分布一致,否则版本间评分差异根本无法归因。我见过有人因为新版难题通过率低就偷偷删场景,这种做法危害非常大,等量产事故发生时会成为整个团队安全责任的污点。场景只能加,不能随意删,这应当成为铁律。
4. 常见问题与排查技巧实录
做了几年这部分工程,说实话踩坑是常态,下面几条算是比较典型的现场经验,基本每个团队都可能遇到,我按"问题现象、排查过程、对策"三条线整理,方便你拿去对照。
4.1 仿真里跑得好,上路就露馅
现象:仿真回归成绩很好,但真车上路问题频发,甚至出现仿真完全没见过的系统性错误。
排查:优先看仿真Harness的传感器保真度,和真实传感器的噪声底、动态范围、安装标定差异。另外检查场景库的天气光照分布,多数仿真只覆盖正常白天,但真实场景大量集中在弱光、逆光和污损镜头的条件下。还有一个我查过很多次才能确认的原因是,仿真交通参与者行为偏"规矩",现实里驾驶员的莽撞程度远超过仿真设定,导致决策系统在仿真里根本没遇到过"强行加塞还不减速"的挑衅式交互。
对策:把仿真场景库的分布朝实际路采数据的统计分布去校准,给场景加入对抗性交通流参数,并且定期引入真实路采日志做重放对比,用"仿真和真车之间的指标gap"反过来校准传感器模型噪声参数,而不是一味提升视觉画质。建议把每一版仿真场景统计和路采统计数据画成一张结构分布对比图,只有二者near close,才允许用仿真结果替代真车测试报告。
4.2 数据少的时候非要去搞大数据平台
现象:团队规模不大,却急着搭建大规模数据采集和标注平台,结果数据量没上去,平台维护却吃掉了大量人力。
排查:问题往往出在"为了闭环而闭环"。闭环的价值在于高频、高质量的考题流动,不在于数据规模。很多团队一天的采增量不足一千公里的时候,没必要建一整套分布式存储和调度系统,一台工作站加一块大硬盘就能跑通手动版闭环。
对策:按"先手动、后工具化、再自动化"三阶段走,蔬菜还没几颗就先别请满汉全席的厨子。先把一条完整链路通过手工脚本跑通,哪怕每周只有一个场景回流到测试集,都要保证流程每一次都能闭环结束。等场景数量超过几千、标注请求开始排队时再上轻量级平台,用最小工具集解决问题,这个顺序反过来一定会出乱子。
4.3 场景库越修越多,回归越来越慢
现象:场景库从几百涨到几万后,全量回归一次要跑十几天,版本迭代根本跑不起来。
排查:先看场景库的健康度,是否长期只增不删、相似场景冗余堆积;再看场景运行时间分布,有没有一半场景其实只需三五秒就能判断通过,却因初始化逻辑被拖到几十秒。
对策:场景库按"频率分层",把运行慢、覆盖度相同的场景做聚类广播,每类保留最具代表性的原型场景,其余放入归档区而不删;给场景增加快速预筛逻辑,先跑一个几秒的轻量版本,只有触发风险标记才跑完整版本。另外把完全无关的场景分配到多个并行任务池同时跑,利用现代CPU和GPU集群的算力,回归时间往往能压缩到原来的十分之一。这里我得特别提醒,归档场景时务必带上原始日志索引和参数化脚本,否则日后想恢复会无从下手。
4.4 数据标注永远跟不上环路节奏
现象:算法团队说标注太慢,标注团队说需求逻辑变太快,两边每天都在互相拉扯。
排查:大部分原因是把"人标"用在了机器该干的环节上。数据闭环里真正需要人标的其实只是很少一部分,大量片段可以靠自动真值生成来完成,比如离线高精地图匹配可以自动生成物体位置真值,轨迹平滑可以自动生成行为意图标签。
对策:把标注请求分成"全自动、半自动、纯人工"三档,全自动尽量用规则管道解决,半自动让人只处理机器学习模型置信度低的片段,纯人工只留给最难的语义理解场景。我们项目做到最后,纯人工标注占比降到了两三成,环路的节奏一下子就被释放了。很多团队把高生产成本的旧习惯搬到新闭环里,自然吃不消。
关于落地的个人经验分享
如果这篇你能记下一件事,请记住:Harness和Loop这两个词,本质上是一套工程体系的左腿和右腿,单靠任何一条都走不了路。我在一个项目里吃过很大的亏:团队花大半年建了非常逼真的仿真Harness,做了几千个场景,却一直没有接真实路采数据的回流管道。结果场景库越跑越旧,模型误判的典型案例不仅没被覆盖,仿真做得再精致也只是以死角为半径画的小圈。后来接上了Loop,回灌了三个月路采样本,才发现之前Harness的不少仿真假设根本站不住。反过来看,如果没有Harness把回灌场景组织成可判分的测试体系,再多的数据也只是日志,等于一堆矿石不经过冶炼上不了战场。
实践上建议你先从"单场景闭环"开始,也就是找一个具体的高速适应巡航避撞场景,完整跑通从采集、检索、回归到修模型的全流程,哪怕工具很粗糙。这个流程跑通一次后,再去谈自动化和大规模,会踏实很多。后续还可以拿这两个概念延伸出场景挖掘工程、评测指标工程等更细的课题,但骨架永远得是Harness和Loop这两根柱子立在那里,缺一根都撑不住自动驾驶的安全验证。
踩过几次坑之后我的体会是:做这套体系的团队里,最受尊重的人不一定是模型调参最溜的算法工程师,反而往往是那个能顺手把一条真实日志三天之内变成回归集里一道新考题的基建工程师。送你一个判断团队是不是真做实事的简单标准——你打开他们场景库看一眼,如果一个月内新增的场景数量是零,那不管口号喊得多响,这套工程体系大概都还停留在PPT阶段。