Apollo planning之交规决策技术

news2024/11/17 21:51:52

Apollo studio 官网:Apollo开发者社区 (baidu.com)

目录

1 双层状态机

2 决策模块的解析 

2.1 参考路径

2.2 交规决策 

2.3 路径决策 

2.4 速度决策

2.5 场景的调度与管理

3 交规决策实现代码解读 

3.1 遍历交规配置文件,存储信息

3.2 交规决策的运行流程 

3.3 场景框架代码

3.3.1 Traffic Light 场景的进入

3.3.2 Traffic Light 场景的 stage

3.3.3 Approach阶段

3.3.4 Cruise阶段

3.3.5 交通灯通过检测与停止墙生成


1 双层状态机

  •  Apollo主要是通过状态机进行决策,不熟悉状态机的读者请参考【自动驾驶决策算法之有限状态机】_有限状态机 自动驾驶_无意2121的博客-CSDN博客
  • 有限状态机不适用于比较复杂的自动驾驶车辆,于是Apollo选择用Top Layer+Bottom Layer的方式,将类似的状态集合到一个底层的状态机中,于是就形成了双层状态机
  • 同时Apollo通过对scenario进行分类,每个scenario又分为一个或多个stage,每个stage又是由不同的task组成。整体流程图如上图所示

2 决策模块的解析 

这里介绍了决策模块的目的与作用

  • 安全性
  • 遵守交规
  • 为平滑器提供信息 

决策模块的上游有Routing、Prediction、Location、Perception等等module,这作为决策模块的输入。最终的输出则是路径、速度、位置的边界,为优化器提供条件 

2.1 参考路径

  • 没有障碍物情况下的默认行车路径
    • 参考路径需要保证连续和平滑(参考线平滑算法,Apollo中默认离散点平滑)
  • 参考路径也用于表达换道需求(在Routing模块已经通过A*算法完成了车道级别的搜索
    • 目标参考路径(优先级高
    • 当前参考路径
  • 参考路径的一种实现方法
    • 根据Routing结果找对对应的道路的中心线
    • 对道路中心线进行平滑

2.2 交规决策 

  • 主要作用
    • 处理红绿灯、Stop Sign,人行横道等交通规则
  • 输入信息
    • 参考路径
    • 高精地图
    • 信号灯状态
  • 输出
    • 虚拟墙(通过对当前交通状态的判断进行是否需要停车的决策

2.3 路径决策 

通过一系列类似决策树的是否判断决定当前要生成哪种路径边界输送到优化器中

各种Path Bound的举例如下

2.4 速度决策

在speed decider中需要通过以下各种各样的判断来生成一个最终的speed bound 

  • 道路限速
  • 路径周边行人,自行车等
  • 通过人行横道时
  • 减速带
  • 路径上过近的车辆,较为拥挤的道路
  • 借道避让时
  •  换道时

 整个 planning 模块的运行流程就如上图所示

2.5 场景的调度与管理

依据场景来做决策规划有以下两个优点
  • 场景之间互不干扰,有利于场景并行开发和独立调参,利于维护与开发
  • 功能之间相互解耦,开发者可以开发自己的特有场景,但定制化的好处背后就是普遍性的不足

3 交规决策实现代码解读 

3.1 遍历交规配置文件,存储信息

场景分类解释
Backside_Vehicle主车后方来车
Crosswalk人行横道
Destination主车前往的目的地
Keep_Clear禁停区
Reference_Line_End参考线结束
Rerouting重新全局规划
Stop_Sign停车
Traffic_Light交通灯
Yield_sign让行

A p o l l o 对 交 通 规 则 的 处 理 是 通 过 f o r 循 环 来 遍 历 traffic_rule_config.pb.txt 中设置的交通规则,处理后相关信息存入 ReferenceLineInfo 

//modules\planning\traffic_rules\traffic_decider.cc
Status TrafficDecider::Execute(
    Frame *frame, ReferenceLineInfo *reference_line_info,
    const std::shared_ptr<DependencyInjector> &injector) {
  CHECK_NOTNULL(frame);
  CHECK_NOTNULL(reference_line_info);
  
  //遍历配置文件
  for (const auto &rule_config : rule_configs_.config()) {
    if (!rule_config.enabled()) {
      ADEBUG << "Rule " << rule_config.rule_id() << " not enabled";
      continue;
    }
    auto rule = s_rule_factory.CreateObject(rule_config.rule_id(), rule_config,
                                            injector);
    if (!rule) {
      AERROR << "Could not find rule " << rule_config.DebugString();
      continue;
    }
    rule->ApplyRule(frame, reference_line_info);
    ADEBUG << "Applied rule "
           << TrafficRuleConfig::RuleId_Name(rule_config.rule_id());
  }
  //处理信息保存在reference_line_info中,作为输入,提供给后续模块。
  BuildPlanningTarget(reference_line_info);
  return Status::OK();
}

3.2 交规决策的运行流程 

前面遍历配置的信息都存储到ReferenceLineInfo中,通过overlap判断与什么场景重叠,通过交通规则判断需要进入哪个场景,再进行一系列stage,stage中又包含很多task

3.3 场景框架代码

3.3.1 Traffic Light 场景的进入

modules/planning/common/reference_line_info.cc
// signal
hdmap::PathOverlap signal_overlap;
if(GetFirstOverlap(map_path.signal_overlaps(),
&signal_overlap)) {
first_encounter_overlaps_.emplace_back(
SIGNAL, signal_overlap);
}

通过overlap重叠进入Traffic Light 场景

modules/planning/scenarios/scenario_manager.cc
if (right_turn && red_light) {
//进入红绿灯无保护右转
const auto& scenario_config =
config_map_[ScenarioConfig::TRAFFIC_LIGHT_UNPROTECTED_RIGHT_TURN]
.traffic_light_unprotected_right_turn_config();
} else if (left_turn) {
//进入红绿灯无保护左转
const auto& scenario_config =
config_map_[ScenarioConfig::TRAFFIC_LIGHT_UNPROTECTED_LEFT_TURN]
.traffic_light_unprotected_left_turn_config();
} else {
//红绿灯有保护
const auto& scenario_config =
config_map_[ScenarioConfig::TRAFFIC_LIGHT_PROTECTED]
.traffic_light_protected_config();
}

根据车道信息与交通信号灯的情况进入不同的Scenario

3.3.2 Traffic Light 场景的 stage

stage_type:
TRAFFIC_LIGHT_PROTECTED_APPROACH 
#靠近阶段
stage_type:
TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE
#进入交叉路口阶段

Traffic Light 场景有两个stage,stage_type在配置文件modules/planning/conf/scenario/traffic_light_protected_ config.pb.txt中进行定义

// traffic_light_protected scenario
TRAFFIC_LIGHT_PROTECTED_APPROACH = 400;
TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE = 401;

这是stage优先级的定义,相当于进入一个scenario会有一个stage执行的顺序

s_stage_factory_.Register(
ScenarioConfig::TRAFFIC_LIGHT_PROTECTED_APPROACH,
[](const ScenarioConfig::StageConfig& config,
const std::shared_ptr<DependencyInjector>&
injector) -> Stage* {
return new
TrafficLightProtectedStageApproach(config, injector);
});
s_stage_factory_.Register(
ScenarioConfig::TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE,
[](const ScenarioConfig::StageConfig& config,
const std::shared_ptr<DependencyInjector>&
injector) -> Stage* {
return new (config, injector);
});

这里stage进行了注册

3.3.3 Approach阶段

//modules\planning\scenarios\scenario.cc
const auto& scenario_config =
  config_map_[ScenarioConfig::TRAFFIC_LIGHT_PROTECTED]
      .traffic_light_protected_config();
// 距离判断:主车离停车小于start_traffic_light_scenario_distance时
// 进入TRAFFIC_LIGHT_PROTECTED场景
if (adc_distance_to_traffic_light < 
    scenario_config.start_traffic_light_scenario_distance()) 
{
    traffic_light_protected_scenario = true;
}

在approach阶段需要进行了距离判断,若距离满足要求就进入traffic_light_protected场景

//modules\planning\conf\scenario\traffic_light_protected_config.pb.txt
scenario_type: TRAFFIC_LIGHT_PROTECTED
traffic_light_protected_config: {
  start_traffic_light_scenario_distance: 5.0
}

这是配置文件 

//modules\planning\scenarios\traffic_light\protected\stage_approach.cc
Stage::StageStatus TrafficLightProtectedStageApproach::Process(
    const TrajectoryPoint& planning_init_point, Frame* frame) {
    ADEBUG << "stage: Approach";
    //APPROACH 正在运行
    CHECK_NOTNULL(frame);
    if (traffic_light_all_done) {
        return FinishStage();
  }
  return Stage::RUNNING;
}

//modules\planning\scenarios\traffic_light\protected\stage_approach.cc
Stage::StageStatus TrafficLightProtectedStageApproach::FinishStage() {
  auto* traffic_light = injector_->planning_context()
                            ->mutable_planning_status()
                            ->mutable_traffic_light();
  traffic_light->clear_done_traffic_light_overlap_id();
  for (const auto& traffic_light_overlap_id :
       GetContext()->current_traffic_light_overlap_ids) {
    traffic_light->add_done_traffic_light_overlap_id(traffic_light_overlap_id);
  }
  //进入下一个Stage:TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE
  next_stage_ = ScenarioConfig::TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE;
  return Stage::FINISHED;
  //APPROACH的Stage完成
}

Approach阶段的定义如上

3.3.4 Cruise阶段

Stage::StageStatus TrafficLightProtectedStageIntersectionCruise::Process(
const common::TrajectoryPoint& planning_init_point, Frame* frame) {
bool stage_done =
stage_impl_.CheckDone(*frame, ScenarioConfig::TRAFFIC_LIGHT_PROTECTED,
config_, injector_->planning_context(), true);
//定义交叉路口
if (stage_done)
//如果通过交叉路口
{ return FinishStage();
//INTERSECTION_CRUISE的stage完成
}
return Stage::RUNNING;
//进入INTERSECTION_CRUISE的RUNNING
}
Stage::StageStatus TrafficLightProtectedStageIntersectionCruise::FinishStage() {
return FinishScenario();
//INTERSECTION_CRUISE的stage完成
}

3.3.5 交通灯通过检测与停止墙生成

ObjectDecisionType stop;
//定义一个停止墙
auto* stop_decision = stop.mutable_stop();
//stop决策的停车原因
stop_decision->set_reason_code(stop_reason_code);
stop_decision->set_distance_s(-stop_distance);
//stop决策的停车安全距离
util::BuildStopDecision(virtual_obstacle_id,
traffic_light_overlap.start_s,
config_.traffic_light().stop_distance(),
StopReasonCode::STOP_REASON_SIGNAL,
wait_for_obstacles,TrafficRuleConfig::RuleId_Name(config_.rule_id()),
config: {
rule_id: TRAFFIC_LIGHT
enabled: true
traffic_light {
stop_distance: 1.0 #停止距离为1.0 单位 m
max_stop_deceleration: 4.0
}
}

配置文件中可以修改停止距离 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195390.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式(三)

三、API 网关详解 1. 网关及作用 主要功能&#xff1a;请求过滤 网关可以为我们提供请求转发、安全认证&#xff08;身份/权限认证&#xff09;、流量控制、负载均衡、降级熔断、日志、监控等功能。 2. 常见的网关系统 2.1 Netflix Zuul &#xff08;1&#xff09;Zuul 是…

进军存储赛道—BNB Greenfield:Web3 数据所有权和效用新标准

最近BNB Chain 自豪地宣布发布BNB Greenfield 白皮书。BNB Greenfield为Web3时代的数据引入了一个全新的结构和经济模式。现在&#xff0c;数据的所有权、使用权和货币化&#xff0c;首先对用户以及BNB Chain生态系统中的所有参与者来说是可能的。BNB Greenfield 使用 BNB 作为…

OSCP_VULHUB_symfonos-2(失败)

文章目录 前言实验攻击尝试hydra爆破ftpmetasploit工具进行SSH登录端口转发1命令注入getshell 1端口转发2提权失败总结前言 这个是练习的第5个机子。 目标地址 https://www.vulnhub.com/entry/symfonos-2,331/ 实验 1.信息收集 1.1 目标ip 1.2 开放端口 nmap -sS -sV -A …

QT入门Buttons之QCommandLinkButton、QDialogButtonBox

目录 一、QCommandLinkButton界面布局介绍 二、QCommandLinkButton基本属性介绍 三、QDialogButtonBox界面布局介绍 1、布局器中的位置及使用 此文为作者原创&#xff0c;转载请标明出处&#xff01; 一、QCommandLinkButton界面布局介绍 一般这两个控件使用较少&#xf…

HarmonyOS/OpenHarmony应用开发-DevEco Studio 3.0与DevEco Studio 3.1版本差异

工程模板和开发语言介绍 DevEco Studio支持包括手机、平板、车机、智慧屏、智能穿戴、轻量级智能穿戴和智慧视觉设备的HarmonyOS应用/服务开发&#xff0c;预置了工程模板&#xff0c;可以根据工程向导轻松创建适应于各类设备的工程&#xff0c;并自动生成对应的代码和资源模板…

C生万物 | 揭开【整型提升】神秘面纱

&#x1f451;作者主页&#xff1a;Fire_Cloud_1 &#x1f3e0;学习社区&#xff1a;烈火神盾 &#x1f517;专栏链接&#xff1a;C生万物 文章目录一、前言二、整型提升的意义所在三、如何进行整型提升❓四、实战演练&#x1f5e1;1、深剖两数求和的内部运算2、三种不同数据类…

机器学习:线性回归分析女性身高与体重之间的关系

机器学习&#xff1a;线性回归分析女性身高与体重之间的关系 创作不易&#xff0c;觉得文章不错或能帮到你学习&#xff0c;记得点赞 收藏哦 文章目录机器学习&#xff1a;线性回归分析女性身高与体重之间的关系一、实验目的二、实验原理三、实验内容四、实验环境五、实验步骤…

C++ 入门基础

✨个人主页&#xff1a; Yohifo &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f38a;每篇一句&#xff1a; 图片来源 The longest way must have its close,the gloomiest night will wear on a morning. 最长的路也有尽头&#xff0c;最黑暗的夜晚也会迎来清晨。 文…

擅长做财务分析的BI软件有哪些?

财务分析是企业数据分析中的一个重要板块&#xff0c;所以基本上BI软件都能做基础的财务数据分析&#xff0c;比如说帆软、永洪、思迈特等&#xff0c;但要说到系统化地、高效地做企业财务分析&#xff0c;还是要看奥威BI软件。 之所以说BI财务分析软件看奥威BI&#xff0c;是…

【万文全解】Java集合源码解析【HashMap】【ArrayList】【JDK源码集合部分】

Java集合源码解析 本文主体部分是作者跟着B站韩顺平老师的课程总结而来&#xff0c;中间穿插自己的理解还有网上各类优质解答 第一节&#xff1a;集合介绍与集合体系图 集合与数组对比&#xff08;引入集合的目的&#xff09; 数组&#xff1a; 长度必须指定&#xff0c;一…

javaEE 初阶 — TCP 流套接字编程

文章目录1. TCP 流套接字1.1 ServerSocket API1.2 Socket API1.3 TCP中的长短连接2. TCP 版本的回显服务器3. TCP 版本的回显客户端4. 如何给多个客户端提供服务1. TCP 流套接字 TCP 不需要一个类&#xff1b;来表示 “TCP” 数据报。 TCP 不是以数据报为单位进行传输的&#x…

拉伯配资“十年一剑”硕果累累 我国注册制改革迈入新征程

从2013年党的十八届三中全会明确提出“推动股票发行注册制变革”&#xff0c;到首届进博会上宣告科创板试点注册制&#xff0c;再到本年2月1日全面施行股票发行注册制变革正式发动&#xff0c;十年风雨兼程&#xff0c;我国注册制逐渐从“试点”走向“全面”。 2013年11月&…

编译链接过程详解

写在前面&#xff1a; 大家都知道&#xff0c;我们在编译器中建好一个**.c或.cpp 文件**&#xff0c;经过编译之后就可以运行了&#xff0c;也就是说我们写的.c 文件最后会变成一个可执行程序&#xff0c;那么 .c 或者 .cpp 文件是如何变成一个可执行程序的呢&#xff1f; 主要…

Vue计算属性和监视属性

目录 计算属性computed 监事属性 深度监视 计算属性computed 计算属性: 定义&#xff1a;要用的属性不存在&#xff0c;要通过已有属性计算得来 2、原理&#xff1a;底层借助了Object.defineproperty方法提供的getter和setter 3、get函数什么时候执行&#xff1f; 1、初…

移动硬盘修复的有效方法,恢复移动硬盘的数据这么做!

硬盘是计算机中的存储设备&#xff0c;是非常重要的部分。当硬盘发生故障&#xff0c;很可能会导致我们电脑里面的数据丢失。所以移动硬盘发生故障&#xff0c;我们一定要想办法修复它。 有没有什么操作方法&#xff0c;我们自己也可以简单进行&#xff1f;移动硬盘修复其实也…

mariadb数据库删除恢复过程

不作不死&#xff0c;不小心使sqlyog导数据选错服务器。把生产机的数据全部删除了。可怕的数据没有做其他过多的备份&#xff0c;只是每天自动crontab 备份。该怎么办呢&#xff1f;头脑一片空白。快&#xff0c; 赶紧看看日备份有没有。马上切换到备份目录&#xff0c;喜出望外…

构建指标体系是一套数据分析的框架,比如看哪些指标,这些指标变化了就会反映什么问题,是这样的吗?

指标体系是指由若干个反映企业业务运营特征的相对独立又相互联系的统计指标所组成的有机整体。近年来&#xff0c;各类企业逐渐认识到业务指标的重要性&#xff0c;从管理者们长期关注的企业绩效考核&#xff0c;到用来体现信息化水平的数据可视化大屏&#xff0c;其背后都离不…

【IoT】寻光智能车与循迹智能车

1、寻光智能车 功能说明 智能寻光小车&#xff0c;智能识别光线强弱&#xff0c;实现小车永远向光最强的地方行走&#xff0c;到光源处小车自动停止。基本车体为三轮、二驱、双层机构。主控芯片采用最常用的51单片机&#xff1b; 驱动采用L9110驱动芯片驱动两个减速直流电机…

Veeam ONE v12 发布 (含下载) - 面向所有工作负载的 IT 监控解决方案

Veeam Availability Suite v12 请访问原文链接&#xff1a;https://sysin.org/blog/veeam-one-12/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;www.sysin.org 概述 保持全面可视性和控制力&#xff0c;以高效执行管理、优化、计划和…

域渗透漏洞

一、域内提权漏洞 (CVE-2021-42287和CVE-2021-42278) 1.1 漏洞介绍 1.1.1 CVE-2021-42278 主机账户的名称尾部应该有一个 $(即 sAMAccountName 属性)&#xff0c;但是域控对此属性并没有任何验证来确保是否带有 $&#xff0c;这允许攻击者模拟域控主机账户。 1.1.2 CVE-2021-42…