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() , 默认值如下: