自动驾驶算法(十):多项式轨迹与Minimun Snap闭式求解原理及代码讲解

本文主要是介绍自动驾驶算法(十):多项式轨迹与Minimun Snap闭式求解原理及代码讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1 多项式轨迹与Minimun Snap闭式求解原理

2 代码解析


1 多项式轨迹与Minimun Snap闭式求解原理

        我们上次说的Minimun Snap,其实我们就在求一个二次函数的最优解:

        也就是优化函数p^TQp在约束Ap=b下的最小值。

        但这是一个渐进最优解而不是解析最优解,是否有一个解析最优解呢?

        我们用Ap = d的形式表达:(d表示每一段路程中的起点和终点的位置、速度、加速度),比如p_{1}(t_0),v_{1}(t_0),a_{1}(t_0),p_{1}(t_1),v_{1}(t_1),a_{1}(t_1)表示第一段起点的位置、速度、加速度、第一段终点的位置、速度、加速度。段数是k段,每段有起点和终点、起点终点有位置、速度加速度三个变量、因此维度为2*3k = 6k。      

        因此我们可以求出一个确定的p,带入 p^TQp后就计算出来了我们的最小值。

        A矩阵的维度就是一共有K段每段是n+1阶的参数,各个段的位置为6,因此维度为k(n+1) * 6K

                                                 A_{total} \begin{bmatrix} p_1\\p_2 \\... \\... \\p_k \end{bmatrix} = \begin{bmatrix} d_1\\d_2 \\... \\... \\d_k \end{bmatrix}

        更进一步的说:

        p = A^{-1}d就是我们要求解的方程。

        我们不妨先看一段,即第一段和第二段:p_i表示第i段。我画了个图:

        那么t^{(i)}这个时间点就是1段的末尾和2段的初始点。

        我们消除重复变量:

        我们一共是k+1个航路点,每个航路点有p、v、a。因此矩阵大小为3(k+1)。

        我们得到 d = Md'

        d' = C[dF dP]T,这里dF表示已知量,包括起点、终点的位移、速度、加速度,也包括中点间的已知量(我们要经过这些点)。dP表示未知量。我们可以看一个简单的例子:

        我们把它写到一起:

        我们就是dP未知,因此我们对dP求导,因此可以求出来dP的解析解。

        我们可以手动增加航路点避免碰撞:

        我们来总结一下闭式求解的步骤:

2 代码解析

        我们只讲解和上篇博客不一样的地方:

        我们先看一下运行结果:

        我们来进行代码复现:

function polys = minimum_snap_single_axis_close_form(wayp,ts,n_order,v0,a0,v1,a1)
% 参数个数 = 阶数+1
n_coef = n_order+1;
% 多项式的段数:航路点-1
n_poly = length(wayp)-1;
% 计算Q 和原来的一样
Q_all = [];
for i=1:n_polyQ_all = blkdiag(Q_all,computeQ(n_order,3,ts(i),ts(i+1)));
end

        这里依旧用n_coef表示参数个数(数量为拟合曲线的最大阶数+1),用n_poly表示多项式的段数,大小为航路点数量-1,Q的构造方式和上篇博客一致,不再赘述。

        我们来看闭式求解的步骤,我们先来计算A矩阵:

% compute A (n_continuous*2*n_poly) * (n_coef*n_poly)
n_continuous = 3;  % 1:p  2:pv  3:pva  4:pvaj  5:pvajs
% A的维度是 3*2*K(航路点个数) 阶数(N+1) * K
A = zeros(n_continuous*2*n_poly,n_coef*n_poly);
% 遍历每一段航路点
for i = 1:n_poly% 位置、速度、加速度for j = 1:n_continuous% 计算具体参数 j--参数个数(阶数+1)for k = j:n_coefif k==jt1 = 1;t2 = 1;else %k>jt1 = tk(i,k-j+1);t2 = tk(i+1,k-j+1);end% 每一段填充首和尾A(n_continuous*2*(i-1)+j,n_coef*(i-1)+k) = prod(k-j+1:k-1)*t1;A(n_continuous*2*(i-1)+n_continuous+j,n_coef*(i-1)+k) = prod(k-j+1:k-1)*t2;endend
end

        我们知道,如果我们的航路点是K段,我们要拟合多项式的次数为N。因此我们的A矩阵大小为航路点为K段,每段的话有起终点、每个起终点有X、V、A三个元素,因此我们的矩阵大小为 K*2*3 * (N+1)*K。

        先给它初始化为0。我们遍历每一段航路点,先计算这段航路点的位移、速度、加速度。

        然后我们计算M矩阵:

M = zeros(n_poly*2*n_continuous,n_continuous*(n_poly+1));
for i = 1:n_poly*2j = floor(i/2)+1;rbeg = n_continuous*(i-1)+1;cbeg = n_continuous*(j-1)+1;M(rbeg:rbeg+n_continuous-1,cbeg:cbeg+n_continuous-1) = eye(n_continuous);
end
M

        计算C矩阵和K矩阵:

% compute C
num_d = n_continuous*(n_poly+1);
C = eye(num_d);
df = [wayp,v0,a0,v1,a1]';% fix all pos(n_poly+1) + start va(2) + end va(2) 
fix_idx = [1:3:num_d,2,3,num_d-1,num_d];
free_idx = setdiff(1:num_d,fix_idx);
C = [C(:,fix_idx) C(:,free_idx)];% K
AiMC = inv(A)*M*C;
R = AiMC'*Q_all*AiMC;n_fix = length(fix_idx);
Rff = R(1:n_fix,1:n_fix);
Rpp = R(n_fix+1:end,n_fix+1:end);
Rfp = R(1:n_fix,n_fix+1:end);
Rpf = R(n_fix+1:end,1:n_fix);

        计算p恢复轨迹、位置、加速度:

dp = -inv(Rpp)*Rfp'*df;p = AiMC*[df;dp];polys = reshape(p,n_coef,n_poly);

这篇关于自动驾驶算法(十):多项式轨迹与Minimun Snap闭式求解原理及代码讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/650189

相关文章

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Django开发时如何避免频繁发送短信验证码(python图文代码)

《Django开发时如何避免频繁发送短信验证码(python图文代码)》Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑... 目录避免频繁发送 验证码1. www.chinasem.cn避免频繁发送 验证码逻辑分析2. 避免频繁

精选20个好玩又实用的的Python实战项目(有图文代码)

《精选20个好玩又实用的的Python实战项目(有图文代码)》文章介绍了20个实用Python项目,涵盖游戏开发、工具应用、图像处理、机器学习等,使用Tkinter、PIL、OpenCV、Kivy等库... 目录① 猜字游戏② 闹钟③ 骰子模拟器④ 二维码⑤ 语言检测⑥ 加密和解密⑦ URL缩短⑧ 音乐播放

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

SQL Server跟踪自动统计信息更新实战指南

《SQLServer跟踪自动统计信息更新实战指南》本文详解SQLServer自动统计信息更新的跟踪方法,推荐使用扩展事件实时捕获更新操作及详细信息,同时结合系统视图快速检查统计信息状态,重点强调修... 目录SQL Server 如何跟踪自动统计信息更新:深入解析与实战指南 核心跟踪方法1️⃣ 利用系统目录

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

RabbitMQ消费端单线程与多线程案例讲解

《RabbitMQ消费端单线程与多线程案例讲解》文章解析RabbitMQ消费端单线程与多线程处理机制,说明concurrency控制消费者数量,max-concurrency控制最大线程数,prefe... 目录 一、基础概念详细解释:举个例子:✅ 单消费者 + 单线程消费❌ 单消费者 + 多线程消费❌ 多

MyBatis-Plus 自动赋值实体字段最佳实践指南

《MyBatis-Plus自动赋值实体字段最佳实践指南》MyBatis-Plus通过@TableField注解与填充策略,实现时间戳、用户信息、逻辑删除等字段的自动填充,减少手动赋值,提升开发效率与... 目录1. MyBATis-Plus 自动赋值概述1.1 适用场景1.2 自动填充的原理1.3 填充策略

在MySQL中实现冷热数据分离的方法及使用场景底层原理解析

《在MySQL中实现冷热数据分离的方法及使用场景底层原理解析》MySQL冷热数据分离通过分表/分区策略、数据归档和索引优化,将频繁访问的热数据与冷数据分开存储,提升查询效率并降低存储成本,适用于高并发... 目录实现冷热数据分离1. 分表策略2. 使用分区表3. 数据归档与迁移在mysql中实现冷热数据分