Direct feedthrough means that the output (or the variable sample time for variable sample time blocks) is controlled directly by the value of an input port signal. Typically, an S-function input port has direct feedthrough if
The output function (mdlOutputs
)
is a function of the input u
. That is, there is
direct feedthrough if the input u
is accessed by mdlOutputs
.
Outputs can also include graphical outputs, as in the case of an XY
Graph scope.
The "time of next hit" function (mdlGetTimeOfNextVarHit
)
of a variable sample time S-function accesses the input u.
An example of a system that requires its inputs (that is, has direct feedthrough) is the operation
$$y=k\times u,$$
where u is the input, k is the gain, and y is the output.
An example of a system that does not require its inputs (that is, does not have direct feedthrough) is the simple integration algorithm
$$y=x,$$
$$\dot{x}=u,$$
where x is the state, $$\dot{x}$$ is the state derivative with respect to time, u is the input, and y is the output. Simulink^{®} integrates the variable $$\dot{x}.$$
It is very important to set the direct feedthrough flag correctly
because it affects the execution order of the blocks in your model
and is used to detect algebraic loops (see Algebraic Loops in Using Simulink).
If the simulation results for a model containing your S-function do
not converge, or the simulation fails, you may have the direct feedthrough
flag set incorrectly. Try turning on the direct feedthrough flag and
setting the Algebraic loop solver diagnostic
to warning
(see the Algebraic loop option
on the Model Configuration Parameters: Diagnostics reference page in Simulink Graphical
User Interface). Subsequently running the simulation displays
any algebraic loops in the model and shows if the engine has placed
your S-function within an algebraic loop.
You can write your S-function to support arbitrary input dimensions. In this case, the Simulink engine determines the actual input dimensions when the simulation is started by evaluating the dimensions of the input vectors driving the S-function. Your S-function can also use the input dimensions to determine the number of continuous states, the number of discrete states, and the number of outputs.
Note A dynamically sized input can have a different size for each instance of the S-function in a particular model or during different simulations, however the input size of each instance of the S-function is static over the course of a particular simulation. |
A C MEX S-function and Level-2 MATLAB^{®} S-function can have multiple input and output ports and each port can have different dimensions. The number of dimensions and the size of each dimension can be determined dynamically.
For example, the following illustration shows two instances of the same S-Function block in a model.
The upper S-Function block is driven by a block with a three-element output vector. The lower S-Function block is driven by a block with a scalar output. By specifying that the S-Function block has dynamically sized inputs, the same S-function can accommodate both situations. The Simulink engine automatically calls the block with the appropriately sized input vector. Similarly, if other block characteristics, such as the number of outputs or the number of discrete or continuous states, are specified as dynamically sized, the engine defines these vectors to be the same length as the input vector.
See Input and Output Ports for more information on configuring S-function input and output ports.
Both Level-2 MATLAB and C MEX S-functions provide the following sample time options, which allow for a high degree of flexibility in specifying when an S-function executes:
Continuous sample time — For S-functions that have continuous states and/or nonsampled zero crossings (see Simulation Phases in Dynamic Systems for an explanation of zero crossings). For this type of S-function, the output changes in minor time steps.
Continuous, but fixed in minor time step sample time — For S-functions that need to execute at every major simulation step, but do not change value during minor time steps.
Discrete sample time — If the behavior of your S-function is a function of discrete time intervals, you can define a sample time to control when the Simulink engine calls the S-function. You can also define an offset that delays each sample time hit. The value of the offset cannot exceed the corresponding sample time.
A sample time hit occurs at time values determined by the formula
TimeHit = (n * period) + offset
where the integer n
is the current simulation
step. The first value of n
is always zero.
If you define a discrete sample time, the engine calls the S-function mdlOutputs
and mdlUpdate
routines
at each sample time hit (as defined in the previous equation).
Variable sample time — A discrete sample time where the intervals between sample hits can vary. At the start of each simulation step, S-functions with variable sample times are queried for the time of the next hit.
Inherited sample time — Sometimes an S-function has no inherent sample time characteristics (that is, it is either continuous or discrete, depending on the sample time of some other block in the system). In this case, you can specify that the sample time is inherited. A simple example of this is a Gain block that inherits its sample time from the block driving it.
An S-function can inherit its sample time from
The driving block
The destination block
The fastest sample time in the system
To specify an S-function sample time is inherited, use -1 in
Level-2 MATLAB S-functions
and INHERITED_SAMPLE_TIME
in C MEX S-functions
as the sample time. For more information on the propagation of sample
times, see How Propagation Affects Inherited Sample
Times in the Simulink User's
Guide.
S-functions can be either single or multirate; a multirate S-function has multiple sample times.
Sample times are specified in pairs in this format: [sample_time
, offset_time
].
The valid sample time pairs for a C MEX S-function are
[CONTINUOUS_SAMPLE_TIME, 0.0] [CONTINUOUS_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET] [discrete_sample_time_period, offset] [VARIABLE_SAMPLE_TIME, 0.0]
where
CONTINUOUS_SAMPLE_TIME = 0.0 FIXED_IN_MINOR_STEP_OFFSET = 1.0 VARIABLE_SAMPLE_TIME = -2.0
and variable names in italics indicate that a real value is required.
Alternatively, you can specify that the sample time is inherited from the driving block. In this case, the C MEX S-function has only one sample time pair, either
[INHERITED_SAMPLE_TIME, 0.0]
or
[INHERITED_SAMPLE_TIME, FIXED_IN_MINOR_STEP_OFFSET]
where
INHERITED_SAMPLE_TIME = -1.0
The valid sample time pairs for a Level-2 MATLAB S-function are
[0 offset] % Continuous sample time [discrete_sample_time_period, offset] % Discrete sample time [-1, 0] % Inherited sample time [-2, 0] % Variable sample time
where variable names in italics indicate that a real value is
required. When using a continuous sample time, an offset
of 1
indicates
the output is fixed in minor integration time steps. An offset
of 0
indicates
the output changes at every minor integration time step.
Use the following guidelines for help with specifying sample times:
A continuous S-function that changes during minor
integration steps should register the [CONTINUOUS_SAMPLE_TIME
, 0.0
]
sample time.
A continuous S-function that does not change during
minor integration steps should register the [CONTINUOUS_SAMPLE_TIME,
FIXED_IN_MINOR_STEP_OFFSET]
sample time.
A discrete S-function that changes at a specified
rate should register the discrete sample time pair, [discrete_sample_time_period
, offset
],
where
discrete_sample_period > 0.0
and
0.0 ≤ offset < discrete_sample_period
A discrete S-function that changes at a variable rate should register the variable-step discrete sample time.
[VARIABLE_SAMPLE_TIME, 0.0]
In a C MEX S-function, the mdlGetTimeOfNextVarHit
routine
is called to get the time of the next sample hit for the variable-step
discrete task. In a Level-2 MATLAB S-function,
the NextTimeHit
property is set in the Outputs
method
to set the next sample hit.
If your S-function has no intrinsic sample time, you must indicate that your sample time is inherited. There are two cases:
An S-function that changes as its input changes, even
during minor integration steps, should register the [INHERITED_SAMPLE_TIME,
0.0]
sample time.
An S-function that changes as its input changes, but
does not change during minor integration steps (that is, remains fixed
during minor time steps), should register the [INHERITED_SAMPLE_TIME,
FIXED_IN_MINOR_STEP_OFFSET]
sample time.
The Scope block is a good example of this type of block. This block runs at the rate of its driving block, either continuous or discrete, but never runs in minor steps. If it did, the scope display would show the intermediate computations of the solver rather than the final result at each time point.
See Sample Times for information on implementing different types of sample times in S-functions.