Matlab Level 2 S-functions and Arrays

6 views (last 30 days)
Yves
Yves on 17 Feb 2015
Edited: Yves on 26 Feb 2020
My Question is the following:
I want to write an S-Function which takes an n-dimensional input, and gives as output the same Array with an added collumn in a chosen dimension.
When I try that I always end up with errors about a missmatch of dimensions:
"Error in 'SetOutputPortDimensions' method of 'Test_simple/Level-2 MATLAB S-Function1'. The dimension of output port 0 should have been set to [4x1], but was instead set to [4x2]."
&
"Error in port widths or dimensions. Output port 1 of 'Test_simple/Constant' is a [4x1x2] matrix."
How can I fix this missmatch of dimensions?
My code: -----------------------------------------------------------------------------------------------------------------------------------------------------------------
function VPSFUNC4S(block)
setup(block);
function setup(block)
block.NumInputPorts = 1;
block.NumOutputPorts = 1;
block.AllowSignalsWithMoreThan2D = 1;
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
block.InputPort(1).DirectFeedthrough = true;
block.OutputPort(1).DimensionsMode = 'Variable';
block.NumContStates = 1;
block.SampleTimes = [0 0];
block.SetAccelRunOnTLC(false);
block.SimStateCompliance = 'DefaultSimState';
block.RegBlockMethod('SetOutputPortDimensions', @SetOutPortDims);
block.RegBlockMethod('Outputs', @Outputs);
function SetOutPortDims(block, idx, di)
di=block.InputPort(1).Dimensions;
di(2)=di(2)+1;
block.OutputPort(idx).Dimensions = di;
function Outputs(block)
Grosse=size(block.InputPort(1).Data);
X=Grosse(2);
block.OutputPort(1).Data=block.InputPort(1).Data;
block.OutputPort(1).Data=[block.OutputPort(1).Data,zeros(1,Grosse(1))];
for k=1:4;
block.OutputPort(1).Data(k,X+1,1)=block.InputPort(1).Data(k,X,:)+10;
end

Accepted Answer

Yves
Yves on 17 Feb 2015
  2 Comments
Richard Crozier
Richard Crozier on 17 Feb 2020
Edited: Richard Crozier on 17 Feb 2020
Sadly the newsreader is dead and therefore so is this link. Can you share the solution agin?
Yves
Yves on 26 Feb 2020
Edited: Yves on 26 Feb 2020
I have no clue what it was, but I still have the code I wrote back then (which works as intended), so I hope this example gives you the information you seek.
function SF_FP(block)
setup(block);
function setup(block)
block.NumDialogPrms = 5;
block.DialogPrmsTunable = {'Tunable','Tunable','Tunable','Tunable','Tunable'};
block.NumInputPorts = 1;
block.NumOutputPorts = 2;
block.AllowSignalsWithMoreThan2D = 1;
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
block.InputPort(1).DirectFeedthrough = true;
block.InputPort(1).DatatypeID = 0;
block.OutputPort(1).DatatypeID = 0;
block.SampleTimes = [0 0];
block.NumContStates = 1;
block.SetAccelRunOnTLC(false);
block.SimStateCompliance = 'DefaultSimState';
block.RegBlockMethod('SetInputPortSamplingMode', @SetInpPortFrameData);
block.RegBlockMethod('SetInputPortDimensions', @SetInpPortDims);
block.RegBlockMethod('Outputs', @Outputs);
function SetInpPortFrameData(block, idx, fd)
block.InputPort(idx).SamplingMode = fd;
block.OutputPort(1).SamplingMode = fd;
block.OutputPort(2).SamplingMode = fd;
function SetInpPortDims(block, idx, di)
block.InputPort(idx).Dimensions = di;
di(2)=di(2)+1;
block.OutputPort(1).Dimensions = di;
block.OutputPort(2).Dimensions = di;
As far as I remember: this did the trick, I think setting the outputport dimension within
function SetInpPortDims(block, idx, di)
Was the solution, you gotta try it, I haven't done any coding in MATLAB since years.
You are really lucky I happen to be at the place were I made this again and got the same email I used to have back then otherwise you would have had no chance for an answer.
If you have closed loops you want to evaluate with your s-functions (example below) you have to evaluate the length of the closed loop in the init function of your s-function block. However as far as I rember I had troubels with properly setting init values using the init functions when blocks rely on data provided by other s-functions.
example:
source ->in_1 mixer -> some process -> split stuff out_1-> go on
^ in_2 | out_2
|_________________________|
You should also check:
block.RegBlockMethod('SetInputPortSamplingMode', @SetInpPortFrameData);
and
function SetInpPortFrameData(block, idx, fd)
block.InputPort(idx).SamplingMode = fd;
block.OutputPort(1).SamplingMode = fd;
block.OutputPort(2).SamplingMode = fd;
I can't remember why I had to do that, but it might be connected to it.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!