本文属于「开放世界玩家载具驾驶」系列的第六篇,承接 P5 的 GPS、路线生命周期与动态重规划。P5 解决车辆需要前往哪里,以及如何在变化的道路世界中维护一条仍然有效的路线;本篇继续追问:当两辆车拥有相同目标、经过相同道路时,为什么它们仍会表现出不同的速度、跟车距离、让行方式与风险接受程度?
本篇的核心结论是:路线决定车辆应该沿哪些道路上下文前进,驾驶策略决定在当前通路上的行为偏好;局部避让负责判断当前几何上哪些动作可行。驾驶策略输入来自驾驶能力、行为倾向、车辆状态和当前上下文,策略结果只能在任务、交通规则、局部几何和车辆能力提供的硬边界内生效,最终运动仍由车辆任务、局部执行器和物理系统完成。
文章基于 GTA5 相关源码阅读笔记整理。公开版本对类名、函数名和项目标识做了匿名化处理;文中将区分代码直接呈现的职责、根据调用关系归纳出的架构抽象,以及尚未进入原型的迁移设想。本文不展开 P7 的局部避让几何,也不展开 P8 的控制量写入、执行器与物理接缝。

上一篇:开放世界玩家载具驾驶 P5:玩家目标如何变成导航——GPS、路线生命周期与动态重规划
引言:同一条路线,不同的驾驶行为
假设两辆车辆从同一地点出发,终点相同,道路图相同,当前路线也完全一致。路线系统为它们提供了相同的道路序列:驶出当前路段,经过前方路口,沿主干道继续前进,在下一处交汇处转向目标区域。从导航数据的角度看,这两辆车没有区别。
但在运行过程中,它们可能呈现出截然不同的行为:
- 一辆车在红灯前较早减速,保持更大的车距,并在相邻车道车辆接近时放弃切线;
- 另一辆车接近路口时仍保持较高速度,只在临近停止线时制动;
- 一辆车在前方车辆减速后延迟跟随,倾向于保留更大的缓冲距离;
- 另一辆车会更早寻找空隙,接受更小的间隔,并在允许的情况下快速完成换道;
- 某辆车在连续碰撞或道路危险发生后,暂时改变风险响应;
- 某辆车即使路线没有改变,也会因为当前任务、驾驶者能力或车辆状态变化而改变速度和间距。
如果把这些差异都归结为“车辆 AI 随机性”,就无法解释它们为什么在同类场景下保持相对稳定的行为倾向;如果只用“驾驶个性”概括,也会把读者引向“系统内部存在一个持续运行、拥有所有交通车辆的个性管理器”这一未经证实的假设。源码阅读呈现出的结构更接近另一种组织方式:
路线与目标
↓
驾驶策略参数
↓
交通情境与任务约束
↓
局部候选与执行参数
↓
车辆执行器
策略层不直接把车辆推向某个坐标,也不负责维护道路路线。它所做的是改变“在可行选择之间如何取舍”。这一区别决定了 P6 与 P5、P7、P8 的边界:P5 维护路线,P6 调制策略,P7 处理眼前障碍与碰撞预测,P8 将已确定的控制意图转化为执行量并交给物理系统。
玩家的感受与系统的职责
玩家通常不会直接看到“风险评价输入”或“策略查询”。玩家看到的是车辆是否表现出谨慎、迟疑或积极的驾驶节奏。对于 AI 车辆,策略差异构成交通流的局部变化;对于玩家车辆,相关状态更多表现为交通规则提示、危险状态识别、辅助行为与统计反馈。两者可以共享道路上下文,但不应归入同一条命令链。
因此,本篇不把“驾驶策略”理解成一种拟人化描述,而把它当作运行时中的一组可观测职责:输入来自哪里,输出影响什么,哪些状态由它拥有,哪些状态必须交给下游系统维护。
一、路线提供计划通路,策略改变取舍
P5 已经说明,路线不是一条静态折线。车辆需要在目标、道路图、路口上下文和路线生命周期之间维护一个可以持续消费的路径结果。路线系统解决的是全局可达性和道路序列问题:从当前位置出发,哪些路段能够把车辆带到目标区域,哪些路口和道路连接关系构成有效通路。
驾驶策略处理的是另一层问题。即便计划通路已经确定,车辆仍需要决定:
- 接近路口时保留多少速度;
- 与前车保持多大距离;
- 是否接受一个可用但较小的换道间隙;
- 面对不确定的路权时,是等待、减速还是继续推进;
- 在路线允许多个车道时,何时倾向于靠近目标车道;
- 遇到交通阻塞时,是维持当前路线,还是把风险信息交给更高层进行重规划;
- 在车辆当前状态不理想时,是继续执行原有意图,还是降低行为强度。
这些决定不等同于改变路线,也不等同于生成最终转向角。它们更接近对路线执行过程施加约束和偏置。
可以把三层关系写成:
目标约束:要到哪里
路线状态:允许经过哪里
驾驶策略:在允许空间内如何选择
如果路线层直接承担“谨慎还是激进”的全部逻辑,路线就会同时拥有道路拓扑、交通行为和驾驶者个性,任何策略变化都可能迫使路线对象重新建立。反过来,如果策略层直接改写车辆物理,策略就越过了执行器边界,无法解释为什么相同的意图在汽车、船舶和飞行器上需要不同的运动实现。
边界例:路线不变时的跟车决策
车辆在主干道上向前行驶,前方出现一辆低速车。路线没有失效,目标也没有变化。保守策略可能降低当前速度并保持距离;积极策略可能提前寻找相邻车道的可行间隙;风险响应较高的策略可能继续靠近,直到下游局部执行器判断必须避让。
这里至少有三种不同层次的状态:
- 路线状态:主干道仍然是有效路线的一部分;
- 策略状态:当前驾驶者对距离、速度和风险的取舍不同;
- 局部执行状态:当前帧应当采用哪一个目标方向、速度上限或候选动作。
把三者合并成“车辆要不要换道”这个布尔值,会丢失决定过程。为便于定位参数来源和消费路径,本文建议保留可追踪的中间语义,使策略输出能够被下游任务消费、被调试系统观察,也能在路线没有变化时单独调整。
二、驾驶个性更接近按需策略查询,而非常驻管理器
从当前已追踪的调用关系看,多处驾驶任务会按需查询驾驶能力、激进程度和交通上下文参数,查询结果由调用方继续消费。本文以 DriverPolicyCalculator 统称这组策略查询职责;该名称不代表源码中存在同名类,也不代表它是唯一计算入口。
这类逻辑的关键特征是:查询职责可以保持轻量,输入状态仍可能包含多层上下文。
本文所说的“近似无状态查询”,仅指当前已追踪的计算职责不负责持有驾驶者身份、路线进度或任务生命周期。它不等同于对源码内部缓存的全面否定,也不排除其他对象保存历史状态。持久信息由调用方或上下文对象维护,策略查询在需要时读取这些信息并返回结果。
可以把它抽象为:

这与“每辆车拥有一个驾驶策略组件”有本质区别。后者会引出组件创建、修改、控制权转移、远景保留和重建恢复等额外生命周期。如果源码证据只支持一个共享的策略计算接口,就不应把它扩写成常驻组件或全局管理器。
策略计算器不拥有的内容
从职责分布看,它不负责以下事项:
- 不拥有道路图和全局路线;
- 不决定车辆任务何时完成;
- 不负责维护车辆当前的局部目标;
- 不直接提交油门、制动或转向控制量;
- 不负责碰撞预测、切线生成和导航网格限制;
- 不接管玩家控制权;
- 不保存所有交通车辆的统一人格状态。
它的输出可能影响上述系统的选择,但影响不等于拥有。这个区分是 P6 的核心边界。
为什么无状态计算可以支持稳定个性
行为稳定性来自输入的稳定性,而不一定来自策略函数内部保存一份可变状态。假设某个驾驶者的能力和激进程度来自持久的模型数据,车辆智能又提供了当前交通情境,那么每次查询只要读取一致输入,就能够得到相对稳定的参数。需要历史记忆时,历史状态可以由驾驶者智能、车辆智能或玩家状态维护,再作为输入参与下一次计算。
这种组织方式有三个好处:
第一,策略计算可以被多个任务复用。巡航、路口处理、换道和警示逻辑只需要以自己的上下文调用,不必复制一套人格判断。
第二,策略计算不会取代任务所有权。任务仍然负责路线、阶段和完成条件,策略只提供执行过程中的调制参数。
第三,远景或简化车辆可以只保留必要输入,不必创建完整的驾驶者对象。车辆智能可以提供“假想驾驶者”的能力和激进程度近似值,使低成本车流也能呈现有差异的行为分布。
三、策略输入从哪里来:默认值、覆盖值与情境值

驾驶策略的输出差异,不能只依赖一个叫作 Aggressiveness 的字段。源码阅读中可以分出至少三类输入来源:持久默认值、显式覆盖值和当前情境值。
1. 持久默认值:驾驶者或模型的行为倾向
角色模型或驾驶者类型可以提供相对稳定的行为倾向,例如驾驶能力、风险容忍度、对交通规则的遵守程度或响应速度。这类数据不等于当前帧的控制命令,它们更接近策略计算的先验。
同一个驾驶者在不同道路上不应每帧重新随机生成性格。稳定的默认输入可以使行为在时间上连续:在相似条件下表现出相似的间距、减速和换道倾向。
2. 显式覆盖值:智能运行时的能力与激进程度
从调用关系看,可以抽象存在任务或状态相关的策略输入覆盖。它们可能来自任务要求、角色状态、车辆当前上下文,或者对默认驾驶能力的临时修正。覆盖值用于让任务在有限范围内改变策略输入,不改变驾驶者的默认输入。
例如,追逐任务可能需要提高接近意愿;护送任务可能需要降低速度波动;车辆受损或驾驶者受到干扰时,策略输入可能被限制在更保守的区间。至于这些覆盖值由哪个具体对象维护,应以调用关系和字段写入证据为准,不能仅凭概念图断言。
3. 情境值:道路、路口与交通事件
策略函数还需要读取即时上下文。红灯、路口距离、前车速度、道路宽度、相邻车道状态、当前路线段以及是否处于高速道路,都会影响同一组基础能力如何被解释。
这类输入具有短周期特征。它们不应被永久写回驾驶者人格,否则一次临时拥堵就可能改变角色的长期行为。更稳妥的做法是将它们作为当前任务或当前帧的上下文,影响本次策略计算结果。
4. 车辆侧近似输入:缺少完整驾驶者对象时的处理
开放世界中的远景车辆、无驾驶者车辆或简化交通实体,可能没有一个完整的角色智能对象。车辆智能可以提供一组“假想驾驶者”参数,使车辆在没有真实乘员的情况下仍能参与交通行为计算。
车辆智能在此处只提供缺少完整驾驶者对象时的近似输入,并不等同于完整驾驶者,也不替代角色智能的全部职责。这是一种运行时降级策略:保持行为接口可用,同时降低数据来源和执行成本。
输入来源不宜压缩为单一优先级序列
默认值、覆盖值和情境值通常不能归结为单一优先级。不同参数可能有不同合并方式:有的参数取显式覆盖,有的参数在范围内夹紧,有的参数由任务直接限制,有的参数只在满足条件时参与计算。
因此,公开抽象更适合写成:
默认输入
+ 显式覆盖
+ 当前情境
+ 任务约束
↓
策略参数计算
而不应画成一条未经证实的优先级栈。
四、策略输出是什么:偏好、软限制与候选评价


策略层的价值,在于把行为倾向转化为下游可以消费的运行参数。根据源码调用关系,可以把输出归纳为三类:行为偏好、策略软限制和候选评价权重。交通规则、任务限制、局部几何和车辆能力属于外部硬边界,不由策略层放宽。
策略软限制:表达驾驶者希望采用的范围
策略软限制可以包括期望速度范围、观察提前量、缓冲距离和等待成本。保守策略通常要求更大的余量,积极策略可能降低部分软限制的权重,但它们仍然不能突破红灯、禁止通行、碰撞边界或车辆动力学限制。
软限制也不等于控制量。例如,“在路口前提前降低期望速度”并不等同于制动踏板值。最终制动量需要由车辆执行层根据当前速度、坡度、抓地力和目标点计算。
偏置:在多个可行选择之间改变倾向
偏置可以影响候选车道、目标方向、跟车距离或换道意愿。它通常不直接决定动作,而是改变候选方案的评价结果。
例如,同一组可行换道候选,保守策略可能对横向移动和前方风险施加更高惩罚;积极策略可能更看重路线保持和前方推进。候选生成、碰撞预测和实际切线实现仍属于 P7 的局部避让系统。
候选评价参数:影响下游如何选择
交通运行时经常需要在多个“暂时都能走”的方向之间做取舍。策略可以提供候选评价所需的权重,例如期望方向、路径侧偏好、风险惩罚或等待成本。
这里需要特别注意:策略输出属于评价依据,候选生成和评价仍由局部任务负责。驾驶策略可以提供风险权重,但不应被描述为拥有避让算法。
常见输出的运行时解释
| 策略结果 | 类型 | 最终所有者或不直接负责的内容 |
|---|---|---|
| 跟车距离偏置 | 策略偏好 | 最终制动量由执行器解释 |
| 路口停止倾向 | 策略偏好 | 红绿灯相位由交通系统维护 |
| 换道接受度 | 候选评价权重 | 碰撞几何由 P7 判定 |
| 速度偏置 | 策略软限制 | 车辆能力由执行器与物理限制 |
| 警示/鸣笛倾向 | 行为偏好 | 实际表现由相关系统消费 |
| 风险惩罚权重 | 候选评价权重 | 候选生成由 P7 负责 |
这个表明确了策略层的权限:它可以改变取舍,但不能把不可行候选变成可行候选,也不能替代拥有相应生命周期的下游系统。
五、相同路口为什么会有不同的通过方式
路口是观察驾驶策略最清晰的场景之一。路线系统告诉车辆要经过哪个路口,通行权系统告诉车辆当前是否具备通过条件,车辆执行任务负责接近停止线并控制速度。策略层位于这些信息之间,改变车辆在接近、等待和通过过程中的行为节奏。
保守策略
保守策略通常表现为更早观察路口状态、更早开始减速、在路权不明确时保留更大余量。它不会改变路线,也不会创造一个新的交通信号,只是提高进入下一阶段前的安全门槛。
当信号从允许变为需要等待时,保守车辆可能已经进入低速状态;即使最终仍然可以通过,也会表现出较大的速度波动。这个结果并不一定是控制器“不稳定”,而可能是策略对不确定性的主动定价。
常规策略
常规策略以路线执行和交通规则为主,保持适中的接近速度和跟车间距。在确定路权允许通过时,它会继续推进;当停止条件明确时,再把减速目标交给执行层。
常规策略的价值在于提供多个特殊驾驶行为之间的基线。没有基线,就无法判断积极或保守参数究竟改变了哪些行为。
积极策略
积极策略更重视路线推进和时间成本,可能在允许范围内保持较高接近速度,接受较小但仍然有效的车距或换道间隙。它并不意味着忽略所有规则,也不意味着可以跳过局部安全检查。
如果积极策略直接写入物理,系统就失去了下游纠正的机会;如果它只调整速度偏置、候选评价和等待门槛,执行器仍然可以根据当前碰撞、路面和车辆状态进行限制。因此,策略与执行需要保持分离。
策略差异不是随机抖动
如果每帧随机改变速度或方向,玩家看到的会是噪声,而非稳定的行为倾向。策略差异需要由稳定输入和明确上下文产生,并通过参数范围控制变化速度。短期波动可以来自道路情境,长期倾向则来自驾驶者和任务输入。
在验证时,应同时检查:
- 相同输入下,策略是否给出稳定范围;
- 情境变化时,参数是否按预期调整;
- 参数变化是否只影响下游拥有的行为;
- 车辆离开当前情境后,临时修正是否被释放;
- 不同车辆是否因为执行器差异而得到不同的运动结果。
六、驾驶策略如何进入车辆任务,而不越过执行边界
P5 的路线持有任务负责维护路线生命周期,P6 的策略层为路线执行提供调制参数,P7 的局部避让任务处理眼前的障碍和候选方向,P8 的执行器才负责将结果写入车辆控制契约。四者可以抽象成以下链路:
Route Holder
↓ 路段、路口、目标上下文
Driving Policy
↓ 速度偏置、间距、风险权重
Local Traffic Task
↓ 局部目标、候选方向、执行条件
Vehicle Executor
↓ 控制量
Physics Feedback
这里的箭头表示信息消费关系,不表示所有系统都由上游直接调用。实际实现可能通过任务字段、共享上下文、辅助查询或事件更新进行传递。公开文章应保持这一层级,避免把推断的调用形态写成确定的同步调用链。
P6 能改变什么
P6 可以改变:
- 目标速度范围;
- 跟车和停止距离参数;
- 换道或通过候选的评价权重;
- 风险和时间成本的相对取舍;
- 警示、鸣笛或路权不确定时的行为倾向;
- 某些任务阶段的行为调制。
P6 不能直接改变什么
P6 不直接拥有:
- 路线是否有效;
- 目标是否完成;
- 当前障碍物的碰撞几何;
- 最终方向盘角度、油门或制动值;
- 车辆刚体的速度和姿态;
- 网络状态的最终权威;
- 玩家与 AI 的控制权迁移。
这些边界用于定位失败。车辆没有减速,可能是策略给出的速度上限不合理,也可能是局部任务没有消费该参数,还可能是执行器没有正确解释,或物理反馈覆盖了控制量。只有责任边界清楚,诊断才有意义。
七、驾驶策略输入与驾驶者能力不是同一个参数
“能力”和“激进程度”经常被合并为一个“驾驶水平”,但它们影响的问题不同。
能力决定能否稳定完成动作
驾驶能力更多影响响应质量和执行稳定性。例如,低能力驾驶者可能需要更大的停止余量、更平滑的速度变化、更低的候选切换频率,或对狭窄路线和复杂路口采用更保守的目标参数。
能力不是“更快”或“更慢”的二值开关。一个能力较高但保守的驾驶者,可能比能力一般但风险偏高的驾驶者行驶得更慢;前者的差异在于能够稳定执行复杂选择,后者的差异在于愿意接受更高风险。
激进程度决定更愿意承担什么代价
激进程度更多影响时间、距离和风险之间的权衡。它可能提高推进优先级,降低等待成本,缩小部分缓冲距离,或提高对换道候选的接受度。但这些改变需要受到道路、任务和执行器条件约束。
两者组合产生更丰富的行为
可以得到四种典型组合:
| 能力 | 激进程度 | 可能表现 |
|---|---|---|
| 高 | 低 | 反应稳定、间距充足、动作保守 |
| 高 | 高 | 路线推进积极、动作连贯、风险接受度高 |
| 低 | 低 | 速度偏低、等待时间长、恢复动作谨慎 |
| 低 | 高 | 选择激进但执行不稳定、容易产生修正 |
这张表用于说明策略输入不能压缩成单一数值。运行时还会叠加车辆类型、道路状态、任务阶段和当前风险。
车辆能力与驾驶者能力也应分离
驾驶者可以具备较高的路线判断能力,但车辆当前抓地力、制动状态或载荷条件不允许继续推进。车辆侧限制应由车辆智能和执行器提供,策略输入不能直接假定“车辆一定能做到”。
反过来,高性能车辆也不能自动获得更积极的决策。车辆能力改变可执行范围,驾驶策略决定如何在范围内选择,两者需要在执行阶段汇合。
八、风险不是一个全局开关,而是一组情境判断
“高风险驾驶”常被写成 bReckless = true。这种表达适合做统计标签,却不足以支持运行时行为。一个车辆或玩家的风险响应至少需要区分:风险来源、风险观察者、风险持续时间和下游消费者。
风险来源
风险可能来自:
- 红灯或路权冲突;
- 逆向或偏离道路方向;
- 车辆压到路面边界;
- 前方车辆突然减速;
- 近距离擦过其他车辆;
- 碰撞、打滑或失控历史;
- 高速道路、宽路或特殊路段上下文;
- 当前任务对速度和接近的要求。
这些来源并不具有相同含义。一次近失事件可能用于玩家统计和反馈;一次红灯状态可能用于交通提示;一次碰撞历史可能影响当前恢复策略。将它们全部折叠为一个布尔值,会使下游无法区分应当采取什么反应。
风险观察者
在已追踪的调用路径中,可以观察到部分道路风险状态被写入玩家信息侧。本文将这组玩家侧风险观察状态统称为 PlayerDrivingContext;它不代表 AI 驾驶个性对象,也不默认参与 AI 车辆的策略计算。
这些状态可能被玩家反馈、统计或其他系统消费;具体消费者需要结合调用点确认。玩家风险观察与 AI 策略存在交集,但两者不应直接等同。
风险持续时间
有些风险是瞬时事件,例如一次近失或一次鸣笛;有些风险需要短时间保持,例如进入高速道路后的状态;有些风险只作为历史统计保留。不同持续时间要求不同所有者:事件记录、上下文状态和长期统计不能放进同一字段。
下游消费者
风险状态可能被以下路径消费:
- 玩家统计或特殊能力;
- 交通提示和警告;
- 车辆 AI 的警示行为;
- 音频表现;
- 任务状态或追逐条件。
消费者不同,所需精度和生命周期也不同。一个用于 UI 的风险标签不应被误认为物理执行器的直接命令。
九、玩家驾驶中的风险响应:与 AI 个性保持边界

玩家车辆和 AI 车辆都处于道路情境中,但“驾驶策略”在两条路径上的作用并不相同。
AI 车辆:策略影响自动决策
AI 车辆没有玩家持续输入,需要根据路线、交通和驾驶者参数自动选择速度、间距、等待与局部行为。驾驶策略因此参与任务和局部执行的参数计算,影响车辆下一步如何解释道路状态。
玩家车辆:系统记录和解释行为
玩家车辆的主要控制源来自玩家输入。系统不能用 AI 个性替代玩家的方向、油门或制动意图,但仍需要观察道路风险、碰撞历史、近失事件和交通规则状态。这些状态可以被玩家反馈、统计或其他系统消费;具体消费者需要结合调用点确认,且不应直接覆盖玩家输入。
为什么两者不能合并
如果把玩家驾驶也强行送入 AI 个性决策,玩家会失去控制一致性;如果完全不记录玩家风险,任务、反馈和世界响应就失去依据。更合理的结构是:
AI 车辆:策略参数 → 自动驾驶任务 → 局部执行
玩家车辆:玩家输入 → 玩家控制链
↓
风险观察与状态记录
两条路径共享道路上下文和部分风险分类,但不共享同一个命令提交者。P4 已经讨论控制源交接,P6 只说明风险模型如何作为观察路径存在,避免把玩家驾驶重新写成 AI 接管。
| 路径 | 主要职责 | 是否提交驾驶命令 |
|---|---|---|
| AI 策略查询 | 调制自动驾驶任务的行为参数 | 间接 |
| 玩家风险观察 | 记录道路风险与事件状态 | 否 |
| 玩家输入链 | 提交玩家驾驶意图 | 是 |
近失事件为什么值得单独处理
近失不是碰撞的同义词。道路运行时可能检测到车辆以较高速度接近、双方边界短暂重叠风险、相对位置快速变化,但最终没有发生实际碰撞。这个事件可以用于玩家驾驶统计,也可以触发特殊反馈。
在迁移和验证时,需要明确速度阈值、空间关系、事件去重和时间窗口等语义。P6 只确认它属于风险观察路径;如何在局部避让中预测碰撞,属于 P7;如何由物理接触产生损伤,属于 P8 或后续损伤篇。
十、策略如何影响红灯、跟车、换道与鸣笛
为了避免“策略函数”停留在抽象层,下面把几类常见行为逐一拆开。每一节都只说明策略影响的层次,不把它扩写成 P7 或 P8。
红灯响应:停止倾向与时间窗口
策略可以影响车辆在发现停止条件后的提前量、减速目标和等待倾向。保守策略更早将路口视为需要准备停止的上下文,积极策略可能在确认仍可通过时保持更高推进意愿。
但红灯相位属于路口通行权系统,车辆策略不能拥有相位;车辆是否已经越过停止线、当前是否允许通过,也需要由路口和路线执行上下文判断。策略只参与“如何接近和等待”,不拥有“灯是什么颜色”这一事实。
跟车响应:距离偏置与速度匹配
跟车表现由前车状态、道路速度、路线目标和驾驶策略共同决定。策略可以改变期望间距、减速提前量和速度匹配的平滑程度。实际制动仍由执行器根据当前速度和车辆状态计算。
这一区分使得同一策略可以适配不同车辆:汽车可能通过轮胎制动完成减速,船舶可能通过推进反向和航向调整完成减速,飞行器则需要遵守完全不同的速度和姿态限制。策略输出应保持在能跨载具理解的意图层,具体运动由类型执行器解释。
换道响应:接受度与候选评价
驾驶策略可以影响是否愿意等待换道候选、对横向移动的惩罚、对路线保持的偏好,以及在等待和推进之间的时间成本权衡。它不应直接生成切线,也不应绕过局部碰撞检查。
P7 将详细讨论局部候选与碰撞预测。P6 只需保留一点:策略为候选评价提供偏置,局部避让系统仍然拥有几何安全判断。
鸣笛和警示:表现入口而非驾驶命令
鸣笛可以由交通情境、玩家风险状态或 AI 驾驶策略触发。策略可能提高或降低鸣笛倾向,交通上下文决定是否存在合理触发条件,表现层负责实际播放和节奏控制。
如果把鸣笛当作驾驶命令,就会把表现和执行混在一起。它可以作为车辆对世界状态的反馈,但不等于车辆已经改变路线、控制权或物理状态。
十一、驾驶策略与局部避让:相邻但不相同
P6 与 P7 的接缝需要在这里明确。两者都可能谈到障碍、距离和风险,但职责不同。
策略层回答:倾向如何变化
策略层可以回答:
- 是否更愿意等待;
- 是否更重视时间成本;
- 是否需要更大的安全间隔;
- 对某类候选的风险惩罚有多高;
- 当前驾驶者是否允许更积极的行为。
避让层回答:当前几何上哪些动作可行
局部避让负责障碍扫描、碰撞预测、道路边界检查和候选几何生成。源码材料显示,这类计算由局部移动任务按自身生命周期调用,并将结果交给局部目标或执行阶段;路线进度仍由路线持有层维护,策略查询也不承担避让结果的保存。
为什么策略不能直接调用避让结果
如果策略层直接保存局部避让结果,就会同时承担几何和恢复状态,削弱 P7 对调用时机、刷新频率和结束条件的所有权。策略只提供风险权重、间距偏好和时间成本,局部任务在自身生命周期内生成并消费避让结果。
上层可以提供偏好,下层负责在硬边界内解释和校验;影响关系不等于生命周期转移。
十二、驾驶策略与物理执行:策略不能写入刚体
策略输出不应直接映射为刚体控制量。它提供可解释的行为参数,执行器在各自的车辆能力和运动学边界内完成解释;同一策略输入因此可以跨载具复用,但不会产生同一套控制律。
物理反馈会反过来限制策略
车辆打滑、路面湿滑、损伤、载荷、倾斜和碰撞反馈,可能使执行器降低实际控制强度。策略影响期望行为,执行器和物理提供可执行性反馈。
如果物理反馈长期无法满足策略目标,车辆任务可能需要降低速度、重新选择局部目标,或把失败上报给路线和任务系统。P6 不负责恢复算法,但需要保留这个出口,否则策略会被错误地当作不受约束的最终权威。
十三、同一路线的三种驾驶配置:一个完整案例

下面以同一条城市路线为例,观察策略如何在不改变全局路线的情况下改变执行行为。为隔离策略变量,假设三辆车使用相同车型、相同道路序列和相同初始交通快照;差异只来自驾驶者默认输入与策略覆盖。运行后,局部目标和速度曲线可以不同,但路线所有权不发生变化。
配置 A:保守驾驶者
策略输入:能力中等,激进程度低,当前任务没有时间压力。路线持有层输出相同的道路序列,局部上下文开始提供前方信号、车辆间距和目标车道信息。
策略输出可能包括:较大的跟车距离、较低的接近速度、较高的换道等待成本和更早的停止准备。局部任务根据这些参数延后并线或先降低速度;执行器只负责稳定完成这些局部目标。
当目标车道短时间不可用时,保守策略更可能继续沿当前路线等待下一次机会,而非接受狭窄间隙。路线和目标保持不变,变化发生在候选评价和速度调制层。
配置 B:常规驾驶者
策略输入为基线值。车辆根据路线、交通规则和局部候选完成适度推进。它既不会长时间等待,也不会主动将所有间隙视为可用。
这个配置用于验证系统的结构一致性:如果基线车辆不能稳定完成路线,说明路线、局部任务或执行器存在问题,不能通过给所有车辆增加激进程度来掩盖。
配置 C:积极驾驶者
策略输入:能力较高,激进程度较高,但道路和任务仍提供硬约束。车辆可能更早寻找目标车道、减少等待、维持较高接近速度,并在候选评价中降低时间成本权重。
局部避让仍需确认实际空间关系,执行器仍需受到车辆动力学限制。如果间隙不满足几何安全条件,积极策略只能继续等待,或向路线持有层提供受阻程度和重新评估倾向;是否提交重规划请求仍由路线生命周期所有者决定。
这个案例证明了什么
三辆车共享:
- 目标;
- 道路图;
- 主路线;
- 路口通行权;
- 车辆任务接口。
三辆车不同的是:
- 策略参数;
- 候选评价;
- 局部目标的更新节奏;
- 执行器消费参数后的运动结果。
因此,策略查询不需要复制三套路线系统,也不需要创建三个全局交通管理器。它只需要在正确的接缝上提供可追踪的调制结果。
十四、失败设计:让集中式对象承担过多职责
P6 最常见的工程错误,是将策略公式与不属于它的状态所有权合并。
失败一:策略对象拥有路线
这种设计让策略对象同时保存目标、路线、局部进度和驾驶风格。优点是调用方便,缺点是任何路线更新都必须通知策略对象,玩家接管、任务切换、远景降级和网络重建都需要处理一套额外同步关系。
路线的生命周期应由路线任务或导航持有层维护,策略只读取路线上下文并提供行为调制。
失败二:策略对象直接写控制量
例如根据激进程度直接写油门、刹车和转向。这样会绕过车辆类型执行器,导致汽车、船舶和飞机只能共享一组不适用的控制语义,也会让物理反馈无法清晰地反馈给上层。
正确做法是让策略输出目标速度、风险权重、间距和候选偏置,由执行器在自身约束内解释。
失败三:全局可变的策略输入表
如果所有车辆共享一张可变表,某辆车的临时风险状态、任务覆盖值或玩家统计可能意外污染其他车辆。更安全的边界是把默认输入、个体覆盖和情境参数分开,并明确写入者与读取者。
失败四:用一个布尔值代表复杂风险
bReckless 可以作为展示或统计标签,却不应承担红灯状态、近失事件、路线偏离、碰撞历史和高速路上下文的全部语义。不同消费者需要不同精度和生命周期,风险模型应保留事件类型、时间窗口和来源。
失败五:把玩家风险响应当成 AI 驾驶
玩家驾驶过程可以产生道路风险状态,但这些状态通常由玩家信息路径观察和维护,不应因此把玩家输入重新交给 AI 策略。观察行为与接管控制是两条不同的路径。
十五、源码阅读中的职责证据:如何判断策略层在哪里

源码逆向时,类名最容易造成职责误判。一个名称包含 Driver、Personality 或 Traffic 的对象,不一定就是驾驶策略的唯一所有者。更可靠的判断方法是观察四类证据。
1. 谁提供输入
查看策略函数的参数和调用前准备过程:它读取驾驶者能力、激进程度、车辆状态还是道路上下文?输入来自角色智能、车辆智能还是玩家信息?输入来源决定了它能代表什么。
2. 谁保存结果
如果函数只返回数值、向量、标志或候选权重,而不保存路线、任务和生命周期状态,通常更接近计算接口。若某个任务把结果存入自己的阶段字段,并在下一次更新时继续消费,任务才是相应行为的持有者。
3. 谁决定调用时机
策略计算的调用者可能是车辆智能、路口处理任务、局部移动任务或玩家状态更新。调用者决定了策略结果适用于哪个上下文,不能只看计算函数名称推断归属。
4. 谁消费输出
需要确认输出进入速度限制、停止距离、换道评分、鸣笛条件还是玩家统计。不同消费者对应不同语义边界,策略层的影响范围由消费关系确定,而非由名称确定。
证据等级
公开文章可以按三层表达:
① 代码直接呈现:某个函数读取某字段、返回某结果,或在某个更新入口被调用。
② 职责抽象:根据多处调用关系归纳出“共享的按需策略查询层”。
③ 迁移方案:将上述职责映射到目标引擎时,计划保留的边界。
只有第一层可以用较肯定的事实语气。第二层使用“可以观察到”“可以抽象为”,第三层明确标记为设计选择。这样既保留源码阅读价值,也避免把逆向分析写成未经证明的实现宣称。
十六、策略层的调试:不要只看车辆最后的位置
驾驶策略的问题经常被误判为最终运动结果异常。如果只观察最终位置,就无法知道是输入、路线、策略、局部任务还是执行器出了问题。一个可用的诊断记录至少应包含以下信息:
Policy Query
├ Driver / Vehicle Context
├ Route Segment
├ Traffic Context
├ Default Inputs
├ Temporary Overrides
├ Policy Outputs
├ Consumer Task
└ Effective Time / Version
输入诊断
确认驾驶者能力和激进程度是否来自正确对象,车辆无驾驶者时使用的近似输入是否被误认为真实角色状态,任务覆盖值是否在预期范围内。
输出诊断
记录策略生成的速度偏置、跟车距离、风险惩罚和候选评价参数,确认它们是否被下游任务读取。策略输出正确但任务仍使用旧缓存时,问题属于接缝更新失败,而非策略计算本身。
消费诊断
确认策略参数进入了哪个任务阶段:接近路口、等待、跟车、换道准备还是恢复。不同阶段可能只消费部分参数,不能把某个参数没有影响当前帧理解为系统没有策略。
时间诊断
如果策略输入来自临时上下文,需要记录有效时间和清除条件。玩家离开高速路、任务结束、车辆更换驾驶者或风险窗口过期后,临时修正必须停止影响后续计算。
结果诊断
最终车辆运动还受到 P7 局部安全检查和 P8 执行器/物理反馈影响。策略参数变化没有直接导致位置变化,并不必然表示策略失效;需要沿着消费链继续检查。
十七、驾驶策略的生命周期:查询、调制、失效与恢复

策略本身可以是无状态的,但其输入和输出仍然有生命周期。一个完整的策略查询周期可以抽象为:
上下文建立
↓
读取默认与覆盖输入
↓
计算当前策略参数
↓
交给任务或局部执行
↓
接收执行反馈
↓
更新情境或释放临时修正
上下文建立
策略查询需要确认驾驶者、车辆、路线段、路口或道路状态是否有效。对象失效、车辆切换、驾驶权迁移和任务结束都可能使旧上下文不再适用。
参数计算
参数计算应当尽量是可重复的。相同输入和相同配置应产生相同或可解释范围内的结果,避免策略层成为隐藏随机源。
交给任务
策略结果可以存入任务阶段,也可以作为一次查询结果使用。存储与否取决于下游生命周期,不应由策略计算器强行决定。
反馈与释放
执行反馈可能导致下一次策略查询改变输入,但反馈不应直接改写驾驶者人格。临时风险窗口、任务覆盖值和路口上下文在离开条件满足后需要释放。
车辆切换与玩家接管
P4 已经讨论控制源交接。P6 需要补充的是:控制源变化后,策略输入的读取路径也可能变化。AI 驾驶时,任务可以主动请求策略;玩家驾驶时,玩家输入成为主要命令来源,策略更多作为风险观察、交通提示或辅助约束存在。切换过程必须避免把旧 AI 策略缓存误用于玩家控制。
十八、与路线、执行器和多载具的兼容性

P6 不详细讲不同载具的控制律,但需要说明策略层为何可以跨载具复用。
共享部分应当是抽象意图和行为约束,例如:
- 推进意愿;
- 停止倾向;
- 风险容忍度;
- 目标保持;
- 时间成本与安全成本权衡;
- 当前任务阶段的行为调制。
专用部分由载具执行器解释:
| 载具 | 策略可共享的内容 | 执行器专用的内容 |
|---|---|---|
| 汽车 | 路线推进、停止倾向、间距偏置 | 车轮转向、制动、牵引力 |
| 船舶 | 目标保持、推进意愿、风险权重 | 舵角、推进器、水面阻力 |
| 飞机 | 目标方向、速度与风险取舍 | 姿态、推力、飞行包线 |
| 直升机 | 目标保持、接近与悬停倾向 | 旋翼、升力、姿态稳定 |
| 火车 | 速度、制动和目标阶段 | 轨道约束、编组和制动距离 |
如果策略层直接输出“左轮转角”或“刹车百分比”,就无法复用于船、飞机和火车;如果只输出“希望推进”“希望保持距离”“风险成本较高”,不同执行器可以在自己的运动学约束中完成解释。
这就是 P2 中“共享契约,不共享控制律”在策略篇的延伸:共享的是行为语义,专用的是空间运动。
十九、迁移启示:保留策略边界,不复制源码结构
本篇不展开 UE5 API、组件拆分或具体工程实现。迁移时需要保留的不是原始类名,而是以下边界:
- 路线系统继续拥有目标和路线生命周期;
- 策略计算能够读取稳定输入和临时上下文;
- 策略输出以行为偏好、软限制和候选评价权重存在;
- 局部避让任务拥有几何预测和候选生成;
- 载具执行器拥有类型专用的控制解释;
- 玩家风险观察与 AI 自动驾驶策略保持不同的命令路径;
- 临时覆盖值具有明确的有效期和释放条件;
- 调试记录可以追踪输入、输出、消费任务和最终反馈。
如果迁移只建立一个“驾驶 AI 管理器”,把路线、个性、避让、物理和玩家风险都塞进去,短期看似方便,长期会失去本篇最重要的组织原则:策略是调制层,不是世界运行时的总所有者。
二十、阶段性小结:驾驶策略改变的是取舍方式
到这里可以重新回答题目:为什么相同路线会产生不同驾驶行为?
因为路线描述车辆应当沿哪些道路上下文前进,不能决定每个驾驶者在速度、间距、等待、换道和风险之间如何取舍。驾驶策略把相对稳定的能力、行为倾向、车辆限制和即时交通情境转换成一组可消费的参数,影响下游任务如何选择与调制。
路线、路口相位、局部碰撞几何和物理控制量分别由对应系统维护。策略通过清晰的接缝改变行为,各自生命周期仍由相应所有者负责。
本篇可以用四条关系收束:
路线决定可行空间
策略决定取舍偏置
局部任务决定当前候选
执行器决定如何运动
玩家车辆还需要增加一条观察路径:道路风险、近失、碰撞和交通状态可以被玩家信息系统记录和解释,但观察行为不等于夺取玩家控制权。
如果说 P5 讨论的是“车辆如何持续知道该去哪里”,那么 P6 讨论的就是“车辆如何在仍然去往同一目标的前提下,表现出不同的驾驶选择”。下一篇将进入更具体的局部问题:当眼前出现行人、物体、车辆或道路边界时,系统如何预测冲突、生成候选方向,并把策略偏置交给局部避让运行时。
二十一、策略参数的有效期必须绑定任务阶段

驾驶策略并非在所有时刻以相同方式生效。车辆接近路口、等待通行、离开路口、跟随前车、准备并线和恢复路线时,虽然读取的基础能力可能相同,但参数的含义和消费者不同。
接近阶段
车辆还没有进入停止线或冲突区域时,策略主要影响速度准备、观察距离和对时间成本的估计。此时提高激进程度,通常意味着延后减速或保留更高推进意愿;降低能力参数,则可能要求任务提前准备,以留出更大的执行误差空间。
等待阶段
车辆已经确认当前不能继续通过,策略对“是否继续尝试”的影响应当受到任务阶段限制。一个合理的策略不应使车辆在等待状态中持续生成新的通过意图,而应影响重新评估频率、保持距离和恢复推进时的条件。通行权仍然由路口系统提供,策略不能自行把等待状态改成允许通过。
通过阶段
通过路口后,策略可能继续影响速度恢复、跟车间距和目标车道保持。这里的策略输出不应直接复用接近阶段的停止参数,否则车辆可能在已经离开冲突区后继续保守减速。参数需要绑定阶段,或者由消费者明确解释其有效范围。
跟随阶段
跟随前车时,策略对距离和速度差的调制最明显。它可以改变目标速度和缓冲范围,但局部任务仍然需要读取前车移动状态、路线方向和障碍几何。策略参数越抽象,越容易被不同执行器复用;将其写成某一种车型的控制量,就会把跟随逻辑锁死在汽车实现上。
并线准备与恢复阶段
并线不是策略单独决定的动作。策略可以改变对候选的等待成本和风险惩罚,局部任务负责生成和检查候选,路线系统负责确认目标车道是否仍然有意义。候选失败后,策略可能影响继续等待还是请求上层重规划,但不能直接把“没有找到间隙”解释为路线失效。
参数有效期的三种形式
策略参数可以是:
- 查询期参数:只在一次任务更新中有效,用于当前帧或当前次决策;
- 阶段期参数:在接近、等待、跟随等任务阶段内保持,阶段结束时释放;
- 任务期参数:由任务覆盖值提供,任务结束、替换或失败时清除。
如果没有明确有效期,旧任务的激进程度可能残留到新任务,玩家接管后也可能继承 AI 的临时策略。P4 讨论控制源迁移时强调了旧命令来源的释放;P6 需要补充的是,策略覆盖值也必须拥有相应的释放路径。
为什么不建议做一个永久“当前驾驶风格”字段
一个永久字段可以保存便捷,但无法表达“这是驾驶者默认倾向,还是当前追逐任务临时覆盖”。当任务结束时,系统只能猜测该字段是否应该恢复;当车辆进入远景或重新载入时,也无法判断哪些值属于持久身份,哪些值只是短时上下文。
更清晰的结构是保留来源:
Default Driver Input
+ Task Override
+ Context Modifier
+ Vehicle Limit
↓
Effective Policy Parameters
最终参数既可以被调试,也可以在任务结束后按来源清除,而不需要通过“恢复到某个神秘默认值”来修复状态。
二十二、从源码到文章:怎样避免把行为现象误写成机制事实
驾驶策略的源码阅读尤其容易出现由结果反推唯一原因的问题。例如,车辆在红灯前提前减速,可能来自驾驶策略的停止距离,也可能来自路线任务的路口上下文、车辆当前速度、道路限速或执行器自身的减速曲线。公开文章需要区分这些可能性,不能用单一类名解释全部现象。
先记录调用关系,再记录概念名称
对于一个返回速度、距离或风险权重的函数,应先记录:
- 它被谁调用;
- 调用时传入了哪些上下文;
- 返回值由谁保存;
- 返回值由谁消费;
- 是否存在默认值、覆盖值和范围限制;
- 任务结束后是否清除相关状态。
只有在这些关系稳定后,才适合把它归纳为“策略计算层”。如果先把对象命名为“驾驶个性管理器”,后续字段就可能被统一归入管理器职责,从而造成架构过拟合。
函数结果不等于最终行为
源码中出现一个速度上限,并不能证明车辆最终以该速度行驶;出现一个换道倾向,也不能证明车辆一定会换道。中间还可能经过:
- 任务阶段的条件判断;
- 道路或路口硬约束;
- 局部候选生成;
- 碰撞和边界检查;
- 执行器的车型限制;
- 物理状态反馈。
文章可以说“该结果为下游提供调制依据”,不宜写成“该函数决定车辆速度”。这也是本系列在匿名化后仍然保留技术可信度的关键。
观察者状态不一定进入驾驶策略
玩家道路风险路径提供了一个重要反例:玩家信息系统可以记录红灯、逆行、路面和近失状态,供统计、警示和世界响应使用,但这些状态不一定反过来改变玩家的直接命令来源。若看到某个状态被更新,就必须继续追踪它的消费者,不能因为名字包含“驾驶”就认定它属于 AI 策略。
代码证据与架构语言的对应方式
公开文章中可以使用下面的四列笔记格式:
| 代码证据 | 直接含义 | 架构抽象 | 公开措辞 |
|---|---|---|---|
| 读取能力与激进程度 | 函数消费驾驶参数 | 策略输入面 | “可以观察到策略读取……” |
| 返回距离/速度参数 | 下游获得调制结果 | 策略输出面 | “可抽象为行为约束……” |
| 被路口/车辆任务调用 | 策略由任务按阶段查询 | 生命周期属于调用者 | “从调用关系看……” |
| 玩家路径写入风险状态 | 风险由玩家信息维护 | 观察路径独立存在 | “不应等同于 AI 人格……” |
这种写法不但能降低过度断言,也能让读者理解为什么某个架构结论不是凭空命名出来的。
二十三、P6 的验证矩阵:同一条路、不同参数、不同消费者
P6 的验证不应只做“车辆是否到达终点”。终点相同并不能证明策略已经正确生效,因为不同策略可能在相同道路上获得相同结果,也可能被下游约束完全覆盖。
维度一:输入稳定性
固定路线、道路、车辆类型和交通上下文,只改变驾驶者默认输入。检查速度偏置、间距和候选评价是否在可预期范围内变化。若输入变化没有任何策略输出差异,需要确认调用路径是否绕开策略层;若变化过大,则需要检查范围限制。
维度二:任务覆盖
固定驾驶者输入,分别施加巡航、护送、追逐和临时接近等任务覆盖。检查任务结束后覆盖是否释放,旧任务是否会影响新任务。这里不验证任务本身的完整行为,而是验证策略输入的来源和有效期。
维度三:道路情境
固定驾驶者和任务,改变红灯、前车距离、道路宽度、目标车道和高速路上下文。检查策略是否读取正确情境,且不会把一次性道路状态永久写回驾驶者默认值。
维度四:局部约束覆盖
使用同一策略输入,改变前方障碍、碰撞风险和导航边界。策略输出可以保持不变,但局部执行结果应该受到 P7 约束。该测试用于确认策略没有越过避让所有权。
维度五:车型解释
将相同的抽象策略输入交给汽车、船舶和飞行器的专用执行器,检查各自能否得到合理的类型语义。测试重点不是让它们产生相同轨迹,而是确认共享输入没有退化成汽车专用控制量。
维度六:玩家路径隔离
在玩家驾驶过程中产生红灯、近失和碰撞上下文,检查系统是否正确记录、提示或统计,同时确认玩家输入不会被 AI 策略覆盖。该项把“风险观察”与“控制接管”分开验证。
验证结果应记录来源
每个测试结果最好附带:
- 默认策略输入;
- 任务覆盖值;
- 当前情境;
- 有效策略输出;
- 实际消费者;
- P7/P8 是否产生覆盖;
- 参数清除时间。
这样出现偏差时,可以回答“哪一层改变了行为”,而不是只知道车辆最终偏离了路线。
AI 协作复盘:把行为差异还原为可验证的输入与边界
驾驶行为差异容易被“谨慎”“鲁莽”“驾驶能力较高”“换道推进倾向较强”等词语概括,但这些描述不能直接说明系统如何实现。AI 在本篇中的作用不是替代判断,也不是生成一套完整的驾驶 AI,而是帮助把跨来源材料压缩成可核对的关系:
- 哪些字段属于默认驾驶者输入;
- 哪些值由角色智能或车辆智能覆盖;
- 哪些状态只属于玩家风险观察路径;
- 哪个任务决定策略查询时机;
- 哪个系统消费速度、间距和风险参数;
- 哪些内容已经进入 P7 的局部避让;
- 哪些内容必须留给 P8 的执行器和物理接缝。
最终仍由人决定哪些关系可以写入公开文章,哪些只能保留为分析假设,哪些需要等原型验证。对这类复杂运行时而言,AI 最有价值的产出不是“生成更多系统”,而是帮助减少错误归属,让每个策略结果都能追溯到输入、消费者和生命周期。
策略可以改变车辆如何取舍,但不能因此成为车辆运行时的唯一所有者。