草庐IT

MPC(模型预测控制)_附matlab例程

尔过留香 2024-01-11 原文

写在前面:
  本文为科研理论笔记的第二篇,其余笔记目录传送门:

理论笔记专栏目录

  介绍结束下面开始进入正题:

1 基本概念

1.1 最优控制

​   最优控制(optimal control):在约束条件下的最优表现,约束条件即物理限制,而对于最优的评判往往需要具体问题具体分析。

​   一个SISO系统的框图如下所示:


​ 对于误差 e e e,从轨迹跟踪的角度出发, ∫ 0 t e 2 d t \int_{0}^{t} {e^2}dt 0te2dt 越小表示系统追踪效果越好;而从输入的角度出发, ∫ 0 t u 2 d t \int_{0}^{t}{u^2}dt 0tu2dt 越小表示系统的输入(能耗)越小。在上述条件下,即可构造系统的代价函数(cost function): J = ∫ 0 t q e 2 + r u 2 d t J=\int_{0}^{t}{qe^2+ru^2}dt J=0tqe2+ru2dt。其中的 q q q r r r称为调节参数,最优化过程即使设计一个控制器使得 J = J m i n J=J_{min} J=Jmin。若使得 q > > r q>>r q>>r 则表示在最优化的过程中更看重误差,反之若 r > > q r>>q r>>q 则表示在最优化的过程中更看重输入。

​   拓展到MIMO系统,系统的状态空间方程一般可以描述为:
{ x ˙ = A x + B u y = C x \begin{cases} \dot x=Ax+Bu\\ y=Cx \end{cases} {x˙=Ax+Buy=Cx
​其中 x = [ x 1 , ⋯   , x n ] T x=[x_1,\cdots,x_n]^T x=[x1,,xn]T为系统状态, u = [ u 1 , ⋯   , u n ] T u=[u_1,\cdots,u_n]^T u=[u1,,un]T为系统输入。

​   类似SISO系统,可设 J = ∫ 0 x e T Q e + u T R u d t J=\int_0^x{e^TQe+u^TRu}dt J=0xeTQe+uTRudt 。其中对角阵 Q = [ q 1 ⋯ 0 ⋮ ⋱ ⋮ 0 ⋯ q n ] Q=\begin{bmatrix}q_1&\cdots &0 \\ \vdots&\ddots&\vdots \\0&\cdots&q_n\end{bmatrix} Q=q100qn R = [ r 1 ⋯ 0 ⋮ ⋱ ⋮ 0 ⋯ r n ] R=\begin{bmatrix}r_1&\cdots &0 \\ \vdots&\ddots&\vdots \\0&\cdots&r_n\end{bmatrix} R=r100rn称为调节矩阵, q 1 ⋯ q n 、 r 1 ⋯ r n q_1\cdots q_n、r_1\cdots r_n q1qnr1rn 称为最优化过程中的权重系数,可相应的调整 x 1 ⋯ x n 、 u 1 ⋯ u n x_1\cdots x_n、u_1\cdots u_n x1xnu1un 的优化权重。

1.2 MPC

​   MPC(model predictive control):模型预测控制,指通过模型预测系统在某一未来时间段内的表现来进行优化控制,因为其多用于数位控制,所以在分析时主要采用离散型状态空间表达式来进行分析,例如对于四轮阿克曼底盘的小车,其离散状态空间表达式可参考前一篇笔记:

四轮移动机器人(小车)数学建模

​   基于模型的预测:在MPC算法中,需要一个描述对象动态行为的模型,这个模型的作用是预测系统未来的动态,即能够根据系统 k k k时刻的状态 x k x_k xk k k k时刻的控制输入 u k u_k uk,预测到 k + 1 k+1 k+1时刻的输出 y k + 1 y_{k+1} yk+1。在这里 k k k时刻的输入正是用来控制系统 k + 1 k+1 k+1时刻的输出,使其最大限度的接近 k + 1 k+1 k+1时刻的输出期望值。故我们强调的是该模型的预测作用,而不是模型的形式。

​   预测区间:规定了希望未来能被预测到多久。从当前时刻 k k k k + N k+N k+N的时间区间。

​   控制区间:控制区间的选择就是一个最优化的问题,其代价函数 J = ∑ i = 0 N − 1 e k + i T Q e k + i + u k + i T R u k + i + e k + N T F e k + N J=\sum_{i=0}^{N-1}{e_{k+i}^TQe_{k+i}+u_{k+i}^TRu_{k+i}+e_{k+N}^TFe_{k+N}} J=i=0N1ek+iTQek+i+uk+iTRuk+i+ek+NTFek+N ,其中 e k + N T F e k + N e_{k+N}^TFe_{k+N} ek+NTFek+N 表示最终代价,即最后 k + N k+N k+N时刻的误差代价。

​   MPC主要分为三步:

​   step1:在 k k k时刻(当前时刻),测量或估计系统的当前状态 x k x_k xk (若 x k x_k xk不可直接测得,则一般采用状态观测器进行估计);

​   step2:基于预测控制量 u k 、 u k + 1 . . . u k + N − 1 u_k、u_{k+1}...u_{k+N-1} ukuk+1...uk+N1 来进行最优化控制;

​   step3:只将 u k u_k uk 施加给系统,进行滚动优化控制。

2 最优化建模

​   MPC的重点在于step2中如何进行最优化控制,最优化的方法很多,下面主要推导一种常用的二次规划(Quadratic Programming)的方法。

​   二次规划的一般形式为: m i n ( Z T Q Z + C T Z ) min(Z^TQZ+C^TZ) min(ZTQZ+CTZ),其中 Z T Q Z Z^TQZ ZTQZ为二次型项, C T Z C^TZ CTZ为线性项。对于二次规划问题的处理当前Matlab、Python、C++等都有很成熟的方法了,所以关键就在于如何将自己的模型化为二次规划的一般形式。

​   设系统的线性离散状态空间表达式为 x ( k + 1 ) = A x ( k ) + B u ( k ) x_{(k+1)}=Ax_{(k)}+Bu_{(k)} x(k+1)=Ax(k)+Bu(k) ,其中 x = [ x 1 , ⋯   , x n ] T , u = [ u 1 , ⋯   , u p ] T x=[x_1,\cdots,x_n]^T,u=[u_1,\cdots,u_p]^T x=[x1,,xn]T,u=[u1,,up]T,状态矩阵 A A A n × n n\times n n×n矩阵,输入矩阵 B B B n × p n\times p n×p矩阵。

​   在 k k k时刻,定义:
X k = [ x ( k ∣ k ) x ( k + 1 ∣ k ) ⋮ x ( k + N ∣ k ) ] ( N + 1 ) n × 1 ; U k = [ u ( k ∣ k ) u ( k + 1 ∣ k ) ⋮ u ( k + N − 1 ∣ k ) ] N p × 1 X_k=\begin{bmatrix} x_{(k|k)}\\ x_{(k+1|k)}\\ \vdots\\ x_{(k+N|k)}\\ \end{bmatrix}_{(N+1)n\times1} ; U_k=\begin{bmatrix} u_{(k|k)}\\ u_{(k+1|k)}\\ \vdots\\ u_{(k+N-1|k)}\\ \end{bmatrix}_{Np\times1} Xk=x(kk)x(k+1k)x(k+Nk)(N+1)n×1Uk=u(kk)u(k+1k)u(k+N1k)Np×1
其中 N N N为预测区间,以 x ( k + 1 ∣ k ) x{(k+1|k)} x(k+1k)为例,括号内|左边的 k + 1 k+1 k+1表示预测的 k + 1 k+1 k+1时刻的状态量,括号内|右边的 k k k表示在 k k k时刻做出的预测。

​   为了简化分析,设输入 y = x y=x y=x,参考量 r = 0 r=0 r=0,则误差 e = y − r = x e=y-r=x e=yr=x,代价函数可化为:
J = ∑ i = 0 N − 1 x ( k + i ∣ k ) T Q x ( k + i ∣ k ) + u ( k + i ∣ k ) T R u ( k + i ∣ k ) + x ( k + N ∣ k ) T F x ( k + N ∣ k ) 即 : J = 误 差 加 权 和 + 输 入 加 权 和 + 终 端 误 差 J=\sum_{i=0}^{N-1}{x_{(k+i|k)}^TQx_{(k+i|k)}+u_{(k+i|k)}^TRu_{(k+i|k)}+x_{(k+N|k)}^TFx_{(k+N|k)}}\\ 即:J=误差加权和+输入加权和+终端误差 J=i=0N1x(k+ik)TQx(k+ik)+u(k+ik)TRu(k+ik)+x(k+Nk)TFx(k+Nk)J=++
​ 由系统初始条件 x ( k ∣ k ) = x ( k ) x_{(k|k)}=x_{(k)} x(kk)=x(k),可递推得:
x ( k + 1 ∣ k ) = A x ( k ∣ k ) + B u ( k ∣ k ) = A x ( k ) + B u ( k ∣ k ) ; x ( k + 2 ∣ k ) = A x ( k + 1 ∣ k ) + B u ( k + 1 ∣ k ) = A 2 x ( k ) + A B u ( k ∣ k ) + B u ( k + 1 ∣ k ) ; ⋮ x ( k + N ∣ k ) = A n x ( k ) + A N − 1 B u ( k ∣ k ) + ⋯ + B u ( k + N − 1 ∣ k ) ; x_{(k+1|k)}=Ax_{(k|k)}+Bu_{(k|k)}=Ax_{(k)}+Bu_{(k|k)};\\ x_{(k+2|k)}=Ax_{(k+1|k)}+Bu_{(k+1|k)}=A^2x_{(k)}+ABu_{(k|k)}+Bu_{(k+1|k)};\\ \vdots \\ x_{(k+N|k)}=A^nx_{(k)}+A^{N-1}Bu_{(k|k)}+\cdots+Bu_{(k+N-1|k)}; x(k+1k)=Ax(kk)+Bu(kk)=Ax(k)+Bu(kk);x(k+2k)=Ax(k+1k)+Bu(k+1k)=A2x(k)+ABu(kk)+Bu(k+1k);x(k+Nk)=Anx(k)+AN1Bu(kk)++Bu(k+N1k);
​ 整理上面 N + 1 N+1 N+1个式子可得(其中的 0 0 0表示 n × p n\times p n×p 的零矩阵):
X k = [ I A A 2 ⋮ A N ] x ( k ) + [ 0 0 ⋯ 0 B 0 ⋯ 0 A B B ⋯ 0 ⋮ ⋮ ⋱ ⋮ A N − 1 B A N − 2 B ⋯ B ] U k X_k=\begin{bmatrix}I\\ A\\ A^2\\ \vdots\\ A^N\end{bmatrix}x_{(k)}+ \begin{bmatrix}0&0&\cdots&0\\ B&0&\cdots&0\\ AB&B&\cdots&0\\ \vdots&\vdots&\ddots&\vdots\\ A^{N-1}B&A^{N-2}B&\cdots&B\end{bmatrix}U_k Xk=IAA2ANx(k)+0BABAN1B00BAN2B000BUk
​ 定义:
M = [ I A A 2 ⋮ A N ] ( N + 1 ) n × n ; C = [ 0 0 ⋯ 0 B 0 ⋯ 0 A B B ⋯ 0 ⋮ ⋮ ⋱ ⋮ A N − 1 B A N − 2 B ⋯ B ] ( N + 1 ) n × N p M=\begin{bmatrix}I\\ A\\ A^2\\ \vdots\\ A^N\end{bmatrix}_{(N+1)n\times n}; C=\begin{bmatrix}0&0&\cdots&0\\ B&0&\cdots&0\\ AB&B&\cdots&0\\ \vdots&\vdots&\ddots&\vdots\\ A^{N-1}B&A^{N-2}B&\cdots&B\end{bmatrix}_{(N+1)n\times Np} M=IAA2AN(N+1)n×nC=0BABAN1B00BAN2B000B(N+1)n×Np
​ 即有: X k = M x ( k ) + C U k X_k=Mx_{(k)}+CU_k Xk=Mx(k)+CUk,其意义是由 k k k时刻的状态量和预测输入量可得出预测状态量。

​   再来将代价函数 J J J化为紧凑形式,例如其中误差加权和及终断误差可化为:
∑ i = 0 N − 1 x ( k + i ∣ k ) T Q x ( k + i ∣ k ) + x ( k + N ∣ k ) T F x ( k + N ∣ k ) = x ( k ∣ k ) T Q x ( k ∣ k ) + x ( k + 1 ∣ k ) T Q x ( k + 1 ∣ k ) + ⋯ + x ( k + N − 1 ∣ k ) T Q x ( k + N − 1 ∣ k ) + x ( k + N ∣ k ) T F x ( k + N ∣ k ) = X k T [ Q ⋯ 0 ⋮ ⋱ ⋮ 0 ⋯ F ] X k \sum_{i=0}^{N-1}{x_{(k+i|k)}^TQx_{(k+i|k)}}+x_{(k+N|k)}^TFx_{(k+N|k)}\\ =x_{(k|k)}^TQx_{(k|k)}+x_{(k+1|k)}^TQx_{(k+1|k)}+\cdots+x_{(k+N-1|k)}^TQx_{(k+N-1|k)}+x_{(k+N|k)}^TFx_{(k+N|k)}\\ =X_k^T\begin{bmatrix}Q&\cdots&0\\ \vdots&\ddots&\vdots\\ 0&\cdots&F\end{bmatrix}X_k i=0N1x(k+ik)TQx(k+ik)+x(k+Nk)TFx(k+Nk)=x(kk)TQx(kk)+x(k+1k)TQx(k+1k)++x(k+N1k)TQx(k+N1k)+x(k+Nk)TFx(k+Nk)=XkTQ00FXk
​ 定义:
Q ‾ = [ Q ⋯ 0 ⋮ ⋱ ⋮ 0 ⋯ F ] ; R ‾ = [ R ⋯ 0 ⋮ ⋱ ⋮ 0 ⋯ R ] \overline Q=\begin{bmatrix}Q&\cdots&0\\ \vdots&\ddots&\vdots\\ 0&\cdots&F\end{bmatrix};\overline R=\begin{bmatrix}R&\cdots&0\\ \vdots&\ddots&\vdots\\ 0&\cdots&R\end{bmatrix} Q=Q00FR=R00R
​ 则有:
J = ∑ i = 0 N − 1 x ( k + i ∣ k ) T Q x ( k + i ∣ k ) + u ( k + i ∣ k ) T R u ( k + i ∣ k ) + x ( k + N ∣ k ) T F x ( k + N ∣ k ) = X k T Q ‾ X K + U k T R ‾ U k J=\sum_{i=0}^{N-1}{x_{(k+i|k)}^TQx_{(k+i|k)}+u_{(k+i|k)}^TRu_{(k+i|k)}+x_{(k+N|k)}^TFx_{(k+N|k)}}\\ =X_k^T\overline QX_K+U_k^T\overline RU_k J=i=0N1x(k+ik)TQx(k+ik)+u(k+ik)TRu(k+ik)+x(k+Nk)TFx(k+Nk)=XkTQXK+UkTRUk
​ 将 X k = M x ( k ) + C U k X_k=Mx_{(k)}+CU_k Xk=Mx(k)+CUk代入 J = X k T Q ‾ X k + U k T R ‾ U k J=X_k^T\overline QX_k+U_k^T\overline RU_k J=XkTQXk+UkTRUk
J = X k T Q ‾ X K + U k T R ‾ U k = ( M x ( k ) + C U k ) T Q ‾ ( M x ( k ) + C U k ) + U k T R ‾ U k = ( x ( k ) T M T + U k T C T ) Q ‾ ( M x ( k ) + C U k ) + U k T R ‾ U k = x ( k ) T M T Q ‾ M x ( k ) + x ( k ) T M T Q ‾ C U k + U k T C T Q ‾ M x ( k ) + U k T C T Q ‾ C U k + U k T R ‾ U k = x ( k ) T M T Q ‾ M x ( k ) + 2 x ( k ) T M T Q ‾ C U k + U k T ( C T Q ‾ C + R ‾ ) U k J=X_k^T\overline QX_K+U_k^T\overline RU_k\\ =(Mx_{(k)}+CU_k)^T\overline Q(Mx_{(k)}+CU_k)+U_k^T\overline RU_k\\ =(x_{(k)}^TM^T+U_k^TC^T)\overline Q(Mx_{(k)}+CU_k)+U_k^T\overline RU_k\\ =x_{(k)}^TM^T\overline QMx_{(k)}+x_{(k)}^TM^T\overline QCU_k+U_k^TC^T\overline QMx_{(k)}+U_k^TC^T\overline QCU_k+U_k^T\overline RU_k\\ =x_{(k)}^TM^T\overline QMx_{(k)}+2x_{(k)}^TM^T\overline QCU_k+U_k^T(C^T\overline QC+\overline R)U_k J=XkTQXK+UkTRUk=(Mx(k)+CUk)TQ(Mx(k)+CUk)+UkTRUk=(x(k)TMT+UkTCT)Q(Mx(k)+CUk)+UkTRUk=x(k)TMTQMx(k)+x(k)TMTQCUk+UkTCTQMx(k)+UkTCTQCUk+UkTRUk=x(k)TMTQMx(k)+2x(k)TMTQCUk+UkT(CTQC+R)Uk
​ 定义: G = M T Q ‾ M 、 E = M T Q ‾ C 、 H = C T Q ‾ C + R ‾ G=M^T\overline QM、E=M^T\overline QC、H=C^T\overline QC+\overline R G=MTQME=MTQCH=CTQC+R;即有:
J = x ( k ) T G x ( k ) + U k T H U k + 2 x ( k ) T E U k J=x_{(k)}^TGx_{(k)}+U_k^THU_k+2x_{(k)}^TEU_k J=x(k)TGx(k)+UkTHUk+2x(k)TEUk
​ 注意到上式第一项 x ( k ) T G x ( k ) x_{(k)}^TGx_{(k)} x(k)TGx(k)仅与初始状态 x ( k ) x_{(k)} x(k)有关,不影响后续优化,后两项形同 Z T Q Z + C T Z Z^TQZ+C^TZ ZTQZ+CTZ,即可用于二次规划得到理想的输入。
  至此MPC算法就介绍完成啦,上面的公式希望大家初学的时候都能手推一遍以便于更好的理解,最后附上一个简单的matlab例程供大家参考。

MPC例程github传送门,注意科学上网

有关MPC(模型预测控制)_附matlab例程的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  5. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  6. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  7. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  8. ruby-on-rails - 如何将验证与模型分开 - 2

    我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:

  9. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  10. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

随机推荐