%% initclear all;close all;clc;format shortE;
%% simulation parameterstStart=0; % [s] simulation start timetEnd=1e-3; % [s] simulation stop time
%% sample timeTs = 10e-6; % [s] sample timedtMax = Ts/10; % [s] maximum step size for simulation
%% system descriptionn = 2; % system orderka = 0.0001; % system parameter 1kb = 0.0001; % system parameter 2
A = [-kb/ka 0; 1 0]; % continuous system matrixB = [1/ka ; 0]; % continuous input matrixG = [1 -1/ka; 0 0]; % continuous 'virtual input' matrix (LFT-form)C = [0 1]; % output to be controlled
%% discretizeAd = expm(A*Ts);e = @(x) expm(A*x);Bd = quadv(e,0,Ts)*B;Gd = quadv(e,0,Ts)*G;
% discrete matrices:A=Ad;B=Bd;G=Gd;
%% Minimax MPC (chapter 11)N = 5; % number of prediction stepsL = 2; % dimension of delta-matrix (number of uncertain parameters) % scalingss(1) = 0.1*1/ka; % 10% error for 1/kas(2) = 0.1*kb; % 10% error for kb
% matrices for LFT-descriptionDx = [ -kb*s(1) 0 ; s(2) 0 ];Du = [s(1); 0];Dp = [0 -s(1); 0 0];
% weightsdataRMPC.Qtilde = eye(N,N) * 1;dataRMPC.Rtilde = eye(N,N) * 0.1;
Asum = kron(eye(N-1,N-1),A);Bsum = kron(eye(N-1,N-1),B);Gsum = kron(eye(N-1,N-1),G);
% definitions on p.145 (eq.11.4a)Atilde = [ zeros( n,(N-1)*n ), zeros( n, n ); Asum, zeros( (N-1)*n, n ) ];Btilde = [ zeros( n,(N-1) ), zeros( n, 1 ); Bsum, zeros( (N-1)*n, 1 ) ];Gtilde = [ zeros( n,(N-1)*L), zeros( n, L ); Gsum, zeros( (N-1)*n, L ) ];
% definitions on p. 145 (eq. 11.4b)Ctilde = kron(eye(N,N),C);DxTilde = kron(eye(N,N),Dx);DpTilde = kron(eye(N,N),Dp);DuTilde = kron(eye(N,N),Du);
%% passing data to simulinkdataRMPC.n = n;dataRMPC.N = N;dataRMPC.L = L;dataRMPC.Atilde = Atilde;dataRMPC.Btilde = Btilde;dataRMPC.Ctilde = Ctilde;dataRMPC.DuTilde = DuTilde;dataRMPC.DxTilde = DxTilde;dataRMPC.Omega = DxTilde * inv(eye(size(Atilde))-Atilde) * Gtilde + DpTilde;dataRMPC.Lambda = inv(eye(size(Atilde))-Atilde) * Gtilde;
%% system for simulationtestSystem = ss(A,B,eye(n,n),0,Ts);x0 = [0;1]; % initial state
%% simulink busclear slBus1;Simulink.Bus.createObject(dataRMPC);
%% simulateopen('model');sim('model');
function [ uOpt, problem, solvertime ] = runRMPC(x,dataRMPC)
%% interface n = dataRMPC.n; N = dataRMPC.N; L = dataRMPC.L; Btilde = dataRMPC.Btilde; Ctilde = dataRMPC.Ctilde; DuTilde = dataRMPC.DuTilde; DxTilde = dataRMPC.DxTilde; Atilde = dataRMPC.Atilde; Lambda = dataRMPC.Lambda; Omega = dataRMPC.Omega; Qtilde = dataRMPC.Qtilde; Rtilde = dataRMPC.Rtilde; %% ensure x to be a column vector size_x=size(x); if (size_x(2)~=1) x=x'; else x=x; end %% problem description % variables t = sdpvar(1,1); U = sdpvar(N,1); tau = sdpvar(N,1); TauTilde = sdpvar(0,0);
% definitions b = [vec2col(x); zeros( (N-1)*n,1 ) ]; % (eq. 11.4c) Psi = DxTilde * inv(eye(size(Atilde))-Atilde) * (Btilde*U + b) + DuTilde*U; % (eq. 11.10c) Xtilde = inv(eye(size(Atilde))-Atilde) * (Btilde*U + b); % (eq. 11.10a) % very unsure about this: for i=1:N zerosBefore = (i-1)*L; zerosAfter = N*L-L-zerosBefore; matrix = tau(i)*eye(L,L); currentLine = [ zeros(L,zerosBefore) matrix zeros(L,zerosAfter) ]; TauTilde = [ TauTilde; currentLine ]; end Stilde = TauTilde; %sdisplay(TauTilde) % robust performance constraint Mconstr = [ t (Ctilde*Xtilde)' U' Psi' ; Ctilde*Xtilde inv(Qtilde)-Ctilde*Lambda*Stilde*Lambda'*Ctilde' zeros(N,N) -Ctilde*Lambda*Stilde*Omega' ; U zeros(N,N) inv(Rtilde) zeros(N,N*L) ; Psi -Omega*Stilde*Lambda'*Ctilde' zeros(N*L,N) TauTilde-Omega*Stilde*Omega' ]; constr1 = [ Mconstr >= 0 ]; % solve problem options=sdpsettings('solver','sdpt3','verbose', 0); diag=solvesdp(constr1,t,options) problem=diag.problem; solvertime=diag.solvertime; U = double(U) t = double(t) tau =double(tau)
% extract first solution uOpt = U(1); end
x = [0;1];u = sdpvar(N,1);obj = 0;for i = 1:N x = A*x + B*u(i); obj = obj + x'*x+u(i)^2;endsolvesdp([],obj)double(u)
% variables t = sdpvar(1,1); U = sdpvar(N,1); tau = sdpvar(N,1); TauTilde = sdpvar(0,0);
% definitions b = [vec2col(x); zeros( (N-1)*n,1 ) ]; % (eq. 11.4c) Psi = DxTilde * inv(eye(size(Atilde))-Atilde) * (Btilde*U + b) + DuTilde*U; % (eq. 11.10c) Xtilde = inv(eye(size(Atilde))-Atilde) * (Btilde*U + b); % (eq. 11.10a)
% very unsure about this (and very unefficient):
> pole(ss(A,B,C,0))
ans =
0
-1
>> tzero(ss(A,B,C,0))
ans =
Empty matrix: 0-by-1
U = sdpvar(N,1);
obj = 0;
for i = 1:
N
obj = obj + x'*x+0.1*U(i)*U(i);
end
solvesdp([],obj);
uOpt = double(U(1));
problem = 0;
solvertime = 0;
%% initclear all;close all;clc;format shortE;
%% simulation parameterstStart=0; % [s] simulation start time
tEnd=8e-4; % [s] simulation stop time
%% sample times
Ts = 10e-6; % [s] sample timedtMax = Ts/10; % [s] maximum step size for simulation
%% reference signalload yRef;
%% initial statex0 = [0 0 0 0 0]'; %% general dataN = 10; % number of prediction stepsn = 5; % system orderL = 9; % number of uncertainties / dimension of square delta-matrix
%% weights Qtilde = eye(N,N) * 1; Rtilde = eye(N,N) * 0.1;
%% LFT-model
% load data load LFTdataZero; % 0% uncertainty%load LFTdataFive; % 5% uncertainty in each parameter
% continuous LFT matricesAc =LFTdata.Ac;Bc =LFTdata.Bc;Gc =LFTdata.Gc;C =LFTdata.C;Dx =LFTdata.Dx;Du =LFTdata.Du;Dp =LFTdata.Dp;
% discretization of LFT modelsysc = ss(Ac,[Bc Gc],zeros(1,n),0);sysd = c2d(sysc,Ts,'zoh');
Ad = sysd.a;tempB = sysd.b;Bd = tempB(:,1);Gd = tempB(:,2:end);
% try to normalize (discrete) system matricesSx = diag([ 2.0000e+00, 1.5625e-02, 1.2800e+02, 1.5625e-02, 1.2800e+02 ]); % computed via prescale.mSu = 1e5;Sp = diag([1e7 1e3 1e0 1e3 1e6 1e7 1e-1 1e-1 1e0]); SxInv = inv(Sx);SuInv = inv(Su);SpInv = inv(Sp);
Ad = SxInv*Ad*Sx;Bd = SxInv*Bd*Su;Gd = SxInv*Gd*Sp;C = C*Sx;Dx = Dx*Sx;Du = Du*Su;Dp = Dp*Sp;
%% problem description yalmip('clear');
t = sdpvar(1,1);x = sdpvar(n,1);U = sdpvar(N,1);yRefN = sdpvar(N,1);
tau = sdpvar(N,1);TauTilde = sdpvar(0,0);
Asum = kron(eye(N-1,N-1),Ad);Bsum = kron(eye(N-1,N-1),Bd);Gsum = kron(eye(N-1,N-1),Gd);Ctilde = kron(eye(N,N),C);
% eq. (11.4)
Atilde = [ zeros( n,(N-1)*n ), zeros( n, n ); Asum, zeros( (N-1)*n, n ) ];Btilde = [ zeros( n,(N-1) ), zeros( n, 1 ); Bsum, zeros( (N-1)*n, 1 ) ];Gtilde = [ zeros( n,(N-1)*L), zeros( n, L ); Gsum, zeros( (N-1)*n, L ) ];
DxTilde = kron(eye(N,N),Dx);DpTilde = kron(eye(N,N),Dp);DuTilde = kron(eye(N,N),Du);
b = [x; zeros( (N-1)*n,1 ) ];
% eq. (11.10)
Xtilde = inv(eye(size(Atilde))-Atilde) * (Btilde*U + b);
Lambda = inv(eye(size(Atilde))-Atilde) * Gtilde;
Psi = DxTilde * inv(eye(size(Atilde))-Atilde) * (Btilde*U + b) + DuTilde*U;
Omega = DxTilde * inv(eye(size(Atilde))-Atilde) * Gtilde + DpTilde;
for i=1:N zerosBefore = (i-1)*L; zerosAfter = N*L-L-zerosBefore; matrix = tau(i)*eye(L,L); currentLine = [ zeros(L,zerosBefore) matrix zeros(L,zerosAfter) ]; TauTilde = [ TauTilde; currentLine ];endStilde = TauTilde;
% robust performance constraintMconstr = [ t (Ctilde*Xtilde)'-yRefN' U' Psi' ; Ctilde*Xtilde-yRefN inv(Qtilde)-Ctilde*Lambda*Stilde*Lambda'*Ctilde' zeros(N,N) -Ctilde*Lambda*Stilde*Omega' ;
U zeros(N,N) inv(Rtilde) zeros(N,N*L) ; Psi -Omega*Stilde*Lambda'*Ctilde' zeros(N*L,N) TauTilde-Omega*Stilde*Omega' ];
constr = [ Mconstr >= 0 ];
% input constraintuMax = 30;if (1) constr = [ constr, U<=SuInv*ones(N,1)*uMax, U>=-SuInv*ones(N,1)*uMax ];end % optimizer objectsolver = 2;switch solver case 1 options=sdpsettings('solver','lmilab'); case 2 options=sdpsettings('solver','sdpt3'); case 3 options=sdpsettings('solver','sedumi');endcontrollerRMPC = optimizer(constr,t,options,{x,yRefN},U(1));
% pass data to simulinkdataRMPC.N = N; dataRMPC.yRef = yRef; dataRMPC.SxInv = SxInv;dataRMPC.Su = Su;
function [ uOpt, problem, solvertime ] = runRMPC(xIn,k) %% get data from workspace controllerRMPC = evalin('base','controllerRMPC'); dataRMPC = evalin('base','dataRMPC'); N = dataRMPC.N; yRef = dataRMPC.yRef; kEnd = length(yRef); %% normalize state measurement xIn=dataRMPC.SxInv*xIn;
%% building reference for prediction (moving horizon) kN = kEnd - N; if ( k < kN) yRefN = yRef(k:k+N-1)'; else % in case of reaching the end of simulation, extend time horizon based on last known value yRefN = [ yRef(k:kEnd) yRef(kEnd)*ones(1,N-(kEnd-k)) ]'; end
%% solve SDP tic; [uOpt, problem] = controllerRMPC{{xIn,yRefN}}; solvertime = toc;
%% denormalize calculated control action uOpt = dataRMPC.Su*uOpt;
end