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



浙公网安备 33010602011771号