基于Frenet优化轨迹的⾃动驾驶动作规划⽅法

news/2024/4/27 8:00:56/文章来源:https://blog.csdn.net/soaring_casia/article/details/129205390

动作规划(Motion Control)在⾃动驾驶汽⻋规划模块的最底层,它负责根据当前配置和⽬标配置⽣成⼀序列的动作,本⽂介绍⼀种基于Frenet坐标系的优化轨迹动作规划⽅法,该⽅法在⾼速情况下的ACC辅助驾驶和⽆⼈驾驶都具有较强的实⽤性,是⽬前普遍采⽤的⼀种动作规划算法。

基于Frenet坐标系的动作规划⽅法是由宝⻢的Moritz Werling提出的,为了简便,我们在后⽂中也会使⽤Werling⽅法简称。

在讨论基于Frenet坐标系的动作规划⽅法之前,⾸先定义什么是最优的动作序列:对于横向控制⽽⾔,假定由于⻋辆因为之前躲避障碍物或者变道或者其他制动原因⽽偏离了期望的⻋道线,那么此时最优的动作序列(或者说轨迹)是在⻋辆制动能⼒的限制下,相对最安全,舒适,简单和⾼效的轨迹。

同样的,纵向的最优轨迹也可以这么定义:如果⻋辆此时过快,或者太接近前⽅⻋辆,那么就必须做减速,具体什么是“舒适⽽⼜简单的”减速呢?

我们可以使⽤ Jerk 这个物理量来描述,Jerk即加速度的变化率,也即加加速度,通常来说,过⾼的加加速度会引起乘坐者的不适,所以,从乘坐舒适性⽽⾔,应当优化Jerk这个量,同时,引⼊轨迹的制动周期 T , 即⼀个制动的操作时间:

1

为什么使⽤Frenet坐标系

在Frenet坐标系中,使⽤道路的中⼼线作为参考线,使⽤参考线的切线向量t和法线向量n建⽴⼀个坐标系,如下图的右图所⽰,这个坐标系即为Frenet坐标系,它以⻋辆⾃⾝为原点,坐标轴相互垂直,分为s⽅向(即沿着参考线的⽅向,通常被称为纵向,Longitudinal)和d⽅向(即参考线当前的法向,被称为横向,Lateral)

相⽐于笛卡尔坐标系(下图的左图),Frenet坐标系明显地简化了问题,因为在公路⾏驶中,我们总是能够简单的找到道路的参考线(即道路的中⼼线),那么基于参考线的位置的表⽰就可以简单的使⽤纵向距离(即沿着道路⽅向的距离)和横向距离(即偏离参考线的距离)来描述,同样的,两个⽅向的速度

的计算也相对简单。

那么现在动作规划问题中的配置空间就⼀共有三个维度:

是规划出来的每⼀个动作的时间点,轨迹和路径的本质区别就是轨迹考虑了时间这⼀维度。Werling的动作规划⽅法⼀个很关键的理念就是将动作规划这⼀⾼维度的优化问题分割成横向和纵向两个⽅向上的彼此独⽴的优化问题,具体来看下⾯的图:

假设⾏为规划层要求当前⻋辆在

越过虚线完成⼀次变道,即⻋辆在横向上需要完成⼀个

以及纵向上完成⼀个 的移动,则可以将s和d分别表⽰为关于t的函数:

(上图右图),那么d,s关于时间t的最优轨迹应该选择哪⼀条呢?

通过这种转换原来的动作规划问题被分割成了两个独立的优化问题,对于横向和纵向的轨迹优化,我们选取损失函数C,将使得C最⼩的轨迹作为最终规划的动作序列。而Werling方法中损失函数的定义,则与我们前⾯提到的加加速度 Jerk 相关。

2

Jerk最⼩化和5次轨迹多项式求解

由于我们将轨迹优化问题分割成了s和d两个⽅向,所以Jerk最⼩化可以分别从横向和纵向进⾏,令p为我们考量的配置(即s或d),加加速度

关于配置p在时间段

内累计的Jerk的表达式为:

现在我们的任务是找出能够使得

,Takahashi的⽂章motion control for AGV in positioning中已经证明,任何Jerk最优化问题中的解都可以使⽤⼀个5次多项式来表⽰:

要解这个⽅程组需要⼀些初始配置和⽬标配置,以横向路径规划为例,初始配置为

,即

时刻⻋辆的横向偏移,横向速度和横向加速度为

,即可得⽅程组:

为了区分横向和纵向,我们使⽤

来分别表⽰d和s⽅向的多项式系数,同理,根据横向的⽬标配置

可得⽅程组:

该⽅程的解可以通过Python的Numpy中的 np.linalg.solve简单求得。⾄此,我们在给定任意的初始配置

,⽬标配置

以及制动时间T的情况下,可以求的对应的d⽅向关于时间t的五次多项式的系数,同理,可以使⽤相同的⽅法来求解纵向(即s⽅向)的五次多项式系数。那么问题来了,我们如何去确定最优的轨迹呢?

Werling⽅法的思路是通过⼀组⽬标配置来求得轨迹的备选集合,然后在备选集合中基于Jerk最⼩化的原则选择最优轨迹 ,我们仍然以d⽅向的优化轨迹为例讲解:

我们可以取如下⽬标配置集合来计算出⼀组备选的多项式集合:

对于优化问题⽽⾔,我们实际上希望⻋辆最终沿着参考线(道路中⼼线)平⾏的⽅向⾏驶,所以我们令

,那么⽬标配置只涉及

两个变量的组合,⽽这两个变量在⽆⼈驾驶的应⽤场景中实际上是受限的,我们可以通过定义

来约束⽬标配置的取值范围,通过 和 来限制采样密度,从⽽在每⼀个制动周期获得⼀个有限的备选轨迹集合,如下图所⽰:

要在备选集合中选择最优轨迹(即上图中的绿⾊轨迹),我们需要设计损失函数,对于不同的场景,损失函数也不相同,以横向轨迹为例,在较⾼速度的情况下,损失函数为:

该损失函数包含三个惩罚项:

其中

是这三个惩罚项的系数,它们的⽐值⼤⼩决定了我们的损失函数更加注重哪⼀个⽅⾯的优化,由此我们可以算出所有备选轨迹的损失,取损失最⼩的备选轨迹作为我们最终的横向轨迹。

值得注意的是,以上的损失函数仅适⽤于相对⾼速度的场景,在极端低速的情况下,⻋辆的制动能⼒是不完整的,我们不再将d表⽰为关于时间t的五次多项式,损失函数也会略有不同,但是这种基于有限采样轨迹,通过优化损失函数搜索最优轨迹的⽅法仍然是⼀样的,在此不再赘述。

讨论完横向的轨迹优化问题,我们再来看看纵向的轨迹优化,在不同的场景下纵向轨迹的优化的损失函数也各不相同,Werling⽅法中将纵向轨迹的优化场景⼤致分成如下三类:

  • 跟⻋

  • 汇流和停⻋

  • ⻋速保持

在本⽂中我们详细了解⻋速保持场景下的纵向轨迹优化,在⾼速公路等应⽤场景中,⽬标配置中并不需要考虑⽬标位置(即 ),所以在该场景下,⽬标配置仍然是 ,⽬标配置变成了 ,损失函数为:

其中 是我们想要保持的纵向速度,第三个惩罚项的引⼊实际上是为了让⽬标配置中的纵向速度尽可能接近设定速度,该情景下的⽬标配置集为:

即优化过程中的可变参数为

,同样,也可以通过设置

来设置轨迹采样的密度,从⽽获得⼀个有限的纵向轨迹集合:

其中,绿线即为纵向最优轨迹。以上我们分别讨论了横向和纵向的最优轨迹搜索⽅法,在应⽤中,我们将两个⽅向的损失函数合并为⼀个,即:

这样,我们就可以通过最⼩化

得到优化轨迹集合(我们不能得到“最优”的轨迹多项式参数,还可以得到“次优”,“次次优”轨迹等等)。

3

事故避免

(Collision Avoiding)

显然,上⾯的轨迹优化损失函数中并没有包含关于障碍物躲避的相关惩罚,并且我们的损失函数中也没有包含最⼤速度,最⼤加速度和最⼤曲率等制动限制,也就是说我们的优化轨迹集合并没有考虑障碍物规避和制动限制因素,不将障碍物避免加⼊到损失函数中的⼀个重要的原因在于碰撞惩罚项的引⼊将代⼊⼤量需要⼈⼯调整的参数(即权重),是的损失函数的设计变得复杂 ,Werling⽅法将这些因素的考量独⽴出来,在完成优化轨迹以后进⾏。

具体来说,我们会在完成所有备选轨迹的损失计算以后进⾏⼀次轨迹检查,过滤掉不符合制动限制的,可能碰撞障碍物的轨迹,检查内容包括:

  • s⽅向上的速度是否超过设定的最⼤限速

  • s⽅向的加速度是否超过设定的最⼤加速度

  • 轨迹的曲率是否超过最⼤曲率

  • 轨迹是否会引起碰撞(事故)

通常来说,障碍物规避⼜和⽬标⾏为预测等有关联,本⾝即使⼀个复杂的课题,⾼级⾃动驾驶系统通常具备对⽬标⾏为的预测能⼒,从⽽确定轨迹是否会发⽣事故。

在本节中,我们关注的重点是⾃动驾驶汽Ctotal =klat Cd +k C lonsC total⻋的动作规划,故后⾯的实例仅涉及静态障碍物的规避和动作规划。

4

基于Frenet优化轨迹的

⾃动驾驶汽⻋动作规划实例

由于planner的代码篇幅过⻓,本实例完整代码请⻅⽂末链接,在此仅讲解算法核⼼代码内容。和之前⼀样,我们仍然使⽤Python来实现该动作规划算法。⾸先,我们⽣成要追踪的参考线以及静态障碍物,参考线的⽣成只要使⽤了我们上⼀节提到的⽴⽅样条插值,代码如下:

⽣成如下参考路径以及障碍物:

其中红线就是我们的全局路径,蓝点为障碍物。定义⼀些参数:

使⽤基于Frenet的优化轨迹⽅法⽣成⼀系列横向和纵向的轨迹,并且计算每条轨迹对应的损失:

其中,⼀个重要的类是五次多项式类,其定义如下:

这⾥的五次多项式的系数的求解过程和我们前⾯的理论讲解是⼀样的,只不过我们使⽤Numpy中的 np.linalg.solve(A, b)⽅法将矩阵解了出来。最后,我们来看⼀下障碍物规避是如何实现的:

由于我们将障碍物规避问题都简化为静态了,所以在这⾥我们只简单地计算了所有规划点到障碍物的距离,⼀句距离预计是否会发⽣碰撞,来看看完整的优化轨迹检查函数:

由此可以看出,最终的优化轨迹的选择并不单纯基于最⼩损失函数,轨迹检查还会过滤掉⼀些轨迹,所以使⽤基于Frenet的优化轨迹来做⾃动驾驶汽⻋的动作规划,通常能够找到有限集的最优解,当最优解⽆法通过检查是,⾃会采⽤“次优解”甚⾄更加“次优的”解。最后我们来看⼀下完整的动作规划效果:

后台回复“21”领取完整代码~

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2023年,尽量还是别裸辞了吧···

你知道什么叫 度日如年 吗?就是在家待业的每一天。你知道什么叫心焦如焚吗?就是投出100份简历却等不来一个回应。 当前就业环境,裁员、失业消息满天飞,好像能有一份工作就不错了,更别说高薪。其实这只是一方面。另一方…

基于BP神经网络的性别识别,BP神经网络详细原理,自编码神经网络代码,神经网络案例之18

目标 背影 BP神经网络的原理 BP神经网络的定义 BP神经网络的基本结构 BP神经网络的神经元 BP神经网络的激活函数, BP神经网络的传递函数 数据 神经网络参数 基于BP神经网络 性别识别的MATLAB代码 效果图 结果分析 展望 背影 男人体内蛋白质比例大,女生…

网易的“草长莺飞二月天”:增长稳健,加码研发,逐浪AI

2月23日,网易发布了2022年第四季度财报。 这是网易与暴雪分道扬镳后的首份财报,加上近期AIGC热度扩散至游戏、教育等各个领域,网易第四季度业绩及其对于GPT等热门技术的探索受到市场关注。 根据财报,第四季度,网易营…

SAFe(Scaled Agile Framework)学习笔记

1.SAFe 概述 SAFe(Scaled Agile Framework)是一种面向大型企业的敏捷开发框架,旨在协调多个团队和部门的协同工作,以实现高效的软件开发和交付。下面是SAFe框架的简单介绍总结: SAFe框架包括以下四个层次&#xff1a…

【LVGL】学习笔记--(1)Keil中嵌入式系统移植LVGL

一 LVGL简介最近emwin用的比较烦躁,同时被LVGL酷炫的界面吸引到了,所以准备换用LVGL试试水。LVGL(轻量级和通用图形库)是一个免费和开源的图形库,它提供了创建嵌入式GUI所需的一切,具有易于使用的图形元素,美丽的视觉效…

Unable to connect to Redis无法连接到Redis

文章目录项目场景:问题描述原因分析:解决方案:项目场景: 提示:这里简述项目相关背景: 在某个项目中的提交按钮不好用 org.springframework.data.redis.RedisConnectionFailureException: Unable to con…

程序员必备的软技能-金字塔原理拆解(上)

原书 290千字,本文预计 14千字,拆解比 20:1,预计阅读时长 15分钟序言日常工作中,常常因为思维、表达方式不对产生不想要的结果:写了一个小时的周报,领导却不满意?跟团队讲了半天自己…

go module构建项目

在go 1.11版本中引入了Go Module内置的包管理模块,是GOPATH的替代品,集成了版本控制和软件包分发支持的功能。即go使用modules管理依赖,项目依赖构建时不需要再依赖GOPATH环境变量。 要使用go module首先要激活modules .升级go到1.11版本 .这…

Mac电脑_GitHub提交项目至仓库

第一步(准备工作): Mac 电脑自带 git , 无需安装 1. 创建一个项目 demo1 在 github 上 2. 创建 ssh 密钥 打开终端: ssh-keygen -t rsa -C "your_emailyouremail.com" 此处输入两次密码, 直接…

MyBatis-常用SQL操作

一、动态SQL 1.概述】 1.1动态SQL: 是 MyBatis 的强大特性之一,解决拼接动态SQL时候的难题,提高开发效 1.2分类: if choose(when,otherwise) trim(where,set) foreach 2.if 2.1 做 where 语句后面条件查询的,if 语句是可以…

【Java基础 下】 027 -- 异常、File、综合案例

目录 一、异常 1、异常的分类 ①、Error ②、Exception ③、小结 2、编译时异常和运行时异常 ①、编译时异常 ②、运行时异常 ③、为什么异常要分成编译时异常和运行时异常? ④、小结(运行时异常和编译时异常的区别) 3、异常的作用 ①、查看b…

WindowsPowerShell 停止、启动、暂停和重启服务、卸载服务

PowerShell 停止、启动、暂停和重启服务、卸载服务 PowerShell 停止、启动、暂停和重启服务 官文 powershell卸载服务 官文 目录PowerShell 停止、启动、暂停和重启服务、卸载服务停止、启动、暂停和重启停止服务启动服务暂停服务重启服务卸载移除服务停止、启动、暂停、重启…

4EVERLAND:ERC-721 Token的存储选择

4EVERLAND:一个 Web3 基础设施,可促进项目更轻松、更快速地托管前端、存储数据/NFT/文件,并在 IPFS、Arweave 和 Dfinity 之上访问它们。 NFT , 数字所有权 使用以太坊标准的 NFT 创新ERC-721解决了互联网内容的主要问题之一:所…

想成为一名专业黑客,但不知道从哪里学起?我来教你。

成为一名黑客需要学什么? 想成为一名专业黑客,但不知道从哪里学起”很多人在后台问过这个问题,今天就为你介绍成为专业黑客必须学习的十个方面的知识,希望能为迷惘中的你指明方向。 想要成为网络hacker黑客?先来学习…

测试员拿到新项目怎么着手测试?不要慌,照做准没错

一、目标 结合公司现有的项目情况制定合理规范的测试流程,提高测试效率和产品质量,尽可能减少客户对产品的问题反馈, 核心还是要加强项目组成员之间的工作交流和沟通,保证整个项目的高效率的按质按量的交付。 二、测试流程说明…

【Unity VR开发】结合VRTK4.0:创建物理按钮

语录: 如今我努力奔跑,不过是为了追上那个曾经被寄予厚望的自己 前言: 使用线性关节驱动器和碰撞体从动器可以轻松创建基于物理的按钮,以使交互者能够在物理上按下按钮控件,然后挂钩到驱动器事件中以了解按钮何时被按…

【PyQt5图形界面编程(2)】:创建工程

创建工程 一、创建工程二、开始开发1、运行Qt5Designer,创建QT窗口2、运行pyUIC,转换xx.ui成xx.py3、main.py中引用xx.py中的类4、打包main.py成main.exe来发布5、执行终端报警处理方法三、其他(如果涉及)1、配置环境变量一、创建工程 采用虚拟环境来创建工程 相关的paka…

MyBatis学习笔记(五) —— MyBatis获取参数值的两种方式

5、MyBatis获取参数值的两种方式 MyBatis获取参数值的两种方式:${} 和 #{} ${} 的本质就是字符串拼接, #{} 的本质就是占位符赋值 ${} 使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号&a…

SpringBoot整合阿里云OSS文件上传、下载、查看、删除

SpringBoot整合阿里云OSS文件上传、下载、查看、删除1、开发准备1.1 前置知识1.2 环境参数1.3 你能学到什么2. 使用阿里云OSS2.1 创建Bucket2.2 管理文件2.3 阿里云OSS文档3. 项目初始化3.1 创建SpringBoot项目3.2 Maven依赖3.3 安装lombok插件4. 后端服务编写4.1 阿里云OSS配置…

4面美团软件测试工程师,却忽略了这一点,直接让我前功尽弃

说一下我面试别人时候的思路 反过来理解,就是面试时候应该注意哪些东西;用加粗部分标注了 一般面试分为这么几个部分: 一、自我介绍 这部分一般人喜欢讲很多,其实没必要。大约5分钟内说清楚自己的职业经历,自己的核…