自动驾驶之轨迹规划8——Apollo参考线和轨迹

Apollo 轨迹规划算法解析 这篇文章主要整理一下前段时间学习的轨迹规划算法,关于轨迹规划问题可以查到的相关资料很多,但能把轨迹规划问题详细说清楚的并不太多,这导致我在学习过程中出现很多疑惑。这里我把Apollo的各个版本轨迹规划算法进行简单总结和汇总。 阅读详情
AI摘要

本文深入讲解了自动驾驶系统中的Routing和Planning模块,特别是referenceline的作用和生成过程。Routing模块根据起点和终点生成路线,而Planning模块在此基础上结合车辆状态和环境信息实时计算referenceline,进一步生成Trajectory。参考线作为Planning的基础,贯穿了整个决策规划流程,涉及地图数据、行驶代价计算和动态障碍物处理等关键环节。

1. abstract

本文主要讲解routing和planning模块中的reference line,我之前一直搞不明白这个reference line是如何生成的,有什么作用,和routing以及planning的关系。现在有了一些心得打算梳理一下:

在这里插入图片描述

决策规划模块负责生成车辆的行驶轨迹。要做到这一点,决策规划模块需要从宏观到局部经过三个层次来进行决策。

  • 第一个层次是Routing的搜索结果。Routing模块的输入是若干个按顺序需要达到的途径点(也可能只有一个起点和终点)。Routing模块根据地图的拓扑结构搜索出可达的完整路线来,这个路线的长度可能是几公里甚至几百公里。因此这个是最为宏观的数据。另外,Routing的搜索结果是相对固定的。在没有障碍物的情况下,车辆会一直沿着原先获取到的Routing路线行驶。只有当车辆驶出了原先规划的路线之外(例如:为了避障),才会重新发送请求给Routing模块,以重新计算路线。
  • 第二个层次就是reference line。决策规划模块会实时的根据车辆的具体位置来计算reference line。reference line的计算会以Routing的路线为基础。但同时,reference line会考虑车辆周边的动态信息,例如:障碍物,交通规则等。reference line是包含车辆所在位置周边一定的范围,通常是几百米的长度。相较于Routing结果,它是较为局部的数据。
  • 第三个层次是Trajectory。Trajectory是决策规划模块的最终输出结果。它的依据是reference line。在同一时刻,reference line可能会有多条,例如:在变道的时候,自车所在车道和目标车道都会有一条reference line。而Trajectory,是在所有可能的结果中,综合决策和优化的结果,最终的唯一结果。因此它是更为具体和局部的数据。轨迹不仅仅包含了车辆的路线,还包含了车辆行驶这条路线时的详细状态,例如:车辆的方向,速度,加速度等等。

参考线是整个决策规划算法的基础。在Planning模块的每个计算循环中,都会先生成参考线,然后在这个基础上进行后面的处理,例如:交通规则逻辑,障碍物投影,路径优化,速度决策等等。可以说,参考线贯穿了整个Planning模块的实现。下面就看下reference line如何在routing和plannin中承前启后的:

在这里插入图片描述
从这幅图中可以看出,这里涉及到三个模块,下面会挨个梳理:

  • routing模块,这部分内容追在Routing模块一文中讲解,本文不再赘述。
  • **pnc_map模块:负责读取和处理Routing搜索结果。**是planning的子模块,因为重要就把他单独拎出来了。
  • planning模块:根据Routing结果和车辆的实时状态(包括周边环境)生成reference line和trajectory。

2. routing

Routing模块正如其名称所示,其主要作用就是根据请求生成路由信息。

模块输入:

  • 地图数据
  • 请求,包括:
  • 开始和结束位置

模块输出:

  • 路由导航信息

2.1 Topo地图
为了计算路由路径,在Routing模块中包含一系列的类用来描述Topo地图的详细结构。这些类的定义位于modules/routing/graph/目录下。它们的说明如下:
在这里插入图片描述
简单来说,Topo地图中最重要的就是节点和边,本质上是一系列的Topo节点以及它们的连接关系,节点对应了道路,边对应了道路的连接关系,这个在Apollo开发者社区的技术文章中着重讲过。如下图所示:
在这里插入图片描述
Routing模块需要的地图结构通过TopoGraph来描述,而TopoGraph的初始化需要一个地图文件。但该地图文件与其他模块需要的地图文件并不一样,这里的地图文件是Proto结构导出的数据。之所以这样做是因为:Routing模块不仅需要地图的Topo结构,还需要知道每条路线的行驶代价。在Proto结构中包含了这些信息。在下面的内容中,我们将看到这个行驶代价是从哪里来的。

很显然,两个地点的导航路径结果通常会有多个。而计算导航路径的时候需要有一定的倾向,这个倾向就是行驶的代价越小越好。我们很自然的想到,影响行驶代价最大的因素就是行驶的距离。

但实际上,影响行驶代价的因素远不止距离这一个因素。距离只是宏观上的考虑,而从微观的角度来看,行驶过程中,需要进行多少次转弯,多少次掉头,多少变道,这些都是影响行驶代价的因素。所以,在计算行驶代价的时候,需要综合考虑这些因素。

再从另外一个角度来看,(在路线已经确定的情况下)行驶的距离是一个物理世界客观存在的结果,这是我们无法改变的。不过,对于行驶过程中,有多在意转弯,掉头和变道,每个人或者每个场景下的偏好就不一样了。而这,就是配置文件“/apollo/modules/routing/conf/routing/config.pb.txt“存在的意义了。这里面配置了上面提到的这些动作的惩罚基数,而这些基数会影响路线时的计算代价。

routing的请求接口是下面这个:

bool Routing::Process(const std::shared_ptr<RoutingRequest> &routing_request, RoutingResponse* const routing_response);

这个接口只有很简洁的两个参数:一个是描述请求的输入参数routing_request,一个是包含结果的输出参数routing_response。它们都是在proto文件中定义的。

2.2 RoutingRequest

message LaneWaypoint {
  optional string id = 1;
  optional double s = 2;
  optional apollo.common.PointENU pose = 3;
}

message LaneSegment {
  optional string id = 1;
  optional double start_s = 2;
  optional double end_s = 3;
}

message RoutingRequest {
  optional apollo.common.Header header = 1;
  repeated LaneWaypoint waypoint = 2;
  repeated LaneSegment blacklisted_lane = 3;
  repeated string blacklisted_road = 4;
  optional bool broadcast = 5 [default = true];
  optional apollo.hdmap.ParkingSpace parking_space = 6;
}

2.3 RoutingResponse:

message RoutingResponse {
  optional apollo.common.Header header = 1;
  repeated RoadSegment road = 2;
  optional Measurement measurement = 3;
  optional RoutingRequest routing_request = 4;

  optional bytes map_version = 5;
  optional apollo.common.StatusPb status = 6;
}

message RoadSegment {
  optional string id = 1;
  repeated Passage passage = 2;
}

message Passage {
  repeated LaneSegment segment = 1;
  optional bool can_exit = 2;
  optional ChangeLaneType change_lane_type = 3 [default = FORWARD];
}

message LaneSegment {
  optional string id = 1;
  optional double start_s = 2;
  optional double end_s = 3;
}

enum ChangeLaneType {
  FORWARD = 0;
  LEFT = 1;
  RIGHT = 2;
};

message Measurement {
  optional double distance = 1;
}

RoutingResponse中的属性说明如下:
在这里插入图片描述
这里的RoadSegment road是最重要的数据。这个数据其实是一个三层的结构体嵌套,它们的说明如下:

  • RoadSegment road:描述道路,一条道路可能包含了并行的几条通路(Passage)。
  • Passage:描述通路,通路是直连不含变道的可行驶区域。一个通路可能包含了前后连接的多个车道。(对应了pac_map中的RouteSegments)
  • LaneSegment:描述车道,车道是道路中的一段,自动驾驶车辆会尽可能沿着车道的中心线行驶。

3. pnc_map

pnc全称是Planning And Control,是Planning用来对接Routing搜索结果的子模块,但他比较重要,这里我把它单独拎出来梳理下。

PncMap类负责对接Routing搜索结果的更新:会根据车辆当前位置,提供车辆周边的RouteSegments信息供ReferenceLineProvider生成ReferenceLine。而这里的RouteSegments对应了routing模块里RoutingResponse里的Passage结构,它其中会包含若干个车道信息。这个RouteSegments类继承自std::vector。RouteSegments中有如下一些方法值得关注:

  • NextAction():车辆接下来要采取的动作。可能是直行,左变道,或者右变道。
  • CanExit():当前通路是否可以接续到Routing结果的另外一个通路上。
  • GetProjection():将一个点投影到当前通路上。返回SLPoint和LaneWaypoint。
  • Stitch():缝合另外一个RouteSegments。即:去除两个RouteSegments间重合的多余部分,然后连接起来。
  • Shrink():缩短到指定范围。
  • IsOnSegment():车辆是否在当前RouteSegments上。
  • IsNeighborSegment():当前RouteSegments是否是车辆的临近RouteSegments。

4. planning

在Planning模块中有以下三个数据结构将是本文关注的重点:

  • ReferenceLine:原始参考线,源码位于planning/reference_line/目录下。根据Routing的搜索结果生成。
  • ReferenceLineInfo:源码位于planning/reference_line/目录下。Planning实现中,逻辑计算的基础数据结构,很多操作都会在这个数据结构上进行(例如:交通规则逻辑,障碍物投影,路径优化,速度决策等)。本文中的“参考线”一词将不区分ReferenceLine和ReferenceLineInfo两个结构。
  • Trajectory:下文中我们将看到,有好几个结构用来描述轨迹。它们在不同的场合下使用。这其中,ADCTrajectory是Planning模块的输出。它是Planning模块一次计算循环中,处理了所有逻辑的最终结果,包含了车辆行驶需要的所有信息。因此,这个数据将直接影响到自动驾驶车辆的行车行为。

5. reference

解析百度Apollo之Routing模块
解析百度Apollo之参考线与轨迹
开发者说丨离散点曲线平滑原理
直播回顾丨Apollo自动驾驶论坛①规划模块算法解析
Apollo Planning Frame
Apollo ReferenceLineProvider
Apollo EMPlanner(v 3.0)
Apollo 6.0 规划算法解析
Apollo 6.0 规划模块算法解析2

apollo参考线平滑demo 在结构化道路中存在道路中心线,可以将其作为车辆行驶的参考线。但是从高精地图上获取的参考线不能直接用,因为高精地图是人为采集的,采集的路径是一对不平滑的离散点,曲率也未必始终连续,如果参考线不平滑可能导致规划出来的轨迹不平滑。 阅读详情

相关推荐

自动驾驶算法详解(1) : Apollo路径规划 Piecewise Jerk Path Optimizer的python实现

本文作为Apollo Planning决策规划代码详细解析系列文章的补充,将使用Python代码以及anaconda环境,来实现Apollo 决策规划Planning 模块里的 Piecewise Jerk Path Optimizer算法。 Piecewise Jerk Path Optimizer算法以上游模块决策的path bound,参考线reference line,规划起点start point为基础,通过在凸空间里将规划问题构建为二次优化问题,调用OSQP 库的求解器进行二次规划问题求解,.

自动驾驶Player的博客 1万+

Apollo:参考线

我们先介绍一下参考线在整个Planning模块中所处的位置:决策规划模块负责生成车辆的行驶轨迹。要做到这一点,决策规划模块需要从宏观到局部经过三个层次来进行决策。第一个层次是Routing的搜索结果。Routing模块的输入是若干个按顺序需要达到的途经点(也可能只有一个起点和一个终点)。Routing模块根据地图的拓扑结构搜索出可达的完整路径来,这个路线的长度可能是几公里甚至几百公里。因此这个是最为宏观的数据。另外,Routing的搜索结果是相对固定的。

OceanStar的博客 4476

Apollo课程学习5——规划

Apollo课程学习5——规划学习前言规划概述一、什么是运动规划二、如何构建汽车的运动规划问题1、A-star算法2、D-star算法3、技术需求运动规划基本方法一、概述二、构造空间什么是规划一、地图路线规划——高等级二、轨迹生成——低等级A*算法——路线规划轨迹的评估Frenet坐标ST图路径-速度解耦规划(轨迹生成)Lattice规划(轨迹生成)最终状态分类一、ST图最终状态二、SL图最终状态 学习前言 今天的学习内容是规划。 规划概述 一、什么是运动规划 规划问题本质上是一个搜索问题,即对一个给定的

weixin_43476492的博客 2254

Apollo:参考线ReferenceLine是如何定义的

位于modules/planning/reference_line/reference_line.h其定义如下。

OceanStar的博客 2602

避开这个坑:你的Apollo参考线为什么不平滑?从离散点平滑到轨迹优化的实战避雷指南

本文深入分析了Apollo自动驾驶系统中参考线不平滑的常见问题,从离散点采样密度、平滑算法权重配置到坐标系转换误差等多方面揭示根源,并提供实战解决方案。针对轨迹优化阶段的隐藏雷区,如预测时域错配和数值稳定性问题,给出了具体调试方法和参数调优指南,帮助开发者实现更平滑的自动驾驶轨迹规划。

weixin_30733003的博客 450

Apollo Lattice Planner实战:5步搞定自动驾驶轨迹规划(附Python代码示例)

本文通过5个步骤详细解析了Apollo自动驾驶框架中的Lattice Planner轨迹规划算法,并提供了完整的Python代码实现。从Frenet坐标系转换、终端状态采样、五次多项式轨迹生成,到碰撞检测与代价评估,手把手教你构建一个核心功能完整的自动驾驶轨迹规划器,助力开发者深入理解并实践轨迹规划算法。

weixin_29054399的博客 497

apollo PlanOnReferenceLine函数

随着自动驾驶技术热,百度的开源工程apollo也更新到8.0版本,很多爱好者们也争相学习apollo工程。本文就从apollo8.0planning模块下的public_road_planner下边的lane_follow_stage.cc浅介绍PlanOnReferenceLine函数提示:以下是本篇文章正文内容,下面案例可供参考以上就是这篇介绍的内容,本文简单介绍了planonreferenceline函数的作用。

betterthanYSD的博客 523

Apollo规划模块基本原理学习笔记(1)

Apollo规划模块入门学习笔记1

weixin_39199083的博客 2672

Apollo 8.0 Lattice Planner算法解析与优化实践

路径规划是自动驾驶系统的核心技术之一,其核心任务是在动态环境中生成安全、舒适的行驶轨迹。Lattice Planner作为百度Apollo平台的核心算法模块,采用采样与优化相结合的混合式架构,通过分层处理机制将规划问题分解为参考线生成、路径采样、代价评估和轨迹优化四个阶段。该算法在Apollo 8.0中实现了40%的采样效率提升,主要得益于自适应采样密度策略和并行化计算架构。在实际工程应用中,Lattice Planner需要平衡实时性、安全性和舒适性等多维度要求,其代价函数设计包含7个关键维度,并支持基于

weixin_29047545的博客 32

Apollo规划模块代码学习(2): 轨迹规划流程理论基础详解(lane follow场景为例)

本文以具体场景Lane follow为例梳理具体的轨迹规划算法流程。详细介绍轨迹规划重要基础:Frenet坐标系列、路径规划速度规划、轨迹平滑算法原理。

qq_41667348的博客 4290

Apollo规划模块:lattice算法原理解析

Apollo规划模块以预测模块、routing模块、高精地图和定位的结果作为输入,输出一条平稳、舒适、安全的轨迹,下游交给控制模块去执行,由控制器完成对局部轨迹的跟踪控制。 Lattice算法属于规划模块,是一种局部轨迹规划器,输出是一条光滑无碰撞满足车辆运动学约束和速度约束的平稳安全的局部轨迹。输入端主要由三部分组成,感知及障碍物信息、参考线信息及定位信息。(预测模块、routing模块、高精地图和定位的结果)输出是带有位置、速度信息的一系列轨迹点组成的平稳、舒适、安全的轨迹。Lattice规划算法是一

qq_41667348的博客 6310

Apollo 8.0 Lattice规划算法解析与工程实践

自动驾驶规划算法是确保车辆安全高效行驶的核心技术,其核心原理是通过状态空间采样和轨迹优化生成可行路径。Lattice算法作为典型采样式规划方法,在Frenet坐标系下进行离散化采样,结合五次多项式轨迹拟合,实现计算效率与轨迹质量的平衡。该技术在Apollo 8.0中通过分层优化架构和GPU加速等工程实践,将计算耗时控制在10ms级,显著提升系统实时性。特别在高速公路巡航和城市结构化道路场景中,Lattice Planner展现出优异的障碍物避让和轨迹平滑能力。通过动态参考线优化和时空联合评估等创新,系统能有

weixin_29032337的博客 113

Apollo9.0 PNC源码学习之Planning模块—— Lattice规划(二):离散化参考线和寻找匹配点

本文详解了参考线的离散化和匹配点的寻找

BigDavid123的博客 1232

百度Apollo决策规划模块相关资料汇总

1.解析百度Apollo自动驾驶平台 2.解析百度Apollo之Routing模块 3.解析百度Apollo之决策规划模块 4.解析百度Apollo之参考线与轨迹 5.Apollo Planning模块源代码分析 6.Apollo 3.5 Planning模块源代码分析 7.apollo介绍之planning模块 8.apollo planning 的软件架构 9.apollo p...

思我所 2753

【笔记】自动驾驶预测与决策规划_Part3_路径与轨迹规划

路径与轨迹规划:基于搜索的路径规划、基于采样的路径规划、基于优化的路径规划

qq_39764867的博客 2892

Ansys Zemax | 多模光纤耦合效率优化与IMAE操作数实战解析

本文详细解析了在Ansys Zemax(OpticStudio)中优化多模光纤耦合效率的实战流程。通过几何图像分析诊断初始效率,并重点介绍了如何利用IMAE操作数将分析工具转化为自动化优化引擎,实现从2%到54%的几何效率飞跃。文章还探讨了引入菲涅尔损耗与偏振计算以逼近真实效率,并分享了关键的避坑指南与高阶技巧。

xk7n92h3p5m的博客 751

自动驾驶决策规划算法第二章——Apollo EM Planner理论篇

111

m0_62664599的博客 7976

C语言专升本编程题

湖南省专升本选拔考试,C语言程序设计内部习题

weixin_45729947的博客 2118

apollo规划部分

参考: 1.apollo介绍之planning模块(四) - 知乎 2.解析百度Apollo之决策规划模块 3.Baidu Apollo代码解析之Planning的结构与调用流程(1) - 知乎 4.Apollo 6.0 规划算法解析 - 知乎 规划部分 整体框架 可以看到规划(planning)模块的上游是Localization, Prediction, Routing模块,而下游是Control模块。Routing模块先规划出一条导航线路,然后Planning模块根据这条线路做局

sinat_39307513的博客 2787

微调大模型如何准备数据集——常用数据集,Alpaca和ShareGPT

在大模型微调中,我们一般使用Alpaca 和 ShareGPT和两种格式的数据集。

Science prince的博客 1097

DA14531之如何Debug(在线调试、Jlink仿真、串口打印)

在线调试和串口打印调试。在线调试是Keil软件配合Jlink编译、烧录、仿真为一体的,其操作包括:运行、停止、打断点,单步运行等。而串口打印调试,只需打开相关配置,让arch_printf()函数正常输出串口数据。若想在初始化完成后打印arch_printf(“goto Loop\r\n”);波特率为115200,接收到串口消息goto Loop。连好线后,点击仿真按钮,在线Jlink调试。

hejinwu1314的博客 1792

百度apollo自动驾驶planning代码学习-Apollo\modules\planning\common\ReferenceLineInfo类代码详解

Apollo planning 模块ReferenceLineInfo类代码详解

weixin_39199083的博客 4066

Unity大世界流式加载:工业级架构与优化秘籍

游戏大厂Unity大世界流式加载框架全景解析:从《原神》《和平精英》等标杆案例出发,深入剖析工业级流式加载的完整技术架构。文章系统介绍了大世界分区块管理、异步加载机制、资源优化策略、多平台适配方案,以及业务联动与团队协作流程。重点阐述了Addressable与AssetBundle应用、空间触发器设计、性能自适应等核心技术,并展望AI预测加载、云游戏等未来方向。全面展现了大厂如何通过流式加载技术实现无缝开放世界体验的技术路径与实践经验。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 609
上一篇: Python读取和处理mf4
IHTY_NUI
博客等级 码龄9年 606粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值