当前位置:   article > 正文

Apollo:决策模块_apollo决策模块

apollo决策模块

概述

决策方式:双层状态机

apollo中的planning模块的场景选择是通过scenario-stage-task并利用状态机对车辆状态和规划功能进行维护的。

  • planning模块是基于Scenario、Stage、Task这样的层次结构的,针对不同的场景设计不同的算法细节。

    • Scenario指定一个特定的问题或者场景。具体下下面目录【Scenario】
    • State指在一个Scenario下的规划方法的粗略步骤
    • task指的是一个具体的处理方法
  • 相应地,一个Scenario包含多个Stage,一个Stage包含多个Task。

在这里插入图片描述

为实现决策功能,设计了一个双层状态机
在这里插入图片描述

  • apollo主要是通过状态机进行决策
  • 有限状态机不适合比较复杂的情况,于是apollo选择Top Layer+Bottom Layer的方式,将类似的状态集合到一个底层的状态机中,于是就形成了双层状态机
  • 同时Apollo通过对scenario进行分类,每个scenario又分为一个或多个stage,每个stage又是由不同的task组成。整体流程图如上图所示

决策模块的输入输出

在这里插入图片描述

决策模块相当于无人驾驶系统的大脑,保障无人车的行车安全,同时也要理解和遵守交通规则。为了实现这样的功能,决策模块为无人车提供了各种的限制信息包括:

  • 1)路径的长度以及左右边界限制;
  • 2)路径上的速度限制;
  • 3)时间上的位置限制。

此外,决策模块几乎利用了所有和无人驾驶相关的环境信息,包括:

  • 1)Routing 信息;
  • 2)道路结构,比如当前车道,相邻车道,汇入车道,路口等信息;
  • 3)交通信号和标示,比如红绿灯,人行横道,Stop Sign,Keep Clear 等;
  • 4)障碍物状态信息,比如障碍物类型,大小,和速度;
  • 5)障碍物预测信息,比如障碍物未来可能的运动轨迹。

正因为决策模块处理了所有上层业务逻辑信息,并抽出了抽象的限制信息,我们保证了下游路径和速度优化的抽象性,并完全和上层的地图,感知,预测的解耦

决策的功能模块

apollo决策主要分为五大功能:

  • 参考路径
  • 交规决策
  • 路径决策
  • 速度决策
  • 决策场景的分类和调度

参考路径

参考路径(Reference Line)在 apollo决策中起着非常重要和关键的作用。

  • 首先,参考路径是在没有障碍物路况下的默认行车路径
  • 其次,后继的交通决策,路径决策和速度决策都是基于参考路径或者参考路径下的Frenet Frame完成的
  • 最后,参考路径也用于表达换道的需求,一般换道有两条参考路径,分别有不同的优先级

其中,优先级搞的路径表示目标路径,优先级低的路径表示当前路径。
在这里插入图片描述
目前在 Apollo 里,参考路径的计算是根据routing的路线,找到相应的高精地图中的道路中心线,然后进行平滑。

交规决策

有了参考路径之后,我们会沿着该路径找到所有在该路径上的交通标示和交通信号灯,并根据一系列的交通规则来决定是否在需要停止在交通标示或者交通信号灯的停止线前。如果需要停止,决策模块会在停止线上生成一个虚拟的墙。虚拟墙会影响后继的路径和速度决策。

如下图,在无人车的参考路径(蓝色)上有交通灯,根据交通灯的状态:

  • 如果是红灯,决策模块会在交通灯的停止线上生成一道虚拟的墙
  • 如果是绿灯,不生成任何虚拟墙

这样我们就完成了绿灯行红灯停的交通规则。其他的交通规则也采取类似的方法,根据规则决定是否在相应的地方放置虚拟墙。
在这里插入图片描述

路径决策

准备知识

  • 什么是变道:变道是指汽车在行驶中,因超车、避让障碍物或在路口转弯时,需要由一个车道进入另一个车道的驾驶操作。变更车道有一定的风险,一定要在确保安全的前提下谨慎变更。基于PreScan Simulink的换道仿真
  • 什么是借道:所谓借道,是指自己车道前方有障碍物、或者视线不明,在不影响对向来车行驶的情况下,暂时驶入对向车道,待越过障碍物后或视线明朗了,再回到自己的车道的临时行驶行为,叫借道行驶。

开始决策

有了根据交通标示和交通信号灯产生的虚拟墙,再加上从感知模块得到的障碍物信息,我们就可以开始进行路径决策。路径决策。路径决策的过程类似下面的决策树:

  • 首先我们判断是否需要进行变道(Lane Change)。
    • 如果我们有多条参考路径并且当前车辆不在优先级最高的参考路径上,则表明需要进行换道
    • 其他情况,不需要换道
  • 在明确换道的情况下,我们需要判断当前路况是否可以进行安全变道
    • 如果安全,路径决策会产生换道的路径边界
    • 如果不可以进行安全换道,那么就产生车道内的路径边界
  • 如果不需要换道,那么接着判断是否需要借道避让(Side Pass)。
    • 判断条件有两个:
      • 当前车道的可行驶宽度不够
      • 前方障碍物为静止状态而且不是由于车流原因静止。比如,路边卸货车流。
  • 如果确定需要借道避让,那么接下来判断是否可以安全借道
    • 如果安全,路径决策会产生借道避让的路径边界
    • 否则产生车道内的路径边界
  • 如果不需要借道避让,那么产生车道内的路径边界。
    在这里插入图片描述

车道内路径边界的决策有图中所示的三种情况:车道内无障碍物,车道前方有障碍物,车道左右方有障碍物。实际路况中会是其中一种情况或者多种情况的组合。

  • 在无障碍物的情况下(左图),路径边界依据车道边界或者道路边界来生成,并留有一定距离的缓冲(绿色虚线)。
  • 在有障碍物的情况下(中图),路径边界会被截止在第一个障碍物的后方
  • 如果车道左右方有障碍物(右图),路径边界的产生会依据车道线和障碍物的边界

在这里插入图片描述
注意,图中的蓝色线是车辆的参考路径(Reference Line),路径边界的生成是在参考路径的Frenet Frame 下完成的

借道的路径边界

  • 街道避让的路径边界产生,是在确认可以安全借道之后完成的。
  • 而是否可以安全借道的决策,目前是依据一系列的规则来做出的,这个决策也可以依据ST图或者数据模型来生成
  • 如下图,路径的边界是依据本车道和借用车道的边界来生成。

在这里插入图片描述

换道的路径边界

  • 换道路径边界的产生与借道避让类似,主要区别是Reference Line(参考线)在换道时是在目标车道上,而借道避让是是在本车道上。

在这里插入图片描述
另外需要强调的是,在做路径决策时,只考虑静止障碍物。动态障碍物是在速度规划时考虑

速度决策

有了路径边界后,我们调用路径优化器(Path Optimizer)得到在边界限制内的平滑路径。得到平滑的路径后,我们就可以在路径上进行速度决策。

速度决策的流程如下图所示。

在这里插入图片描述

  • 我们首先对一整条路径或者部分路径产生一个或者多个速度限制边界(Path Bounds),然后对多个速度边界进行集成,得到最终的路径上的速度限制边界(Speed Bound Over s)。
  • 得到速度限制之后,我们在利用 ST 图来得到时间上的位置限制边界(Position Bound Over )。
  • 最后我们把速度边界和位置边界传给速度优化器(Speed Optimizer)得到平滑的速度规划。

speed bound decider

在很多情况下,出于行车安全和遵守交规的原因,需要对车辆的速度进行限制。比如,当路径旁边有行人时,我们要减速慢行;当我们要借道避让时,也要减速慢行。这样的速度限制可能是对整条路径,比如道路限速,也有可能是对路径中的一小段,比如减速带。

如下图,沿着路径(s)有三种不同的限制:

  • 道路限制(黄色)
  • 减速带(绿色)
  • 行人限制(绿色)。

为了得到整条路径的综合限速,我们把这几种限速集成到一起。如右下图

在这里插入图片描述

得到路径上的速度边界之后,我们就可以利用ST图来求解时间上的位置边界。下图是一个简单的 ST 图的例子,我们用这个例子来简单解释我们为什么需要 ST 图以及如何从 ST 图上得到时间上的位置边界。

左图是一个简单的驾驶场景

  • 右侧灰色方框代表自动驾驶主车,蓝线是主车的路径;
  • 左侧黑色方框代表障碍车
  • 红线是障碍车的预测行驶轨迹。

把障碍车的预测轨迹和主车的路径的交汇关系在 ST 图中表示出来。如下右图:

  • t1 为障碍车预测轨迹和主车路径的交汇时间;
  • s1,s2 为交汇时障碍车在主车路径上的位置;
  • s1 代表车尾位置,s2 代表车头位置。

在这里插入图片描述
在st图中,我们的目标是找到一条不和障碍物碰撞的曲线,同时,曲线还需要满足我们之前计算的路径上的速度限制,即曲线的斜率不能超过 v 的限边界。找到最优的一条曲线后,我们根据曲线计算时间上的位置限制边界
在这里插入图片描述

例如,如果我们找到红色的曲线为最优曲线,时间上的位置限制就为红虚线段。

在 x,y 平面中,就表现为主车在障碍车换道前进行超车。反之,绿色的曲线和绿色虚线段表示主车在障碍车换道后,进行跟随。
在这里插入图片描述

有了路径上的速度限制,及时间上的位置限制之后,我们就可以把这两个决策传递给速度优化器得到平滑的速度规划,即在路径上的每个点的时间。生成速度规划后,我们就可以结合路径和速度生成最终的 Planning 的轨迹。

以上就是 Apollo 决策的一些基本设计和实现。

决策场景

什么是场景

场景的概念首次在Apollo3.5中提出

  • 场景可以是地图中有一定特征的路段,比如红绿灯路口,
  • 也可以是无人车想要完成的一系列复杂的动作,比如停车场景,借道避让场景

场景的优点:

  • 场景之间互不干扰,可以并行开发和调参;
  • 同时可以在一个场景里可以实现一系列的有时序或依赖关系的复杂任务。

场景的缺点:

  • 首先,场景的通用部分会带来代码的冗余,不便于代码的升级维护;
  • 其次,场景的划分,尤其是保证场景之间没有功能上的覆盖也很困难;
  • 最后,有了多个场景之后,需要额外的逻辑来进行场景识别以及处理场景之间的转换。

场景分类

在这里插入图片描述
场景的划分其实没有特别严格的规定,同时这也取决于自动驾驶的应用场景,比如送货小车和高速卡车在场景的划分上肯定不太一样。上图中,我们给出了 Apollo 场景分类的一个例子,来尽量保证每个场景之间相对独立,这样的分类设计仅供大家参考。

我们把场景分为两大类,Lane Follow 和 Lane Breaking:

  • Lane Follow场景下主车沿一条车道驾驶,该车道前方一定距离内没有其他车道与其交汇或者穿越;并且主车也没有切换到其他车道的意图
  • 非 Lane follow 的其他场景被分类为 Lane Breaking。

在 Lane Breaking 下,我们又细分为三个小类:

  • Intersection 是所有的路口场景;
  • Active Pass 包括了所有临时借道的场景;
  • Lane Switch 包括了所有换道的场景(包括车道合并)。

场景的识别和转换

有了场景的分离之后,我们就可以对场景进行识别和转换。对于选择哪个场景,我们采用了两层的识别机制。

  • 首先,每一个场景自己会根据当前的环境信息,确定是否属于自己的场景,并返回该信息给场景管理器,场景管理器再统一进行选择,以保证场景的选择最优
  • 场景的退出也由每个场景自己决定,比如场景运行完成或者内部出错。一旦进行一个场景,该场景会有较高优先级来完成。

在这里插入图片描述

接下来,我们用借道避让场景的一个实现,来说明场景是如何实现的。

在这里插入图片描述
在这个场景中,我们有6个state(阶段),每个state完成借道避让的一个步骤,类似于有限状态机中的一个状态。主要state有一定的时序依赖关系,如果在一个state(阶段)中发现环境变化了,或者出现错误,就会出现state之间的跳转或者退出该场景。

在这里插入图片描述
在每一个state(阶段)中,都要实现上图中的功能,保留交规决策,路径决策,路径优化,速度决策,速度优化。

我们把每个功能定义为一个或者几个基本的 Task(任务),每个 Stage(阶段)或者直接调用(使用默认参数),或者修改参数,或者修改输入值。这样的实现可以极大的提高场景之间的代码复用。

在上述的 Apollo 决策的实现中,我们使用了路径和速度分离的方法。这样的实现极大的简化了决策和优化问题,但是同时也使得最终轨迹不一定是最优的。

我们同时也在探索一些方法,使得路径和速度的决策和优化能够关联起来。
在这里插入图片描述
一种可能的方法(如左图所示)是路径决策时输出几种不同的路径,在速度决策和优化时,同时考虑多条路径,并选出最优轨迹。

另外一种思路(如右图所示)是速度和路径之间形成反馈环,如果速度决策和优化时发现路径决策不理想,会反馈至路径决策,重新进行路径决策和优化。


主要功能

scenario功能模块中的主要功能如下:

  1. 通过cenario_manager作为scenario场景的执行和处理的入口,是由PublicRoadPlanner::Plan()调用
  2. scenario及其子类,通过定义的场景以及config配置文件具体执行后继的scenario-stage-task流程
  3. tasks及其子类
  4. 整个scenario的数据信息来源来自于ReferenceLineInfo类,其中主要通过reference_line, lanes, vehicle_state以及adc_planning_point.

场景的实现主要包含三种类:

  • ScenarioManager:场景管理器类。负责注册,选择和创建Scenario。
  • Scenario:描述一个特定的场景(例如:Side Pass)。该类中包含了CreateStage方法用来创建Stage。一个Scenario可能有多个Stage对象。在Scenario中会根据配置顺序依次调用Stage::Process方法。该方法的返回值决定了从一个Stage切换到另外一个Stage。
  • Stage:如上面所说,一个Scenario可能有多个Stage对象。场景功能实现的主体逻辑通常是在Stage::Process方法中。

在这里插入图片描述

场景管理 scenario_manager

planning模块对于scenario的切换的代码是在scenario_manager中实现的,目前apollo一共支持11中场景和场景的定义

  • Lane Follow scenario:默认驾驶场景,包括本车道保持、变道、基本转弯
  • Bare intersection unprotected:无保护裸露交叉路口
  • Stop sign unprotected:无保护停止标志
  • Traffic light protected:有保护交通灯,即有明确的交通指示灯(左转、右转)
  • Traffic light unprotected left turn:无保护交通灯左转,即没有明确的左转指示灯,需要避让对向的直行来车
  • Traffic light unprotected right turn:无保护交通灯右转,需要避让交通流
  • Pull over :靠边停车
  • Emergency pull over :紧急靠边
  • Narrow street u turn :窄道掉头
  • Park and go:停车和启动
  • Yield sign:让路标志

车道保持

车道保持场景是默认的驾驶场景,它不仅仅包含单车道巡航。同时也包含了:

  • 换道行驶
  • 遵循基本的交通约定
  • 基本转弯

在这里插入图片描述

Side Pass

在这种情况下,如果在自动驾驶车辆(ADC)的车道上有静态车辆或静态障碍物,并且车辆不能在不接触障碍物的情况下安全地通过车道,则执行以下策略:

  • 检查邻近车道是否接近通行
  • 如果无车辆,进行绕行,绕过当前车道进入邻道
  • 一旦障碍物安全通过,回到原车道上

在这里插入图片描述

停止标识???

停止标识有两种分离的驾驶场景:

  • 未保护:在这种情况下,汽车预计会通过具有双向停车位的十字路口。因此,我们的ADC必须爬过并测量十字路口的交通密度,然后才能继续走上它的道路。
    在这里插入图片描述

  • 受保护:在此场景中,汽车预期通过具有四向停车位的十字路口导航。我们的ADC将必须对在它之前停下来的汽车进行测量,并在移动之前了解它在队列中的位置。

在这里插入图片描述

场景配置

在apollo的planning中,场景首先通过配置文件进行配置

Scenario的配置在“planning/conf/scenario”文件夹中。以pull over场景为例,在对应的scenario type中配置包含的stage列表,在stage中配置其包含的task列表。

从配置文件中也可以看出一个Scenario包含多个Stage,一个Stage包含多个Task。
在这里插入图片描述

场景注册

  • Init函数负责对场景的初始化
  • RegisterScenario负责场景的注册
    • 实际上,注册的方式就是读取配置文件。这里读取的配置文件位于/modules/planning/conf/scenario目录下

在这里插入图片描述

场景转换(确认)

void ScenarioManager::Update(const common::TrajectoryPoint& ego_point,
                             const Frame& frame) {
  • 1
  • 2

场景转换在ScenarioManager::Update中实现,这个函数有两个输入:

  • TrajectoryPoint包含了车辆的基础位置,速度,加速度,方向等自车信息。
  • Frame:代表了一次planning循环计算之后所有的需要存储的结果和中间信息

在这里插入图片描述

Update函数首先调用Observe函数,获取当前要处理的overlaps。

  • 在apollo里 Overlap 是指地图上任意重合的东西
  • 比如PNC_JUNCTION里是道路之间有相互重合,SIGNAL是信号灯与道路有重合,STOP_SIGN是停止标志与道路有重合,YIELD_SIGN是合标志与道路有重合。

在这里插入图片描述

而ScenarioManager::ScenarioDispatch函数则会对场景进行具体的处理,在apollo 6.0的planning模块中共有2种处理模式,分别是经典模式(能够有具体的场景定义的)与学习模式(通过深度学习进行场景处理的),分别会根据配置文件调用其后的ScenarioManager::ScenarioLearningDispatch与ScenarioManager::ScenarioNoLearningDispatch。

ScenarioManager::ScenarioNoLearningDispatch则是通过车辆状态frame中的scenario_type对车辆具体场景模块进行切换 ScenarioManager::Select*Scenario,并且由场景执行stage。

在这里插入图片描述

参考

  • https://blog.csdn.net/weixin_65089713/article/details/128848411
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号