模型预测控制(MPC)的简单实现 — Matlab

参考文章:原理推导

基于离散模型,首先复述其首先原理,然后基于简单的无人机模型进行仿真。

原理

问题描述

考虑离散系统:
x k + 1 = A x k + B u k {x_{k + 1}} = A{x_k} + B{u_k} xk+1=Axk+Buk

k k k 时刻,预测 N N N 个周期的状态 X k X_k Xk 以及对应的控制输入 U k U_k Uk可以表示为:
X k = [ x ( k ∣ k ) x ( k + 1 ∣ k ) x ( k + 2 ∣ k ) ⋮ x ( k + N ∣ k ) ] , U k = [ u ( k ∣ k ) u ( k + 1 ∣ k ) u ( k + 2 ∣ k ) ⋮ u ( k + N ∣ k ) ] X_k=\begin{bmatrix} x(k|k) \\ x(k+1|k) \\ x(k+2|k) \\ \vdots\\ x(k+N|k) \end{bmatrix}, U_k=\begin{bmatrix} u(k|k) \\ u(k+1|k) \\ u(k+2|k) \\ \vdots\\ u(k+N|k) \end{bmatrix} Xk= x(kk)x(k+1∣k)x(k+2∣k)x(k+Nk) ,Uk= u(kk)u(k+1∣k)u(k+2∣k)u(k+Nk)

假设跟踪目标为0,那么代价函数可以表示为:
J = ∑ k N − 1 ( X k T Q X k + u k T R u k ) + X N T F X N = ∑ 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 ) T F x ( k + N ) \begin{aligned}J&=\displaystyle\sum_{k}^{N-1}(X_k^TQX_k+u_k^TRu_k)+X_N^TFX_N \\ &=\displaystyle\sum_{i=0}^{N-1}(x(k+i|k)^TQx(k+i|k)+u(k+i|k)^TRu(k+i|k))+x(k+N)^TFx(k+N)\end{aligned} J=kN1(XkTQXk+ukTRuk)+XNTFXN=i=0N1(x(k+ik)TQx(k+ik)+u(k+ik)TRu(k+ik))+x(k+N)TFx(k+N)

通过计算 U k U_k Uk 来最小化代价函数 J J J,那么 u ( k ∣ k ) u(k|k) u(kk) 即为当前时刻的最优输出 ,那么怎么计算 U k U_k Uk 就成了问题的关键。

计算过程

由于设计控制器目标为最优化控制输入 u u u,所以需要消除状态 x x x,于是将 X k X_k Xk 展开:
x ( k ∣ k ) = x k x ( k + 1 ∣ k ) = A x ( k ∣ k ) + B u ( k ∣ k ) x ( k + 2 ∣ k ) = A x ( k + 1 ∣ k ) + B u ( k + 1 ∣ k ) = A 2 x ( k ∣ k ) + A B u ( k ∣ k ) + B u ( k + 1 ∣ k ) ⋮ x ( k + N ∣ k ) = A N x ( k ∣ k ) + A N − 1 B u ( k ∣ k ) + ⋯ + B u ( k + N − 1 ∣ k ) \begin{aligned} x(k|k)&=x_k \\ x(k+1|k)&=Ax(k|k)+Bu(k|k) \\ x(k+2|k)&=Ax(k+1|k)+Bu(k+1|k)=A^2x(k|k)+ABu(k|k)+Bu(k+1|k) \\ \vdots \\ x(k+N|k)&=A^Nx(k|k)+A^{N-1}Bu(k|k)+\cdots+Bu(k+N-1|k) \end{aligned} x(kk)x(k+1∣k)x(k+2∣k)x(k+Nk)=xk=Ax(kk)+Bu(kk)=Ax(k+1∣k)+Bu(k+1∣k)=A2x(kk)+ABu(kk)+Bu(k+1∣k)=ANx(kk)+AN1Bu(kk)++Bu(k+N1∣k)

将展开后的方程组用矩阵形式表示:
X k = [ I A A 2 ⋮ A N ] x k + [ O B A B B ⋮ ⋮ ⋱ A N − 1 B A N − 2 B ⋯ B ] U k = M x k + C U k \begin{aligned}X_k&=\begin{bmatrix} I \\ A \\ A^2 \\ \vdots \\ A^N\end{bmatrix}x_k+\begin{bmatrix} O \\ B \\ AB & B \\ \vdots & \vdots & \ddots \\ A^{N-1}B & A^{N-2}B & \cdots & B \end{bmatrix}U_k \\ &=Mx_k+CU_k \end{aligned} Xk= IAA2AN xk+ OBABAN1BBAN2BB Uk=Mxk+CUk

将代价函数 J J J 展开,可以化为:
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 ) T F x ( k + N ) = [ x ( k ∣ k ) x ( k + 1 ∣ k ) ⋮ x ( k + N ∣ k ) ] T [ Q Q ⋱ F ] [ x ( k ∣ k ) x ( k + 1 ∣ k ) ⋮ x ( k + N ∣ k ) ] + [ u ( k ∣ k ) u ( k + 1 ∣ k ) ⋮ u ( k + N − 1 ∣ k ) ] T [ R R ⋱ R ] [ u ( k ∣ k ) u ( k + 1 ∣ k ) ⋮ u ( k + N − 1 ∣ k ) ] = X k T Q ‾ X k + U k T R ‾ U k \begin{aligned}J&=\displaystyle\sum_{i=0}^{N-1}(x(k+i|k)^TQx(k+i|k)+u(k+i|k)^TRu(k+i|k))+x(k+N)^TFx(k+N) \\ &=\begin{bmatrix} x(k|k) \\ x(k+1|k) \\ \vdots\\ x(k+N|k) \end{bmatrix}^T\begin{bmatrix} Q \\ & Q \\ & & \ddots \\ & & & F \end{bmatrix}\begin{bmatrix} x(k|k) \\ x(k+1|k) \\ \vdots\\ x(k+N|k) \end{bmatrix}+\begin{bmatrix}u(k|k) \\ u(k+1|k) \\ \vdots\\ u(k+N-1|k) \end{bmatrix}^T\begin{bmatrix} R \\ & R \\ & & \ddots \\ & & & R \end{bmatrix}\begin{bmatrix} u(k|k) \\ u(k+1|k) \\ \vdots\\ u(k+N-1|k) \end{bmatrix} \\ &= X_k^T\overline{Q}X_k+U_k^T\overline{R}U_k \end{aligned} J=i=0N1(x(k+ik)TQx(k+ik)+u(k+ik)TRu(k+ik))+x(k+N)TFx(k+N)= x(kk)x(k+1∣k)x(k+Nk) T QQF x(kk)x(k+1∣k)x(k+Nk) + u(kk)u(k+1∣k)u(k+N1∣k) T RRR u(kk)u(k+1∣k)u(k+N1∣k) =XkTQXk+UkTRUk

然后将上述的矩阵形式代入到代价函数中, J J J 又可以简化为:
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 R 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 = x k T G x k + 2 x k T E U k + U k T H U k \begin{aligned}J &= X_k^T\overline{Q}X_k+U_k^T\overline{R}U_k \\ &=(Mx_k+CU_k)^T\overline {Q}(Mx_k+CU_k)+U_k^R\overline{R}U_k \\ &=x_k^T{M^T}\bar QM{x_k} + x_k^T{M^T}\bar QC{U_k} + U_k^T{C^T}\bar QM{x_k} + U_k^T{C^T}\bar QC{U_k} + U_k^T\bar R{U_k} \\ &=x_k^T{M^T}\bar QM{x_k} + 2x_k^T{M^T}\bar QC{U_k} + U_k^T({C^T}\bar QC + \bar R){U_k} \\ &=x_k^TG{x_k} + 2x_k^TE{U_k} + U_k^TH{U_k} \end{aligned} J=XkTQXk+UkTRUk=(Mxk+CUk)TQ(Mxk+CUk)+UkRRUk=xkTMTQˉMxk+xkTMTQˉCUk+UkTCTQˉMxk+UkTCTQˉCUk+UkTRˉUk=xkTMTQˉMxk+2xkTMTQˉCUk+UkT(CTQˉC+Rˉ)Uk=xkTGxk+2xkTEUk+UkTHUk

最终,代价函数可以表示为:
J = x k T G x k + 2 x k T E U k + U k T H U k G = M T Q ˉ M E = M T Q ˉ C H = C T Q ˉ C + R ˉ \begin{gathered}J = x_k^TG{x_k} + 2x_k^TE{U_k} + U_k^TH{U_k} \\ G = {M^T}\bar QM \\E = {M^T}\bar QC \\H = {C^T}\bar QC + \bar R \end{gathered} J=xkTGxk+2xkTEUk+UkTHUkG=MTQˉME=MTQˉCH=CTQˉC+Rˉ

然后通过最小化成本函数得到最优解。最简单的方法是使用二次规划(Quadratic Programming, QP),可以直接调用 Matlab 中的 quadprog() 函数。

Matlab 仿真

模型

下面的方程是无人机平移运动的状态空间方程。 以该系统为控制对象。
[ x ˙ v ˙ x s v ˙ x a ˙ x ] = [ 0 0 1 0 0 − 1 T d 1 T d − 1 0 0 0 1 0 0 a 1 x a 2 x ] [ x v x s v x a x ] + [ 0 0 0 b 1 x ] θ r e f [ y ˙ v ˙ y s v ˙ y a ˙ y ] = [ 0 0 1 0 0 − 1 T d 1 T d − 1 0 0 0 1 0 0 a 1 y a 2 y ] [ y v y s v y a y ] + [ 0 0 0 b 1 y ] φ r e f \begin{bmatrix} \dot x \\ \dot v_{xs} \\ \dot v_x \\ \dot a_x \end{bmatrix}=\begin{bmatrix} 0 & 0 & 1 & 0 \\ 0 & -\cfrac{1}{T_d} & \cfrac{1}{T_d} & -1 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & a_{1x} & a_{2x} \end{bmatrix}\begin{bmatrix} x \\ v_{xs} \\ v_x \\ a_x \end{bmatrix}+\begin{bmatrix} 0 \\ 0 \\ 0 \\ b_{1x} \end{bmatrix}{\theta _{ref}} \\ \begin{bmatrix} \dot y \\ \dot v_{ys} \\ \dot v_y \\ \dot a_y \end{bmatrix}=\begin{bmatrix} 0 & 0 & 1 & 0 \\ 0 & -\cfrac{1}{T_d} & \cfrac{1}{T_d} & -1 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & a_{1y} & a_{2y} \end{bmatrix}\begin{bmatrix} y \\ v_{ys} \\ v_y \\ a_y \end{bmatrix}+\begin{bmatrix} 0 \\ 0 \\ 0 \\ b_{1y} \end{bmatrix}{\varphi_{ref}} x˙v˙xsv˙xa˙x = 00000Td1001Td10a1x011a2x xvxsvxax + 000b1x θref y˙v˙ysv˙ya˙y = 00000Td1001Td10a1y011a2y yvysvyay + 000b1y φref

其中, a 1 x = a 1 y = − 1.4 a_{1x}= a_{1y}=-1.4 a1x=a1y=1.4 a 2 x = a 2 y = − 7.2 a_{2x}= a_{2y}=-7.2 a2x=a2y=7.2 b 1 x = b 1 y = 0.1177 b_{1x}= b_{1y}=0.1177 b1x=b1y=0.1177 T d = 0.08 T_{d}=0.08 Td=0.08。要求在 5 s 5 s 5s 以内收敛于原点,无人机位置的初始位置为 ( 5 m , 4 m ) (5 m, 4 m) (5m,4m)

仿真

主函数

clear;clc;
close all;

%% UAV Model
Sim_Time = 10;
Ts = 0.01;
[Ad, Bd] = UAV_Model(Ts);

%% Initialize
Predict_Step = 20;
Q = diag([200, 30, 20, 1]); % Elements depends on states
F = diag([200, 30, 20, 1]); % Elements depends on states
R = diag([0.0002]);         % Elements depends on input

X = [5, 0, 0, 0]';
Y = [4, 0, 0, 0]';

[G, E, H] = MPC_Matrices(Ad, Bd, Q, R, F, Predict_Step);    % Call MPC_Matrices

%% Start Simulate
for i = 1:1:Sim_Time/Ts
    t(i) = i*Ts;
    
    pitch_ref = Prediction(X, Y, G, E, H);
    roll_ref = Prediction(Y, X, G, E, H);
    
    % State update under the input
    X = Ad*X + Bd*pitch_ref;
    Y = Ad*Y + Bd*roll_ref;
    
    % Data Record
    X_Ap(i,:) = X;
    Y_Ap(i,:) = Y;
    Ref_pitch_Ap(i) = pitch_ref;
    Ref_roll_Ap(i) = roll_ref;
end

figure('Name','State and Reference','NumberTitle','off')
% X Direction
subplot(221)
plot(t, X_Ap(:,1),'r',t, X_Ap(:,2),t, X_Ap(:,4),'linewidth',1.5);grid;
legend('Pos','Vel','Acc');
legend('boxoff');
xlabel('Time(s)');ylabel('States');title('(a) X Direction');
subplot(222)
plot(t, Ref_pitch_Ap,'linewidth',1.5);grid;
xlabel('Time(s)');ylabel('Att(rad)');title('(b) Ref Pitch');
% Y Direction
subplot(223)
plot(t, Y_Ap(:,1),'r',t, Y_Ap(:,2),t, Y_Ap(:,4),'linewidth',1.5);grid;
legend('Pos','Vel','Acc');
legend('boxoff');
xlabel('Time(s)');ylabel('States');title('(a) Y Direction');
subplot(224)
plot(t, Ref_roll_Ap,'linewidth',1.5);grid;
xlabel('Time(s)');ylabel('Att(rad)');title('(b) Ref Roll');

% Dynamic Plot
figure('Name','Dynamic Plot','NumberTitle','off')
for i = 1:1:Sim_Time/Ts
    drawnow;
    t(i) = i*Ts;
    
    x_pos(i) = X_Ap(i,1);
    y_pos(i) = Y_Ap(i,1);
    plot(x_pos,y_pos,'b',x_pos(i),y_pos(i),'*');
    text(-3,3,['Time:  ',num2str(t(i))],'FontSize',13);
    axis([-5,5,-5,5]);
    grid on;
    pause(0.001);
end
% End Dynamic Plot

UAV_Model.m

%{
    UAV model include position, velocity, delayed-velocity and acceleration
in X-axis and Y-axis. State = [Pos, Vel-delay, Vel, Acc];
%}

function [Ad, Bd] = UAV_Model(Ts)

Td = 0.08;
a1 = -1.4;
a2 = -7.2;
b1 = 0.1177;

A = [0     0    1    0;
     0 -1/Td 1/Td   -1;
     0     0    0    1;
     0     0   a1   a2];

B = [0     0    0   b1]';

C = [1     0    0    0];
D = 0;

[Ad, Bd, Cd, Dd] = c2dm(A, B, C, D, Ts);

end

MPC_Matrices.m

function [G, E, H] = MPC_Matrices(A, B, Q, R, F, N)
% N is predict length
n = size(A, 1);
p = size(B, 2);

M = [        eye(n);     
      zeros(N*n, n)];
C = zeros((N + 1)*n, N*p); 

% Caculate M and C
tmp = eye(n);
for i = 1 : N
    rows = i*n + (1 : n); % the current row
    C(rows, :) = [tmp*B, C(rows - n, 1 : end - p)];
    tmp = A*tmp;
    M(rows,:) = tmp;
end

% Caculate Q_bar and R_bar
Q_bar = blkdiag(kron(eye(N), Q), F);
R_bar = kron(eye(N), R);

% Caculate G, E, H
G = M'*Q_bar*M;
E = M'*Q_bar*C; 
H = C'*Q_bar*C+R_bar;

end

Prediction.m

%{
    Numerical solution of MPC: Quadratic Programming.
    *x_k: Current axis state
    *y_k: Another axis state
    *G
    *E
    *H
%}
function u_k = Prediction(x_k, y_k, G, E, H)

U_k = quadprog(H, 2*E'*x_k);  % E'*x_k is to satisfied quadprog form
u_k = U_k(1, 1);   % Select the first action as output

end

将所有文件放到同一路径下,运行主函数即可。运行结果如下:
在这里插入图片描述

附上两张实现过程的说明 (汇报PPT用的,懒得翻译了)。
在这里插入图片描述
在这里插入图片描述

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值