MATLAB Answers

0

Setting output of a continuous S-Function

Asked by Chris Lim on 15 Jun 2016
Latest activity Answered by Dhruvesh Patel on 8 Aug 2016
Hi,
I have a continuous S-Function that solves the derivatives for various state properties within a ICE cylinder. As such, the output of the function is set to output the integral of those derivatives for each timestep which is a 7 element vector (1 for each of the properties being calculated)
block.OutputPort(1).Data = block.ContStates.Data;
At some point in the cycle I would like to change the value of this output to an explicit value (ie. not the integral of the derivative) such as below (in this case the explicit value being x):
block.OutputPort(1).Data = block.ContStates.Data;
block.OutputPort(1).Data(3) = x;
I'm using a if statement to switch into this alternative output. Through debugging, I think I've verified that Simulink is entering this block of code at the right point - however the output of the S-Function remains as the integral of the derivatives which gives me a non-finite error.
Any help or suggestions that would allow me to explicitly set the output of a continous S-Function would be much appreciated.
Thanks,
Chris

  0 Comments

Sign in to comment.

1 Answer

Answer by Dhruvesh Patel on 8 Aug 2016

If I am understanding correctly, you are trying to update the output of a MATLAB S-function block conditionally.
The following code depicts a simplified representative case which you can adapt to suit your requirement.
function myMSfunc2(block)
% Level-2 MATLAB file S-Function for continuous time demo
setup(block);
%endfunction
function setup(block)
%%Register number of input and output ports
block.NumInputPorts = 1;
block.NumOutputPorts = 1;
%%Setup functional port properties to dynamically
%%inherited.
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
block.InputPort(1).Dimensions = 2;
block.InputPort(1).DirectFeedthrough = true;
block.OutputPort(1).Dimensions = 2;
%%Set block sample time to continuous
block.SampleTimes = [0 0];
%%Set the block simStateCompliance to default (i.e., same as a built-in block)
block.SimStateCompliance = 'DefaultSimState';
%%Register methods
block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
block.RegBlockMethod('InitializeConditions', @InitConditions);
block.RegBlockMethod('Outputs', @Output);
block.RegBlockMethod('Update', @Update);
%endfunction
function DoPostPropSetup(block)
%%Setup Dwork for data logging/states
block.NumDworks = 1;
block.Dwork(1).Name = 'X';
block.Dwork(1).Dimensions = 2;
block.Dwork(1).DatatypeID = 0;
block.Dwork(1).Complexity = 'Real';
block.Dwork(1).UsedAsDiscState = true;
%endfunction
function InitConditions(block)
%%Initialize Dwork
block.Dwork(1).Data = [0;0];
%endfunction
function Output(block)
block.OutputPort(1).Data = block.Dwork(1).Data;
% changing the output conditionally
if(block.Dwork(1).Data(1)>=0.2)
block.OutputPort(1).Data(1) = 2;
end
%endfunction
function Update(block)
block.Dwork(1).Data = block.InputPort(1).Data;
%endfunction
The Output function has an if statement which updates the output based on a condition; which is what you are looking for. Also, notice the DWork vector used to store state information. It is recommended to use Work vectors instead of global variables to store persistent data. More about DWork vectors can be found here. Also check the article on Writing MATLAB S-functions for more information.

  0 Comments

Sign in to comment.