How to set a constraint to limit rate of change of output in s function
5 views (last 30 days)
Show older comments
I have a simulink model where I have used an s-function block and based on the value of Preq and SOC the s-function provides an output based the algorithm shown below. I want the rate of change of output y(1) to be limited to 50. Please let me know how to do it. I am using fmincon optimization to obtain the output. I think a non linear constraint must be used to do this where the difference between the current output value and the previous output value must be 50. but I do not know how to call the current output value and previous output value while using an s function
function [sys,x0,str,ts,simStateCompliance] = trail1(t,x,u,flag)
switch flag
% Initialization %
case 0
[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes;
% Derivatives %
case 1
sys=mdlDerivatives(t,x,u);
% Update %
case 2
sys=mdlUpdate(t,x,u);
% Outputs %
case 3
sys=mdlOutputs(t,x,u);
% GetTimeOfNextVarHit %
case 4
sys=mdlGetTimeOfNextVarHit(t,x,u);
% Terminate %
case 9
sys=mdlTerminate(t,x,u);
% Unexpected flags %
otherwise
DAStudio.error('Simulink:blocks:unhandledFlag', num2str(flag));
end
% end sfuntmpl
%
%=============================================================================
% mdlInitializeSizes
% Return the sizes, initial conditions, and sample times for the S-function.
%=============================================================================
%
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates = 0;
sizes.NumDiscStates = 0;
sizes.NumOutputs = 3; %% the three outputs are the power delivered by fuel cell, battery and the equivalent factor
sizes.NumInputs = 2; %% Inputs are Power required and SOC
sizes.DirFeedthrough = 1; %% because output is a function of SOC
sizes.NumSampleTimes = 1; %% at least one sample time is needed
sys = simsizes(sizes);
%
% initialize the initial conditions
%
x0 = [];
%
% str is always an empty matrix
%
str = [];
%
% initialize the array of sample times
%
ts = [-1 0];
% Specify the block simStateCompliance. The allowed values are:
% 'UnknownSimState', < The default setting; warn and assume DefaultSimState
% 'DefaultSimState', < Same sim state as a built-in block
% 'HasNoSimState', < No sim state
% 'DisallowSimState' < Error out when saving or restoring the model sim state
simStateCompliance = 'UnknownSimState';
% end mdlInitializeSizes
%
%=============================================================================
% mdlDerivatives
% Return the derivatives for the continuous states.
%=============================================================================
%
function sys=mdlDerivatives(t,x,u) %#ok<*INUSD>
sys = [];
% end mdlDerivatives
%
%=============================================================================
% mdlUpdate
% Handle discrete state updates, sample time hits, and major time step
% requirements.
%=============================================================================
%
function sys=mdlUpdate(t,x,u)
sys = [];
% end mdlUpdate
%
%=============================================================================
% mdlOutputs
% Return the block outputs.
%=============================================================================
%
function sys=mdlOutputs(t,x,u)
%constants initialization
Pbatt_char= 7000;
SOC_min=0.4;
SOC_max=0.90;
Pfc_min=5000;
Pfc_max=7000;
Pbatt_max=15000;
%define Matrix Aeq
Aeq=[0 1 0;1 0 1];
%define Matrix beq
mu = 0.6;
beq=[(1-2*mu*((u(2)-0.5*(SOC_max-SOC_min))/(SOC_max-SOC_min))); u(1)];
%define boundary conditions
lb=[Pfc_min, 0, -Pbatt_char];
ub=[Pfc_max, 100, Pbatt_max];
%defining initial conditions
x0 = [7000 0 6000];
options = optimoptions('fmincon','Algorithm','active-set','Display','off','MaxFunctionEvaluations',1000,'MaxIterations',100);
[y,fval] = fmincon('OF_ECMS',x0,[],[],Aeq,beq,lb,ub,[],options); %#ok<*ASGLU>
Pfc=y(1); Pbatt=y(3); alpha=y(2);
sys = [Pfc Pbatt alpha];
% end mdlOutputs
%
%=============================================================================
% mdlGetTimeOfNextVarHit
% Return the time of the next hit for this block. Note that the result is
% absolute time. Note that this function is only used when you specify a
% variable discrete-time sample time [-2 0] in the sample time array in
% mdlInitializeSizes.
%=============================================================================
%
function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1; % Example, set the next hit to be one second later.
sys = t + sampleTime;
% end mdlGetTimeOfNextVarHit
%
%=============================================================================
mdlTerminate
Perform any end of simulation tasks.
% =============================================================================
function sys=mdlTerminate(t,x,u)
sys = [];
% end mdlTerminate
Objective function code is
function f = OF_ECMS(x)
f = (x(1)+x(2)*x(3));
2 Comments
Answers (1)
Stephen Eltinge
on 7 Dec 2022
Hi aditya,
To write an S-Function block that recalls its previous output, please look into adding a discrete state to the S-Function. See the "unit delay" Level-2 MATLAB S-Function example for a simple starting point. You should then be able to use the state's data to provide an additional constraint for your optimization function.
6 Comments
Stephen Eltinge
on 10 Jan 2023
Hi aditya,
Please try replacing "OutPort" with "OutputPort" in its four occurrences near the end of your code.
See Also
Categories
Find more on Naming Conventions in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!