代码段
% MATLAB program for Linear MPC: Single-input system
clear all;
close all
% System parameters and simulation parameters
A=[0.9 0.2;-0.4 0.8];
B=[0.1;0.01];
NT=50;N=5;n=2;m=1;
Q=eye(n); QN=Q; R=eye(m);
Fx=[1 0;0 1;-1 0;0 -1];gx=[1;1;1;1];
Fu=[1;-1];gu=[1;1];
x0=[10;5];
x=zeros(n,NT+1); x(:,1)=x0;
Xk=zeros(n*(N+1),1); Xk(1:n,1)=x0;
u=zeros(m,NT);
Uk=zeros(m*N,1);
zk=[Xk;Uk];
% constructing AX,BU,QX,RU,FX,gX,FU,gU,H
for i=1:N+1
AX((i-1)*n+1:i*n,:)=A^(i-1);
end
for i=1:N+1
for j=1:N
if i>j
BU((i-1)*n+1:i*n,(j-1)*m+1:j*m)=A^(i-j-1)*B;
else
BU((i-1)*n+1:i*n,(j-1)*m+1:j*m)=zeros(n,m);
end
end
end
QX=Q;RU=R;
FX=Fx;gX=gx;FU=Fu;gU=gu;
for i=1:N-1
QX=blkdiag(QX,Q); RU=blkdiag(RU,R);
FX=blkdiag(FX,Fx);gX=[gX;gx];
FU=blkdiag(FU,Fu);gU=[gU;gu];
end
QX=blkdiag(QX,QN);
FX=blkdiag(FX,Fx);
gX=[gX;gx];
H=blkdiag(QX,RU);
% simulating system with MPC
for k=1:NT
xk=x(:,k);
fun = @(z)z'*H*z;
F=blkdiag(FX,FU);g=[gX;gU];Feq=[eye((N+1)*n) -BU];geq=AX*xk;
lb=[];ub=[];
z=fmincon(fun,zk,F,g,Feq,geq,lb,ub)
u(:,k)=z((N+1)*n+1:(N+1)*n+m,1);
x(:,k+1)=A*x(:,k)+B*u(:,k);
zk=z;
end
% plotting response
figure(1)
time = (0:NT);
subplot(2,1,1)
plot(time,x(1,:),'r.-','LineWidth',.7)
hold on
plot(time,x(2,:),'k.-','LineWidth',.7)
legend('$x_1$','$x_2$','Interpreter','latex');
%axis ([0 50-10 10])
xlabel('$k$','Interpreter','latex');ylabel('$\textbf{x}_{k}$','Interpreter','latex');
subplot(2,1,2)
stairs(time(1:end-1),u,'r.-','LineWidth',.7)
%axis([0 50 -10 0])
xlabel('$k$','Interpreter','latex');ylabel('${u}_{k}$','Interpreter','latex');
仿真:
注意:上面也可以把状态的不等式约束放入变量最大最小值中:
MATLAB program for Linear MPC: Single-input system (alternate code for LMPC_1.m with constraints defined using lb and ub)
clear all;
close all
% System parameters and simulation parameters
A=[0.9 0.2;-0.4 0.8];
B=[0.1;0.01];
NT=50;N=5;n=2;m=1;
Q=eye(n); QN=Q; R=eye(m);
xmin=-10;xmax=10;umin=-1;umax=1;
x0=[10;5];
x=zeros(n,NT+1); x(:,1)=x0;
Xk=zeros(n*(N+1),1); Xk(1:n,1)=x0;
u=zeros(m,NT);
Uk=zeros(m*N,1);
zk=[Xk;Uk];
% constructing AX,BU,QX,RU,H
for i=1:N+1
AX((i-1)*n+1:i*n,:)=A^(i-1);
end
for i=1:N+1
for j=1:N
if i>j
BU((i-1)*n+1:i*n,(j-1)*m+1:j*m)=A^(i-j-1)*B;
else
BU((i-1)*n+1:i*n,(j-1)*m+1:j*m)=zeros(n,m);
end
end
end
QX=Q;RU=R;
for i=1:N-1
QX=blkdiag(QX,Q); RU=blkdiag(RU,R);
end
QX=blkdiag(QX,QN);
H=blkdiag(QX,RU);
% simulating system with MPC
for k=1:NT
xk=x(:,k);
fun = @(z)z'*H*z;
F=[];g=[];Feq=[eye((N+1)*n) -BU];geq=AX*xk;
lb=[xmin*ones(1,(N+1)*n),umin*ones(1,N*m)];
ub=[xmax*ones(1,(N+1)*n),umax*ones(1,N*m)];
z=fmincon(fun,zk,F,g,Feq,geq,lb,ub);
u(:,k)=z((N+1)*n+1:(N+1)*n+m,1);
x(:,k+1)=A*x(:,k)+B*u(:,k);
zk=z;
end
% plotting response
figure(1)
time = (0:NT);
subplot(2,1,1)
plot(time,x(1,:),'r.-','LineWidth',.7)
hold on
plot(time,x(2,:),'k.-','LineWidth',.7)
legend('$x_1$','$x_2$','Interpreter','latex');
%axis ([0 50-10 10])
xlabel('$k$','Interpreter','latex');ylabel('$\textbf{x}_{k}$','Interpreter','latex');
grid on
ax = gca;
set(gca,'xtick',[0:5:50])
set(gca,'ytick',[-10:5:10])
ax.GridAlpha = 1
ax.GridLineStyle = ':'
subplot(2,1,2)
stairs(time(1:end-1),u,'r.-','LineWidth',.7)
%axis([0 50 -10 0])
xlabel('$k$','Interpreter','latex');ylabel('${u}_{k}$','Interpreter','latex');
grid on
ax = gca;
set(gca,'xtick',[0:5:50])
set(gca,'ytick',[-1:.5:1])
ax.GridAlpha = 1
ax.GridLineStyle = ':'
print -dsvg lmpc1
注意:上面代码发现计算中变量比较多,会损失计算效率,下面给出改进:
% MATLAB program for Linear MPC: Reducing online computation (method 1)
clear all;
close all
% System parameters and simulation parameters
A=[0.9 0.2;-0.4 0.8];
B=[0.1;0.01];
NT=50;N=5;n=2;m=1;
Q=eye(n); QN=Q; R=eye(m);
Fx=[1 0;0 1;-1 0;0 -1];gx=[10;10;10;10];
Fu=[1;-1];gu=[1;1];
x0=[10;5];
x=zeros(n,NT+1); x(:,1)=x0;
Xk=zeros(n*(N+1),1); Xk(1:n,1)=x0;
u=zeros(m,NT);
Uk=zeros(m*N,1);
zk=Uk;
% constructing AX,BU,QX,RU
for i=1:N+1
AX((i-1)*n+1:i*n,:)=A^(i-1);
for j=1:N
if i>j
BU((i-1)*n+1:i*n,(j-1)*m+1:j*m)=A^(i-j-1)*B;
else
BU((i-1)*n+1:i*n,(j-1)*m+1:j*m)=zeros(n,m);
end
end
end
QX=Q;RU=R;
FX=Fx;gX=gx;FU=Fu;gU=gu;
for i=1:N-1
QX=blkdiag(QX,Q); RU=blkdiag(RU,R);
FX=blkdiag(FX,Fx);gX=[gX;gx];
FU=blkdiag(FU,Fu);gU=[gU;gu];
end
QX=blkdiag(QX,QN);
FX=blkdiag(FX,Fx);
gX=[gX;gx];
H=BU'*QX*BU+RU;
% simulating system with MPC
for k=1:NT
xk=x(:,k);
qk=2*xk'*AX'*QX*BU;rk=xk'*AX'*QX*AX*xk;
fun = @(z)z'*H*z+qk*z+rk;
F=[FX*BU;FU];g=[gX-FX*AX*xk;gU];Feq=[];geq=[];
lb=[];ub=[];
z=fmincon(fun,zk,F,g,Feq,geq,lb,ub);
u(:,k)=z(1:m,1);
x(:,k+1)=A*x(:,k)+B*u(:,k);
zk=z;
end
% plotting response
figure(1)
time = (0:NT);
subplot(2,1,1)
plot(time,x(1,:),'r.-','LineWidth',.7)
hold on
plot(time,x(2,:),'k.-','LineWidth',.7)
legend('$x_1$','$x_2$','Interpreter','latex');
axis([0 50 -10 10])
xlabel('$k$','Interpreter','latex');ylabel('$\textbf{x}_{k}$','Interpreter','latex');
grid on
ax = gca;
set(gca,'xtick',[0:5:50])
set(gca,'ytick',[-10:5:10])
ax.GridAlpha = 1
ax.GridLineStyle = ':'
subplot(2,1,2)
stairs(time(1:end-1),u,'r.-','LineWidth',.7)
%axis([0 50 -10 0])
xlabel('$k$','Interpreter','latex');ylabel('${u}_{k}$','Interpreter','latex');
grid on
ax = gca;
set(gca,'xtick',[0:5:50])
set(gca,'ytick',[-1:.5:1])
ax.GridAlpha = 1
ax.GridLineStyle = ':'
print -dsvg lmpc3
对于给定轨迹跟踪:
% MATLAB program for Linear MPC: Set point tracking
clear all;
close all
% System parameters and simulation parameters
A=[0.9 0.2;-0.4 0.8];
B=[0.1;0.01];
NT=50;N=5;n=2;m=1;
Q=eye(n); QN=Q; R=eye(m);
xr=[3;2];ur=pinv(B)*(eye(n)-A)*xr;
Fx=[1 0;0 1;-1 0;0 -1];gx=[10;10;10;10]-Fx*xr;
Fu=[1;-1];gu=[1;1]-Fu*ur;
x0=[10;5];
x=zeros(n,NT+1); x(:,1)=x0-xr;
Xk=zeros(n*(N+1),1); Xk(1:n,1)=x0;
u=zeros(m,NT);
Uk=zeros(m*N,1);
zk=[Xk;Uk];
% constructing AX,BU,QX,RU,FX,gX,FU,gU,H
for i=1:N+1
AX((i-1)*n+1:i*n,:)=A^(i-1);
end
for i=1:N+1
for j=1:N
if i>j
BU((i-1)*n+1:i*n,(j-1)*m+1:j*m)=A^(i-j-1)*B;
else
BU((i-1)*n+1:i*n,(j-1)*m+1:j*m)=zeros(n,m);
end
end
end
QX=Q;RU=R;
FX=Fx;gX=gx;FU=Fu;gU=gu;
for i=1:N-1
QX=blkdiag(QX,Q); RU=blkdiag(RU,R);
FX=blkdiag(FX,Fx);gX=[gX;gx];
FU=blkdiag(FU,Fu);gU=[gU;gu];
end
QX=blkdiag(QX,QN);
FX=blkdiag(FX,Fx);
gX=[gX;gx];
H=blkdiag(QX,RU);
% simulating system with MPC
for k=1:NT
xk=x(:,k);
fun = @(z)z'*H*z;
F=blkdiag(FX,FU);g=[gX;gU];Feq=[eye((N+1)*n) -BU];geq=AX*xk;
lb=[];ub=[];
z=fmincon(fun,zk,F,g,Feq,geq,lb,ub);
u(:,k)=z((N+1)*n+1:(N+1)*n+m,1);
x(:,k+1)=A*x(:,k)+B*u(:,k);
zk=z;
end
% plotting response
figure(1)
time = (0:NT);
subplot(2,1,1)
plot(time,x(1,:)+xr(1),'r.-','LineWidth',0.7)
hold on
plot(time,x(2,:)+xr(2),'k.-','LineWidth',0.7)
legend('$x_1$','$x_2$','Interpreter','latex');
axis ([0 50 -10 10])
xlabel('$k$','Interpreter','latex');ylabel('$\textbf{x}_{k}$','Interpreter','latex');
grid on
ax = gca;
set(gca,'xtick',[0:5:50])
set(gca,'ytick',[-10:5:10])
ax.GridAlpha = 1
ax.GridLineStyle = ':'
subplot(2,1,2)
stairs(time(1:end-1),u-pinv(B)*(A-eye(n))*xr,'r.-','LineWidth',0.7)
axis ([0 50 -1 1])
xlabel('$k$','Interpreter','latex');ylabel('${u}_{k}$','Interpreter','latex');
grid on
ax = gca;
set(gca,'xtick',[0:5:50])
set(gca,'ytick',[-1:.5:1])
ax.GridAlpha = 1
ax.GridLineStyle = ':'
print -dsvg lmpc5