268 lines
8.4 KiB
C
268 lines
8.4 KiB
C
/**************************************************************************
|
|
Description: Ïðîãðàììà - óïàêîâùèê.
|
|
|
|
Àâòîð: Óëèòîâñêèé Ä.È.
|
|
Äàòà ïîñëåäíåãî îáíîâëåíèÿ: 2021.09.23
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
#define S_FUNCTION_NAME wrapper_inu
|
|
#define S_FUNCTION_LEVEL 2
|
|
#include "simstruc.h"
|
|
#include "math.h"
|
|
#include "wrapper_inu.h"
|
|
|
|
|
|
|
|
#define MDL_UPDATE
|
|
/* Function: mdlUpdate ====================================================
|
|
* Abstract:
|
|
* This function is called once for every major integration time step.
|
|
* Discrete states are typically updated here, but this function is useful
|
|
* for performing any tasks that should only take place once per
|
|
* integration step.
|
|
*/
|
|
static void mdlUpdate(SimStruct *S, int_T tid)
|
|
{
|
|
const real_T *u = (const real_T*) ssGetInputPortRealSignal(S,0);
|
|
real_T *xD = ssGetDiscStates(S);
|
|
real_T *rW = ssGetRWork(S);
|
|
int_T *iW = ssGetIWork(S);
|
|
|
|
controller(S, u, xD, rW, iW);
|
|
|
|
}//end mdlUpdate
|
|
|
|
|
|
|
|
/* Function: mdlCheckParameters ===========================================
|
|
* Abstract:
|
|
* mdlCheckParameters verifies new parameter settings whenever parameter
|
|
* change or are re-evaluated during a simulation.
|
|
*/
|
|
#define MDL_CHECK_PARAMETERS /* Change to #undef to remove function */
|
|
#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
|
|
static void mdlCheckParameters(SimStruct *S)
|
|
{
|
|
int i;
|
|
|
|
// Ïðîâåðÿåì è ïðèíèìàåì ïàðàìåòðû è ðàçðåøàåì èëè çàïðåùàåì èõ ìåíÿòü
|
|
// â ïðîöåññå ìîäåëèðîâàíèÿ
|
|
for (i=0; i<NPARAMS; i++)
|
|
{
|
|
// Input parameter must be scalar or vector of type double
|
|
if (!mxIsDouble(ssGetSFcnParam(S,i)) || mxIsComplex(ssGetSFcnParam(S,i)) ||
|
|
mxIsEmpty(ssGetSFcnParam(S,i)))
|
|
{
|
|
ssSetErrorStatus(S,"Input parameter must be of type double");
|
|
return;
|
|
}
|
|
// Ïàðàìåòð ì.á. òîëüêî ñêàëÿðîì, âåêòîðîì èëè ìàòðèöåé
|
|
if (mxGetNumberOfDimensions(ssGetSFcnParam(S,i)) > 2)
|
|
{
|
|
ssSetErrorStatus(S,"Ïàðàìåòð ì.á. òîëüêî ñêàëÿðîì, âåêòîðîì èëè ìàòðèöåé");
|
|
return;
|
|
}
|
|
|
|
// Parameter not tunable
|
|
// ssSetSFcnParamTunable(S, i, SS_PRM_NOT_TUNABLE);
|
|
// Parameter tunable (we must create a corresponding run-time parameter)
|
|
ssSetSFcnParamTunable(S, i, SS_PRM_TUNABLE);
|
|
// Parameter tunable only during simulation
|
|
// ssSetSFcnParamTunable(S, i, SS_PRM_SIM_ONLY_TUNABLE);
|
|
|
|
}//for (i=0; i<NPARAMS; i++)
|
|
|
|
}//end mdlCheckParameters
|
|
|
|
#endif //MDL_CHECK_PARAMETERS
|
|
|
|
|
|
#define MDL_PROCESS_PARAMETERS /* Change to #undef to remove function */
|
|
#if defined(MDL_PROCESS_PARAMETERS) && defined(MATLAB_MEX_FILE)
|
|
/* Function: mdlProcessParameters =========================================
|
|
* Abstract:
|
|
* This method will be called after mdlCheckParameters, whenever
|
|
* parameters change or get re-evaluated. The purpose of this method is
|
|
* to process the newly changed parameters. For example "caching" the
|
|
* parameter changes in the work vectors. Note this method is not
|
|
* called when it is used with the Real-Time Workshop. Therefore,
|
|
* if you use this method in an S-function which is being used with the
|
|
* Real-Time Workshop, you must write your S-function such that it doesn't
|
|
* rely on this method. This can be done by inlining your S-function
|
|
* via the Target Language Compiler.
|
|
*/
|
|
static void mdlProcessParameters(SimStruct *S)
|
|
{
|
|
int_T *iW = ssGetIWork(S);
|
|
|
|
iW[0] = 1;//processParameters
|
|
}
|
|
#endif //MDL_PROCESS_PARAMETERS
|
|
|
|
|
|
|
|
/* Function: mdlInitializeSizes ===========================================
|
|
* Abstract:
|
|
* The sizes information is used by Simulink to determine the S-function
|
|
* block's characteristics (number of inputs, outputs, states, etc.).
|
|
*/
|
|
static void mdlInitializeSizes(SimStruct *S)
|
|
{
|
|
//---------------------------------------------------------------------
|
|
// Number of expected parameters
|
|
ssSetNumSFcnParams(S, NPARAMS);
|
|
|
|
// Â íîðìàëüíîì ðåæèìå ðàáîòû, äëÿ îáðàáîòêè ïàðàìåòðîâ âûçûâàåì ô-öèþ
|
|
// mdlCheckParameters()
|
|
#ifdef MATLAB_MEX_FILE
|
|
// Êîë-âî îæèäàåìûõ è ôàêòè÷åñêèõ ïàðàìåòðîâ äîëæíî ñîâïàäàòü
|
|
if(ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S))
|
|
{
|
|
// Ïðîâåðÿåì è ïðèíèìàåì ïàðàìåòðû
|
|
mdlCheckParameters(S);
|
|
}
|
|
else
|
|
{
|
|
return;// Parameter mismatch will be reported by Simulink
|
|
}
|
|
#endif // MATLAB_MEX_FILE
|
|
|
|
//---------------------------------------------------------------------
|
|
// Register the number and type of states the S-Function uses
|
|
ssSetNumContStates(S, 0); // number of continuous states
|
|
ssSetNumDiscStates(S, OUTPUT_0_WIDTH); // number of discrete states
|
|
|
|
//---------------------------------------------------------------------
|
|
// Óñòàíàâëèâàåì êîë-âî âõ-ûõ ïîðòîâ
|
|
if (!ssSetNumInputPorts(S, 1)) return;
|
|
// Óñòàíàâëèâàåì êîë-âî ñèãíàëîâ âî âõ-îì ïîðòó
|
|
ssSetInputPortWidth(S, 0, INPUT_0_WIDTH);
|
|
|
|
// Çàÿâëÿåì, ÷òî äëÿ íàøåãî âõ-ãî ïîðòà íåò direct feedthrough
|
|
ssSetInputPortDirectFeedThrough(S, 0, 0);
|
|
|
|
// Òðåáóåì, ÷òîáû ñèãíàëû âî âõîäíîì ïîðòó øëè ïîñëåäîâàòåëüíî, à íå
|
|
// â ðàçáðîñ
|
|
ssSetInputPortRequiredContiguous(S, 0, 1); // direct input signal access
|
|
|
|
//---------------------------------------------------------------------
|
|
// Óñòàíàâëèâàåì êîë-âî âûõ-ûõ ïîðòîâ
|
|
if (!ssSetNumOutputPorts(S, 1)) return;
|
|
// Óñòàíàâëèâàåì êîë-âî ñèãíàëîâ â âûõ-îì ïîðòó
|
|
ssSetOutputPortWidth(S, 0, OUTPUT_0_WIDTH);
|
|
|
|
//---------------------------------------------------------------------
|
|
// Number of sample times
|
|
ssSetNumSampleTimes(S, 1);
|
|
|
|
//---------------------------------------------------------------------
|
|
// Set size of the work vectors
|
|
ssSetNumRWork( S, RWORK_0_WIDTH); // number of real work vector elements
|
|
ssSetNumIWork( S, IWORK_0_WIDTH); // number of integer work vector elements
|
|
ssSetNumPWork( S, 0); // number of pointer work vector elements
|
|
ssSetNumModes( S, 0); // number of mode work vector elements
|
|
ssSetNumNonsampledZCs( S, 0); // number of nonsampled zero crossings
|
|
// ssSetNumDWork(S, 1);
|
|
|
|
// ssSetDWorkWidth(S, 0, 12);//Inm
|
|
// ssSetDWorkDataType(S, 0, SS_DOUBLE);
|
|
|
|
//---------------------------------------------------------------------
|
|
/*
|
|
* All options have the form SS_OPTION_<name> and are documented in
|
|
* matlabroot/simulink/include/simstruc.h. The options should be
|
|
* bitwise or'd together as in
|
|
* ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE | SS_OPTION_name2))
|
|
*/
|
|
// Ñ ïîìîùüþ îïöèè SS_OPTION_EXCEPTION_FREE_CODE îáåùàåì, ÷òî â
|
|
// íàøåé ïðîãðàììå íåò "èñêëþ÷åíèé"
|
|
ssSetOptions(S, (SS_OPTION_EXCEPTION_FREE_CODE));
|
|
|
|
}//end mdlInitializeSizes
|
|
|
|
|
|
|
|
/* Function: mdlInitializeSampleTimes =====================================
|
|
* Abstract:
|
|
* This function is used to specify the sample time(s) for your
|
|
* S-function. You must register the same number of sample times as
|
|
* specified in ssSetNumSampleTimes.
|
|
*/
|
|
static void mdlInitializeSampleTimes(SimStruct *S)
|
|
{
|
|
double dt;
|
|
|
|
// Øàã äèñêðåòèçàöèè
|
|
dt = mxGetPr(ssGetSFcnParam(S,NPARAMS-1))[0];
|
|
|
|
// Register one pair for each sample time
|
|
ssSetSampleTime(S, 0, dt);
|
|
ssSetOffsetTime(S, 0, 0.0);
|
|
|
|
}//end mdlInitializeSampleTimes
|
|
|
|
|
|
#define MDL_START // Change to #undef to remove function
|
|
#if defined(MDL_START)
|
|
/* Function: mdlStart =====================================================
|
|
* Abstract:
|
|
* This function is called once at start of model execution. If you
|
|
* have states that should be initialized once, this is the place
|
|
* to do it.
|
|
*/
|
|
static void mdlStart(SimStruct *S)
|
|
{
|
|
int_T *iW = ssGetIWork(S);
|
|
|
|
iW[0] = 1;//processParameters
|
|
iW[1] = 1;//start
|
|
}
|
|
#endif // MDL_START
|
|
|
|
|
|
|
|
/* Function: mdlOutputs ===================================================
|
|
* Abstract:
|
|
* In this function, you compute the outputs of your S-function
|
|
* block. Generally outputs are placed in the output vector(s),
|
|
* ssGetOutputPortSignal.
|
|
*/
|
|
static void mdlOutputs(SimStruct *S, int_T tid)
|
|
{
|
|
real_T *y = ssGetOutputPortRealSignal(S,0);
|
|
real_T *xD = ssGetDiscStates(S);
|
|
|
|
int i;
|
|
|
|
// OUTPUTS
|
|
for (i=0; i<OUTPUT_0_WIDTH; i++)
|
|
y[i] = xD[i];
|
|
|
|
}//end mdlOutputs
|
|
|
|
|
|
|
|
/* Function: mdlTerminate =================================================
|
|
* Abstract:
|
|
* In this function, you should perform any actions that are necessary
|
|
* at the termination of a simulation. For example, if memory was
|
|
* allocated in mdlStart, this is the place to free it.
|
|
*/
|
|
static void mdlTerminate(SimStruct *S)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
/*=============================*
|
|
* Required S-function trailer *
|
|
*=============================*/
|
|
|
|
#ifdef MATLAB_MEX_FILE // Is this file being compiled as a MEX-file?
|
|
#include "simulink.c" // MEX-file interface mechanism
|
|
#else
|
|
#include "cg_sfun.h" // Code generation registration function
|
|
#endif
|