Added MATLAB rewrite of the CARNOT optimisation function
This commit is contained in:
parent
adf4d0e02a
commit
7f9719cc64
15 changed files with 463 additions and 0 deletions
177
Simulink/mpc_simulink/casadi_block.m
Normal file
177
Simulink/mpc_simulink/casadi_block.m
Normal file
|
@ -0,0 +1,177 @@
|
|||
classdef casadi_block < matlab.System & matlab.system.mixin.Propagates
|
||||
% untitled Add summary here
|
||||
%
|
||||
% This template includes the minimum set of functions required
|
||||
% to define a System object with discrete state.
|
||||
|
||||
properties
|
||||
% Public, tunable properties.
|
||||
|
||||
end
|
||||
|
||||
properties (DiscreteState)
|
||||
end
|
||||
|
||||
properties (Access = private)
|
||||
% Pre-computed constants.
|
||||
casadi_solver
|
||||
x0
|
||||
lbx
|
||||
ubx
|
||||
lbg
|
||||
ubg
|
||||
end
|
||||
|
||||
methods (Access = protected)
|
||||
function num = getNumInputsImpl(~)
|
||||
num = 2;
|
||||
end
|
||||
function num = getNumOutputsImpl(~)
|
||||
num = 1;
|
||||
end
|
||||
function dt1 = getOutputDataTypeImpl(~)
|
||||
dt1 = 'double';
|
||||
end
|
||||
function dt1 = getInputDataTypeImpl(~)
|
||||
dt1 = 'double';
|
||||
end
|
||||
function sz1 = getOutputSizeImpl(~)
|
||||
sz1 = [1,1];
|
||||
end
|
||||
function sz1 = getInputSizeImpl(~)
|
||||
sz1 = [1,1];
|
||||
end
|
||||
function cp1 = isInputComplexImpl(~)
|
||||
cp1 = false;
|
||||
end
|
||||
function cp1 = isOutputComplexImpl(~)
|
||||
cp1 = false;
|
||||
end
|
||||
function fz1 = isInputFixedSizeImpl(~)
|
||||
fz1 = true;
|
||||
end
|
||||
function fz1 = isOutputFixedSizeImpl(~)
|
||||
fz1 = true;
|
||||
end
|
||||
function setupImpl(obj,~,~)
|
||||
% Implement tasks that need to be performed only once,
|
||||
% such as pre-computed constants.
|
||||
|
||||
import casadi.*
|
||||
|
||||
T = 10; % Time horizon
|
||||
N = 20; % number of control intervals
|
||||
|
||||
% Declare model variables
|
||||
x1 = SX.sym('x1');
|
||||
x2 = SX.sym('x2');
|
||||
x = [x1; x2];
|
||||
u = SX.sym('u');
|
||||
|
||||
% Model equations
|
||||
xdot = [(1-x2^2)*x1 - x2 + u; x1];
|
||||
|
||||
% Objective term
|
||||
L = x1^2 + x2^2 + u^2;
|
||||
|
||||
% Continuous time dynamics
|
||||
f = casadi.Function('f', {x, u}, {xdot, L});
|
||||
|
||||
% Formulate discrete time dynamics
|
||||
% Fixed step Runge-Kutta 4 integrator
|
||||
M = 4; % RK4 steps per interval
|
||||
DT = T/N/M;
|
||||
f = Function('f', {x, u}, {xdot, L});
|
||||
X0 = MX.sym('X0', 2);
|
||||
U = MX.sym('U');
|
||||
X = X0;
|
||||
Q = 0;
|
||||
for j=1:M
|
||||
[k1, k1_q] = f(X, U);
|
||||
[k2, k2_q] = f(X + DT/2 * k1, U);
|
||||
[k3, k3_q] = f(X + DT/2 * k2, U);
|
||||
[k4, k4_q] = f(X + DT * k3, U);
|
||||
X=X+DT/6*(k1 +2*k2 +2*k3 +k4);
|
||||
Q = Q + DT/6*(k1_q + 2*k2_q + 2*k3_q + k4_q);
|
||||
end
|
||||
F = Function('F', {X0, U}, {X, Q}, {'x0','p'}, {'xf', 'qf'});
|
||||
|
||||
% Start with an empty NLP
|
||||
w={};
|
||||
w0 = [];
|
||||
lbw = [];
|
||||
ubw = [];
|
||||
J = 0;
|
||||
g={};
|
||||
lbg = [];
|
||||
ubg = [];
|
||||
|
||||
% "Lift" initial conditions
|
||||
X0 = MX.sym('X0', 2);
|
||||
w = {w{:}, X0};
|
||||
lbw = [lbw; 0; 1];
|
||||
ubw = [ubw; 0; 1];
|
||||
w0 = [w0; 0; 1];
|
||||
|
||||
% Formulate the NLP
|
||||
Xk = X0;
|
||||
for k=0:N-1
|
||||
% New NLP variable for the control
|
||||
Uk = MX.sym(['U_' num2str(k)]);
|
||||
w = {w{:}, Uk};
|
||||
lbw = [lbw; -1];
|
||||
ubw = [ubw; 1];
|
||||
w0 = [w0; 0];
|
||||
|
||||
% Integrate till the end of the interval
|
||||
Fk = F('x0', Xk, 'p', Uk);
|
||||
Xk_end = Fk.xf;
|
||||
J=J+Fk.qf;
|
||||
|
||||
% New NLP variable for state at end of interval
|
||||
Xk = MX.sym(['X_' num2str(k+1)], 2);
|
||||
w = {w{:}, Xk};
|
||||
lbw = [lbw; -0.25; -inf];
|
||||
ubw = [ubw; inf; inf];
|
||||
w0 = [w0; 0; 0];
|
||||
|
||||
% Add equality constraint
|
||||
g = {g{:}, Xk_end-Xk};
|
||||
lbg = [lbg; 0; 0];
|
||||
ubg = [ubg; 0; 0];
|
||||
end
|
||||
|
||||
% Create an NLP solver
|
||||
prob = struct('f', J, 'x', vertcat(w{:}), 'g', vertcat(g{:}));
|
||||
options = struct('ipopt',struct('print_level',0),'print_time',false);
|
||||
solver = nlpsol('solver', 'ipopt', prob, options);
|
||||
|
||||
obj.casadi_solver = solver;
|
||||
obj.x0 = w0;
|
||||
obj.lbx = lbw;
|
||||
obj.ubx = ubw;
|
||||
obj.lbg = lbg;
|
||||
obj.ubg = ubg;
|
||||
end
|
||||
|
||||
function u = stepImpl(obj,x,t)
|
||||
disp(t)
|
||||
tic
|
||||
w0 = obj.x0;
|
||||
lbw = obj.lbx;
|
||||
ubw = obj.ubx;
|
||||
solver = obj.casadi_solver;
|
||||
lbw(1:2) = x;
|
||||
ubw(1:2) = x;
|
||||
sol = solver('x0', w0, 'lbx', lbw, 'ubx', ubw,...
|
||||
'lbg', obj.lbg, 'ubg', obj.ubg);
|
||||
|
||||
u = full(sol.x(3));
|
||||
toc
|
||||
end
|
||||
|
||||
function resetImpl(obj)
|
||||
% Initialize discrete-state properties.
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue