3
planning中的场景管理
Apollo中的规划里的一个重要思想就是基于场景划分来调用不同的task处理,而其中如何进行场景分配便是实现该思想的核心。从上面的配置参数可以看到目前Apollo设定了16种场景,而场景下的具体切换逻辑也比较复杂,scenario_manager的具体流程逻辑如下图所示:
在上图红框中的场景判断中,我只画了第一步的场景判断,红框内的5种场景为大类,剩余的场景在这5大类中再细分做出判断。另外需要注意的是,红框内的5种场景是有优先级顺序的,即如果判断为某种场景后,后续的场景也就不再判断。下面从这5种场景出发,介绍一下Apollo中的场景判断条件,以及每个大类场景下包含哪些细分的场景小类。
1. ParkAndGo
该场景的判断条件为车辆是否静止,并且距离终点10m以上,并且当前车辆已经off_lane或者不在城市道路上,在该场景下采用的是open_space相关的算法。个人感觉该场景在驶离目标车道并正常规划失败导致的停车时会触发,利用open_space方法使其重新回到正常道路上,因此也是场景判断中首先需要check的。
2. Intersection
在该场景下,又可细分四个场景。首先,根据先前计算的地图中第一个遇到的overlap来确定大类型,是包含交通标识的交叉口,还是其他交叉口。其次,若是包含交通标识的交叉口,还细分为stop_sign、traffic_light以及yield_sign,具体结构图如下所示。
3. PullOver
PullOver场景即靠边停车,需要满足以下条件才可切换到该场景:
不在change_line的时候,即reference_line只有一条
当前位置距离终点在一定范围内并且满足pullover可以执行的最短距离
地图中能够找到pullover的位置
终点的位置不在交叉路口附近
能查找到最右边车道的lane_type,并且该车道允许pullover
只有从lane_follow场景下才能切换到pullover
大体逻辑如上述所示,具体的参数设置可以查看代码。
4. ValetParking
ValetParking场景即代客泊车,判断逻辑如下:
从routing中得到target_parking_spot_id
从地图中搜索是否存在path能够抵达该parking_spot
查询当前位置至parking_spot的距离,满足条件即可切换至该场景
5. DeadEnd
Apollo 7.0中新增的断头路场景,增加了"三点掉头"功能,增加了驶入驶出的能力,扩展了城市路网运营边界。"三点掉头"功能基于open space planner框架,包含以下几个部分:断头路场景转换、开放空间ROI构建、掉头轨迹规划。下列图片展现了从进入DeadEnd到驶离DeadEnd的整个过程,后续我也会详细了解该算法实现逻辑。
上面就是Apollo中的场景切换及管理逻辑。在每个场景scenario下,还分为一个或多个stage,而每个stage下面,又划分了多个task来完成相应的规划任务。以用到最多的lane_follow场景为例,它就包含了一个stage——lane_follow_default_stage,而在这个stage下包含了多个task,如下图所示:
仔细查看lane_follow场景下的task,我们可以看出Apollo的规划思路也是横纵向解耦,先规划path,再规划speed。具体的,对于path来说,先做出是否需要lane_change或者lane_borrow的决策,再根据决策状态来生成凸空间,最终基于reference_line及凸空间求解一个二次优化问题,从而得到优化后的path。对于speed来说,是基于ST图进行DP+QP的优化方法,先利用DP来找到一个cost值最小的可行解,再利用QP对可行解进行平滑,得到最终平滑后的ST图点集。最终,基于s值对path和speed进行融合,得到一条平滑的轨迹。
4
总结
至此,Apollo 7.0 planning的核心框架及核心算法的输入都已经解释清楚了,总体来看Apollo规划的整体思路非常清晰,但是细节部分真的需要花费大量时间来理解,我觉得如果没能将这套算法部署到实车上跑过的话,很多算法可能真的无法很好地理解。
我个人也陆陆续续看这套代码有两年多了,始终觉得很多细节都没有深入理解透,代码光看是肯定不行的,如果没有条件在实车,或者是仿真里实际运行,解决相应场景下遇到的问题的话,是始终不能转变为自己的知识的,希望与大家共勉,也欢迎大家有任何疑问在评论区留言交流。
- End -
原文标题 : 百度Apollo7.0 规划算法框架解析(干货)