• Apollo planning之PathAssessmentDecider


    目录

    1 路径评估决策概览

    2 路径评估决策具体流程

    2.1 路径重复使用

    2.2 去掉无效路径

    2.3 分析并加入重要信息,提供给速度决策器

    2.4 排序选出最优的轨迹

    2.5 更新必要信息


    1 路径评估决策概览

    路径评估决策是规划模块的task,属于task中的decider类别。依据原先设计好的规则,对各种path进行assess,排序得到最优的路径,并在规划路径上的采样点添加标签作为路径筛选的依据,并为速度规划提供限制

    1. //输入
    2. Status PathAssessmentDecider::Process(Frame* const frame, ReferenceLineInfo* const reference_line_info)
    3. //输出最优路径并保存在reference_line_info

    2 路径评估决策具体流程

    2.1 路径重复使用

    1. ... ...
    2. // 如果路径重复使用则跳过
    3. if (FLAGS_enable_skip_path_tasks && reference_line_info->path_reusable()) {
    4. return Status::OK();
    5. ... ...

    2.2 去掉无效路径

    1. ... ...
    2. // 1. 删掉无效路径.
    3. std::vector valid_path_data;
    4. for (const auto& curr_path_data : candidate_path_data) {
    5. // RecordDebugInfo(curr_path_data, curr_path_data.path_label(),
    6. // reference_line_info);
    7. if (curr_path_data.path_label().find("fallback") != std::string::npos) {
    8. if (IsValidFallbackPath(*reference_line_info, curr_path_data)) {
    9. valid_path_data.push_back(curr_path_data);
    10. }
    11. } else {
    12. if (IsValidRegularPath(*reference_line_info, curr_path_data)) {
    13. valid_path_data.push_back(curr_path_data);
    14. }
    15. }
    16. }
    17. const auto& end_time1 = std::chrono::system_clock::now();
    18. std::chrono::duration<double> diff = end_time1 - end_time0;
    19. ADEBUG << "Time for path validity checking: " << diff.count() * 1000
    20. << " msec.";
    21. ... ...

    其中fallback的无效路径是偏离参考线、偏离道路的路径。regular的无效路径是偏离参考线、偏离道路,发生碰撞,停在相邻的逆向车道的路径 

    2.3 分析并加入重要信息,提供给速度决策器

    1. ... ...
    2. // 2. 分析并加入重要信息给speed决策
    3. size_t cnt = 0;
    4. const Obstacle* blocking_obstacle_on_selflane = nullptr;
    5. for (size_t i = 0; i != valid_path_data.size(); ++i) {
    6. auto& curr_path_data = valid_path_data[i];
    7. if (curr_path_data.path_label().find("fallback") != std::string::npos) {
    8. // remove empty path_data.
    9. if (!curr_path_data.Empty()) {
    10. if (cnt != i) {
    11. valid_path_data[cnt] = curr_path_data;
    12. }
    13. ++cnt;
    14. }
    15. continue;
    16. }
    17. SetPathInfo(*reference_line_info, &curr_path_data);
    18. // 修剪所有的借道路径,使其能够以in-lane结尾
    19. if (curr_path_data.path_label().find("pullover") == std::string::npos) {
    20. TrimTailingOutLanePoints(&curr_path_data);
    21. }
    22. // 找到 blocking_obstacle_on_selflane, 为下一步选择车道做准备
    23. if (curr_path_data.path_label().find("self") != std::string::npos) {
    24. const auto blocking_obstacle_id = curr_path_data.blocking_obstacle_id();
    25. blocking_obstacle_on_selflane =
    26. reference_line_info->path_decision()->Find(blocking_obstacle_id);
    27. }
    28. // 删掉空路径
    29. if (!curr_path_data.Empty()) {
    30. if (cnt != i) {
    31. valid_path_data[cnt] = curr_path_data;
    32. }
    33. ++cnt;
    34. }
    35. // RecordDebugInfo(curr_path_data, curr_path_data.path_label(),
    36. // reference_line_info);
    37. ADEBUG << "For " << curr_path_data.path_label() << ", "
    38. << "path length = " << curr_path_data.frenet_frame_path().size();
    39. }
    40. valid_path_data.resize(cnt);
    41. // 如果没有有效路径,退出
    42. if (valid_path_data.empty()) {
    43. const std::string msg = "Neither regular nor fallback path is valid.";
    44. AERROR << msg;
    45. return Status(ErrorCode::PLANNING_ERROR, msg);
    46. }
    47. ADEBUG << "There are " << valid_path_data.size() << " valid path data.";
    48. const auto& end_time2 = std::chrono::system_clock::now();
    49. diff = end_time2 - end_time1;
    50. ADEBUG << "Time for path info labeling: " << diff.count() * 1000 << " msec.";
    51. ... ...

    2.4 排序选出最优的轨迹

    1. ... ...
    2. // 3. Pick the optimal path.
    3. std::sort(valid_path_data.begin(), valid_path_data.end(),
    4. std::bind(ComparePathData, std::placeholders::_1,
    5. std::placeholders::_2, blocking_obstacle_on_selflane));
    6. ADEBUG << "Using '" << valid_path_data.front().path_label()
    7. << "' path out of " << valid_path_data.size() << " path(s)";
    8. if (valid_path_data.front().path_label().find("fallback") !=
    9. std::string::npos) {
    10. FLAGS_static_obstacle_nudge_l_buffer = 0.8;
    11. }
    12. *(reference_line_info->mutable_path_data()) = valid_path_data.front();
    13. reference_line_info->SetBlockingObstacle(
    14. valid_path_data.front().blocking_obstacle_id());
    15. const auto& end_time3 = std::chrono::system_clock::now();
    16. diff = end_time3 - end_time2;
    17. ADEBUG << "Time for optimal path selection: " << diff.count() * 1000
    18. << " msec.";
    19. reference_line_info->SetCandidatePathData(std::move(valid_path_data));
    20. ... ...

    排序算法的流程具体如下:

    ComparePathData

    路径排序:(道路评估的优劣通过排序获得)

    • 1.空的路径永远排在后面

    • 2.regular path 优先于 fallback path,regular path 的补集包含 fallback path 的补集

    • 3.如果self-lane有一个存在,选择self-lane。如果都存在,选择较长的。如果长度接近,选择self-lane。如果self-lane都不存在,选择较长的路径

    • 4.如果路径长度接近,且都要借道:

      • (1) 都要借逆向车道,选择距离短

      • (2) 针对具有两个借道方向的情况:

        • 有障碍物,选择合适的方向,左或右借道

        • 无障碍物,根据adc的位置选择借道方向

      • (3) 路径长度相同,相邻车道都是前向的,选择较早返回自车道的路径

      • (4) 如果路径长度相同,前向借道,返回自车道时间相同,选择从左侧借道的路径

    • 5.最后如果两条路径相同,则 lhs is not < rhl排序之后:选择最优路径,即第一个路径

    2.5 更新必要信息

    1. // 4. Update necessary info for lane-borrow decider's future uses.
    2. // Update front static obstacle's info.
    3. auto* mutable_path_decider_status = injector_->planning_context()
    4. ->mutable_planning_status()
    5. ->mutable_path_decider();
    6. if (reference_line_info->GetBlockingObstacle() != nullptr) {
    7. int front_static_obstacle_cycle_counter =
    8. mutable_path_decider_status->front_static_obstacle_cycle_counter();
    9. mutable_path_decider_status->set_front_static_obstacle_cycle_counter(
    10. std::max(front_static_obstacle_cycle_counter, 0));
    11. mutable_path_decider_status->set_front_static_obstacle_cycle_counter(
    12. std::min(front_static_obstacle_cycle_counter + 1, 10));
    13. mutable_path_decider_status->set_front_static_obstacle_id(
    14. reference_line_info->GetBlockingObstacle()->Id());
    15. } else {
    16. int front_static_obstacle_cycle_counter =
    17. mutable_path_decider_status->front_static_obstacle_cycle_counter();
    18. mutable_path_decider_status->set_front_static_obstacle_cycle_counter(
    19. std::min(front_static_obstacle_cycle_counter, 0));
    20. mutable_path_decider_status->set_front_static_obstacle_cycle_counter(
    21. std::max(front_static_obstacle_cycle_counter - 1, -10));
    22. }
    23. // Update self-lane usage info.
    24. if (reference_line_info->path_data().path_label().find("self") !=
    25. std::string::npos) {
    26. // && std::get<1>(reference_line_info->path_data()
    27. // .path_point_decision_guide()
    28. // .front()) == PathData::PathPointType::IN_LANE)
    29. int able_to_use_self_lane_counter =
    30. mutable_path_decider_status->able_to_use_self_lane_counter();
    31. if (able_to_use_self_lane_counter < 0) {
    32. able_to_use_self_lane_counter = 0;
    33. }
    34. mutable_path_decider_status->set_able_to_use_self_lane_counter(
    35. std::min(able_to_use_self_lane_counter + 1, 10));
    36. } else {
    37. mutable_path_decider_status->set_able_to_use_self_lane_counter(0);
    38. }
    39. // Update side-pass direction.
    40. if (mutable_path_decider_status->is_in_path_lane_borrow_scenario()) {
    41. bool left_borrow = false;
    42. bool right_borrow = false;
    43. const auto& path_decider_status =
    44. injector_->planning_context()->planning_status().path_decider();
    45. for (const auto& lane_borrow_direction :
    46. path_decider_status.decided_side_pass_direction()) {
    47. if (lane_borrow_direction == PathDeciderStatus::LEFT_BORROW &&
    48. reference_line_info->path_data().path_label().find("left") !=
    49. std::string::npos) {
    50. left_borrow = true;
    51. }
    52. if (lane_borrow_direction == PathDeciderStatus::RIGHT_BORROW &&
    53. reference_line_info->path_data().path_label().find("right") !=
    54. std::string::npos) {
    55. right_borrow = true;
    56. }
    57. }
    58. mutable_path_decider_status->clear_decided_side_pass_direction();
    59. if (right_borrow) {
    60. mutable_path_decider_status->add_decided_side_pass_direction(
    61. PathDeciderStatus::RIGHT_BORROW);
    62. }
    63. if (left_borrow) {
    64. mutable_path_decider_status->add_decided_side_pass_direction(
    65. PathDeciderStatus::LEFT_BORROW);
    66. }
    67. }
    68. const auto& end_time4 = std::chrono::system_clock::now();
    69. diff = end_time4 - end_time3;
    70. ADEBUG << "Time for FSM state updating: " << diff.count() * 1000 << " msec.";
    71. // Plot the path in simulator for debug purpose.
    72. RecordDebugInfo(reference_line_info->path_data(), "Planning PathData",
    73. reference_line_info);
    74. return Status::OK();
    1. 更新front static obstacle's info,即前方静态障碍物的信息
    2. 更新self-lane usage info,即自车道使用信息
    3. 更新side-pass direction,根据PathDeciderStatusleft_borrowright_borrow,即判断是从左侧借道,还是从右侧借道

    本文参考路径评估决策 — Apollo Auto 0.0.1 文档 (daobook.github.io)

    如有侵权,请联系删除

  • 相关阅读:
    Jenkins List Git Branches插件 构建选择指定git分支
    湖北省2022年高企申报奖励补贴以及申报材料流程讲解(认定条件要求内容)
    数字音频工作站(DAW)fl studio 21 for mac 21.2.3.3586中文版图文安装教程
    【kubernetes篇】使用Harbor仓库管理kubernetes镜像
    事件派发触发以及自定义事件派发dispatchEvent-——————派发键盘事件
    基于 elementUI / elementUI plus,实现 主要色(主题色)的一件换色(换肤)
    【web-解析目标】(1.1.1)解析内容和功能:web信息抓取
    CSP-J1 CSP-S1 初赛 第1轮 数学问题(数论、排列组合等)
    Spring源码全解析,帮你彻底学习Spring源码
    c++23中的新功能之七三个新的扩展
  • 原文地址:https://blog.csdn.net/weixin_65089713/article/details/126334055