MATLAB: S-function error

MATLABs-functionsimulink

Hello, I have problem with my s-function
=== Simulation (Elapsed: 3 sec) ===
Number of unfalsified controllers at the end =
30
Error:An error occurred while running the simulation and the simulation was terminated
Caused by:
Error in 'planta/ /Controller Selector' while executing MATLAB S-function 'Supervisor', flag = 3 (output), at time 0.05.
Array indices must be positive integers or logical values.
And this is my s-function:
function [sys,x0,str,ts] = Supervisor(t,x,u,flag, ...
C_p, C_i, C_d)
persistent u_dat
global delta %delta - sampling time
%initialize
sys=[];x0=[];str=[];ts=[];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>> Initialization routine <<< %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if flag == 0
sizes = simsizes;
[u_dat.K, u_dat.m] = form_K_set(C_p, C_i, C_d);
u_dat.total_number = u_dat.m; % initial number of elements of the candidate controller set K
sizes.NumContStates = 0;
sizes.NumDiscStates = 0;
sizes.NumOutputs = u_dat.total_number + 4;
sizes.NumInputs = u_dat.total_number;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
u_dat.J = zeros(u_dat.m,1);
u_dat.index = [1:u_dat.m]';
u_dat.temp = zeros(u_dat.m,0); %%% for determining instantaneous cost
u_dat.myj = zeros(u_dat.m,0);
u_dat.count = 0;
[u_dat.kp, u_dat.ki, u_dat.kd] = set_K_parameter(u_dat.K, u_dat.index, u_dat.m);
u_dat.cur_index = u_dat.m;
str = []; ts = [delta 0];% sample time is delta
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
elseif flag == 1
sys = [];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>> state update routine <<< %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
elseif flag == 2
kp_current = u_dat.kp;
ki_current = u_dat.ki;
kd_current = u_dat.kd;
u_dat.count = u_dat.count + 1;
u_dat.J = u; %% Input u(n) is the cost of n th Candidate Controller
j=0; %% Initilize the number of Unfalsified Controller
for i=1:u_dat.m % u_dat.m - # of unfalsified controller candidates
[cp, ci, cd] = set_K_parameter(u_dat.K, u_dat.index, i);
if u_dat.J(u_dat.index(i)) <= 0 %% if ith controller is unfalsified
j = j+1; %% j : # of unfalsified Controllers
u_dat.index(j) = u_dat.index(i);
end
end
p = u_dat.J(u_dat.cur_index); %% Cost of current Controller
u_dat.m = j; %% # of unfalsified controllers up to now
if u_dat.m == 0 %% If all controllers has been falsified
error('All Controllers Has been falsified; try increasing the set of initial candidate controllers');
elseif (p > 0) %%% If cost of current controller > 0, change the controller
[c, next_controller] = min(u_dat.J(u_dat.index(1:u_dat.m))); %%% New Controller selection Criterion
u_dat.kp = u_dat.K(u_dat.index(next_controller), 1);
u_dat.ki = u_dat.K(u_dat.index(next_controller), 2);
u_dat.kd = u_dat.K(u_dat.index(next_controller), 3);
u_dat.cur_index = u_dat.index(next_controller);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>> Output routine <<< %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
elseif flag == 3
if (u_dat.count == 1)
plot_Contr_index('change')%for simulink scope initialization, changing the attributes of controller index scope lines
end
u_dat.controller=[]; %%% For online Simulink Plot of unfalsified controller indices
for i=1:u_dat.total_number
u_dat.controller=[u_dat.controller inf];
end
for i=1:u_dat.m
u_dat.controller(u_dat.index(i)) = u_dat.index(i);
end
% out put kp,ki,kd, Current Controller Index & all Unfalsified Controller Index
sys = [u_dat.kp; u_dat.ki; u_dat.kd; u_dat.cur_index; u_dat.controller'];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
elseif flag == 4
sys = [];
elseif flag == 9
sys = [];
disp('Number of unfalsified controllers at the end = ')
disp(u_dat.m)
end
Is my first time using the block s-function and i don't know what happened

Best Answer

  • We can predict that set_K_parameter has side effects: you call it inside the loop but you never use the output values.
    u_dat.J(u_dat.index(i)) is not changed in the loop in any obvious way, so there is no obvious reason to do the test after calling the set -- but if set_K_parameter has hidden side effects, that would give a reason.
    We can speculate that set_K_parameter has a side effect on u_dat.index
    That said: the error message appears to be arising from a mdlOutputs (flag == 3) being invoked after mdlTerminate (flag == 9), which is not to be expected. In a case where mdlOutputs is invoked after termination, we could speculate that other states might have been invoked, and that the state of the variables might be inconsistent.
    We could also speculate that this might have been the first output call, and that the problem is occuring in the call to plot_Contr_index('change') rather than in working with the indices.
    I suggest adding a few more disp() statements, such as showing the flag called with, and adding an error in flag 3 if u_dat.index(i) is <= 0 or not an integer.