please explain me how does the code work?
显示 更早的评论
classdef STLC_lti < handle
%STLC_lti generic ABCD/ABuBwCDuDw system controller
%
% system properties
properties
sys % system as control toolbox objec
sysd
nx
ny
nu
nw
x0
K
system_data
is_det % if this is 1, will use only Wref as disturbance (e.g., ignore
% potential uncertainty defined in w_ub and w_lb).
% If empty, this is decided in reset_data() based on w_ub and w_lb.
end
% controller properties
properties
u_lb
u_ub
u_delta = Inf
ts % sampling time
L % horizon
time
nb_stages = 1
var
stl_list
encoding % specifies the technique for encoding TODO
min_rob = 0.01 % TODO: if rob==0 use non robust encoding
lambda_rho = 1 % weight of robustness in the cost function
bigM = 1000
nrm = 1 % norm (default is 1)
solver_options
model_data
controller % YALMIP parametric problem for the controller
end
% adversary properties
properties
Wref % this defines a default or initial disturbance vector
w_lb % lower bound on w relative to Wref
w_ub % upper bound on w relative to Wref
max_react_iter =10 % maximum number of iterations
adversary % YALMIP parametric problem for the adversary
end
% plotting properties
properties
h
xlabel % labels (names) for x signals
ylabel
ulabel
wlabel
plot_x % indices of states to plot
plot_y % indices of outputs to plot
plot_u % index of inputs to plot
plot_w % index of disturbances to plot
end
% misc
properties
stop_button = 1
verbose
end
methods
% Constructor
function Sys = STLC_lti(varargin)
switch nargin
case 2
% constructor from AB system
A = varargin{1};
Bu = varargin{2};
Bw = [];
C = [];
Du = [];
Dw = [];
case 3
% constructor from ABuBw system
A = varargin{1};
Bu = varargin{2};
Bw = varargin{3};
C = [];
Du = [];
Dw = [];
case 4
% constructor from ABCD system
A = varargin{1};
Bu = varargin{2};
Bw = [];
C = varargin{3};
Du = varargin{4};
Dw = [];
% constructor from ABuBwCDuDw system
case 6
A = varargin{1};
Bu = varargin{2};
Bw = varargin{3};
C = varargin{4};
Du = varargin{5};
Dw = varargin{6};
end
nx = max([size(A,1), size(Bu,1), size(Bw,1),1]);
nu = max([size(Bu,2), size(Du,1)]);
if nu == 0
errormSys('System must have at least one input (non empty Bu or Du matrix)');
end
nw = max([size(Bw,2), size(Dw,1),1]);
ny = max([size(C,1), size(Du,1), size(Dw,1),1]);
% default plots everything
Sys.plot_x = 1:max([size(A,1), size(Bu,1), size(Bw,1)]);
Sys.plot_u = 1:nu;
Sys.plot_y = 1:max([size(C,1), size(Du,1), size(Dw,1)]);
Sys.plot_w = 1:max([size(Bw,2), size(Dw,1)]);
% checks empty matrices
if isempty(A) % no state
A = zeros(nx,nx);
end
if isempty(Bu)
Bu = zeros(nx,nu);
end
if isempty(Bw) % no disturbance
Bw = zeros(nx,nw);
end
if isempty(C)
C = zeros(ny,nx);
end
if isempty(Du)
Du = zeros(ny,nu);
end
if isempty(Dw)
Dw = zeros(ny,nw);
end
Sys.sys = ss(A,[Bu Bw],C,[Du Dw]);
Sys.nx = size(A,2);
Sys.nu = size(Bu,2);
Sys.nw = size(Bw,2);
Sys.ny = size(C,1);
Sys.x0 = zeros(Sys.nx,1);
Sys.K = zeros(Sys.nx,1); % additive component for control
% default label names
Sys.xlabel = cell(1,nx);
for iX = 1:Sys.nx
Sys.xlabel{iX} = ['x' num2str(iX)];
end
for iY = 1:Sys.ny
Sys.ylabel{iY} = ['y' num2str(iY)];
end
for iU = 1:Sys.nu
Sys.ulabel{iU} = ['u' num2str(iU)];
end
for iW = 1:Sys.nw
Sys.wlabel{iW} = ['w' num2str(iW)];
end
% default options
solver = 'gurobi'; % gurobi, cplex, glpk
timeLimit = 2000;
gapLimit = 0.1;
gapAbsLimit = 0.01;
solnLimit = Inf;
verb = 1;
Sys.solver_options = sdpsettings('verbose', verb,'solver', solver, ...
'gurobi.TimeLimit', timeLimit, ...
'gurobi.MIPGap', gapLimit, ...
'gurobi.MIPGapAbs', gapAbsLimit, ...
'gurobi.SolutionLimit', solnLimit,...
'cachesolvers',1);
% default values for input constraints - note, forces u to 0
Sys.u_lb = zeros(1,Sys.nu);
Sys.u_ub = zeros(1,Sys.nu);
Sys.u_delta = Inf*ones(1,Sys.nu);
% default values for disturbance constraints - note:w_lb and w_ub are relative to Wref
% i.e., wref+w_lb <= w <= wref + w_ub. Thus by default, w == Wref
Sys.w_lb = zeros(1,Sys.nw);
Sys.w_ub = zeros(1,Sys.nw);
end
% default objective function r is the robust sat. and wr a weight
function obj = get_objective(Sys, X, Y, U,W, rho,wr,wt1)
switch nargin
case {4,5}
obj = norm(sum(abs(U),2), Sys.nrm); % minimize U
case 6
obj = norm(sum(abs(U),2), Sys.nrm)-norm(sum(rho,2), Sys.nrm); % minimize U penalized by r
case 7
obj = norm(sum(abs(U),2), Sys.nrm)-wr*norm(sum(rho,2), Sys.nrm);
case 8
obj = -wr*wt1*norm(rho(:,1), Sys.nrm)-wr*norm(sum(rho(:,2:end),2), Sys.nrm)+norm(sum(abs(U),2), Sys.nrm);
end
end
% System step, using the continuous time simulation
function [Y,T,X] = system_step(Sys, u0, t, x0, w0)
U = [u0; w0];
[Y,T,X] = lsim(Sys.sys, U',t-t(1),x0);
end
% Get disturbance - default reads Wref, adds random value in
% disturbance range
function w = get_disturbance(Sys)
it = Sys.system_data.time_index;
w = [Sys.Wref(:,it) Sys.Wref(:,it+1)];
if ~Sys.is_det
dw = ((Sys.w_ub-Sys.w_lb)').*(2*rand(Sys.nw,1)-1)/3;
w = w + [dw dw];
end
end
% Applies input for one discrete step, updates the model data
% requires that compute_input was called before
function Sys = apply_input(Sys)
Sys = STLC_apply_input(Sys);
end
% Computes the optimizer object for the controller
function controller = get_controller(Sys,enc)
if nargin < 2
if isempty(Sys.encoding)
enc = 'robust';
else
enc = Sys.encoding;
end
end
Sys.sysd = c2d(Sys.sys, Sys.ts);
controller = STLC_get_controller(Sys,enc);
end
% Computes the optimizer object for the adversary/disturbance
function adversary = get_adversary(Sys)
Sys.sysd = c2d(Sys.sys, Sys.ts);
adversary = STLC_get_adversary(Sys);
end
% reset system and model data
function Sys = reset_data(Sys)
if isempty(Sys.Wref)
Sys.Wref = 0*Sys.time;
end
if isempty(Sys.is_det)
if any(Sys.w_ub-Sys.w_lb)
Sys.is_det = 0;
else
Sys.is_det = 1;
end
end
% implements nb_stages here
if Sys.nb_stages>1
fprintf('Updating time and Wref based on nb_stages=%d\n', Sys.nb_stages); % TODO unverbose/verbose that out
nb_stages_=Sys.nb_stages;
time_ = Sys.time;
ntime = zeros(1, nb_stages_*numel(time_));
for istage = 0:nb_stages_-1
ntime(istage*numel(time_)+1:(istage+1)*numel(time_))= time_+istage*(time_(end)+time_(2)) ;
end
Sys.time = ntime;
Sys.Wref = repmat(Sys.Wref,1,Sys.nb_stages);
Sys.nb_stages=1;
end
Sys.sysd = c2d(Sys.sys, Sys.ts);
Sys.system_data=struct;
Sys.model_data=struct;
Sys.system_data.time = [];
Sys.system_data.U = [];
Sys.system_data.X = Sys.x0;
Sys.system_data.Y = [];
Sys.system_data.W = [];
Sys.system_data.time_index = 1;
Sys.model_data.time_index = 0;
Sys.model_data.time = [];
Sys.model_data.X = [];
Sys.model_data.Y = [];
Sys.model_data.U = [];
Sys.model_data.W = [];
Sys.model_data.Wbad = [];
end
%
function [Sys, status] = compute_input(Sys, controller)
% computes the next input and update model data
% status is 0 if everything is OK
[Sys, status] = STLC_compute_input(Sys, controller);
end
% computes the next disturbance and update model data
% status is 0 if a bad disturbance was found, 1 if control is
% good (no bad disturbance exist and -1 if some other error occured
function [Sys, status] = compute_disturbance(Sys, adversary)
[Sys, status] = STLC_compute_disturbance(Sys, adversary);
end
% Combines compute_input and compute_disturbance, and tries to
% find an input valid for all possible disturbances.
function [Sys, status_u, status_w] = compute_input_adv(Sys, controller, adversary)
[Sys, status_u, status_w] = STLC_compute_input_adv(Sys, controller, adversary);
end
% Executes the controller in open loop mode
function [Sys] = run_open_loop(Sys, controller)
Sys = STLC_run_open_loop(Sys, controller);
end
% Executes the controller in a receding horizon (MPC)
function [Sys] = run_deterministic(Sys, controller)
STLC_run_deterministic(Sys, controller);
end
% Executes controller and adversary in open loop
function Sys = run_open_loop_adv(Sys, controller, adversary)
STLC_run_open_loop_adv(Sys, controller, adversary)
end
% Executes controller and adversary in receding horizon mode (MPC)
function Sys = run_adversarial(Sys, controller, adversary)
STLC_run_adversarial(Sys, controller, adversary)
end
function rob = monitor(Sys,phi,enc)
Sys.h = [];
col = ['r','b','g'];
Sys.stl_list{1} = phi;
Sys.min_rob= -Sys.bigM;
Sys.controller = get_controller(Sys,enc);
Sys = Sys.run_open_loop(Sys.controller);
rob = Sys.model_data.rob;
figure;
hold on;
plot(Sys.model_data.time(1:size(rob,2)), rob(1,:), 'g', 'LineWidth',2);
end
% Default plot function
function Sys = update_plot(Sys)
Sys = STLC_update_plot(Sys);
end
function Wn = sensing(Sys)
Wn = STLC_sensing(Sys);
end
end
end
回答(1 个)
Steven Lord
2019-8-27
0 个投票
You should probably ask the author your questions about this code. You might also suggest that he or she comment their code which may preemptively answer future questions.
类别
在 帮助中心 和 File Exchange 中查找有关 Response Computation and Visualization 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!