当前位置: 首页 > news >正文

自动驾驶之轨迹规划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实现中,逻辑计算的基础数据结构,很多操作都会在这个数据结构上进行(例如:交通规则逻辑,障碍物投影,路径优化,速度决策等)。本文中的“参考线”一词将不区分ReferenceLineReferenceLineInfo两个结构。
  • 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&#xff0c;我之前一直搞不明白这个reference line是如何生成的&#xff0c;有什么作用&#xff0c;和routing以及planning的关系。现在有了一些心得打算梳理一下&#xff1a; 决策规划模块负责生成车辆的行…...

ES6 - promise.all和race方法的用法详解

文章目录 一、前言二、Promise.all()1&#xff0c;第一句&#xff1a;Promise.all()方法接受一个数组作为参数&#xff0c;且每一个都是 Promise 实例2&#xff0c;第二句&#xff1a;如果不是&#xff0c;就会先调Promise.resolve方法&#xff0c;将参数转为 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——缓存菜品套餐+购物车功能实现

缓存菜品——需求设计与分析 问题说明 用户访问量过大带来的一个直接效果就是响应速度慢&#xff0c;使用体验下降。 实现思路 使用redis缓存菜品数据&#xff0c;减少数据库查询操作。 页面展示上基本就是同一个分类在同一页&#xff0c;所以key-value结构可以使用不同的分…...

学习笔记|大模型优质Prompt开发与应用课(二)|第四节:大模型帮你写代码,小白也能做程序

文章目录 01软件开发产业趋势与技术革新软件开发产业趋势与技术革新技术性人才很受欢迎软件开发产业趋势与技术革新技术门槛越来越低 02 大模型驱动的软件开发需求分析prompt 产品设计开发和测试prompt输出回复promptpromptprompt回复 发布和部署promptprompt 维护和更新prompt…...

建造者设计模式 + 高阶函数 => DSL

该设计模式适用于创建复杂对象&#xff0c;该复杂对象通常是由各个部分的子对象用一定的算法或者步骤构成&#xff0c;针对每个子对象内部算法和步骤通常是稳定的&#xff0c;但是该复杂对象的确实由于不同的需求而选择使用不同的子对象进行组装。对于构建该复杂的对象&#xf…...

重学C++系列之智能指针简单介绍

一、什么是智能指针 在使用堆内存时&#xff0c;就像使用栈内存空间一样&#xff0c;可以实现自释放的功能&#xff0c;智能指针在C库中也是类模板之一。 二、智能指针有几种 有四种。auto_ptr, unique_ptr, shared_ptr, weak_ptr 其中后三个是C11支持&#xff0c;第一个已经被…...

LabVIEW开发航天器动力学与控制仿真系统

LabVIEW开发航天器动力学与控制仿真系统 计算机仿真是工程设计和验证的非常有用的工具。它节省了大量的时间、金钱和精力。航天器动力学与控制仿真系统由LabVIEW程序开发&#xff0c;它是模拟航天器等动态系统的有用工具。还可轻松与硬件连接并输出真实信号。 项目采用系统工…...

享元模式——实现对象的复用

1、简介 1.1、概述 当一个软件系统在运行时产生的对象数量太多&#xff0c;将导致运行代价过高&#xff0c;带来系统性能下降等问题。例如&#xff0c;在一个文本字符串中存在很多重复的字符&#xff0c;如果每个字符都用一个单独的对象来表示&#xff0c;将会占用较多的内存…...

【GreenDao】关联表实现,父表关联多个子表

要在GreenDao中实现温湿度采集器表和采集数据表的关联&#xff0c;并在删除温湿度表时同时删除对应的采集数据&#xff0c;可以按照以下步骤进行操作&#xff1a; 在GreenDao的实体类中定义温湿度采集器表&#xff08;Parent Table&#xff09;和采集数据表&#xff08;Child …...

python网站创建005:数据交互

目标&#xff1a;本章讲解不同控件下&#xff0c; 数据在前端和后端之间的交互 控件有&#xff1a; 输入框 密码输入框 单选框 多选框 下拉框 多行文本框 不同控件中如何将数据传入后端&#xff1f;请看一下html代码 <!DOCTYPE html> <html> <head><meta …...

golang 字符串操作、处理

一、golang的字符串长度 1. len()内置系统函数&#xff0c;计算字符串结果是字符串的字节长度&#xff0c;不是字符长度 //1.ASCII字符串长度&#xff08;字节长度&#xff09; str1 : "wo ai zhong guo" fmt.Println(len(str1)) //15//2.带中文的字符串长度&…...

Nginx配置WebSocket反向代理

1、WebSocket协议 ​ WebSocket协议相比较于HTTP协议成功握手后可以多次进行通讯&#xff0c;直到连接被关闭。但是WebSocket中的握手和HTTP中的握手兼容&#xff0c;它使用HTTP中的Upgrade协议头将连接从HTTP升级到WebSocket。这使得WebSocket程序可以更容易的使用现已存在的…...

devops(后端)

1.前言 该devpos架构为gitlabjenkinsharbork8s&#xff0c;项目是java项目&#xff0c;流程为从gitlab拉取项目代码到jenkins&#xff0c;jenkins通过maven将项目代码打成jar包&#xff0c;通过dockerfile构建jdk环境的镜像并把jar包放到镜像中启动&#xff0c;构建好的镜像通…...

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命令注册服务&#xff08;建议使用&#xff09; 单个和多个注册&#xff0c;多个后面多加了s 在Prometheus上做consul的服务发现 部署…...

JAVA SE -- 第十二天

&#xff08;全部来自“韩顺平教育”&#xff09; 常用类 一、包装类 1、包装类的分类 ①针对八种基本数据类型相应的引用类型--包装类 ②有了类的特点&#xff0c;就可以调用类中的方法 ③ 基本数据类型包装类booleanBooleancharCharacterbyteByteshortShortintInteger…...

实战:工作中对并发问题的处理

大家好&#xff0c;我是 方圆。最近在接口联调时发生了数据并发修改问题&#xff0c;我想把这个问题讲解一下&#xff0c;并把当时提出的解决方案进行实现&#xff0c;希望它能在大家以后在遇到同样的问题时提供一些借鉴和思考的方向。原文还是收录在我的 Github: enthusiasm 中…...

腾讯云Cloud Studio:基于Claude快速完成Excel工资自动核算

目录 1 什么是Cloud Studio&#xff1f;2 注册与代码管理2.1 账号注册2.2 Git关联 3 实战&#xff1a;Excel工资自动核算3.1 创建项目与配置3.2 “念咒师”Claude GPT3.3 代码编写与运行 1 什么是Cloud Studio&#xff1f; Cloud Studio是腾讯云为开发者提供的一个基于浏览器的…...

Spring Boot OAuth2 快速入门示例

系统要求 Spring Authorization Server 需要JDK1.8及以上版本。 项目搭建 使用在线项目初始化器 https://start.spring.io/ 生成项目[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ljKbMI4H-1690726855433)(images/screenshot_1690602511482.png)…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...