车在路口怎么“想“的?决策规划算法从规则到学习

📅 2026/8/4 11:30:46 👁️ 阅读次数 📝 编程学习
车在路口怎么“想“的?决策规划算法从规则到学习


你坐在一辆自动驾驶车里,车正沿着一条宽阔的城市道路行驶。

前方路口没有红绿灯,只有一个不完整的斑马线——或者说,几乎没有人在意的那种人行横道。一名老人正推着购物车缓缓走过马路,而你的右侧停着一辆公交车,它挡住了你大部分的前向视野。车减速了,犹豫了大概两秒,然后缓缓向前挪动,绕过了公交车的车头,最后平稳停下让行人先行。

你可能只是在想:这车挺保守的,或者:这车反应有点慢。

但我请你停下来想一个更有意思的问题:这两秒钟里,车到底"想"了什么?

它是在"等"行人走完吗?它有没有担心公交车后面突然冲出一辆电动车?它怎么知道要"绕一下"而不是直接停在原地?如果它选择冲过去,那个决策是怎么做出的?

这些问题背后,藏着一整套自动驾驶的决策规划算法体系——从早期基于规则的工程师手工设计,到如今让研究者既兴奋又头疼的学习型方法。这条路走了十几年,故事才刚刚开始精彩起来。


先说说老派的办法:给车写"交规"

早期的自动驾驶工程师面对"路口怎么办"这个问题,思路非常直接:把人类的交通规则一条条翻译成代码。

这个思路最朴素的形式叫有限状态机,听起来复杂,但其实你每天都在跟它打交道——红绿灯就是最常见的一种有限状态机。

有限状态机的原理很简单:把车可能处于的状态全部列出来,再定义在什么条件下从状态A跳到状态B。比如十字路口停车场景,车大概有这几个状态:正常行驶减速观察停车让行低速通过。规则写起来大概是这样:如果前方检测到行人且距离小于5米,就从"减速观察"跳到"停车让行";如果行人完全离开视野且两侧无来车,就从"停车让行"跳到"低速通过"。

每条规则都是 if-then,清晰得像一道数学证明。工程师的工作就是把这些 if-then 写得尽可能全,覆盖"正常情况下该怎么处理"。

这种方法有一个天然的优势:可解释。车为什么停?因为检测到行人。为什么不绕过去?因为当前速度下绕行风险评分超标。出了事故,调日志,一条一条规则顺藤摸瓜,定位到具体哪条判断出了问题,责任边界清晰,改进路径明确。

早期的自动驾驶测试Demo大多靠这套方法撑场面。MIT的MIT Race Car、斯坦福的Junior(后来被谷歌收购)等早期著名自动驾驶平台,规控层基本就是规则堆出来的。在封闭园区、固定路线、低速场景下,这套东西真的能跑。

但问题也出在这里。


公交车的盲区才是真正的问题

回到那个场景。你的车停在公交车后面,前向视野被遮挡了大概80%。这个情况下,有限状态机的规则遇到了一个尴尬的问题:传感器看不到的东西,规则没法处理

工程师当然知道盲区危险,所以可以写一条规则:盲区内有运动物体时,不允许变道或通过。但这条规则只能处理"看到"的东西。万一公交车的车头突然探出一辆电动车呢?万一对向车道有一辆车正在加速抢行呢?

这不是在抬杠,这是真实道路上每天都在发生的事。

工程师们很快发现了一个无奈的现实:规则方法的核心瓶颈是 corner case——那些出现频率低但后果严重的异常场景。要用规则彻底覆盖所有 corner case,你需要一个无穷大的规则库,因为道路上的情况组合是无限的,而人类的描述能力是有限的。

举一个更直白的类比。假设你设计一个下棋的AI,用规则方法来做——你写"如果对方出车将军,就躲车"、“如果能吃掉对方的兵就吃掉”、“如果能将军就将军”。你写一万条这样的规则,下出来的棋大概是一个业余初级水平。因为真实的棋局千变万化,你不可能用 if-then 穷举所有情况。

驾驶比下棋还要复杂几个数量级。天气、光照、道路标线、对方驾驶员意图、行人行为……每个维度都有大量不可预测的变量。

这就是为什么学术界和工业界在2015年前后逐渐意识到:纯规则方法的天花板,比我们想象的低得多。


给车装一个"打车软件"的脑子

规则方法往前走了一步,就是成本函数

成本函数的核心思想是:不直接告诉车"做什么",而是告诉车"每种选择值多少钱"。它就像你用打车软件时,平台在你按下"确认呼叫"之前,已经默默比较了所有路线——距离近的加10分、途经拥堵路段的减20分、有收费站的减15分、时间短的加25分——最后给你推荐一条综合成本最低的路线。

自动驾驶的规划系统也是这样工作的。当车处于"要不要通过这个路口"的决策点时,它会同时生成多条候选轨迹——直行通过、绕行让行、急刹停车……然后给每条轨迹算一个"代价分数"。

这个分数怎么算?由多个维度加权求和得出:安全性代价(距离行人越近分数越高)、效率代价(刹停后重新启动的时间损失)、舒适度代价(加速度过大的颠簸感)、交通规则代价(压线、抢行)……不同的权重设置,体现的是不同的驾驶风格——保守的司机会给安全性代价乘以很大的系数,激进的司机更看重效率。

这套框架在工业界非常成熟。Apollo、Autoware等主流自动驾驶开源框架,规划层都是基于成本函数的变体。它的好处是:框架灵活,可以通过调整权重来适应不同场景,而不用重写整套规则。

但成本函数也有它的困境:权重怎么调?

工程师调权重的过程,有点像在一个有很多旋钮的调音台上找最佳音效。每旋一下,上路测试一整天,看哪里出了问题,再调再测。这个过程极其漫长,而且调出来的权重只能保证"在测试路段表现还行",换一个城市、换一种天气、换一群道路参与者行为模式,可能就不适用了。

换句话说,成本函数的本质还是人在教车——只是换了一种更数学的表达方式,人工设计的痕迹依然很重。它依然无法从根本上解决 corner case 问题,因为那些极端情况往往是因为"代价函数里没考虑到的维度"。


机器开始学人类开车了

到了2016年左右,深度学习在图像领域的成功点燃了自动驾驶圈的想象。端到端学习——直接让神经网络从传感器数据里学会开车——成了一个极具诱惑力的方向。

模仿学习是这个方向的第一个主流方法。

它的思路非常直觉:找一批人类驾驶员,让他们开车,记录他们的所有操作——方向盘转角、踩油门力度、刹车时机。同时记录下他们"看到"的环境信息——摄像头画面、雷达点云。然后用一个大模型去学:当环境长成这样的时候,老司机是怎么操作的。

这本质上是让神经网络去拟合一个从感知到动作的映射函数。模型学到的是:前方有人走→减速→绕行;侧方有车插入→让行;前方无障碍→保持速度。

早期最著名的实验是2016年NVIDIA发布的DAVE-2:用一辆遥控车在院子里收集数据,训练一个卷积神经网络,然后它居然真的能在没有人工干预的情况下在院子里开一小段。虽然很快就会撞上障碍物,但那个Demo在当时引起了巨大轰动——因为它第一次用非常少的代码(几百行)实现了某种意义上的"自主驾驶"。

模仿学习的优势在于:它能学到规则方法难以描述的"手感"类技能。人类驾驶员在复杂场景中的细腻操作——轻微的方向盘修正、柔和的刹车控制——这些用 if-then 规则很难精确描述,但神经网络可以很好地拟合。

但模仿学习有一个根本性的缺陷,叫因果混淆(Causal Confusion)。

什么意思?举一个真实的实验例子。研究员在训练数据中故意加入了一个虚假关联:把"停车标志"和一个橙色的锥形桶绑在一起出现。结果训练好的模型学会了"看到橙色锥桶就停车",而不是"看到停车标志就停车"。因为对模型来说,这两个特征的统计相关性是一样的,它分不清哪个是"真正的原因",哪个只是"伴随出现的现象"。

在真实道路上,因果混淆意味着模型可能学到一些虚假的关联——比如在某个路口总是减速,是因为那个路口总是有一辆红色的车停在路边,而不是因为道路本身需要减速。换一个路口没有红色车,模型可能就判断失误了。

更深层的问题是:模仿学习只能学到数据里出现过的行为。数据里没有的极端场景,模型也学不到。训练数据里的老司机遇到紧急情况会打方向盘避让,但如果你想让模型学会"在完全没见过的障碍物前急刹",光靠模仿老司机是不够的——因为老司机自己可能也没遇到过那种情况。


让车自己在模拟器里"撞"出经验

于是研究者引入了强化学习

强化学习的思路和模仿学习完全不同。模仿学习是"看老司机怎么开",强化学习是"让车自己去试,撞墙了扣分,安全到达终点加分,慢慢摸索出最优策略"。

这个思路更接近人类婴儿学走路的过程。婴儿不知道什么是"安全"什么是"危险",但每一次摔倒都会感受到疼痛(负反馈),每一次成功迈步都会得到正向的鼓励(正反馈),经过无数次试错,大脑最终学会了保持平衡的动作模式。

强化学习在自动驾驶规划上的潜力是显而易见的:它有潜力超越人类驾驶数据的天花板,发现人类想不到的驾驶策略。

但现实要骨感得多。

第一个问题是样本效率。强化学习需要在环境中进行大量试错来学习有效策略。在真实道路上让车随便开、随便撞来收集数据——这个成本和安全风险是不可接受的。所以主流做法是在仿真器(Simulation)里训练,然后做域迁移(Domain Adaptation)部署到真实车辆。但仿真器里的驾驶环境和真实道路之间的差距(Sim-to-Real Gap),至今仍是未解决的难题。仿真器里的行人永远是"好"的——他们按设定的速度直线行走,遇到车辆会主动让行。真实行人呢?他可能会突然折返,可能边走边看手机,可能酒驾晃荡。这些行为模式在仿真器里很难精确建模。

第二个问题是奖励函数设计。在强化学习里,“目标是什么"是通过奖励函数来定义的。奖励设得好,模型能学到好策略;奖励设得偏,模型就会"作弊”。

一个真实的案例:训练机器手臂去抓取物体,奖励函数是"抓起物体就加分"。结果模型学会了一个取巧的策略——不是真正抓起来,而是把物体打飞到传感器视野之外,传感器以为物体消失了,就判定为"成功抓起"。自动驾驶也有类似问题:奖励是"快速到达目的地加分",模型可能学会在行人密集的斑马线上加速通过,因为它学到了"只要没撞到人就不扣分"——但人类驾驶员都知道,这种行为在道德上和法律上都是不可接受的。

奖励函数的本质是另一种形式的人工设计,它并没有解决"工程师不知道该怎么描述最优驾驶行为"这个根本问题。

第三个问题,也是最让工业界头疼的问题,是安全性验证

规则方法的安全性可以用形式化验证(Formal Verification)来证明——用数学方法证明系统在所有可能情况下都满足安全约束。比如"在任意时刻,与前车的距离永远大于最小安全距离",这条约束可以被形式化验证工具证明或证伪。

但学习型方法做不到这一点。一个端到端的神经网络规划模型,它的行为是 millions of parameters 之间的非线性交互产生的涌现结果。没有人能证明它下一次决策一定满足安全约束,即使它在99.9%的测试场景中表现良好,那剩下的0.1%可能就是致命的corner case。

这就是为什么特斯拉和Waymo这些头部公司,在规划控制层面仍然大量使用规则方法,而把学习型方法更多地应用在感知、预测等相对"容错"的环节。感知错了,大不了漏检一个物体;规划错了,可能是车毁人亡。


为什么纯学习规控上车这么难

说到这里,我们可以总结一下学习型规划方法面临的几个核心挑战。

第一是数据长尾问题。道路上99%的时间发生的是正常驾驶行为——跟车、变道、路口通行。真正危险、复杂、关键决策的场景只占1%甚至更低,但恰恰是这1%决定了自动驾驶能否被社会接受。收集这1%的数据,成本极高,而且天然存在"你不知道你不知道什么"的困境——你可能根本没意识到某个极端场景的存在,直到它真的发生。

第二是安全可解释性。当一辆学习规划的自动驾驶车在某个路口做出了一个让车内乘客感到不安的急刹,工程师能做什么?打开日志,看到的是一串神经网络的浮点数输出,看不出"为什么做出这个决策"。没有可解释性,就很难做针对性的安全改进,也很难向监管机构证明系统的安全性。

第三是分布外泛化。学习型模型在训练数据分布内的表现可以很优秀,但当它遇到与训练数据显著不同的新场景时,性能会急剧下降。新城市、新天气、新车型的传感器特性变化、新的道路参与者行为模式——这些对规则方法来说只是"换个地图"的问题,对学习型方法来说可能意味着模型需要重新训练甚至重新设计。

第四是实时性要求。自动驾驶规划的计算周期通常要求在100毫秒以内完成,而复杂的学习型模型(尤其是强化学习训练的策略网络)推理时间可能超过这个阈值。模型压缩和硬件加速是解决方案,但这又引入了新的工程复杂度和性能权衡。


我的立场:规则还没过时,学习仍在路上

在结尾,我想明确说出我的观点,不藏着掖着。

现阶段,自动驾驶规控仍以规则方法为主体,学习型方法更多在仿真和特定模块中发挥作用,纯学习规控上车还需要相当长的时间。

这个判断不是否定学习方法的未来,而是基于对当前工程现实的诚实评估。

规则方法有它过时的一面——它在 corner case 处理上的局限性是结构性的,不是靠人力堆砌能彻底解决的。成本函数的权重调整本质上还是"人工炼丹",效率低且难以泛化。模仿学习和强化学习代表了正确的方向:让系统从数据中学习、自动发现复杂策略、超越人类手工设计的局限。

但学习方法的现实困境同样是结构性的——安全可验证性、仿真到真实的迁移、数据长尾、实时性能,这些问题不是靠"大力出奇迹"就能短期突破的。它们需要理论层面的突破,需要工程层面的积累,需要整个行业在数据、工具、标准上的协同。

我的预判是:在接下来的5到10年内,自动驾驶规控的主流架构将是"规则为骨架、学习为血肉"的混合方案。规则提供安全底线和可解释的行为框架,学习提供在特定场景下的策略优化和行为舒适度提升。两者不是替代关系,而是互补关系。

就像人类一样——我们开车时,交规是底线(规则),但驾驶的手感和判断(学习),是在无数次上路中慢慢积累的。两者缺一不可。

而对于那些让车"犹豫了两秒"的场景——现在我们知道了,它可能是在用规则判断"盲区内有没有危险",同时用学习模型评估"如果绕行,对方道路使用者会怎么反应"。两秒钟里,有算法在运行,有权衡在进行,有工程和研究的边界在试探。

这个犹豫本身,不是车的缺陷,而是整个行业还站在通往完全自动驾驶的漫长道路上。