自动驾驶之轨迹规划8——Apollo参考线和轨迹
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
相关文章:
自动驾驶之轨迹规划8——Apollo参考线和轨迹
1. abstract 本文主要讲解routing和planning模块中的reference line,我之前一直搞不明白这个reference line是如何生成的,有什么作用,和routing以及planning的关系。现在有了一些心得打算梳理一下: 决策规划模块负责生成车辆的行…...
ES6 - promise.all和race方法的用法详解
文章目录 一、前言二、Promise.all()1,第一句:Promise.all()方法接受一个数组作为参数,且每一个都是 Promise 实例2,第二句:如果不是,就会先调Promise.resolve方法,将参数转为 Promise 实例再进…...
CAD .NET 15.0 企业版 Crack
CAD .NET 15.0 企业版 企业版 企业版 企业版 企业版 Updated: June 14, 2023 | Version 15.0 NEW CAD .NET is a library for developing solutions in .NET environment. It supports AutoCAD DWG/ DXF, PLT and other CAD formats. The library can be used in a wide rang…...
苍穹外卖day07——缓存菜品套餐+购物车功能实现
缓存菜品——需求设计与分析 问题说明 用户访问量过大带来的一个直接效果就是响应速度慢,使用体验下降。 实现思路 使用redis缓存菜品数据,减少数据库查询操作。 页面展示上基本就是同一个分类在同一页,所以key-value结构可以使用不同的分…...
学习笔记|大模型优质Prompt开发与应用课(二)|第四节:大模型帮你写代码,小白也能做程序
文章目录 01软件开发产业趋势与技术革新软件开发产业趋势与技术革新技术性人才很受欢迎软件开发产业趋势与技术革新技术门槛越来越低 02 大模型驱动的软件开发需求分析prompt 产品设计开发和测试prompt输出回复promptpromptprompt回复 发布和部署promptprompt 维护和更新prompt…...
建造者设计模式 + 高阶函数 => DSL
该设计模式适用于创建复杂对象,该复杂对象通常是由各个部分的子对象用一定的算法或者步骤构成,针对每个子对象内部算法和步骤通常是稳定的,但是该复杂对象的确实由于不同的需求而选择使用不同的子对象进行组装。对于构建该复杂的对象…...
重学C++系列之智能指针简单介绍
一、什么是智能指针 在使用堆内存时,就像使用栈内存空间一样,可以实现自释放的功能,智能指针在C库中也是类模板之一。 二、智能指针有几种 有四种。auto_ptr, unique_ptr, shared_ptr, weak_ptr 其中后三个是C11支持,第一个已经被…...
LabVIEW开发航天器动力学与控制仿真系统
LabVIEW开发航天器动力学与控制仿真系统 计算机仿真是工程设计和验证的非常有用的工具。它节省了大量的时间、金钱和精力。航天器动力学与控制仿真系统由LabVIEW程序开发,它是模拟航天器等动态系统的有用工具。还可轻松与硬件连接并输出真实信号。 项目采用系统工…...
享元模式——实现对象的复用
1、简介 1.1、概述 当一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题。例如,在一个文本字符串中存在很多重复的字符,如果每个字符都用一个单独的对象来表示,将会占用较多的内存…...
【GreenDao】关联表实现,父表关联多个子表
要在GreenDao中实现温湿度采集器表和采集数据表的关联,并在删除温湿度表时同时删除对应的采集数据,可以按照以下步骤进行操作: 在GreenDao的实体类中定义温湿度采集器表(Parent Table)和采集数据表(Child …...
python网站创建005:数据交互
目标:本章讲解不同控件下, 数据在前端和后端之间的交互 控件有: 输入框 密码输入框 单选框 多选框 下拉框 多行文本框 不同控件中如何将数据传入后端?请看一下html代码 <!DOCTYPE html> <html> <head><meta …...
golang 字符串操作、处理
一、golang的字符串长度 1. len()内置系统函数,计算字符串结果是字符串的字节长度,不是字符长度 //1.ASCII字符串长度(字节长度) str1 : "wo ai zhong guo" fmt.Println(len(str1)) //15//2.带中文的字符串长度&…...
Nginx配置WebSocket反向代理
1、WebSocket协议 WebSocket协议相比较于HTTP协议成功握手后可以多次进行通讯,直到连接被关闭。但是WebSocket中的握手和HTTP中的握手兼容,它使用HTTP中的Upgrade协议头将连接从HTTP升级到WebSocket。这使得WebSocket程序可以更容易的使用现已存在的…...
devops(后端)
1.前言 该devpos架构为gitlabjenkinsharbork8s,项目是java项目,流程为从gitlab拉取项目代码到jenkins,jenkins通过maven将项目代码打成jar包,通过dockerfile构建jdk环境的镜像并把jar包放到镜像中启动,构建好的镜像通…...
Ubuntu安装企业微信
Ubuntu安装企业微信_ubuntu下安装企业微信_星光2020的博客-CSDN博客 在Ubuntu环境安装企业微信可以参考 https://github.com/zq1997/deepin-wine 所述的方法 首先运行 $ wget -O- https://deepin-wine.i-m.dev/setup.sh | sh 然后就可以像安装其它软件一样安装企业微信或其它…...
Prometheus 的应用服务发现及黑河部署等
目录 promtool检查语法 部署Prometheus Server 检查语法是否规范 部署node-exporter 部署Consul 直接请求API进行服务注册 使用register命令注册服务(建议使用) 单个和多个注册,多个后面多加了s 在Prometheus上做consul的服务发现 部署…...
JAVA SE -- 第十二天
(全部来自“韩顺平教育”) 常用类 一、包装类 1、包装类的分类 ①针对八种基本数据类型相应的引用类型--包装类 ②有了类的特点,就可以调用类中的方法 ③ 基本数据类型包装类booleanBooleancharCharacterbyteByteshortShortintInteger…...
实战:工作中对并发问题的处理
大家好,我是 方圆。最近在接口联调时发生了数据并发修改问题,我想把这个问题讲解一下,并把当时提出的解决方案进行实现,希望它能在大家以后在遇到同样的问题时提供一些借鉴和思考的方向。原文还是收录在我的 Github: enthusiasm 中…...
腾讯云Cloud Studio:基于Claude快速完成Excel工资自动核算
目录 1 什么是Cloud Studio?2 注册与代码管理2.1 账号注册2.2 Git关联 3 实战:Excel工资自动核算3.1 创建项目与配置3.2 “念咒师”Claude GPT3.3 代码编写与运行 1 什么是Cloud Studio? Cloud Studio是腾讯云为开发者提供的一个基于浏览器的…...
Spring Boot OAuth2 快速入门示例
系统要求 Spring Authorization Server 需要JDK1.8及以上版本。 项目搭建 使用在线项目初始化器 https://start.spring.io/ 生成项目[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ljKbMI4H-1690726855433)(images/screenshot_1690602511482.png)…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...
医疗AI模型可解释性编程研究:基于SHAP、LIME与Anchor
1 医疗树模型与可解释人工智能基础 医疗领域的人工智能应用正迅速从理论研究转向临床实践,在这一过程中,模型可解释性已成为确保AI系统被医疗专业人员接受和信任的关键因素。基于树模型的集成算法(如RandomForest、XGBoost、LightGBM)因其卓越的预测性能和相对良好的解释性…...
