3、行为决策层详解:有限状态机(FSM)、决策树、基于规则的方法
各位同学,欢迎来到行为决策层。这一层,说白了就是自动驾驶的「大脑皮层」——感知层告诉车「看到了什么」,规划层告诉车「怎么动」,而行为决策层,负责回答那个最核心的问题:「现在该干什么?」
我个人习惯把行为决策层比作一个老司机。老司机开车,不会每秒钟都重新计算一遍路径,而是根据路况快速判断:该跟车?该变道?该让行?还是该刹停?这些判断,就是行为决策。
今天咱们就聊聊三种最经典的行为决策方法:有限状态机、决策树,还有基于规则的方法。嗯,这三种方法,我在实际项目中都用过,各有各的脾气。
3.1 有限状态机(FSM)—— 最朴素的「状态切换」
有限状态机,英文叫 Finite State Machine,简称 FSM。说白了,就是给自动驾驶定义一堆「状态」,然后规定好状态之间怎么切换。
举个例子:一个最简单的 FSM 可能包含这几个状态:
- INIT:初始化
- CRUISE:巡航行驶
- FOLLOW:跟车
- STOP:停车
- EMERGENCY:紧急制动
每个状态都有明确的进入条件和退出条件。比如:
- 从 CRUISE 切换到 FOLLOW:当前方检测到障碍物且距离小于安全阈值时。
- 从 FOLLOW 切换到 CRUISE:当前方障碍物消失或距离大于安全阈值时。
核心要点:FSM 的关键在于「状态转移表」。你想想看,如果状态转移条件写错了,车就会在路口反复横跳,像个新手司机一样犹豫不决。
我在项目中遇到过一件事。有一次,我们的车在高速上遇到前车急刹,FSM 从 CRUISE 切到了 EMERGENCY。但 EMERGENCY 状态结束后,它直接切回了 CRUISE,结果车猛地加速——因为没经过 FOLLOW 状态。嗯,这就是状态转移设计不严谨的典型问题。
我的建议:设计 FSM 时,一定要画一张完整的状态转移图。每个状态都要问自己三个问题:
- 从哪些状态可以进入当前状态?
- 当前状态可以切换到哪些状态?
- 切换条件是什么?有没有优先级?
3.2 决策树 —— 把「如果-那么」画成树
决策树,比 FSM 更直观。它就像一张流程图,每个节点是一个判断条件,每个分支是一个决策结果。
举个例子:判断「是否应该变道」的决策树:
是否要变道?
├── 是:目标车道是否有车?
│ ├── 有:目标车道后车距离是否足够?
│ │ ├── 是:执行变道
│ │ └── 否:放弃变道,保持当前车道
│ └── 无:执行变道
└── 否:保持当前车道
决策树的优点很明显:可解释性极强。你问它「为什么变道」,它能告诉你「因为目标车道没车,且当前车道前车太慢」。这在工程调试和安全性验证中,价值巨大。
但决策树也有坑。我曾经踩过一个坑:决策树的深度太深,导致实时性不够。你想想看,如果一棵树有 10 层,每层有 3 个分支,那最坏情况下要判断 3^10 次——这在高速场景下根本来不及。
避坑指南:我曾经在项目中把决策树深度控制在 5 层以内,超过 5 层的逻辑,我会拆成多个子决策树,或者用规则表替代。记住:决策树不是越深越聪明,而是越浅越可靠。
3.3 基于规则的方法 —— 老司机的「经验库」
基于规则的方法,说白了就是把老司机的经验写成「if-then」规则。比如:
- 规则1:如果前车刹车灯亮起,且距离小于 30 米,则执行减速。
- 规则2:如果本车速度大于 120 km/h,则禁止变道。
- 规则3:如果路口有行人,且行人正在过马路,则停车等待。
这些规则,通常来自三方面:
- 交通法规:比如「红灯停、绿灯行」。
- 工程经验:比如「跟车距离至少保持 2 秒时距」。
- 测试反馈:比如「在雨天,制动距离增加 30%」。
我个人习惯把规则分成三个等级:
| 等级 | 描述 | 示例 |
|---|---|---|
| 硬规则 | 违反会导致安全事故,必须遵守 | 「遇到红灯必须停车」 |
| 软规则 | 违反不会立即出事,但影响体验 | 「变道前打转向灯至少 3 秒」 |
| 建议规则 | 根据场景动态调整,可忽略 | 「拥堵路段建议走中间车道」 |
基于规则的方法,最大的问题是「规则冲突」。比如:规则 A 说「遇到障碍物要绕行」,规则 B 说「实线禁止变道」。如果障碍物正好在实线路段,车该怎么办?
我的解决方案:给每条规则分配一个优先级。硬规则优先级最高,软规则次之,建议规则最低。当规则冲突时,优先级高的规则胜出。如果优先级相同,则选择「最安全」的那个。
3.4 三种方法的对比与选择
好了,三种方法都讲完了。你可能会问:到底该用哪一种?
我的经验是:没有银弹。实际项目中,往往是三种方法混合使用。
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| FSM | 结构清晰,状态切换明确 | 状态爆炸,难以处理复杂场景 | 高速公路巡航、泊车等结构化场景 |
| 决策树 | 可解释性强,调试方便 | 深度过大时实时性差 | 变道决策、路口通行等中等复杂度场景 |
| 规则方法 | 简单直接,易于维护 | 规则冲突,难以覆盖所有场景 | 安全约束、法规合规等确定性场景 |
我记得在做一个城市道路项目时,我们用了这样的混合架构:
- 顶层用 FSM 管理「巡航-跟车-停车-紧急」等宏观状态。
- 每个状态内部,用决策树处理具体决策(比如「跟车状态下,是否要变道」)。
- 最底层,用规则库做安全兜底(比如「任何状态下,遇到行人必须停车」)。
嗯,这个架构跑了两年,没出过大的逻辑问题。
最后一个小技巧:不管你用哪种方法,一定要给行为决策层加一个「超时保护」。比如,如果某个状态停留超过 5 秒没有切换,就强制进入安全模式。为什么?因为我在测试中遇到过 FSM 卡死在某个状态,车一直原地打转——有了超时保护,至少能保证车停下来。
好了,行为决策层的内容就到这里。下一章,咱们聊聊运动规划层——也就是怎么把「决策」变成「方向盘和油门」的具体指令。