Apollo9.0 Planning2.0决策规划算法代码详细解析 (4): PlanningComponent::Proc()

🌟 面向自动驾驶规划算法工程师的专属指南 🌟

欢迎来到《Apollo9.0 Planning2.0决策规划算法代码详细解析》专栏!本专栏专为自动驾驶规划算法工程师量身打造,旨在通过深入剖析Apollo9.0开源自动驾驶软件栈中的Planning2.0模块,帮助读者掌握自动驾驶决策规划算法的核心原理与实现细节。

🔍 VSCode+GDB:精准调试,洞悉代码逻辑 🔍

在自动驾驶算法的开发过程中,调试是至关重要的一环。本专栏将带你深入掌握VSCode+GDB这一强大的调试工具组合,让你能够逐行分析代码,精准定位问题,从而洞悉算法背后的逻辑与原理。通过实战演练,你将学会如何高效地利用调试工具,提升代码质量与开发效率。

💻 C++语法同步讲解:构建算法基石 💻

C++作为自动驾驶领域的主流编程语言,其重要性不言而喻。本专栏在解析算法代码的同时,将同步介绍C++语法,从基础到进阶,涵盖数据类型、控制结构、面向对象编程等核心知识点。通过系统学习,你将能够熟练运用C++语言编写高效、可维护的自动驾驶规划算法代码。

🚀 掌握自动驾驶PNC工程师从业能力 🚀

完成本专栏的学习后,你将具备自动驾驶PNC(规划、导航与控制)工程师的从业能力。你将能够深入理解自动驾驶决策规划算法的设计思路与实现方法,掌握Apollo9.0 Planning2.0模块的核心技术,为自动驾驶汽车的智能决策提供有力支持。

🚀 Apollo9.0 Planning2.0:探索自动驾驶技术前沿 🚀

Apollo9.0作为百度开源的自动驾驶软件栈,其Planning2.0模块在决策规划算法方面取得了显著进展。本专栏将带你深入探索Apollo9.0 Planning2.0的奥秘,揭秘其背后的算法原理与实现细节。通过系统学习,你将能够站在自动驾驶技术的前沿,为自动驾驶汽车的未来发展贡献力量。

🎉 立即加入,开启自动驾驶规划算法之旅 🎉

无论你是自动驾驶领域的初学者,还是有一定经验的工程师,本专栏都将为你提供宝贵的学习资源与实战机会。立即加入《Apollo9.0 Planning2.0决策规划算法代码详细解析》专栏,与我们一起探索自动驾驶技术的无限可能,共同推动自动驾驶技术的未来发展!

一、PlanningComponent::Proc() 简介

PlanningComponent::Proc() 作为整个planning 模块的入口,每个planning周期都会执行一次,主要提供以下一些功能:

  1. CheckRerouting() 重新路由判断
  2. 更新local_view_,local_view_中包含一次planning需要的所有外部信息
  3. CheckInput() 检查输入
  4. 规划器进行规划,并给输出轨迹赋值
  5. 更新轨迹的时间戳,并且发布轨迹

二、PlanningComponent::CheckRerouting() 重新路由判断

PlanningComponent::CheckRerouting()函数读取 planning的结果,判断是否需要重新规划routing,如果需要重新routing,调用rerouting_client_发送rerouting请求;

void PlanningComponent::CheckRerouting() {auto* rerouting = injector_->planning_context()->mutable_planning_status()->mutable_rerouting();if (!rerouting->need_rerouting()) {return;}common::util::FillHeader(node_->Name(),rerouting->mutable_lane_follow_command());auto lane_follow_command_ptr =std::make_shared<apollo::external_command::LaneFollowCommand>(rerouting->lane_follow_command());rerouting_client_->SendRequest(lane_follow_command_ptr);rerouting->set_need_rerouting(false);
}

三、更新local_view_

local_view_中包含一次planning需要的所有外部信息:

struct LocalView {std::shared_ptr<prediction::PredictionObstacles> prediction_obstacles;std::shared_ptr<canbus::Chassis> chassis;std::shared_ptr<localization::LocalizationEstimate> localization_estimate;std::shared_ptr<perception::TrafficLightDetection> traffic_light;std::shared_ptr<relative_map::MapMsg> relative_map;std::shared_ptr<PadMessage> pad_msg;std::shared_ptr<storytelling::Stories> stories;std::shared_ptr<PlanningCommand> planning_command;std::shared_ptr<routing::LaneWaypoint> end_lane_way_point;
};

更新前:

更新后:

local_view_.planning_command为例,语法细节如下:

local_view_.planning_command =std::make_shared<PlanningCommand>(planning_command_);

在这段代码中,local_view_.planning_command 被赋予了一个新的std::shared_ptr<PlanningCommand>,该指针指向一个通过 std::make_shared<PlanningCommand> 新创建的 PlanningCommand 对象。这个新对象是通过拷贝构造函数从 planning_command_ 初始化而来的。

具体步骤如下:

  1. 内存分配和对象构造std::make_shared<PlanningCommand>(planning_command_) 调用会首先分配一块足够大的内存区域来同时存储 PlanningCommand 对象和与之关联的引用计数(以及可能的控制块,用于存储删除器等)。然后,在这块内存上构造一个 PlanningCommand 对象,作为参数传递的 planning_command_ 被用作这个新对象的拷贝源。

  2. 智能指针初始化:构造好的 PlanningCommand 对象地址被传递给 std::shared_ptr<PlanningCommand> 的构造函数,从而创建一个管理这个新对象的智能指针。此时,引用计数被初始化为1,表示有一个 std::shared_ptr 实例(即我们刚刚创建的)正在指向这个对象。

  3. 赋值操作:最后,这个新创建的 std::shared_ptr<PlanningCommand> 被赋值给 local_view_.planning_command。如果 local_view_.planning_command 之前已经指向了一个 PlanningCommand 对象,那么那个对象的引用计数会递减(如果递减到0,则对象会被自动删除)。然后,local_view_.planning_command 开始指向新创建的对象。

需要注意的是,由于 std::make_sharedstd::shared_ptr 的使用,这段代码是线程安全的(在赋值操作本身这一层面,但前提是 local_view_planning_command_ 的访问已经被适当地同步了,比如通过互斥锁)。此外,它也符合RAII(资源获取即初始化)原则,因为智能指针的构造函数会自动管理资源的获取(在这里是对象的创建和内存的分配),而析构函数则会在适当的时候(比如智能指针离开其作用域时)自动释放资源(在这里是减少引用计数并在必要时删除对象)。

还有一点很重要,就是 PlanningCommand 类必须有一个可访问的拷贝构造函数,因为 std::make_shared 在这里使用了它来从 planning_command_ 创建新对象。如果 PlanningCommand 是不可拷贝的(即它的拷贝构造函数被删除或声明为 delete),那么这段代码将无法编译。

四、PlanningComponent::CheckInput() 检查输入

bool PlanningComponent::CheckInput() {ADCTrajectory trajectory_pb;auto* not_ready = trajectory_pb.mutable_decision()->mutable_main_decision()->mutable_not_ready();if (local_view_.localization_estimate == nullptr) {not_ready->set_reason("localization not ready");} else if (local_view_.chassis == nullptr) {not_ready->set_reason("chassis not ready");} else if (HDMapUtil::BaseMapPtr() == nullptr) {not_ready->set_reason("map not ready");} else {// nothing}if (FLAGS_use_navigation_mode) {if (!local_view_.relative_map->has_header()) {not_ready->set_reason("relative map not ready");}} else {if (!local_view_.planning_command ||!local_view_.planning_command->has_header()) {not_ready->set_reason("planning_command not ready");}}if (not_ready->has_reason()) {AINFO << not_ready->reason() << "; skip the planning cycle.";common::util::FillHeader(node_->Name(), &trajectory_pb);planning_writer_->Write(trajectory_pb);return false;}return true;
}

五、调用规划器进行规划,并给输出轨迹赋值

  ADCTrajectory adc_trajectory_pb;planning_base_->RunOnce(local_view_, &adc_trajectory_pb);auto start_time = adc_trajectory_pb.header().timestamp_sec();common::util::FillHeader(node_->Name(), &adc_trajectory_pb);

 默认的planning_base_是OnLanePlanning,数据结构如下:

六、更新轨迹的时间戳,并且发布轨迹

  const double dt = start_time - adc_trajectory_pb.header().timestamp_sec();for (auto& p : *adc_trajectory_pb.mutable_trajectory_point()) {p.set_relative_time(p.relative_time() + dt);}planning_writer_->Write(adc_trajectory_pb);

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

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

相关文章

vAPI靶场

前言 自行去搭建vAPI靶场&#xff0c;配合postman使用 vapi1 创建用户 第一个用户 {"username": "shi","name": "shi1","course": "nihao","id": 10 } 第二个用户 {"username": "hui…

论文理解【LLM-CV】—— 【MAE】Masked Autoencoders Are Scalable Vision Learners

文章链接&#xff1a;Masked Autoencoders Are Scalable Vision Learners代码&#xff1a;GitHub - facebookresearch/mae发表&#xff1a;CVPR 2022领域&#xff1a;LLM CV一句话总结&#xff1a;本文提出的 MAE 是一种将 Transformer 模型用作 CV backbone 的方法&#xff0c…

制作一个流水灯,控制发光二极管由上至下再由下至上反复循环点亮显示,每次点亮一个发光二级管(Proteus 与Keil uVision联合仿真)

一、代码编写 &#xff08;1&#xff09;编写程序来控制发光二极管由上至下的反复循环流水点亮&#xff0c;每次点亮一个发光二极管。 #define uchar unsigned char // 定义uchar为unsigned char类型uchar tab[] {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f, 0x7f, 0x…

一个不错的 SQL 编码风格的指南

前言 SQL语句的编写对于我们后端开发者而言是一个必备的技巧&#xff0c;在日常工作中&#xff0c;SQL语言编写的质量不仅仅会影响到团队的合作效率与项目的可维护性&#xff0c;还直接关系到数据库的性能优化与数据安全。今天大姚给大家分享一个不错的 SQL 编码风格的指南&am…

【Qt】控件概述(4)—— 输出类控件

输出类控件 1. QLineEdit——单行输入框2. QTextEdit——多行输入框3. QComboBox——下拉框4. QSpinBox——微调框5. QDateEdit && QTimeEdit && QDateTimeEdit6 QDial——旋钮7. QSlider——滑动条 1. QLineEdit——单行输入框 QLineEdit是一个单行的输入框&…

定时器实验(Proteus 与Keil uVision联合仿真)

一、 &#xff08;1&#xff09;设置TMOD寄存器 T0工作在方式1&#xff0c;应使TMOD寄存器的M1、M001&#xff1b;应设置C/T*0&#xff0c;为定时器模式&#xff1b;对T0的运行控制仅由TR0来控制&#xff0c;应使相应的GATE位为0。定时器T1不使用&#xff0c;各相关位均设为…

执行路径带空格的服务漏洞

原理 当系统管理员配置Windows服务时&#xff0c;必须指定要执行的命令&#xff0c;或者运行可执行文件的路径。 当Windows服务运行时&#xff0c;会发生以下两种情况之一。 1、如果给出了可执行文件&#xff0c;并且引用了完整路径&#xff0c;则系统会按字面解释它并执行 …

Listen1 0.8.2| 免费无广告,整合多平台音乐,界面简洁,操作便捷。

Listen 1 是一款开源且免费的跨平台音乐播放器&#xff0c;它能够整合多个主流音乐平台的资源&#xff0c;让你在一个应用中就能听到来自不同平台的歌曲。无论你是网易云音乐、QQ音乐还是虾米音乐的用户&#xff0c;你都可以通过 Listen 1 来享受无缝的音乐体验。它支持网易云音…

【每天学个新注解】Day 16 Lombok注解简解(十五)—@FieldNameConstants

FieldNameConstants 根据属性名生成常量类的常量。 1、如何使用 加在需要根据属性名生成常量的属性上。 2、代码示例 例&#xff1a; FieldNameConstants public class Test {private String iAmAField;private int andSoAmI;FieldNameConstants.Exclude private int asA…

【机器学习(十一)】糖尿病数据集分类预测案例分析—XGBoost分类算法—Sentosa_DSML社区版

文章目录 一、XGBoost算法二、Python代码和Sentosa_DSML社区版算法实现对比(一) 数据读入和统计分析(二)数据预处理(三)模型训练与评估(四)模型可视化 三、总结 一、XGBoost算法 关于集成学习中的XGBoost算法原理&#xff0c;已经进行了介绍与总结&#xff0c;相关内容可参考【…

openEuler 24.03 (LTS) 部署 K8s(v1.31.1) 高可用集群(Kubespray Ansible 方式)

写在前面 实验需要一个 CNI 为 flannel 的 K8s 集群之前有一个 calico 的版本有些旧了,所以国庆部署了一个v1.31.1 版本 3 * master 5 * work时间关系直接用的工具 kubespray博文内容为部署过程以及一些躺坑分享需要科学上网理解不足小伙伴帮忙指正 &#x1f603;,生活加油 99…

第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例

JPA教程 - JPA查询OrderBy两个属性示例 以下代码显示如何按两个属性排序&#xff0c;一个升序&#xff0c;另一个降序。 List l em.createQuery("SELECT e FROM Professor e " "JOIN e.department d ORDER BY d.name, e.name DESC").getResultList();例子…

数据结构实验二 顺序表的应用

数据结构实验二 顺序表的应用 一、实验目的 1、掌握建立顺序表的基本方法。 2、掌握顺序表的插入、删除算法的思想和实现&#xff0c;并能灵活运用 二、实验内容 用顺序表实现病历信息的管理与查询功能。具体要求如下: 1.利用教材中定义顺序表类型存储病人病历信息(病历号…

什么是高斯积分,以及如何求它的值(error function)

文章目录 什么是高斯积分高斯积分与误差函数的关系求值证明过程技巧1 两个相互独立的积分的乘积转为双重积分技巧2 富比尼定理技巧3 坐标系转换总结 什么是高斯积分 高斯积分的公式如下&#xff1a; 高斯积分与误差函数的关系 参考wiki&#xff0c;误差函数的定义如下&…

SQL自用小结

推荐一下这个知识点总结 《数据库系统概论》第五版 学习笔记总目录 1. SQL概述 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是一种用于定义、查询、更新和控制关系数据库的标准化语言。 它包含了数据定义语言&#xff08;DDL&#xff0…

Unity MVC框架演示 1-1 理论分析

本文仅作学习笔记分享与交流&#xff0c;不做任何商业用途&#xff0c;该课程资源来源于唐老狮 1.一般的图解MVC 什么是MVC我就不说了&#xff0c;老生常谈&#xff0c;网上有大量的介绍&#xff0c;想看看这三层都起到什么职责&#xff1f;那就直接上图吧 2.我举一个栗子 我有…

“迷雾深渊”炮击图设计

python尝试C题目&#xff0c;ai查错审码还写“代码解读”和学习总结。 (笔记模板由python脚本于2024年09月29日 10:51:58创建&#xff0c;本篇笔记适合喜欢python&#xff0c;鼓捣算法的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/…

【EXCEL数据处理】保姆级教程 000016案例 vlookup函数。

【EXCEL数据处理】000016案例 vlookup函数。 前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【EXCEL数据处理】保姆级教…

【目标检测】工程机械车辆数据集2690张4类VOC+YOLO格式

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2694 标注数量(xml文件个数)&#xff1a;2694 标注数量(txt文件个数)&#xff1a;2694 标注…

k8s 中的金丝雀发布(灰度发布)

目录 1 什么是金丝雀发布 2 Canary 发布方式 3 Canary 两种发布方式实操 3.1 准备工作 3.1.1 将 nginx 命名两个版本 v1 与 v2 3.1.2 暴露端口并指定微服务类型 3.1.3 进入 pod 修改默认发布文件 3.1.4 测试 service 是否正常 3.2 基于权重的灰度发布 3.2.1 创建 Igress 资源类…