schdint.c
上传用户:loeagle
上传日期:2013-03-02
资源大小:1236k
文件大小:8k
源码类别:

通讯编程文档

开发平台:

Matlab

  1. /* $Revision: 1.25 $ */
  2. /*
  3.  * SCHDINT   A Simulink scheduling integration
  4.  *
  5.  *           Syntax:  [sys, x0] = schdint(t, x, u, flag, TD, TS, Modulo)
  6.  *
  7.  *      This block will reset the integration to be zero at K*TD(1) + TD(2).
  8.  *      TS: sampling time of the integration. This is a discrete-time block.
  9.  *      Modulo: Limitation of the integration. When State is larger than this
  10.  *              value it will do x=rem(x,Modulo) computation.
  11.  *
  12.  * Wes Wang Dec. 8, 1994
  13.  * Copyright 1996-2001 The MathWorks, Inc.
  14.  */
  15. #define S_FUNCTION_NAME schdint
  16. #ifdef MATLAB_MEX_FILE
  17. #include "mex.h"      /* needed for declaration of mexErrMsgTxt */
  18. #endif
  19. /*
  20.  * need to include simstruc.h for the definition of the SimStruct and
  21.  * its associated macro definitions.
  22.  */
  23. #include "simstruc.h"
  24. #include "tmwtypes.h"
  25. #include <math.h>
  26. /* For RTW */
  27. #if defined(RT) || defined(NRT)  
  28. #undef  mexPrintf
  29. #define mexPrintf printf
  30. #endif
  31. /*
  32.  * Defines for easy access of the input parameters
  33.  */
  34. #define NUM_ARGS   3
  35. #define TD         ssGetArg(S,0)
  36. #define TS         ssGetArg(S,1)
  37. #define Modulo     ssGetArg(S,2)
  38. /*
  39.  * mdlInitializeSizes - called to initialize the sizes array stored in
  40.  *                      the SimStruct.  The sizes array defines the
  41.  *                      characteristics (number of inputs, outputs,
  42.  *                      states, etc.) of the S-Function.
  43.  */
  44. static void mdlInitializeSizes(SimStruct *S)
  45. {
  46.   /*
  47.    * Set-up size information.
  48.    */ 
  49.     
  50.   if (ssGetNumArgs(S) == NUM_ARGS) {
  51.     real_T td;
  52.     real_T ts;
  53.     real_T mod_bound; 
  54.     if ((mxGetN(TD)*mxGetM(TD) != 1) &&
  55. (mxGetN(TD)*mxGetM(TD) != 2)) {
  56. #ifdef MATLAB_MEX_FILE
  57.       mexErrMsgTxt("The reset time must be a scalar or a vector of length 2");
  58. #endif
  59.     }
  60.     if ((mxGetN(TS)*mxGetM(TS) != 1) &&
  61. (mxGetN(TS)*mxGetM(TS) != 2)) {
  62. #ifdef MATLAB_MEX_FILE
  63.       mexErrMsgTxt("The sample time must be a scalar or a vector of length 2");
  64. #endif
  65.      }
  66.     if (mxGetN(Modulo)*mxGetM(Modulo) != 1) {
  67. #ifdef MATLAB_MEX_FILE
  68.       mexErrMsgTxt("The modulo number must be a scalar value.");
  69. #endif
  70.     }
  71.     mod_bound = mxGetPr(Modulo)[0];
  72.     if (mod_bound <= 0) {
  73. #ifdef MATLAB_MEX_FILE
  74.       mexErrMsgTxt("The modulo number can be positive number only.");
  75. #endif
  76.     }           
  77.     td = mxGetPr(TD)[0];
  78.     ts = mxGetPr(TS)[0];
  79.     ssSetNumContStates(    S, 0);
  80.     ssSetNumDiscStates(    S, -1);
  81.     ssSetNumInputs(        S, -1);
  82.     ssSetNumOutputs(       S, -1);
  83.     ssSetDirectFeedThrough(S, 0);
  84.     ssSetNumInputArgs(     S, NUM_ARGS);
  85.     if (td < ts) {
  86. #ifdef MATLAB_MEX_FILE
  87.       mexErrMsgTxt("The reset interval cannot be smaller than the sample time.");
  88. #endif
  89.     }
  90.     if (ts / td < 10e-10)
  91.         ssSetNumSampleTimes(   S, 1);
  92.     else
  93.         ssSetNumSampleTimes(   S, 2);
  94.     ssSetNumRWork(         S, 2);
  95.     ssSetNumIWork(         S, 1);
  96.     ssSetNumPWork(         S, 0);
  97.   } else {
  98. #ifdef MATLAB_MEX_FILE
  99.     char_T err_msg[256];
  100.     sprintf(err_msg, "Wrong number of input arguments passed to S-function MEX-file.n"
  101.     "%d input arguments were passed in when expecting %d input arguments.n", ssGetNumArgs(S) + 4, NUM_ARGS + 4);
  102.     mexErrMsgTxt(err_msg);
  103. #endif
  104.   }
  105. }
  106. /*
  107.  * mdlInitializeSampleTimes - initializes the array of sample times stored in
  108.  *                            the SimStruct associated with this S-Function.
  109.  */
  110. static void mdlInitializeSampleTimes(SimStruct *S)
  111. {
  112.   real_T sampleTime, offsetTime;
  113.   /*
  114.    * Note, blocks that are continuous in nature should have a single
  115.    * sample time of 0.0.
  116.    */
  117.   real_T td = mxGetPr(TD)[0];
  118.   real_T ts = mxGetPr(TS)[0];  
  119.   if (ts / td >= 1.0e-10){
  120.       sampleTime = mxGetPr(TD)[0];
  121.       if ((mxGetN(TD) * mxGetM(TD)) == 2)
  122.           offsetTime = mxGetPr(TD)[1];
  123.       else
  124.           offsetTime = 0.;
  125.     
  126.       ssSetSampleTimeEvent(S, 1, sampleTime);
  127.       ssSetOffsetTimeEvent(S, 1, offsetTime);
  128.   }
  129.   sampleTime = mxGetPr(TS)[0];
  130.   if ((mxGetN(TS) * mxGetM(TS)) == 2)
  131.     offsetTime = mxGetPr(TS)[1];
  132.   else
  133.     offsetTime = 0.;
  134.   
  135.   ssSetSampleTimeEvent(S, 0, sampleTime);
  136.   ssSetOffsetTimeEvent(S, 0, offsetTime);      
  137. }
  138. /*
  139.  * mdlInitializeConditions - initializes the states for the S-Function
  140.  */
  141. static void mdlInitializeConditions(real_T *x0, SimStruct *S)
  142. {
  143.   real_T *current_drive_time  = ssGetRWork(S);
  144.   real_T *last_time = ssGetRWork(S) + 1;
  145.   real_T sampleTime;
  146.   int_T    *hitted_num = ssGetIWork(S);
  147.   int_T in_length = ssGetNumInputs(S);
  148.   int_T i;
  149.   
  150.   if (ssGetT(S) <= 0) {
  151.     sampleTime = mxGetPr(TS)[0];    
  152.     /*take the following number instead of 0 to avoid additive error for miss hitting*/
  153.     *current_drive_time = 0.0;
  154.     *last_time = ssGetT(S)-sampleTime;
  155.     *hitted_num = 0;
  156.     for (i=0; i<in_length; i++)
  157.       x0[i] = 0.0;
  158.   }
  159. }
  160. /*
  161.  * mdlOutputs - computes the outputs of the S-Function
  162.  */
  163. static void mdlOutputs(real_T *y, const real_T *x, const real_T *u, SimStruct *S, int_T tid)
  164. {
  165.   int_T in_length = ssGetNumInputs(S);
  166.   int_T i;
  167. #ifdef MATLAB_MEX_FILE
  168.   if (0) {
  169.     char_T err_msg[256];
  170.     sprintf(err_msg, "Output checking point Time: %fn", ssGetT(S));
  171.     mexPrintf(err_msg);
  172.     for (i = 0; i<in_length; i++) {
  173.       sprintf(err_msg, "State %f, [%i]n", x[i], i);
  174.       mexPrintf(err_msg);
  175.     }
  176.   }
  177. #endif
  178.   if (ssIsMajorTimeStep(S)){
  179.     for (i=0; i<in_length;i++)
  180.       y[i] = x[i];
  181.   }
  182. }
  183. /*
  184.  * mdlUpdate - computes the discrete states of the S-Function
  185.  */
  186. static void mdlUpdate(real_T *x, const real_T *u, SimStruct *S, int_T tid)
  187. {
  188.   real_T *current_drive_time  = ssGetRWork(S);
  189.   real_T *last_time = ssGetRWork(S) + 1;
  190.   real_T current_time = ssGetT(S);
  191.   real_T sampleTime, offsetTime, time_step, it_time;
  192.   
  193.   int_T    *hitted_num = ssGetIWork(S);    
  194.   int_T in_length = ssGetNumInputs(S);
  195.   int_T i;
  196.   
  197.   it_time = mxGetPr(TS)[0];    
  198.   sampleTime = mxGetPr(TD)[0];
  199.   if ((mxGetN(TD) * mxGetM(TD)) == 2)
  200.     offsetTime = mxGetPr(TD)[1];
  201.   else
  202.     offsetTime = 0.;
  203.   
  204.   /* calculation only if the time is passed offset time. */
  205.   if (current_time >= offsetTime) {
  206.     real_T mod_bound;
  207.     
  208.     mod_bound = mxGetPr(Modulo)[0];
  209.     time_step = current_time - (*last_time);
  210.     time_step = time_step < it_time ? time_step : it_time;
  211.     *current_drive_time += time_step;
  212. #ifdef MATLAB_MEX_FILE
  213.     if (0) {
  214.        char_T err_msg[256];
  215.        sprintf(err_msg, "Current_drive_time %f, Current_time %f, Sample_time %f, hitted_num %i, offsetTime %fn", *current_drive_time, current_time, sampleTime, *hitted_num, offsetTime);
  216.   mexPrintf(err_msg);        
  217.     }
  218. #endif
  219.     /*
  220.     if ((*current_drive_time >= sampleTime) || ((*hitted_num>0) && (current_time >= (real_T)(*hitted_num) * sampleTime + offsetTime))){
  221.     */
  222.     if ((*current_drive_time >= sampleTime) || ( current_time >= (real_T)(*hitted_num) * sampleTime + offsetTime ) ){
  223.       /*reset*/
  224.       for (i=0; i<in_length; i++) {
  225. /*    sprintf(err_msg, "x %f, time_step %fn", x[i], time_step);
  226.       mexPrintf(err_msg);                        
  227.       */
  228. x[i] = u[i] * time_step;
  229. if (mxIsInf(mod_bound))
  230.   x[i] = x[i];
  231. else
  232.   x[i] = fmod(x[i], mod_bound);               
  233.       }
  234.       *hitted_num += 1;
  235.       /*take the following number instead of 0 to avoid additive error for miss hitting*/
  236.       *current_drive_time = sampleTime/1000000000;
  237.     } else {
  238.       for (i=0; i<in_length; i++) {
  239. /*    sprintf(err_msg, "ELSE x %f, time_step %fn", x[i], time_step);
  240.       mexPrintf(err_msg);                                        
  241.       */
  242. x[i] += u[i] * time_step;
  243. if (mxIsInf(mod_bound))
  244.   x[i] = x[i];
  245. else
  246.   x[i] = fmod(x[i], mod_bound); 
  247.       }
  248.     }
  249.   }
  250.   if (current_time > *last_time)
  251.     *last_time = current_time;
  252. #ifdef MATLAB_MEX_FILE
  253.     if (0) {
  254.       char_T err_msg[256];
  255.       for (i = 0; i<in_length; i++) {
  256.          sprintf(err_msg, "State %f, [%i]n", x[i], i);
  257.          mexPrintf(err_msg);
  258.       }
  259.     }
  260. #endif
  261. }
  262. /*
  263.  * mdlDerivatives - computes the derivatives of the S-Function
  264.  */
  265. static void mdlDerivatives(real_T *dx, const real_T *x, const real_T *u, SimStruct *S, int_T tid)
  266. {
  267. }
  268. /*
  269.  * mdlTerminate - called at termination of model execution.
  270.  */
  271. static void mdlTerminate(SimStruct *S)
  272. {
  273. }
  274. #ifdef   MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
  275. #include "simulink.c"      /* MEX-File interface mechanism */
  276. #else
  277. #include "cg_sfun.h"       /* Code generation registration function */
  278. #endif