Documentos de Académico
Documentos de Profesional
Documentos de Cultura
S-Functions
Used to create a block that runs C++ code in Simulink Reasons you need to write an S-Function
Your Simulink model is too complex You need to read in from or write to a file You need to access hardware (AD or DA cards) You need to access external programs (3DLinx)
Simulink model for the x-axis of one wheel in the landing gear model
Introduction to C++
Variables
double y; const int SIZE = 10; bool z = true;
Arrays
double a[SIZE], b[SIZE][SIZE]; a[2] = 3.0; b[2][3] = y/2.0;
If
if(x>3 && x<-5) { z = false; y = 3.0; } else if(!z || x==8) { x = 6; } else { x += 5; }
For
for(int i = 0; i<10; i++) { a[i] = 5.0; }
While
while(i>2) i-=10.0;
Functions
// Prototype (You need the semicolon) double CalculateSomething(int x, double y);
double CalculateSomething(int x, double y) { double answer; if(x>3) answer = sin(y); // #include <math.h> else answer = double(x); return answer; }
Starting an S-Function
Open a pre-existing S-Function in Visual C++ and save a copy with a new name like Test.cpp Change this line to have the same name as the file name
#define S_FUNCTION_NAME Test
Now you have the general format so all you have to do is change the code to make it do what you want it to do.
Callback Functions
Functions that you write and Simulink calls to run your code
Initialize sizes
Sets the number and sizes of the output and input ports static void mdlInitializeSizes(SimStruct *S)
Initialize conditions
Initializes anything you need it to (variables, read in file, etc.) static void mdlInitializeConditions(SimStruct *S)
Start model
Runs when you start the model running static void mdlStart(SimStruct *S)
Outputs
Runs each time step to calculate the outputs of the block static void mdlOutputs(SimStruct *S, int_T tid)
Terminate
Runs when you stop the model static void mdlTerminate(SimStruct *S)
Simulink Functions
Functions that you can call to get information or set up stuff
Initializing sizes
Set the number of input ports and set the with of each port if (!ssSetNumInputPorts(S, 2)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortWidth(S, 1, 1); Set the number of output ports and set the with of each port if (!ssSetNumOutputPorts(S,1)) return; ssSetOutputPortWidth(S, 0, 1);
Inputs Read in numbers from the inputs to the block InputRealPtrsType inPtrs1 = ssGetInputPortRealSignalPtrs(S,0); InputRealPtrsType inPtrs2 = ssGetInputPortRealSignalPtrs(S,1); double x = *inPtrs1[0]; double y = *inPtrs2[0];
Outputs
Write the results to the outputs of the block real_T *out = ssGetOutputPortRealSignal(S,0); out[0]=x+y;
Other
Get the step size double dt=ssGetStepSize(S); Get the simulation time double time=ssGetT(S);
Transformation Matrix
// Calculates the transformation matrix from body to earth // coordinates from the given Euler angles. void Transformation(double answer[3][3], double psi, double theta, double phi) { answer[0][0]=cos(psi)*cos(theta); answer[0][1]=sin(psi)*cos(theta); answer[0][2]=-sin(theta); answer[1][0]=cos(psi)*sin(theta)*sin(phi)-sin(psi)*cos(phi); answer[1][1]=sin(psi)*sin(theta)*sin(phi)+cos(psi)*cos(phi); answer[1][2]=cos(theta)*sin(phi); answer[2][0]=cos(psi)*sin(theta)*cos(phi)+sin(psi)*sin(phi); answer[2][1]=sin(psi)*sin(theta)*cos(phi)-cos(psi)*sin(phi); answer[2][2]=cos(theta)*cos(phi); }
Matrix Multiplication
// Multiplies a 3x3 matrix by a 3 element vector. void Multiply(double answer[3], const double A[3][3], const double B[3]) { for(int i=0; i<3; i++) { answer[i]=0.0; for(int j=0; j<3; j++) { answer[i]+=A[j][i]*B[j]; } } }