Hi, everybody, I got one problem when using S-function dynamic output. The input dimensions of my S function module is constant, i.e., 4,

Hi, everybody, I got one problem when using S-function dynamic output. The input dimensions of my S function module is constant, i.e., 4, But the dimensions of my output is dynamic, it is relative to but not the same as the values of one input. Thus, my question is how I set the number of dimension for output in a dynamic or variable way. And I check the matlab document, What it says is the dimension of output is needed to be the same as the dimension of input if we get to use variable output dimensions.

Risposte (2)

You haven't mentioned if you're writing a MATLAB S-function, or a C S-function, but this page in the documentation points to demos for both types of S-functions with variable-sized outputs.

13 Commenti

Tanks for your reply. Actully, I prefer to use Level-2 MALAB language S-function because all my sub-function are based on MALAB language. If it impossible, i have to use C Sfunction. The dimensions of my output depend on the calculation of one input value. That means, I should do a complicated calculation using that input value, then i can obtain how many dimensions of the output I should use. Is this possible?
Variable-size signals in Simulink require you to specify the maximum (upper limit) size that the signal can attain. So you need to set the maximum size in SetInputPortDims(), and set the actual size based on the input value in the Outputs() function by assigning block.OutputPort(1).CurrentDimensions.
Many thanks for ur response, but i still suffered from problems
% Level-2 MATLAB file S-Function for unit delay demo.
% Copyright 1990-2009 The MathWorks, Inc.
% $Revision: 1.1.6.2 $
global pipe_old;
global pipe_new;
global length; %define global variables
length=600; %initialize global variables
setup(block);
%endfunction
function setup(block)
block.NumDialogPrms = 1;
%%Register number of input and output ports
block.NumInputPorts = 1;
block.NumOutputPorts = 1;
%%Setup functional port properties to dynamically
%%inherited.
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% Register the properties of the input port
block.InputPort(1).Complexity = 'Inherited';
block.InputPort(1).DataTypeId = -1;
block.InputPort(1).SamplingMode = 'Sample';
block.InputPort(1).DimensionsMode = 'Fixed';
block.InputPort(1).DirectFeedthrough = false;
% Register the properties of the output port
block.OutputPort(1).DimensionsMode = 'Variable';
block.OutputPort(1).SamplingMode = 'Sample';
%%Set block sample time to inherited
block.SampleTimes = [-1 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('SetInputPortDimensions', @SetInpPortDims);
%block.RegBlockMethod('SetOutputPortDimensions', @SetOutPortDims);
block.RegBlockMethod('Outputs', @Output);
%block.RegBlockMethod('Update', @Update);
%endfunction
function DoPostPropSetup(block)
block.SignalSizesComputeType = 'FromInputValueAndSize';
%endfunction
function SetInpPortDims(block, idx, di)
% Set compiled dimensions
block.InputPort(idx).Dimensions = di;
% block.InputPort(idx).Dimensions = di;
block.OutputPort(1).Dimensions = di;
%endfunction
%function SetOutPortDims(block, idx, di)
% block.OutputPort(idx).Dimensions = di;
% block.InputPort(1).Dimensions = di;
%endfunction
function Output(block)
global pipe_old;
global pipe_new;
% define in_pipe
pipe=struct('slug_num',[],'slug',[]);
pipe.slug=struct('size',[],'length',[],'position',[],'pH',[]);
in_pipe=pipe;
in_pipe.slug_num=1;
in_pipe.slug.size=0;
in_pipe.slug.length=0;
in_pipe.slug.position=0;
in_pipe.slug.pH=0;
sample_time=0.0001;
flow=block.InputPort(1).Data(1);
pH=block.InputPort(1).Data(2);
Amain=0.2;
if flow~=0
size=flow*sample_time;
in_pipe.slug_num=1;
in_pipe.slug.size=size;
in_pipe.slug.length=size/Amain;
in_pipe.slug.position=0;
in_pipe.slug.pH=pH;
pipe1_update=1;
%update pipe 1
[out_pipe, pipe_new] = pipe_update(pipe_old,in_pipe,Amain);%%%%%%%%caliculate output
else
pipe1_update=0;
end
dimension=out_pipe.slug_num*4;
block.OutputPort(1).CurrentDimensions = dimension; %%%%determine output size
j=dimension/4;
for i=1:j %output all the data
block.OutputPort(1).Data(4*(i-1)+1)=out_pipe.slug(i).size;
block.OutputPort(1).Data(4*(i-1)+2)=out_pipe.slug(i).length;
block.OutputPort(1).Data(4*(i-1)+3)=out_pipe.slug(i).position;
block.OutputPort(1).Data(4*(i-1)+4)=out_pipe.slug(i).pH;
end
This is the error as follow, but i felt i have set the sample time correctly.
ERROR: The signal at output port 1 of 'DYNAMIC_SIZE_TEST/MATLAB file (level-2) S-Function' is a variable-size signal with a nondiscrete sample time. The sample time for any variable-size signal must be discrete.
You've set your sample time to be inherited:
block.SampleTimes = [-1 0];
Perhaps the blocks connected to the input/output of the S-function are configured for continuous-time? Turning on Sample Time Colors might help.
Hi,Kaustubha,thanks for ur answer, I have solved that sample time problem, still back to the my dynamic output setting. I set the parameters as follows, but found some errors :
(1)Error evaluating registered method 'Outputs' of MATLAB S-Function 'msfcn_unit_delay' in 'DYNAMIC_SIZE_TEST/MATLAB file (level-2) S-Function'.
(2)Invalid variable dimensions assignment for output port 1 of 'DYNAMIC_SIZE_TEST/MATLAB file (level-2) S-Function'. Variable dimensions must be an array of nonnegative integers and each integer cannot exceed the maximum dimension
I think my problem is on the maximum dimension, could you show some details how to set the the maximum dimension, or give me some refferences
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function setup(block)
%%inherited.
block.SetPreCompInpPortInfoToDynamic;
block.SetPreCompOutPortInfoToDynamic;
% Register the properties of the input port
block.InputPort(1).Complexity = 'Inherited';
block.InputPort(1).DataTypeId = -1;
block.InputPort(1).SamplingMode = 'Sample';
block.InputPort(1).DimensionsMode = 'Fixed';
block.InputPort(1).DirectFeedthrough = false;
% Register the properties of the output port
block.OutputPort(1).DimensionsMode = 'Variable';
block.OutputPort(1).SamplingMode = 'Sample';
%%Register methods
block.RegBlockMethod('PostPropagationSetup', @DoPostPropSetup);
block.RegBlockMethod('SetInputPortDimensions', @SetInpPortDims);
block.RegBlockMethod('Outputs', @Output);
function DoPostPropSetup(block)
block.SignalSizesComputeType = 'FromInputValueAndSize';
function SetInpPortDims(block, idx, di)
% Set compiled dimensions
block.InputPort(idx).Dimensions = di;
block.OutputPort(1).Dimensions = di;
function Output(block)
[out_pipe, pipe_new] = pipe_update(pipe_old,in_pipe,Amain);
%%%%%%%% caliculate output
dimension=out_pipe.slug_num*4;
for i=1:out_pipe.slug_num %output all the data
block.OutputPort(1).Data(4*(i-1)+1)=out_pipe.slug(i).size;
block.OutputPort(1).Data(4*(i-1)+2)=out_pipe.slug(i).length;
block.OutputPort(1).Data(4*(i-1)+3)=out_pipe.slug(i).position;
block.OutputPort(1).Data(4*(i-1)+4)=out_pipe.slug(i).pH;
end
Please see the demo I pointed in my initial answer which shows you how to setup maximum dimensions, etc. As I commented before:
"Variable-size signals in Simulink require you to specify the maximum (upper limit) size that the signal can attain. So you need to set the maximum size in SetInputPortDims(), and set the actual size based on the input value in the Outputs() function by assigning block.OutputPort(1).CurrentDimensions."
Please look at SetInputPortDims() and Outputs() function in the demo that I pointed to.
Hi,Kaustubha, good to receive ur reply, I am a PhD student, what the computer and matlab software i used are from uni., thus, here i have no idea how to associate my liscence with avtivate key (i know my liscence with avtivate key), even i tried, i can not access the the content you attached before. I have sent the email to ur customer support, but still not any response. could you send me some document (word, pdf or whatever) about that, my email: yiqi.liu@awmc.uq.edu.au
Yiqi: What version of MATLAB are you using? Are you saying that when you enter "msfcndemo_varsize" at your MATLAB prompt, the demo doesn't open up? Note that variable-size signals were introduced in Simulink in R2009b, so if you don't have access to that model, it is likely that you are using an older version, and cannot avail of this feature.
"Variable-size signals in Simulink require you to specify the maximum (upper limit) size that the signal can attain. So you need to set the maximum size in SetInputPortDims(), and set the actual size based on the input value in the Outputs() function by assigning block.OutputPort(1).CurrentDimensions."
Is this also valid for C S-functions? I am trying to develop a C S-function with the same funcionality, but I can't set the size of the output to be bigger than the initial size set using ssSetOutputPortWidth. Here is the error I get:
error_sfun.png

Accedi per commentare.

Tanks for your reply. Actully, I prefer to use Level-2 MALAB language S-function because all my sub-function are based on MALAB language. If it impossible, i have to use C Sfunction. The dimensions of my output depend on the calculation of one input value. That means, I should do a complicated calculation using that input value, then i can obtain how many dimensions of the output I should use. Is this possible?

1 Commento

Yes you can get multi-dimensional output out of a 1D input. Just remember to set the correct output port dimension.( block.OutputPort(portid).Dimensions=dim, where dim=[m,n] for an mxn output.), It your outsize changes based on the logic in your program set the output port dimension to -1.

Accedi per commentare.

Prodotti

Richiesto:

il 10 Ago 2012

Commentato:

il 22 Ago 2023

Community Treasure Hunt

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

Start Hunting!

Translated by