In this example, you will use the basic methods in the S-Function Builder to model a two-input, two-output discrete state-space system with two states. The state-space matrices are parameters to the S-function, and the S-function input and output are vectors.
You can investigate this example from sfbuilder_example
. If you would like to study a manually written version
of the created S-function, see dsfunc.c
. Note that to create a S-function from an example S-Function
Builder model, you need to build the model first.
Specify the number of discrete states and their initial conditions, the sample mode, and
the sample time of the S-function. This example contains two discrete states, each
initialized to 1
, and a discrete sample mode with a sample time of
1
. Ensure that the Direct feedthrough is
selected, because the current values of the S-function inputs are used to compute its
outputs.
Use the Ports and Parameters table on the bottom of the editor to specify the ports and parameters of the S-function. For this example, we have one input, one output port, and four parameters.
To set or change the values of the block parameters, you can:
Double-click the S-Function Builder block on the model.
Use the Block Parameters from the context menu.
Alternatively, you can store the state-space matrices in variables in the MATLAB® workspace and enter the variable names into the Value field for each parameter. Enter the values in the image for state-space parameters on the Value field of the Block Parameters table.
In this example, The Outputs_wrapper
method calculates the S-function
output as a function of the input and state vectors and the state-space matrices. In the
outputs code, reference S-function parameters using the parameter names defined on the
Ports and Parameters table. Index into 2-D matrices using a scalar
index, again keeping in mind that S-functions use zero-based indexing. For example, to
access the element C(2,1)
in the S-function parameter
C
, use C[1]
in the S-function code.
void dsfunc_builder_Outputs_wrapper(const real_T *u, real_T *y, const real_T *xD, const real_T *xC, const real_T *A, const int_T p_width0, const real_T *B, const int_T p_width1, const real_T *C, const int_T p_width2, const real_T *D, const int_T p_width3) { /* Output_BEGIN */ y[0]=C[0]*xD[0]+C[2]*xD[1]+D[0]*u[0]+D[2]*u[1]; y[1]=C[1]*xD[0]+C[3]*xD[1]+D[1]*u[0]+D[3]*u[1]; /* Output_END */ } |
The Update_wrapper
method updates the discrete states. As with the
outputs code, use the S-function parameter names and index into 2-D matrices using a scalar
index, keeping in mind that S-functions use zero-based indexing. For example, to access the
element A(2,1)
in the S-function parameter A
, use
A[1]
in the S-function code. The variable xD
stores
the final values of the discrete states. Enter the following code in the
Update_wrapper
function.
void dsfunc_builder_Update_wrapper(const real_T *u, real_T *y, real_T *xD, const real_T *A, const int_T p_width0, const real_T *B, const int_T p_width1, const real_T *C, const int_T p_width2, const real_T *D, const int_T p_width3) { /* Update_BEGIN */ real_T tempX[2] = {0.0, 0.0}; tempX[0]=A[0]*xD[0]+A[2]*xD[1]+B[0]*u[0]+B[2]*u[1]; tempX[1]=A[1]*xD[0]+A[3]*xD[1]+B[1]*u[0]+B[3]*u[1]; xD[0] = tempX[0]; xD[1] = tempX[1]; /* Update_END */ } |
Click the arrow under Build
and select the following options:
Show compile steps
Create a debuggable MEX-file
Generate wrapper TLC
To learn more about what each option does, see Build S-Functions Automatically Using S-Function Builder.
To build your S-function, click Build on the toolstrip to create an
executable file for this S-function. You can now run the model and compare the output to the
original discrete state-space S-function contained in sfcndemo_dsfunc
.
S-Function | S-Function Builder