大家好,我已经把CSDN上的博客迁移到了知乎上,欢迎大家在知乎关注我的专栏慢慢悠悠小马车(https://zhuanlan.zhihu.com/duangduangduang)。希望大家可以多多交流,互相学习。
目录
PathBoundsDecider是负责计算道路上可行区域边界的类,其产生的结果如下面代码所示,是对纵向s等间隔采样、横向d对应的左右边界。这样,即限定了s的范围,又限定了d的范围。(注:代码中大多用小写L代表横向,我为了容易辨别,使用d)PathBoundsDecider类继承自Decider类,而Decider类继承自Task类,所以PathBoundsDecider也是Apollo中众多任务的其中之一。文件路径是 apollo\modules\planning\tasks\deciders\path_bounds_decider\path_bounds_decider.cc,基于apollo 5.5.0版本。
// PathBoundPoint contains: (s, l_min, l_max).
using PathBoundPoint = std::tuple<double, double, double>;
// PathBound contains a vector of PathBoundPoints.
using PathBound = std::vector<PathBoundPoint>;
1. 处理流程
PathBoundsDecider类的主要工作在Process()中完成,在该函数中,分4种场景对PathBound进行计算,按处理的顺序分别是fallback、pull over、lane change、regular,regular场景根据是否lane borrow又分为no borrow、left borrow、right borrow,这3种子场景是在一个函数内处理的。之所以要不同场景对应不同的处理方式,我认为是在不同的场景下,自车会有不同的决策和行为,因此要考察的纵向和横向的范围就不一样,在计算时也要考虑不同的环境模型上下文。要注意的是,fallback对应的PathBound一定会生成,其余3个场景只有1个被激活,成功生成PathBound后退出函数。
Status PathBoundsDecider::Process(Frame* const frame,
ReferenceLineInfo* const reference_line_info) {
...
// Initialization.
InitPathBoundsDecider(*frame, *reference_line_info);
// Generate the fallback path boundary.
PathBound fallback_path_bound;
Status ret = GenerateFallbackPathBound(*reference_line_info, &fallback_path_bound);
...
// Update the fallback path boundary into the reference_line_info.
std::vector<std::pair<double, double>> fallback_path_bound_pair;
for (size_t i = 0; i < fallback_path_bound.size(); ++i) {
fallback_path_bound_pair.emplace_back(std::get<1>(fallback_path_bound[i]),
std::get<2>(fallback_path_bound[i]));
}
candidate_path_boundaries.emplace_back(std::get<0>(fallback_path_bound[0]),
kPathBoundsDeciderResolution,
fallback_path_bound_pair);
candidate_path_boundaries.back().set_label("fallback");
//1.先生成fallback界限,存入candidate_path_boundaries,并标记为“fallback”
// If pull-over is requested, generate pull-over path boundary.
...
if (plan_pull_over_path) {
PathBound pull_over_path_bound;
Status ret = GeneratePullOverPathBound(*frame, *reference_line_info,
&pull_over_path_bound);
if (!ret.ok()) {
AWARN << "Cannot generate a pullover path bound, do regular planning.";
} else {
// Update the fallback path boundary into the reference_line_info.
std::vector<std::pair<double, double>> pull_over_path_bound_pair;
for (size_t i = 0; i < pull_over_path_bound.size(); ++i) {
pull_over_path_bound_pair.emplace_back(std::get<1>(pull_over_path_bound[i]),
std::get<2>(pull_over_path_bound[i]));
}
candidate_path_boundaries.emplace_back(std::get<0>(pull_over_path_bound[0]),
kPathBoundsDeciderResolution, pull_over_path_bound_pair);
candidate_path_boundaries.back().set_label("regular/pullover");
//2.生成pullover界限,存入candidate_path_boundaries,并标记为“regular/pullover”
reference_line_info->SetCandidatePathBoundaries(
std::move(candidate_path_boundaries));
return Status::OK();
}
}
// If it's a lane-change reference-line, generate lane-change path boundary.
if (FLAGS_enable_smarter_lane_change && reference_line_info->IsChangeLanePath()) {
PathBound lanechange_path_bound;
Status ret = GenerateLaneChangePathBound(*reference_line_info,
&lanechange_path_bound);
...
// Update the fallback path boundary into the reference_line_info.
std::vector<std::pair<double, double>> lanechange_path_bound_pair;
for (size_t i = 0; i < lanechange_path_bound.size(); ++i) {
lanechange_path_bound_pair.emplace_back(std::get<1>(lanechange_path_bound[i]),
std::get<2>(lanechange_path_bound[i]));
}
candidate_path_boundaries.emplace_back(std::get<0>(lanechange_path_bound[0]),
kPathBoundsDeciderResolution, lanechange_path_bound_pair);
candidate_path_boundaries.back().set_label("regular/lanechange");
//3.生成lanechange界限,存入candidate_path_boundaries,并标记为“regular/lanech