第七篇(下),MPC工程化总结

2023-05-16

目录

一、引言

二、MPC的理解与实现

2.1 模型设计与实现

2.2 MPC工程实现步骤

三、参考资料

3.1 基础理论

3.2 Refer to Apollo

3.3 其它实例参考

3.4 MATLAB中的MPC

四、demo代码


一、引言

接上文,继续。

所谓“上文”

二、MPC的理解与实现

一样,还是直接上干货。

2.1 模型设计与实现

基本和LQR一致,状态方程、AB矩阵、状态与控制的选择、双线性离散化、QR矩阵,参考前面的LQR就好。

不同的是:

  • 要定义一个预测步数Np,并基于Np对ABQR等矩阵做增广;
  • 而且MPC可以考虑空间状态变量的各种约束,而LQR、PID等只能考虑输入输出的约束;
  • MPC还有一个优点,就是允许模型存在误差,不像LQR中的模型精度那么高;
  • 损失函数方面,LQR做0~∞积分,MPC做Np有限积分,这也导致了求解方法的不同。

说点儿其它的,在损失函数cost function的计算中,互为转置的项可以合并同类项,理解了这个点有些推导过程才能看的懂。

还有就是,如果状态量不用偏差而直接用相应的参数,则需要改模型改cost function的设计;另外,暂不考虑模型的变化,以横向位置替换横向偏差做状态量为例,则cost function里得减去横向位置参考才合乎常理,这时,代入cost function推导可以得出,最终的结果为quadprog()里的参数f需要减去状态x的参考项。

2.2 MPC工程实现步骤

  1.  拿到车体参数;
  2. 选取状态量和控制量,建模;
  3. 对AB矩阵做离散化;
  4. 设定QR矩阵;
  5. 设定预测步数Np,并基于Np对ABQR做增广;
  6. 设定相关参数的约束、各状态的当前值;
  7. 转化为QP问题求解得到Np步的控制向量u
  8. 使用u(0)做控制,并递推一步u迭代到下一轮MPC过程;
  9. 慢慢调参吧。。。

三、参考资料

老规矩,首先感谢各位大神。

3.1 基础理论

参考1:

无人驾驶之车辆控制 (2)MPC模型预测控制算法_小郑同学爱学习的博客-CSDN博客_mpc控制算法

你还在用PID?MPC模型预测控制,从公式到代码!_哔哩哔哩_bilibili

MPC学习笔记(一):手推MPC公式_煜个头头的博客-CSDN博客_mpc推导

参考2:有些代码

MPC模型预测控制(二)-MATLAB代码实现_tingfenghanlei的博客-CSDN博客_mpc代码

MPC模型预测控制_tingfenghanlei的博客-CSDN博客_mpc模型预测控制大牛知乎

自动驾驶——模型预测控制(MPC)理解与实践_wisdom_bob的博客-CSDN博客_mpc 自动驾驶

3.2 Refer to Apollo

参考1:

Apollo-MPC的框架介绍,这个博主有Apollo其它模块的介绍可以看看,前后逻辑比较清楚;用预瞄点的曲率做前馈

自动驾驶(七十六)---------Apollo MPC之代码解析_一实相印的博客-CSDN博客_自动驾驶控制代码

Apollo-MPC二次规划的简单推导

Apollo控制算法MPC分析(一) - 知乎

有一些Apollo的代码

Apollo代码学习(六)—模型预测控制(MPC)_follow轻尘的博客-CSDN博客_apollo mpc代码

参考2:开源Apollo中LQR的位置和计算车体参数、AB矩阵的位置

..\apollo-master\modules\control\controller\mpc_controller.cc

ComputeControlCommand()、Init()、LoadControlConf()

3.3 其它实例参考

参考1:极重要,是我自己实现的主要refer

demo基础参考

自编Matlab代码实现MPC基本算法_玄在天涯的博客-CSDN博客_matlab mpc

基础参考做了引申,固定点跟踪

自编Matlab代码实现MPC定点跟踪_玄在天涯的博客-CSDN博客_mpc算法matlab

参考2:

一个MPC简单matlab实例

模型预测控制(MPC)解析(一) - 古月居

3.4 MATLAB中的MPC

核心是依赖quadprog(),结合着代码讲吧。

四、demo代码

上主菜:

function y = Fcn_MPC(Ca_f, Ca_r, mass_f, mass_r, WheelBase, VehicleSpeed_mps, ...
                     LatErr, LatErr_d, AngleErr, AngleErr_d, ...
                     ts)

WholeMass = mass_f + mass_r;
l_f = WheelBase * (1 - mass_f/WholeMass);
l_r = WheelBase * (1 - mass_r/WholeMass);
Iz = l_f*l_f*mass_f + l_r*l_r*mass_r;

dim_state = 4; %状态4个
dim_ctrl = 1; %控制1个

A = zeros(4,4);
A(1,2) = 1;
A(2,2) = (Ca_f+Ca_r) / WholeMass / VehicleSpeed_mps * -1;
A(2,3) = (Ca_f+Ca_r) / WholeMass;
A(2,4) = (Ca_r*l_r-Ca_f*l_f) / WholeMass / VehicleSpeed_mps;
A(3,4) = 1;
A(4,2) = (Ca_r*l_r-Ca_f*l_f) / Iz / VehicleSpeed_mps;
A(4,3) = (Ca_f*l_f-Ca_r*l_r) / Iz;
A(4,4) = (Ca_f*l_f*l_f+Ca_r*l_r*l_r) / Iz / VehicleSpeed_mps * -1;
A = (eye(4)-ts*0.5*A) \ (eye(4)+ts*0.5*A); % Apollo的双线性离散化

B = [0 0 0 0]';
B(2) = Ca_f / WholeMass;
B(4) = Ca_f * l_f / Iz;
B = B * ts;

Q = zeros(4,4);
Q(1,1) = 2;
Q(2,2) = 2;
Q(3,3) = 1;
Q(4,4) = 1;

R = 0.1;

% 当前状态量
x0 = [LatErr, LatErr_d, AngleErr, AngleErr_d]';

% 预测步长
Np=10;

% 增广
A_ext = zeros(dim_state*Np, dim_state);
B_ext = zeros(dim_state*Np, Np);
Q_ext = zeros(dim_state*Np);
R_ext = zeros(dim_ctrl*Np);
for i=1:1:Np
    At_tmp = A^i;
    for row = 1 : 1 : dim_state
        for col = 1 : 1 : dim_state
            A_ext(dim_state*(i-1)+row, col) = At_tmp(row,col);
        end
    end

    for j=1:1:i
        Bt_tmp = (A^(i-j)) * B;
        for row = 1 : 1 : dim_state
            B_ext(dim_state*(i-1)+row, j) = Bt_tmp(row,1);
        end
    end

    for row = 1 : 1 : dim_state
        for col = 1 : 1 : dim_state
            Q_ext(dim_state*(i-1)+row, dim_state*(i-1)+col) = Q(row,col); % Qt/Rt是对角Q/R阵,这里用row_Q其实代表方阵维数,QR都是方阵
        end
    end

    for row = 1 : 1 : dim_ctrl
        for col = 1 : 1 : dim_ctrl
            R_ext(dim_ctrl*(i-1)+row, dim_ctrl*(i-1)+col) = R(row,col); % Qt/Rt是对角Q/R阵,这里用row_Q其实代表方阵维数,QR都是方阵
        end
    end
end

% 控制量ut的初始值
persistent p_u0;
if isempty(p_u0)
    p_u0 = zeros(Np,1);
end

% quadprog()所需参数
H = 2*(B_ext'*Q_ext*B_ext + R_ext);
f = (2*x0'*A_ext'*Q_ext*B_ext)';
qp_A = [B_ext; -B_ext];
state_constr = zeros(dim_state*Np, 1); % state_constr也要做增广,以匹配公式中的维度
constr_tmp = [0.5 1 0.5/180*pi 1/10]';
for i = 1 : 1 : Np
    for j = 1 : 1 : dim_state
        state_constr(dim_state*(i-1)+j) = constr_tmp(j);
    end
end
b = [state_constr-A_ext*x0; state_constr+A_ext*x0];% b是根据对状态的约束得来的,
                                                   % [0.5 1 0.5/180*pi 1/10],即横向误差约束到半米以内、变化率1m/s以内、
                                                   % HandingAngleError(也就是HeadingAngle)在0.5°以内、HeadingAngleErrorRate在0.1rad以内
lb = -20/180*pi*ones(Np,1); % 控制量ut的上下限,即方向盘转角
ub = 20/180*pi*ones(Np,1); % ±20°
opts = optimoptions('quadprog','Algorithm','active-set');
% quadprog()所需参数

% solve qp problem
[u, fval, exitflag]=quadprog(H, f, qp_A, b, [], [], lb, ub, p_u0, opts);

p_u0 = [u(2:Np); u(Np)];

y = u(1);

这是一步的操作,实际应用要在每个控制循环调用一次,LQR也是一样。

续上3.2.3里quadprog()的问题,这个一定要做options,否则仿真能过但无法code generation,至于quadprog()的实现原理。。。。。。反正我code generation直接给我造出了5000+的代码量,say byebye就好,下面是做options的方案:

doc quadprog或Generate Code for quadprog- MATLAB & Simulink- MathWorks 中国

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

第七篇(下),MPC工程化总结 的相关文章

  • 学习c/c++ 推荐学习什么书籍?

    学习编程包含以下几个重要方面 xff1a 了解语言的语法 知道那些特性可以使用和何时使用 写出可读性好的代码 编译器可以理解 xff0c 但是下一个人是否可以阅读呢 xff1f 在一个更高层次设计结构良好的程序 为了学习一门语言 xff0c
  • 深入理解 http 反向代理(nginx)

    要理解什么是 反向代理 reverse proxy 自然你得先知道什么是 正向代理 forward proxy 另外需要说的是 一般提到反向代理 通常是指 http 反向代理 但反向代理的范围可以更大 比如 tcp 反向代理 在这里 不打算
  • 01-【Royal TSX】Mac上最好用的SSH工具Royal TSX使用教程

    参考文章 xff1a https www jianshu com p 0206980f529e
  • 数据结构:线性结构(C语言)

    文章目录 线性结构线性表什么是线性表线性表的抽象类型描述线性表的实现 广义表广义表定义多重链表 堆栈什么是堆栈堆栈的抽象数据类型描述堆栈的顺序存储实现堆栈的链式存储实现堆栈的应用 队列什么是队列队列的抽象数据类型描述队列的顺序存储实现队列的
  • 树(C语言)

    文章目录 树树的定义树的一些基本术语树的表示 树 树的定义 树 xff08 Tree xff09 xff1a n n 0
  • 堆(C语言)

    文章目录 堆 heap 什么是堆最小堆的操作操作集的实现 C语言 堆 heap 什么是堆 定义 堆 heap 是计算机科学中一类特殊的数据结构的统称 堆通常是一个可以被看做一棵树的数组对象 性质 结构性 xff1a 用数组表示的完全二叉树
  • VS2017中fopen等函数报错解决方法

    文章目录 VS2017中fopen 函数报错解决方法问题解决方法 VS2017中fopen 函数报错解决方法 问题 用VS2017写C语言代码的时候 xff0c 代码中使用了fopen 函数 xff0c 调试之后报错如下 xff1a err
  • 定位,浮动,BFC

    文章目录 1 xff0c 定位1 margin 与 padding 区别 xff1a 2 定位 xff1a 2 xff0c 元素分类 xff0c 浮动 xff0c BFC1 1 常见块级元素 xff1a 1 2 常见行内元素 xff1a 1
  • 表排序

    文章目录 表排序 表排序 思想 当待排数组中的元素不是简简单单的整数 xff0c 而是复杂的结构体 xff0c 那么移动元素所花费的时间就不能忽略不计了 xff0c 这时候我们要减少元素之间移动的次数了 表排序就是这么一个排序 xff0c
  • 循环链表的实现

    循环链表的实现 说明 参考资料 传智播客扫地僧的数据结构教学视频 线性表基本知识 参考 该实现的说明 C语言实现基于单向链表 xff0c 参考实现算法和数据的分离 实现 circular list h span class token ma
  • Ubuntu20.04安装与配置记录

    Ubuntu20 04安装与配置记录 原文地址 xff1a Ubuntu20 04安装与配置记录 一 Ubuntu系统盘制作 1 1 Windows环境下制作系统盘 下载Ubuntu系统 xff0c 选择桌面版 下载工具系统盘制作工具Ruf
  • C++单例写法记录

    C 43 43 单例写法记录 源码地址 一 饿汉式 1 1 静态指针 静态垃圾回收类 instance h ifndef INSTANCE H define INSTANCE H include lt string gt include l
  • 堆栈应用:表达式求值(C语言)

    文章目录 堆栈应用 xff1a 表达式求值 xff08 C语言 xff09 两个定义大致过程具体代码 堆栈应用 xff1a 表达式求值 xff08 C语言 xff09 两个定义 中缀表达式 xff1a 运算符号位于两个运算数之间 如 xff
  • andrsoid studio 长期编辑

    andrsoid studio 2020 02 08 修改build gradle配置 Top level build file where you can add configuration options common to all s
  • 使用 Maven 搭建 Mybatis 环境

    一 创建项目 1 点击 File gt New gt Module 2 选择左侧的 Maven xff0c 由于只是创建一个普通的项目 xff0c 此处点击 Next 即可 3 输入 GroupId 和 ArtifactId 4 配置 ma
  • ubuntu安装npm命令

    ubuntu安装npm命令 摘要 xff1a npm全称Node Package Manager xff0c 是node的包管理工具 xff0c 是用JavaScript写出来的工具 xff0c 被内置进了node中 xff0c 是随同No
  • zynq操作系统: Linux驱动开发AXIDMA篇

    前言 由于bram形式的速率限制 xff0c 在同样紧急的时间条件下 xff0c 还是改回了axidma的方式来降维打击 xff0c 对于几兆的速率 xff0c 颇有种杀鸡用牛刀的感觉 xff0c 没办法 xff0c 原来的刀就是差一点 x
  • C# 对RabbitMQ使用

    1 安装NuGet包RabbitMQ Client 2 生产者 确认机制 1 含义 xff1a 就是应答模式 xff0c 生产者发送一条消息之后 xff0c Rabbitmq服务器做了个响应 xff0c 表示收到了 2 特点 xff1a 异
  • CSS—— grid 网格布局

    文章目录 1 grid 网格布局 1 grid 网格布局 display gridgrid 属性是以下属性的简写属性 默认 grid gap xff0c none xff0c 200px 网格之间的距离grid template rows
  • 【图文解析】给定一个链表,判断链表中是否有环

    目录 例题描述解题思路代码实现 例题描述 给定一个链表 xff0c 判断链表中是否有环 为了表示给定链表中的环 xff0c 我们使用整数 pos 来表示链表尾连接到链表中的位置 xff08 索引从 0 开始 xff09 如果 pos 是 1

随机推荐

  • Centos7执行yum install *时出现“Peer‘s Certificate has expired.“

    一 引言 今天在安装OpenResty的时候 xff0c 出现了 34 Peer 39 s Certificate has expired 34 的问题 xff0c 详细错误如下 xff1a root 64 kubernetes sudo
  • git常用指令

    1 查看分支创建来源 指令 xff1a git reflog show 分支名 由图可以看出a分支是由master创建出来的 2 查看分支情况 查看远程分支 指令 xff1a git branch r 查看所有分支 指令 xff1a git
  • 利其器(2)——idea常用配置_提高开发效率

    文章目录 简介编码设置设置idea支持生成唯一序列化id全字母代码提示调出Run Dashboard显示方法分隔符忽略大小写提示自动导入包单行显示多个Tabs设置鼠标滚轮 43 96 ctrl 96 修改字体大小设置保存自动格式化等配置终端
  • 换硬币问题

    编写程序实现用一元人民币换成一分 xff0c 两分 xff0c 五分的硬币共50枚 三重循环 include lt stdio h gt int main int x y z x y z 分别表示一分 两分 五分的个数 for x 61 0
  • 最新ubuntu22.04 下列软件包有未满足的依赖关系 解决方案--------------------------------------------------记因为配环境而耽误的一天

    今天真的崩溃一整天了 xff0c 一直一直都在找错一直一直都在找解决方案 xff0c 我发现VM真的超多超多BUG的 xff0c 感兴趣的话可以跟我聊聊 当然这篇讲的主要不是这些BUG xff0c 而是依赖关系 如果你出现类似的情况 xff
  • python获取当前执行py文件的绝对路径

    python获取当前执行py文件的绝对路径 python3 home appuser test py span class token comment 获取当前执行py文件的绝对路径 span py file path span class
  • 【iOS】NSAttributedString 相关

    1 富文本的相关属性字段 NSAttributedString Key xff08 1 xff09 paragraphStyle span class token keyword let span paraStyle span class
  • python奇技淫巧:命令行输出漂亮的表格

    前言 最近想着用 Python写一个命令行的管理各种资源的信息的管理工具 xff0c 比如阿里云的ECS等信息 xff0c 基本的功能就是同步阿里云的资源的信息到数据库 xff0c 然后可以使用命令行查询 展现信息在命令行中的 xff0c
  • Android_基础_String资源带参数

    转载自 https www cnblogs com leelugen p 6685905 html Android 基础 String资源带参数 在android 开发 xff0c 我们通常会用string xml资源去设置textview
  • es6 — class 类,原型,原型链

    文章目录 1 意义2 语法1 由来2 constructor 3 类实例3 1 使用new 调用3 2类的继承 4 新写法5 取值函数 getter 存值函数 setter 2 原型以及原型链1 原型2 原型链3 instanceof 1
  • SQLServer注释快捷键

    SQLServer中的批量注释 批量注释批量取消注释 批量注释 Ctrl 43 K C 按住Ctrl键不放 然后依次按下K和C 批量取消注释 Ctrl 43 K U 按住Ctrl键不放 然后依次按下K和U
  • 【面试宝典】软件测试工程师2021烫手精华版(第一章测试理论篇)

    前言 xff1a 翻了很多论坛博客关于面试的文章 xff0c 很多都是不完整的 xff0c 还都是比较常见规规矩矩的 xff0c 那大家刷过的基本都不拿出来了 xff0c 都是一些大家平时见得不多 xff0c 但是面试官很看中的一些题 第一
  • uniapp package.json和mainfest.json,如何区分环境变量

    uniapp在hbuilder中 xff0c 导航的运行就是development xff0c 发行就是production package json 如果是往服务器上发布版本 xff0c 则是打包成zip在服务器上解压 xff0c 但注意
  • VSCode扩展时出错XHRfaile问题解决

    问题 VScode扩展插件链接网络失败XHR faile错误 解决办法 1 第一步 xff1a 文件 gt 首选项 gt 设置 gt 如下图 xff1a 2 第二步 xff1a 用户 gt 应用程序 gt 代理服务器 gt 如下图操作 xf
  • HDFS的启动流程和HA

    HDFS的启动流程 当 NameNode 启动时HDFS首先将Fsimage读入内存对元数据进行恢复 xff0c 然后再读edits文件中的更新操作在恢复后的元数据上进行执行 xff0c 使得此时的NameNode中保存的是停止前的最新状态
  • 『XXG笔记』Github pages 自定义域名

    x1f44b 本文章为我 XXG 原创 xff0c 由于个人能力有限 xff0c 此笔记可能会错漏 过时 或需要补充 x1f4d6 笔记文章由于多平台发布 xff0c 为了修改方便 xff0c 可以参观我的博客 xff1a https xx
  • 第十八篇,Simulink with Git

    一 综述 本篇以MATLAB R2021b为基础讲解如何对Simulink模型做Git管理 xff0c mdl与slx均可 Git并非只能对手写代码做版本管理 xff0c 它的应用十分广泛 xff0c 囊括了各种使用编程语言编写的代码 脚本
  • 第十九篇,解析法求解五阶多项式

    x0为初始约束 xff0c 时间为0 xff1b x1为结束约束 xff0c 时间为t coef 为求解结果 xff0c 定义x 61 at 5 43 bt 4 43 ct 3 43 dt 2 43 et 43 f xff0c 则coef
  • 第二十篇,Simulink使用痛点记录

    在工作实践中发现了MATLAB amp amp Simulink一些虽不致项目失败但的确很不方便的点 xff0c 记录下来以备持续研究 xff0c 并做分享 xff1b 都是个人认为比较基础的能力或者容易做到的特性 xff0c MATLAB
  • 第七篇(下),MPC工程化总结

    目录 一 引言 二 MPC的理解与实现 2 1 模型设计与实现 2 2 MPC工程实现步骤 三 参考资料 3 1 基础理论 3 2 Refer to Apollo 3 3 其它实例参考 3 4 MATLAB中的MPC 四 demo代码 一