• Apollo planning之PathDecider


    目录

    1 路径决策的概览

    2 路径决策的代码流程及框架

    3 相关算法解析


    1 路径决策的概览

    上一个任务中获得了最优的路径,PathDecider的功能是根据静态障碍物做出自车的决策

    1. //输入
    2. Status PathDecider::Process(const ReferenceLineInfo *reference_line_info, const PathData &path_data, PathDecision *const path_decision)
    3. //输出的时候,路径决策的信息都保存到了path_decision中

    2 路径决策的代码流程及框架

    Process函数的主要功能是调用了MakeObjectDecision函数。而在MakeObjectDecision函数中调用了MakeStaticObstacleDecision函数。

    路径决策的主要功能都在MakeStaticObstacleDecision中

    上图的红框中是循环体的主要内容,主要功能是遍历每个障碍物做决策

    1. Status PathDecider::Process(const ReferenceLineInfo *reference_line_info,
    2. const PathData &path_data,
    3. PathDecision *const path_decision) {
    4. // skip path_decider if reused path
    5. if (FLAGS_enable_skip_path_tasks && reference_line_info->path_reusable()) {
    6. return Status::OK();
    7. }
    8. std::string blocking_obstacle_id;
    9. if (reference_line_info->GetBlockingObstacle() != nullptr) {
    10. blocking_obstacle_id = reference_line_info->GetBlockingObstacle()->Id();
    11. }
    12. // 调用MakeObjectDecision函数
    13. if (!MakeObjectDecision(path_data, blocking_obstacle_id, path_decision)) {
    14. const std::string msg = "Failed to make decision based on tunnel";
    15. AERROR << msg;
    16. return Status(ErrorCode::PLANNING_ERROR, msg);
    17. }
    18. return Status::OK();
    19. }
    20. bool PathDecider::MakeObjectDecision(const PathData &path_data,
    21. const std::string &blocking_obstacle_id,
    22. PathDecision *const path_decision) {
    23. // path decider的主要功能在MakeStaticObstacleDecision中
    24. if (!MakeStaticObstacleDecision(path_data, blocking_obstacle_id,
    25. path_decision)) {
    26. AERROR << "Failed to make decisions for static obstacles";
    27. return false;
    28. }
    29. return true;
    30. }

    3 相关算法解析

    算法解析已经展示在下面的代码段中了

    1. ... ...
    2. // 1.获取frenet坐标下的path路径
    3. const auto &frenet_path = path_data.frenet_frame_path();
    4. if (frenet_path.empty()) {
    5. AERROR << "Path is empty.";
    6. return false;
    7. }
    8. ... ...
    1. ... ...
    2. // 2.遍历每个障碍物,做决策
    3. for (const auto *obstacle : path_decision->obstacles().Items()) {
    4. const std::string &obstacle_id = obstacle->Id();
    5. const std::string obstacle_type_name =
    6. PerceptionObstacle_Type_Name(obstacle->Perception().type());
    7. ADEBUG << "obstacle_id[<< " << obstacle_id << "] type["
    8. << obstacle_type_name << "]";
    9. ... ...
    1. // 2.1 如果障碍物不是静态的或者是virtual的,就跳过
    2. if (!obstacle->IsStatic() || obstacle->IsVirtual()) { // (stop fence,各种fence)
    3. continue;
    4. }
    1. // 2.2 如果障碍物已经有 ignore/stop 决策,就跳过
    2. if (obstacle->HasLongitudinalDecision() &&
    3. obstacle->LongitudinalDecision().has_ignore() &&
    4. obstacle->HasLateralDecision() &&
    5. obstacle->LateralDecision().has_ignore()) {
    6. continue;
    7. }
    8. if (obstacle->HasLongitudinalDecision() &&
    9. obstacle->LongitudinalDecision().has_stop()) {
    10. // STOP decision
    11. continue;
    12. }
    1. // 2.3 如果障碍物挡住了路径,加stop决策
    2. if (obstacle->Id() == blocking_obstacle_id &&
    3. !injector_->planning_context()
    4. ->planning_status()
    5. .path_decider()
    6. .is_in_path_lane_borrow_scenario()) {
    7. // Add stop decision
    8. ADEBUG << "Blocking obstacle = " << blocking_obstacle_id;
    9. ObjectDecisionType object_decision;
    10. *object_decision.mutable_stop() = GenerateObjectStopDecision(*obstacle);
    11. path_decision->AddLongitudinalDecision("PathDecider/blocking_obstacle",
    12. obstacle->Id(), object_decision);
    13. continue;
    14. }
    1. // 2.4 如果是clear-zone,跳过
    2. if (obstacle->reference_line_st_boundary().boundary_type() ==
    3. STBoundary::BoundaryType::KEEP_CLEAR) {
    4. continue;
    5. }
    1. // 2.5 如果障碍物不在路径上,跳过
    2. ObjectDecisionType object_decision;
    3. object_decision.mutable_ignore();
    4. const auto &sl_boundary = obstacle->PerceptionSLBoundary();
    5. if (sl_boundary.end_s() < frenet_path.front().s() ||
    6. sl_boundary.start_s() > frenet_path.back().s()) {
    7. path_decision->AddLongitudinalDecision("PathDecider/not-in-s",
    8. obstacle->Id(), object_decision);
    9. path_decision->AddLateralDecision("PathDecider/not-in-s", obstacle->Id(),
    10. object_decision);
    11. continue;
    12. }
    1. // 2.6 nudge判断,如果距离静态障碍物距离太远,则忽略。
    2. // 如果静态障碍物距离车道中心太近并且不能避让,则停止,添加停止点信息。
    3. // 如果横向方向很近并且可以避让,则避开,添加避让信息。
    4. if (curr_l - lateral_radius > sl_boundary.end_l() ||
    5. curr_l + lateral_radius < sl_boundary.start_l()) {
    6. // 1. IGNORE if laterally too far away.
    7. path_decision->AddLateralDecision("PathDecider/not-in-l", obstacle->Id(),
    8. object_decision);
    9. } else if (sl_boundary.end_l() >= curr_l - min_nudge_l &&
    10. sl_boundary.start_l() <= curr_l + min_nudge_l) {
    11. // 2. STOP if laterally too overlapping.
    12. *object_decision.mutable_stop() = GenerateObjectStopDecision(*obstacle);
    13. if (path_decision->MergeWithMainStop(
    14. object_decision.stop(), obstacle->Id(),
    15. reference_line_info_->reference_line(),
    16. reference_line_info_->AdcSlBoundary())) {
    17. path_decision->AddLongitudinalDecision("PathDecider/nearest-stop",
    18. obstacle->Id(), object_decision);
    19. } else {
    20. ObjectDecisionType object_decision;
    21. object_decision.mutable_ignore();
    22. path_decision->AddLongitudinalDecision("PathDecider/not-nearest-stop",
    23. obstacle->Id(), object_decision);
    24. }
    25. } else {
    26. // 3. NUDGE if laterally very close.
    27. if (sl_boundary.end_l() < curr_l - min_nudge_l) { // &&
    28. // sl_boundary.end_l() > curr_l - min_nudge_l - 0.3) {
    29. // LEFT_NUDGE
    30. ObjectNudge *object_nudge_ptr = object_decision.mutable_nudge();
    31. object_nudge_ptr->set_type(ObjectNudge::LEFT_NUDGE);
    32. object_nudge_ptr->set_distance_l(
    33. config_.path_decider_config().static_obstacle_buffer());
    34. path_decision->AddLateralDecision("PathDecider/left-nudge",
    35. obstacle->Id(), object_decision);
    36. } else if (sl_boundary.start_l() > curr_l + min_nudge_l) { // &&
    37. // sl_boundary.start_l() < curr_l + min_nudge_l + 0.3) {
    38. // RIGHT_NUDGE
    39. ObjectNudge *object_nudge_ptr = object_decision.mutable_nudge();
    40. object_nudge_ptr->set_type(ObjectNudge::RIGHT_NUDGE);
    41. object_nudge_ptr->set_distance_l(
    42. -config_.path_decider_config().static_obstacle_buffer());
    43. path_decision->AddLateralDecision("PathDecider/right-nudge",
    44. obstacle->Id(), object_decision);
    45. }
    46. }

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

    若侵权,请联系删除 

  • 相关阅读:
    Java知识总结
    shell脚本判断语句
    如何考取 AWS 技术认证
    【实战项目】高并发内存池(上)
    力扣第47天--- 第647题、第516题
    miui编译第三方卡米 对应的修改步骤位置
    内网学习笔记(8)
    面试官:小伙子,说说C/C++是如何进行内存管理的?我:……
    Linux网络编程9——UDP 和 本地/网络套接字
    用户虚拟地址转化成物理地址,物理地址转换成内核虚拟地址,内核虚拟地址转换成物理地址,虚拟地址和对应页的关系
  • 原文地址:https://blog.csdn.net/weixin_65089713/article/details/126342929