Apollo源码解析:决策规划PathBoundsDecider
附赠自动驾驶最全的学习资料和量产经验:链接
一、概述
PathBoundsDecider 是lanefollow 场景下,所调用的第 4 个 task,它的作用主要是:
-
根据借道信息、道路宽度生成FallbackPathBound
-
根据借道信息、道路宽度生成、障碍物边界生成PullOverPathBound、LaneChangePathBound、RegularPathBound中的一种
二、PathBoundsDecider的具体逻辑如下:
1、PublicRoadPlanner 的 LaneFollowStage 配置了以下几个task 来实现具体的规划逻辑,PathBoundsDecider 是第四个task,PathBoundsDecider根据lane borrow决策器的输出、本车道以及相邻车道的宽度、障碍物的左右边界,来计算path 的boundary,从而将path 搜索的边界缩小,将复杂问题转化为凸空间的搜索问题,方便后续使用QP算法求解;
PathBoundsDecider生成的每个bound,后续都会生成对应的轨迹
scenario_type: LANE_FOLLOW
stage_type: LANE_FOLLOW_DEFAULT_STAGE
stage_config: {
stage_type: LANE_FOLLOW_DEFAULT_STAGE
enabled: true
task_type: LANE_CHANGE_DECIDER
task_type: PATH_REUSE_DECIDER
task_type: PATH_LANE_BORROW_DECIDER
task_type: PATH_BOUNDS_DECIDER
task_type: PIECEWISE_JERK_PATH_OPTIMIZER
task_type: PATH_ASSESSMENT_DECIDER
task_type: PATH_DECIDER
task_type: RULE_BASED_STOP_DECIDER
task_type: ST_BOUNDS_DECIDER
task_type: SPEED_BOUNDS_PRIORI_DECIDER
task_type: SPEED_HEURISTIC_OPTIMIZER
task_type: SPEED_DECIDER
task_type: SPEED_BOUNDS_FINAL_DECIDER
# task_type: PIECEWISE_JERK_SPEED_OPTIMIZER
task_type: PIECEWISE_JERK_NONLINEAR_SPEED_OPTIMIZER
task_type: RSS_DECIDER
}
PathBoundsDecider被调用流程与其他task类似:
2、PathBoundsDecider计算path上可行使区域边界,其输出是对纵向s等间距采样,横向s对应的左右边界,以此来作为下一步路径搜索的边界约束;与其他task一样,PathBoundsDecider的主要逻辑在Process() 方法中。
在Process() 方法中分四种情况对pathBound进行计算,按照处理顺序分别是fallback、pullover、lanechange、regular,不同的boundary对应不同的应用场景,其中fallback对应的path bound一定会生成,其余3个只有一个被激活,即按照顺序一旦有有效的boundary生成,就结束该task。
Process() 方法的代码及详细备注如下,首先看下整体代码,下文会对其中的模块做详细介绍:
Status PathBoundsDecider::Process(
Frame* const frame, ReferenceLineInfo* const reference_line_info) {
// Sanity checks.
CHECK_NOTNULL(frame);
CHECK_NOTNULL(reference_line_info);
// 如果道路重用置位,则跳过PathBoundsDecider
// Skip the path boundary decision if reusing the path.
if (FLAGS_enable_skip_path_tasks && reference_line_info->path_reusable()) {
return Status::OK();
}
std::vector<PathBoundary> candidate_path_boundaries;
// const TaskConfig& config = Decider::config_;
// Initialization.
// 用规划起始点自车道的lane width去初始化 path boundary
// 如果无法获取规划起始点的道路宽度,则用默认值目前是5m,来初始化
InitPathBoundsDecider(*frame, *reference_line_info);
// Generate the fallback path boundary.
// 生成fallback_path_bound,无论何种场景都会生成fallback_path_bound
// 生成fallback_path_bound时,会考虑借道场景,向哪个方向借道,对应方向的path_bound会叠加这个方向相邻车道宽度
PathBound fallback_path_bound;
Status ret =
// 生成fallback_path_bound,
// 首先计算当前位置到本车道两侧车道线的距离;
// 然后判断是否借道,并根据借道方向叠加相邻车道的车道宽度
// 带有adc的变量表示与自车相关的信息
GenerateFallbackPathBound(*reference_line_info, &fallback_path_bound);
if (!ret.ok()) {
ADEBUG << "Cannot generate a fallback path bound.";
return Status(ErrorCode::PLANNING_ERROR, ret.error_message());
}
if (fallback_path_bound.empty()) {
const std::string msg = "Failed to get a valid fallback path boundary";
AERROR << msg;
return Status(ErrorCode::PLANNING_ERROR, msg);
}
if (!fallback_path_bound.empty()) {
CHECK_LE(adc_frenet_l_, std::get<2>(fallback_path_bound[0]));
CHECK_GE(adc_frenet_l_, std::get<1>(fallback_path_bound[0]));
}
// Update the fallback path boundary into the reference_line_info.
// 将fallback_path_bound存入到candidate_path_boundaries
std::vector<std::pair<double, double>>