APOLLO:lane_borrow_decider代码解读

2023-10-17 01:59

本文主要是介绍APOLLO:lane_borrow_decider代码解读,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

APOLLO:lane_borrow_decider代码解读

  • 一、作用:是否产生变道决策
  • 二、数据结构
  • 三、代码逻辑
  • 四、参考链接

一、作用:是否产生变道决策

是否nuge前方静态、低速障碍物),并将决策结果保存到 reference_line_info和mutable_path_decider_status 中。在这里插入图片描述

二、数据结构

定义了一个path_decider_status:(message PathDeciderStatus)
auto* mutable_path_decider_status = injector_->planning_context() ->mutable_planning_status() ->mutable_path_decider();
Injector_是DependencyInjector类的对象, 通过planning_context()方法返回一个PlanningContext对象, 然后通过mutable_planning_status()返回PlanningStatus 对象,
PlanningStatus 是proto定义的一个类,至于如何通过->mutable_path_decider()调用到PathDeciderStatus,这点还不太清楚。

message PathDeciderStatus {enum LaneBorrowDirection {LEFT_BORROW = 1;   // borrow left neighbor laneRIGHT_BORROW = 2;  // borrow right neighbor lane}optional int32 front_static_obstacle_cycle_counter = 1 [default = 0];optional int32 able_to_use_self_lane_counter = 2 [default = 0];optional bool is_in_path_lane_borrow_scenario = 3 [default = false];optional string front_static_obstacle_id = 4 [default = ""];repeated LaneBorrowDirection decided_side_pass_direction = 5;
}

三、代码逻辑

1、首先在Process()中判断路径是否复用,如果是则跳过,然后调用IsNecessaryToBorrowLane(*frame, *reference_line_info))来判断是否进行变道,如果是在把变道决策信息存入 reference_line_info中;
2、判断是否变道:

bool PathLaneBorrowDecider::IsNecessaryToBorrowLane(const Frame& frame, const ReferenceLineInfo& reference_line_info) {auto* mutable_path_decider_status = injector_->planning_context()->mutable_planning_status()->mutable_path_decider();//判断当前是否借道场景中if (mutable_path_decider_status->is_in_path_lane_borrow_scenario()) {// If originally borrowing neighbor lane:// 根据数值优化求解轨迹后的信息计算是否退出借道场景(如:避让输出轨迹无解时退出借道)if (mutable_path_decider_status->able_to_use_self_lane_counter() >= 6) {// If have been able to use self-lane for some time, then switch to// non-lane-borrowing.mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(false);mutable_path_decider_status->clear_decided_side_pass_direction();AINFO << "Switch from LANE-BORROW path to SELF-LANE path.";}} else {//如果当前不处于借道场景中,以下条件都满足时才能借道// If originally not borrowing neighbor lane:// ADC requirements check for lane-borrowing:// 只有一条参考线,才能借道// 起点速度小于最大借道允许速度// 阻塞障碍物必须远离路口// 阻塞障碍物会一直存在// 阻塞障碍物与终点位置满足要求// 为可侧面通过的障碍物ADEBUG << "Blocking obstacle ID["<< mutable_path_decider_status->front_static_obstacle_id() << "]";// ADC requirements check for lane-borrowing:if (!HasSingleReferenceLine(frame)) { //只有一条参考线return false;}if (!IsWithinSidePassingSpeedADC(frame)) { //起点速度小于最大借道允许速度return false;}// Obstacle condition check for lane-borrowing:if (!IsBlockingObstacleFarFromIntersection(reference_line_info)) {return false; //阻塞障碍物必须远离路口}if (!IsLongTermBlockingObstacle()) { //阻塞障碍物会一直存在return false;}if (!IsBlockingObstacleWithinDestination(reference_line_info)) {return false; // 阻塞障碍物与终点位置满足要求}if (!IsSidePassableObstacle(reference_line_info)) {return false; //为可侧面通过的障碍物}// switch to lane-borrowing// set side-pass direction// 在无避让方向时重新计算避让方向,若左、右借道空间均不满足则不借道,is_in_path_lane_borrow_scenario_标志为false;// 左借道条件满足左借道、右借道条件满足右借道,is_in_path_lane_borrow_scenario_为true。const auto& path_decider_status =injector_->planning_context()->planning_status().path_decider();if (path_decider_status.decided_side_pass_direction().empty()) {// first time init decided_side_pass_directionbool left_borrowable;bool right_borrowable;//根据车道线类型判断是否可以借道CheckLaneBorrow(reference_line_info, &left_borrowable, &right_borrowable);if (!left_borrowable && !right_borrowable) {mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(false);return false; //左右借道都不满足时,重新计算} else {//满足左侧或者右侧借道条件mutable_path_decider_status->set_is_in_path_lane_borrow_scenario(true);if (left_borrowable) {mutable_path_decider_status->add_decided_side_pass_direction(PathDeciderStatus::LEFT_BORROW);}if (right_borrowable) {mutable_path_decider_status->add_decided_side_pass_direction(PathDeciderStatus::RIGHT_BORROW);}}}AINFO << "Switch from SELF-LANE path to LANE-BORROW path.";}return mutable_path_decider_status->is_in_path_lane_borrow_scenario();
}

2.1 IsWithinSidePassingSpeedADC

bool PathLaneBorrowDecider::IsWithinSidePassingSpeedADC(const Frame& frame) {return frame.PlanningStartPoint().v() < FLAGS_lane_borrow_max_speed;()这个值为5m/s,也就是初始速度不能大于5m/s?
}

2.2 IsLongTermBlockingObstacle() ,FLAGS_long_term_blocking_obstacle_cycle_threshold的默认值是3,具体代表啥意思?

bool PathLaneBorrowDecider::IsLongTermBlockingObstacle() {if (injector_->planning_context()->planning_status().path_decider().front_static_obstacle_cycle_counter() >=FLAGS_long_term_blocking_obstacle_cycle_threshold) {ADEBUG << "The blocking obstacle is long-term existing.";return true;} else {ADEBUG << "The blocking obstacle is not long-term existing.";return false;}
}

2.3IsBlockingObstacleWithinDestination 障碍物不在终点范围内

  if (blocking_obstacle_s - adc_end_s >reference_line_info.SDistanceToDestination()) {return false;}return true;I0516 20:26:24.494535  2986 path_lane_borrow_decider.cc:193] Blocking obstacle is at s = 59.4525
I0516 20:26:24.494540  2986 path_lane_borrow_decider.cc:194] ADC is at s = 53.983
I0516 20:26:24.494544  2986 path_lane_borrow_decider.cc:195] Destination is at s = 87.8644

2.4 IsSidePassableObstacle里面的IsNonmovableObstacle,前方最近的障碍物距离自车不是很远(35m),前方最近的障碍物在路边,或者是在停车道上,前方最近的障碍物的前方(15m内)没有其他障碍物

  //目标太远,不借道if (obstacle.PerceptionSLBoundary().start_s() >adc_sl_boundary.end_s() + kAdcDistanceThreshold) {ADEBUG << " - It is too far ahead and we are not so sure of its status.";return false;}// Obstacle is parked obstacle.//目标停止时借道if (IsParkedVehicle(reference_line_info.reference_line(), &obstacle)) {ADEBUG << "It is Parked and NON-MOVABLE.";return true;}double delta_s = other_obstacle->PerceptionSLBoundary().start_s() -obstacle.PerceptionSLBoundary().end_s();if (delta_s < 0.0 || delta_s > kObstaclesDistanceThreshold) {continue;}

2.5 CheckLaneBorrow,以2米为间隔遍历车前100m的参考线,判断左右车道线,如果是白线或者黄线,则不变道,log信息如下:

I0516 20:26:24.494583  2986 path_lane_borrow_decider.cc:316] s[53.983] left_lane_boundary_type[DOTTED_YELLOW]
I0516 20:26:24.494601  2986 path_lane_borrow_decider.cc:330] s[53.983] right_neighbor_lane_borrowable[SOLID_WHITE]
I0516 20:26:24.494607  2986 path_lane_borrow_decider.cc:316] s[55.983] left_lane_boundary_type[DOTTED_YELLOW]
I0516 20:26:24.494613  2986 path_lane_borrow_decider.cc:316] s[57.983] left_lane_boundary_type[DOTTED_YELLOW]
I0516 20:26:24.494618  2986 path_lane_borrow_decider.cc:316] s[59.983] left_lane_boundary_type[DOTTED_YELLOW]
I0516 20:26:24.494623  2986 path_lane_borrow_decider.cc:316] s[61.983] left_lane_boundary_type[DOTTED_YELLOW]
I0516 20:26:24.494628  2986 path_lane_borrow_decider.cc:316] s[63.983] left_lane_boundary_type[DOTTED_YELLOW]
I0516 20:26:24.494633  2986 path_lane_borrow_decider.cc:316] s[65.983] left_lane_boundary_type[DOTTED_YELLOW]
I0516 20:26:24.494638  2986 path_lane_borrow_decider.cc:316] s[67.983] left_lane_boundary_type[DOTTED_YELLOW]

四、参考链接

1、参考资料1
2、参考资料2

这篇关于APOLLO:lane_borrow_decider代码解读的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/222191

相关文章

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

MCU7.keil中build产生的hex文件解读

1.hex文件大致解读 闲来无事,查看了MCU6.用keil新建项目的hex文件 用FlexHex打开 给我的第一印象是:经过软件的解释之后,发现这些数据排列地十分整齐 :02000F0080FE71:03000000020003F8:0C000300787FE4F6D8FD75810702000F3D:00000001FF 把解释后的数据当作十六进制来观察 1.每一行数据

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

D4代码AC集

贪心问题解决的步骤: (局部贪心能导致全局贪心)    1.确定贪心策略    2.验证贪心策略是否正确 排队接水 #include<bits/stdc++.h>using namespace std;int main(){int w,n,a[32000];cin>>w>>n;for(int i=1;i<=n;i++){cin>>a[i];}sort(a+1,a+n+1);int i=1

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训