matlab的例程-S-function研究

一、例程

二、continuous 连续处理方式



 三、absolute tolerance (绝对容差)

这个s函数允许用户设置每个连续状态的绝对容差。 在这种情况下,有两种连续状态,它们的绝对容差可以使用参数设置
 这就是一个基本例子

范德波尔方程

 


 

一个输入可以设置常数Mu 以及 状态的输入的绝对容差可以设置

两个状态的绝对容差
 

 

输入 u[0]

 

 

 



 四、代码分析

/* Copyright 2000-2010 The MathWorks, Inc. */

/* File : sfun_atol.c
* Abstract :
*
* Example of an S-function with sets different absolute tolerances 
* for each continuous state. The system modeled is this 2-D ODE,
* x1' = x2 
* x2' = Mu[(1-x1^2)x2] - x1
* which is the van der Pol equation. The constant Mu is set through
* an inport and the absolute tolerance for each state is set by parameters
* to the S-function.
* 
*/


#define S_FUNCTION_NAME sfun_atol
#define S_FUNCTION_LEVEL 2

/*
* Need to include simstruc.h for the definition of the SimStruct and
* its associated macro definitions.
*/
#include "simstruc.h"

#define IS_PARAM_DOUBLE(pVal) (mxIsNumeric(pVal) && !mxIsLogical(pVal) &&\
!mxIsEmpty(pVal) && !mxIsSparse(pVal) && !mxIsComplex(pVal) && mxIsDouble(pVal))


/*====================*
* S-function methods *
*====================*/

#define MDL_CHECK_PARAMETERS
#if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
/*
* Check to make sure that each parameter is 1-d and positive
*/
static void mdlCheckParameters(SimStruct *S)
{

const mxArray *pVal0 = ssGetSFcnParam(S,0);
const mxArray *pVal1 = ssGetSFcnParam(S,1);

if ( mxGetNumberOfElements(ssGetSFcnParam(S,0)) != 1 || !IS_PARAM_DOUBLE(pVal0)) {
ssSetErrorStatus(S, "Parameter to S-function must be a scalar");
return;
} 
else if (mxGetPr(ssGetSFcnParam(S,0))[0] < 0) {
ssSetErrorStatus(S, "Parameter to S-function must be non-negative");
return;
}

if (mxGetNumberOfElements(ssGetSFcnParam(S,1)) != 1 || !IS_PARAM_DOUBLE(pVal1)) {
ssSetErrorStatus(S, "Parameter to S-function must be a scalar");
return;
} 
else if (mxGetPr(ssGetSFcnParam(S,1))[0] < 0) {
ssSetErrorStatus(S, "Parameter to S-function must be non-negative");
return;
} 
}
#endif

static void mdlInitializeSizes(SimStruct *S)
{

ssSetNumSFcnParams(S, 2); /* Number of expected parameters */
#if defined(MATLAB_MEX_FILE)
/*
* Check the initial settings of the parameters
*/
if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
mdlCheckParameters(S);
if (ssGetErrorStatus(S) != NULL) return;
} else {
return;
}
#endif

{
int iParam = 0;
int nParam = ssGetNumSFcnParams(S);

for ( iParam = 0; iParam < nParam; iParam++ )
{
ssSetSFcnParamTunable( S, iParam, SS_PRM_SIM_ONLY_TUNABLE );
}
}

ssSetNumContStates(S, 2);
ssSetNumDiscStates(S, 0);

if (!ssSetNumInputPorts(S, 1)) return;
ssSetInputPortWidth(S, 0, 1);

if (!ssSetNumOutputPorts(S, 2)) return;
ssSetOutputPortWidth(S, 0, 1);
ssSetOutputPortWidth(S, 1, 1);

ssSetNumSampleTimes(S, 1);
ssSetOperatingPointCompliance(S, USE_DEFAULT_OPERATING_POINT);

ssSetOptions(S, 0);
}


static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, CONTINUOUS_SAMPLE_TIME);
ssSetOffsetTime(S, 0, 0.0);
ssSetModelReferenceSampleTimeDefaultInheritance(S);
}


#define MDL_INITIALIZE_CONDITIONS
#if defined(MDL_INITIALIZE_CONDITIONS)
/*
* Set the initial conditions to [0 2]
*/
static void mdlInitializeConditions(SimStruct *S)
{
real_T *x0 = ssGetContStates(S);

/* Initialize to the inputs */
x0[0] = 2.0;
x0[1] = 0.0;

}
#endif /* MDL_INITIALIZE_CONDITIONS */


#define MDL_START 
#if defined(MDL_START) 
/*
* Set the absolute tolerances based on the parameters
*/
static void mdlStart(SimStruct *S)
{
const real_T absTol0 = ( mxGetPr(ssGetSFcnParam(S,0)) )[0];
const real_T absTol1 = ( mxGetPr(ssGetSFcnParam(S,1)) )[0];

/* Absolute tolerance is not used by fixed-step solvers
* Therefore every call to absolute tolerance API must be guarded
*/

if ( ssIsVariableStepSolver(S) ) {
ssSetStateAbsTol(S, 0, absTol0); 
ssSetStateAbsTol(S, 1, absTol1); 
}
}
#endif /* MDL_START */


#define MDL_PROCESS_PARAMETERS
#if defined(MDL_PROCESS_PARAMETERS) && defined(MATLAB_MEX_FILE)
/*
* Process any changes to parameters
*/
static void mdlProcessParameters(SimStruct *S)
{

const real_T absTol0 = ( mxGetPr(ssGetSFcnParam(S,0)) )[0];
const real_T absTol1 = ( mxGetPr(ssGetSFcnParam(S,1)) )[0];

/* Absolute tolerance is not used by fixed-step solvers
* Therefore every call to absolute tolerance API must be guarded
*/
if ( ssIsVariableStepSolver(S) ) {
ssSetStateAbsTol(S, 0, absTol0); 
ssSetStateAbsTol(S, 1, absTol1); 
}
}
#endif


static void mdlOutputs(SimStruct *S, int_T tid)
{
real_T *y1 = ssGetOutputPortRealSignal(S,0);
real_T *y2 = ssGetOutputPortRealSignal(S,1);
real_T *x = ssGetContStates(S);


/* Set the outputs to the continuous states */
*y1 = x[0];
*y2 = x[1];

#ifdef PRINT_ABS_TOL
if (ssIsMajorTimeStep(S)) { 
ssPrintf("Abs tol %.16g %.16g \n", ssGetStateAbsTol(S,0), 
ssGetStateAbsTol(S,1));
}
#endif
}


#define MDL_DERIVATIVES
#if defined(MDL_DERIVATIVES)
static void mdlDerivatives(SimStruct *S)
{
real_T *dx = ssGetdX(S);
real_T *x = ssGetContStates(S);
InputRealPtrsType u0 = ssGetInputPortRealSignalPtrs(S,0);
real_T Mu = *u0[0];

dx[0] = x[1];
dx[1] = Mu*((1.0 - x[0]*x[0])*x[1]) - x[0];
}
#endif /* MDL_DERIVATIVES */


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

 

 

posted on 2021-11-29 15:07  Ablerry  阅读(562)  评论(0)    收藏  举报