🌟 面向自动驾驶规划算法工程师的专属指南 🌟
欢迎来到《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决策规划算法代码详细解析》专栏,与我们一起探索自动驾驶技术的无限可能,共同推动自动驾驶技术的未来发展!
正文:
Apollo Planning 2.0的框架更新涉及多个方面,这些更新旨在提升自动驾驶系统的灵活性、可扩展性和性能。
以下是Apollo Planning 2.0 的框架图:
其中,Apollo的PlanningComponent在自动驾驶系统中扮演着至关重要的角色。其主要作用可以归纳为以下几点:
PlanningComponent功能介绍:
一、核心功能
1、决策规划:
- PlanningComponent是自动驾驶系统中负责决策规划的组件。它基于来自其他模块(如预测、底盘和定位等)的输入信息,计算出车辆在未来一段时间内的行驶轨迹、速度、加速度等关键参数。
- 这些规划结果将直接指导车辆的实际驾驶操作,确保车辆能够安全、高效地行驶。
2、事件触发机制:
- PlanningComponent是一个事件触发的组件,即它不会持续运行,而是等待特定的事件或条件触发时才开始工作。这些事件通常包括同时收到预测、底盘和定位信息等。
- 这种设计有助于减少不必要的计算资源消耗,并提高系统的响应速度和效率。
二、数据处理流程
1、输入数据检查:
- 在进行决策规划之前,PlanningComponent会首先进行输入数据的检查,确保所有必要的数据都已正确接收并准备好。
- 这些输入数据包括预测信息(如障碍物位置、速度等)、底盘信息(如车辆当前状态、控制指令等)和定位信息(如车辆位置、姿态等)。
2、数据融合与处理:
- PlanningComponent会将这些输入数据进行融合和处理,以构建出一个全面的车辆行驶环境模型。
- 这个模型将作为决策规划的基础,用于评估不同行驶策略的风险和收益,并选择出最优的行驶方案。
3、决策规划与输出:
- 基于构建的车辆行驶环境模型,PlanningComponent会进行决策规划,计算出车辆在未来一段时间内的行驶轨迹。
- 这些规划结果将以特定的数据结构(如ADCTrajectory)输出给控制模块(Control Module),用于指导车辆的实际驾驶操作。
三、支持多种规划模式和场景
- Apollo的PlanningComponent支持多种规划模式和场景,包括NaviPlanning(用于高速公路的导航规划)、OnLanePlanning(对高速公路以及城市道路的处理)和OpenSpacePlanning(主要处理自主泊车以及狭窄道路等场景)。
- 这种灵活性使得Apollo自动驾驶系统能够适应不同的道路条件和驾驶需求,提供更加智能和安全的驾驶体验。
综上所述,Apollo的PlanningComponent是自动驾驶系统中不可或缺的一部分,它负责基于输入数据进行决策规划,并输出指导车辆实际驾驶操作的规划结果。通过支持多种规划模式和场景以及不断优化和改进算法和功能,Apollo的PlanningComponent为自动驾驶系统提供了强大的决策支持能力。
本文将重点解析PlanningComponent的init()函数。
PlanningComponent::init() 介绍
init()函数主要有以下几个重要功能:
一、初始化injector_
injector_ = std::make_shared<DependencyInjector>();
class DependencyInjector {
public:
DependencyInjector() = default;
~DependencyInjector() = default;
PlanningContext* planning_context() { return &planning_context_; }
FrameHistory* frame_history() { return &frame_history_; }
History* history() { return &history_; }
EgoInfo* ego_info() { return &ego_info_; }
apollo::common::VehicleStateProvider* vehicle_state() {
return &vehicle_state_;
}
LearningBasedData* learning_based_data() { return &learning_based_data_; }
private:
PlanningContext planning_context_;
FrameHistory frame_history_;
History history_;
EgoInfo ego_info_;
apollo::common::VehicleStateProvider vehicle_state_;
LearningBasedData learning_based_data_;
};
DependencyInjector提供不同的planning模块运行所需要的所有信息。
DependencyInjector(依赖注入器)的设计模式 主要体现在依赖注入(Dependency Injection, 简称DI)的过程中。依赖注入是一种面向对象编程中的设计模式,其核心思想是将对象之间的依赖关系从对象内部移到对象外部,通过外部方式(如构造函数、setter方法或接口)将依赖项注入到对象中。DependencyInjector作为这一过程的执行者,扮演着至关重要的角色。
依赖注入器(DependencyInjector)的作用:
1、创建和管理依赖实现:
- DependencyInjector负责创建和管理依赖项的具体实现。这些依赖项可能是其他对象、服务或资源,它们在应用程序中被多个组件所共享或需要。
2、注入依赖项:
- DependencyInjector将创建好的依赖项注入到需要它们的对象中。这通常通过构造函数、setter方法或接口注入的方式实现。
3、降低耦合度:
- 通过将依赖关系从对象内部移到外部,并由DependencyInjector统一管理,可以显著降低对象之间的耦合度。这使得各个组件更加独立,易于维护和测试。
4、 提高可扩展性和灵活性:
- 当需要添加新的依赖项或替换现有的依赖项时,只需在DependencyInjector中进行相应的配置,而无需修改依赖项的使用者代码。这提高了系统的可扩展性和灵活性。
二、创建planning的实例,默认配置创建的是OnLanePlanning
三、创建planning 模块需要的reader和writter
planning_command_reader_ = node_->CreateReader<PlanningCommand>(
config_.topic_config().planning_command_topic(),
[this](const std::shared_ptr<PlanningCommand>& planning_command) {
AINFO << "Received planning data: run planning callback."
<< planning_command->header().DebugString();
std::lock_guard<std::mutex> lock(mutex_);
planning_command_.CopyFrom(*planning_command);
});
traffic_light_reader_ = node_->CreateReader<TrafficLightDetection>(
config_.topic_config().traffic_light_detection_topic(),
[this](const std::shared_ptr<TrafficLightDetection>& traffic_light) {
ADEBUG << "Received traffic light data: run traffic light callback.";
std::lock_guard<std::mutex> lock(mutex_);
traffic_light_.CopyFrom(*traffic_light);
});
以planning_command_reader_ 为例,收到topic name是 config_.topic_config().planning_command_topic() 的信号后,调用回调函数给 planning_command_ 赋值,
其中,topic name 来自 config_.topic_config().planning_command_topic() , 默认值如下: