Apollo学习——planning模块(3)之planning_base

news2025/5/17 1:04:48

planning_componentplanning_baseon_lane_planningnavi_planning 的关系


1. 模块关系总览

继承层次
  • PlanningComponent:Cyber RT 框架中的 入口组件,负责调度规划模块的输入输出和管理生命周期。
  • PlanningBase:规划算法的 抽象基类,定义通用接口(如 Init(), RunOnce())。
  • OnLanePlanningNaviPlanning:继承自 PlanningBase具体规划器实现,分别针对不同场景设计的动态多态子类。
调用关系
PlanningComponent → (通过指针调用) PlanningBase → OnLanaPlanning/NaviPlanning → 具体规划算法

2. 各模块作用详解

(1) PlanningComponent
  • 功能定位

    • 数据集成:接收上游模块的输入(如 PredictionObstacles 障碍物预测、LocalizationEstimate 定位数据、Chassis 底盘信息)。
    • 生命周期管理:通过 Init() 初始化规划器(选择 OnLanePlanningNaviPlanning),在 Proc() 中触发规划主流程。
    • 消息发布:输出规划轨迹 ADCTrajectory、路由请求 RoutingRequest 和学习数据 PlanningLearningData
  • 核心代码逻辑

    // 初始化时根据配置选择规划模式
    if (FLAGS_use_navigation_mode) {
      planning_base_ = std::make_unique<NaviPlanning>(injector_);
    } else {
      planning_base_ = std::make_unique<OnLanePlanning>(injector_);
    }
    
(2) PlanningBase
  • 功能定位

    • 抽象接口定义:提供规划算法的统一接口(如 RunOnce()Plan()),确保子类实现一致性。
    • 数据封装:管理 Frame 对象(包含车辆状态、环境信息)和 DependencyInjector(依赖注入容器,集成场景、车辆模型等)。
    • 多态支持:通过虚函数机制实现动态绑定,允许运行时切换 OnLanePlanningNaviPlanning
  • 关键成员

    • Frame:整合当前车辆状态、障碍物信息、参考线等上下文数据。
    • ReferenceLineInfo:存储参考线及其动态决策信息,供轨迹规划使用。
(3) OnLanePlanning
  • 功能定位

    • 高精地图规划:基于高精地图生成参考线,适用于 城市道路复杂交通场景(如红绿灯路口、人行道)。
    • 场景机制:内置双层状态机(Scenario + Stage),支持 LaneFollowScenario(车道保持)、TrafficLightProtectedScenario(交通灯路口)等场景。
    • 任务调度:调用 PublicRoadPlanner 等规划器,执行具体的路径优化算法(如 EM Planner、Lattice Planner)。
  • 典型流程

    1. 生成参考线(ReferenceLineProvider)。
    2. 场景切换判定(ScenarioManager::Update())。
    3. 执行场景内的多阶段任务(Stage + Task)。
(4) NaviPlanning
  • 功能定位

    • 相对地图规划:基于实时生成的相对地图(relative_map),适用于 高速公路 或其他 规则简单场景
    • 轻量化设计:简化参考线生成逻辑,依赖车道级导航信息而非全局高精地图。
    • 高效处理:优化算法复杂度,适合长距离、低动态障碍物的场景。
  • 与 OnLanePlanning 的差异

    特性OnLanePlanningNaviPlanning
    地图依赖高精地图相对地图(动态生成)
    适用场景城市道路、复杂交通高速公路、规则简单道路
    场景切换机制支持多场景状态机场景逻辑简化
    计算资源消耗较高较低

3. 数据流与功能协作

协作流程
  1. 输入触发
    • PlanningComponentProc() 由上游消息(如障碍物预测)触发,整合 LocalView 数据包。
  2. 规划执行
    • 调用 planning_base_->RunOnce(),由具体子类(OnLanePlanningNaviPlanning)实现规划逻辑。
  3. 场景与任务
    • OnLanePlanning 中通过 ScenarioManager 切换场景,执行阶段任务(如绕障、停车)。
    • NaviPlanning 直接生成参考线并规划轨迹,跳过复杂场景判定。
  4. 结果输出
    • 发布 ADCTrajectory 轨迹至控制模块,完成闭环。
关键交互点
  • DependencyInjector:注入全局依赖(如车辆状态、历史轨迹),供所有子类共享。
  • PlanningLearningData:在 RL_TEST 模式下收集强化学习训练数据。

总结

  • PlanningComponent 是入口,负责数据集成与调度。
  • PlanningBase 定义框架,实现多态支持。
  • OnLanePlanning 面向复杂场景,NaviPlanning 面向高速场景,二者通过继承实现功能差异化。

基类:planning_base

规划器(OnLanePlanning、NaviPlanning)需要重写的函数有

  //初始化
  virtual apollo::common::Status Init(const PlanningConfig& config);//可以不重写

  virtual std::string Name() const = 0;

  virtual void RunOnce(const LocalView& local_view, ADCTrajectory* const adc_trajectory) = 0;
  
  virtual apollo::common::Status Plan( const double current_time_stamp, const std::vector<common::TrajectoryPoint>& stitching_trajectory, ADCTrajectory* const trajectory) = 0;

不需要重写的有

  //判断规划是否完成
  bool IsPlanningFinished( const ADCTrajectory::TrajectoryType& current_trajectory_type) const;
  // 为轨迹添加设置路的左右边界
  bool GenerateWidthOfLane(const Vec2d& current_location, Vec2d& left_point, Vec2d& right_point);

 protected:
 //规划模块生成轨迹数据时填充协议头信息(Header)的核心方法
  virtual void FillPlanningPb(const double timestamp, ADCTrajectory* const trajectory_pb);
  //加载规划器 默认使用apollo::planning::PublicRoadPlanner
  void LoadPlanner();

代码解释

namespace apollo {
namespace planning {

using apollo::common::Status;

PlanningBase::PlanningBase(const std::shared_ptr<DependencyInjector>& injector): injector_(injector) {}

PlanningBase::~PlanningBase() {}
//如果不重写,则使用基类Init,加载参数
Status PlanningBase::Init(const PlanningConfig& config) {
  injector_->planning_context()->Init();
  config_ = config;
  return Status::OK();
}
//判断规划状态是否完成
bool PlanningBase::IsPlanningFinished(
    const ADCTrajectory::TrajectoryType& current_trajectory_type) const {
  const auto frame = injector_->frame_history()->Latest();
  //判断当前轨迹类型是否为OPEN SPACE 泊车
  if (current_trajectory_type == apollo::planning::ADCTrajectory::OPEN_SPACE) {
    AINFO << "Current trajectory type is: OPEN SPACE";
    if (frame->open_space_info().openspace_planning_finish()) {
      AINFO << "OPEN SPACE: planning finished";
      return true;
    } else {
      AINFO << "OPEN SPACE: planning not finished";
      return false;
    }
  } else {
    // const auto frame = injector_->frame_history()->Latest();
    if (nullptr == frame || frame->reference_line_info().empty() ||
        nullptr == local_view_.planning_command) {
      AINFO << "Current reference point is empty;";
      return true;
    }
    const auto& reference_line_info = frame->reference_line_info().front();
    // Check if the ReferenceLineInfo is the last passage.
    const auto& reference_points =
        reference_line_info.reference_line().reference_points();
    if (reference_points.empty()) {
      AINFO << "Current reference points is empty;";
      return true;
    }
    const auto& last_reference_point = reference_points.back();
    const std::vector<hdmap::LaneWaypoint>& lane_way_points =
        last_reference_point.lane_waypoints();
    if (lane_way_points.empty()) {
      AINFO << "Last reference point is empty;";
      return true;
    }
    // Get the end lane way point.
    if (nullptr == frame->local_view().end_lane_way_point) {
      AINFO << "Current end lane way is empty;";
      return true;
    }
    bool is_has_passed_destination = injector_->planning_context()
                                         ->planning_status()
                                         .destination()
                                         .has_passed_destination();
    AINFO << "Current passed destination:" << is_has_passed_destination;
    return is_has_passed_destination;
  }
}
// 规划模块生成轨迹数据时填充协议头信息(Header)的核心方法
// 时间戳同步:设置轨迹消息的全局时间戳
// 多传感器时间对齐:记录激光雷达、摄像头、雷达等传感器的原始数据时间戳
// 路由信息传递:复制当前路由请求的元数据
void PlanningBase::FillPlanningPb(const double timestamp,
                                  ADCTrajectory* const trajectory_pb) {
  trajectory_pb->mutable_header()->set_timestamp_sec(timestamp); // timestamp通常通过Clock::NowInSeconds()获取系统当前时间
  // 多传感器时间对齐
  if (local_view_.prediction_obstacles->has_header()) {
    trajectory_pb->mutable_header()->set_lidar_timestamp(
        local_view_.prediction_obstacles->header().lidar_timestamp());
    trajectory_pb->mutable_header()->set_camera_timestamp(
        local_view_.prediction_obstacles->header().camera_timestamp());
    trajectory_pb->mutable_header()->set_radar_timestamp(
        local_view_.prediction_obstacles->header().radar_timestamp());
  }
  // local_view_.planning_command包含来自Routing模块的全局路径请求
  trajectory_pb->mutable_routing_header()->CopyFrom(
      local_view_.planning_command->header());
}
//加载规划器默认apollo::planning::PublicRoadPlanner
void PlanningBase::LoadPlanner() {
  // Use PublicRoadPlanner as default Planner
  std::string planner_name = "apollo::planning::PublicRoadPlanner";
  if ("" != config_.planner()) {
    planner_name = config_.planner();
    planner_name = ConfigUtil::GetFullPlanningClassName(planner_name);
  }
  planner_ =
      cyber::plugin_manager::PluginManager::Instance()->CreateInstance<Planner>(
          planner_name);
}
//设置路的左右边界
bool PlanningBase::GenerateWidthOfLane(const Vec2d& current_location,
                                       Vec2d& left_point, Vec2d& right_point) {
  double left_width = 0, right_width = 0;
  const auto frame = injector_->frame_history()->Latest();
  if (nullptr == frame || frame->reference_line_info().empty()) {
    AINFO << "Reference lane is empty!";
    return false;
  }
  const auto& reference_line_info = frame->reference_line_info().front();
  // get current SL
  common::SLPoint current_sl;
  reference_line_info.reference_line().XYToSL(current_location, &current_sl);
  // Get the lane width of vehicle location
  bool get_width_of_lane = reference_line_info.reference_line().GetLaneWidth(
      current_sl.s(), &left_width, &right_width);
  AINFO << "get_width_of_lane: " << get_width_of_lane
        << ", left_width: " << left_width << ", right_width: " << right_width;
  if (get_width_of_lane && left_width != 0 && right_width != 0) {
    AINFO << "Get the width of lane successfully!";
    SLPoint sl_left_point, sl_right_point;
    sl_left_point.set_s(current_sl.s());
    sl_left_point.set_l(left_width);
    sl_right_point.set_s(current_sl.s());
    sl_right_point.set_l(-right_width);
    reference_line_info.reference_line().SLToXY(sl_left_point, &left_point);
    reference_line_info.reference_line().SLToXY(sl_right_point, &right_point);
    return true;
  } else {
    AINFO << "Failed to get the width of lane!";
    return false;
  }
}

}  // namespace planning
}  // namespace apollo

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

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

相关文章

当 AI 邂逅丝路:揭秘「丝路智旅」,用 RAG 重塑中阿文化旅游体验

目录 系统命名:丝路智旅 (Silk Road Intelligent Travel)系统概述系统架构设计系统功能模块技术选型:为何是它们?系统优势与特点未来展望与扩展总结在数字浪潮席卷全球的今天,古老的丝绸之路正在以一种全新的方式焕发生机。当深厚的文化底蕴遇上尖端的人工智能技术,会碰撞…

18.Excel数据透视表:第1部分创建数据透视表

一 什么是数据透视表 通过万花筒可以用不同的方式査看里面画面图像&#xff0c;在excel中可以将数据透视表看作是对准数据的万花筒&#xff0c;用不同角度去观察数据&#xff0c;也可以旋转数据&#xff0c;对数据进行重新排列&#xff0c;对大量的数据可以快速的汇总和建立交叉…

CSS AI 通义灵码 VSCode插件安装与功能详解

简介 在前端开发领域&#xff0c;页面调试一直是个繁琐的过程&#xff0c;而传统开发中美工与前端的对接也常常出现问题。如今&#xff0c;阿里云技术团队推出的通义灵码智能编码助手&#xff0c;为前端开发者带来了新的解决方案&#xff0c;让开发者可以像指挥者一样&#xf…

【Linux网络】TCP全连接队列

TCP 相关实验 理解 listen 的第二个参数 基于刚才封装的 TcpSocket 实现以下测试代码对于服务器, listen 的第二个参数设置为 1, 并且不调用 accept测试代码链接 test_server.cc #include "tcp_socket.hpp"int main(int argc, char* argv[]) {if (argc ! 3) {pri…

HTML 颜色全解析:从命名规则到 RGBA/HSL 值,附透明度设置与场景应用指南

一、HTML 颜色系统详解 HTML 中的颜色可以通过多种方式定义&#xff0c;包括颜色名称、RGB 值、十六进制值、HSL 值等&#xff0c;同时支持透明度调整。以下是详细分类及应用场景&#xff1a; 1. 颜色名称&#xff08;预定义关键字&#xff09; HTML 预定义了 140 个标准颜色名…

深度剖析多模态大模型中的视频编码器算法

写在前面 随着多模态大型语言模型(MLLM)的兴起,AI 理解世界的能力从静态的文本和图像,进一步拓展到了动态的、包含丰富时空信息的视频。视频作为一种承载了动作、交互、场景变化和声音(虽然本文主要聚焦视觉部分)的复杂数据形式,为 MLLM 提供了理解真实世界动态和因果关…

游戏引擎学习第282天:Z轴移动与摄像机运动

运行游戏&#xff0c;展示目前进展 我们目前正在进行一个游戏开发项目。昨天&#xff0c;我们实现了基于房间的角色移动系统&#xff0c;并且加入了摄像机的跟随滚动功能。这是我们首次进入“游戏逻辑设计”阶段&#xff0c;也就是说&#xff0c;我们开始构建游戏本身的行为和…

aws 实践创建policy + Role

今天Cyber 通过image 来创建EC2 的时候,要添加policy, 虽然是administrator 的role, 参考Cyber 提供的link: Imageshttps://docs.cyberark.com/pam-self-hosted/14.2/en/content/pas%20cloud/images.htm#Bring 1 Step1:

【HarmonyOS 5】鸿蒙星闪NearLink详解

【HarmonyOS 5】鸿蒙星闪NearLink详解 一、前言 鸿蒙星闪NearLink Kit 是 HarmonyOS 提供的短距离通信服务&#xff0c;支持星闪设备间的连接、数据交互。例如&#xff0c;手机可作为中心设备与外围设备&#xff08;如鼠标、手写笔、智能家电、车钥匙等&#xff09;通过星闪进…

WF24 wifi/蓝牙模块串口与手机蓝牙通信

usb-ttl ch340接线 打开串口工具SSCOM&#xff0c;端口号选择ch340接的那个口&#xff0c;波特率改成115200 DX-SMART_2.0.5.apk下载 手机打开DX-SMART软件 点击透传-搜索BLE-连接WF24-BLE 连接成功串口会收到消息 [14:37:10.591]收←◆ BLE_CONNECT_SUCCESS发送命令ATBLUFI…

通义千问席卷日本!开源界“卷王”阿里通义千问成为日本AI发展新基石

据日本经济新闻&#xff08;NIKKEI&#xff09;报道&#xff0c;通义千问已成为日本AI开发的新基础&#xff0c;其影响力正逐步扩大&#xff0c;深刻改变着日本AI产业的格局。 同时&#xff0c;日本经济新闻将通义千问Qwen2.5-Max列为全球AI模型综合评测第六名&#xff0c;不仅…

流程编辑器Bpmn与LogicFlow学习

工作流技术如何与用户交互结合&#xff08;如动态表单、任务分配&#xff09;处理过 XML 与 JSON 的转换自定义过 bpmn.js 的样式&#xff08;如修改节点颜色、形状、图标&#xff09;扩展过上下文菜单&#xff08;Palette&#xff09;或属性面板&#xff08;Properties Panel&…

Figma 新手教程学习笔记

&#x1f4fa; 视频地址&#xff1a;Figma新手教程2025&#xff5c;30分钟高效掌握Figma基础操作与UI设计流程_哔哩哔哩_bilibili &#x1f9ed; 课程结构 Figma 简介&#xff08;00:38&#xff09; 熟悉工作环境&#xff08;01:49&#xff09; 操作界面介绍&#xff08;03:…

配置Spark环境

1.上传spark安装包到某一台机器&#xff08;自己在finaShell上的机器&#xff09;。 2.解压。 把第一步上传的安装包解压到/opt/module下&#xff08;也可以自己决定解压到哪里&#xff09;。对应的命令是&#xff1a;tar -zxvf 安装包 -C /opt/module 3.重命名。进入/opt/mo…

Window下Jmeter多机压测方法

1.概述 Jmeter多机压测的原理&#xff0c;是通过单个jmeter客户端&#xff0c;控制多个远程的jmeter服务器&#xff0c;使他们同步的对服务器进行压力测试。 以此方式收集测试数据的好处在于&#xff1a; 保存测试采样数据到本地机器通过单台机器管理多个jmeter执行引擎测试…

视频图像压缩领域中 DCT 的 DC 系数和 AC 系数详解

引言 在数字图像与视频压缩领域&#xff0c;离散余弦变换&#xff08;Discrete Cosine Transform, DCT&#xff09;凭借其卓越的能量集中特性&#xff0c;成为JPEG、MPEG等国际标准的核心技术。DCT通过将空域信号映射到频域&#xff0c;分离出DC系数&#xff08;直流分量&…

能源设备数据采集

在全球可持续发展目标与环境保护理念日益深入人心的时代背景下&#xff0c;有效管理和优化能源使用已成为企业实现绿色转型、提升竞争力的关键路径。能源设备数据采集系统&#xff0c;作为能源管理的核心技术支撑&#xff0c;通过对各类能源生产设备运行数据的全面收集、深度分…

Go语言安装proto并且使用gRPC服务(2025最新WINDOWS系统)

1.protobuf简介 protobuf 即 Protocol Buffers&#xff0c;是一种轻便高效的结构化数据存储格式&#xff0c;与语言、平台无关&#xff0c;可扩展可序列化。protobuf 性能和效率大幅度优于 JSON、XML 等其他的结构化数据格式。protobuf 是以二进制方式存储的&#xff0c;占用空…

[Linux性能优化] 线程卡顿优化。Linux加入USB(HID)热插拔线程占用CPU优化。Linux中CPU使用率过高优化

文章目录 [Linux性能优化] 线程卡顿优化。0、省流版本一、问题定位&#xff1a;CPU 资源分析二、线程卡顿现场复现线程优化前图片 三、线程卡顿优化方向1.如果是轮询方式2.如果是事件驱动方式 四、修改方式线程优化后图片 [Linux性能优化] 线程卡顿优化。 0、省流版本 如果采…

Ubuntu20.04下如何源码编译Carla,使用UE4源码开跑,踩坑集合

一、简介 作为一个从事算法研究的人员,无人驾驶仿真一直是比较重要的一部分,但是现在比较常见的算法验证都是在carla这个开源仿真平台上做的,所以我有二次开发carla的需求,今天就来讲讲编译CARLA。 网上的教材很多,但还是推荐大家看官网教程:Linux build - CARLA Simul…