📄 homopuls.c
字号:
/* * HOMOPULS A SIMULINK homonic pulse generator. * * Syntax: [sys, x0] = homopuls(t,x,u,flag,sample,divider,offset) * * Wes Wang 8/18/1994 revised 1/24/1996. * Copyright (c) 1994-96 by The MathWorks, Inc. * All Rights Reserved * $Revision: 1.1 $ $Date: 1996/04/01 19:02:56 $ */#define S_FUNCTION_NAME homopuls#ifdef MATLAB_MEX_FILE#include <stdio.h> /* needed for declaration of sprintf */#include "mex.h" /* needed for declaration of mexErrMsgTxt */#endif/* * need to include simstruc.h for the definition of the SimStruct and * its associated macro definitions. */#include "simstruc.h"/* * Defines for easy access of the input parameters */#define NUM_ARGS 3#define SAMPLE_TIME ssGetArg(S,0)#define DIVIDER_EACH ssGetArg(S,1)#define OFFSET_EACH ssGetArg(S,2)/* * mdlInitializeSizes - called to initialize the sizes array stored in * the SimStruct. The sizes array defines the * characteristics (number of inputs, outputs, * states, etc.) of the S-Function. */static void mdlInitializeSizes (S) SimStruct *S;{ /* * Set-up size information. */ if (ssGetNumArgs(S) == NUM_ARGS) { int dividerSize; if ((mxGetN(SAMPLE_TIME) * mxGetM(SAMPLE_TIME)) > 1) {#ifdef MATLAB_MEX_FILE mexErrMsgTxt("The sample time is a scalar.");#endif } if ((mxGetN(DIVIDER_EACH) != 1) && (mxGetM(DIVIDER_EACH) != 1)) {#ifdef MATLAB_MEX_FILE mexErrMsgTxt("The divider must be a vector");#endif } if ((mxGetN(OFFSET_EACH) != 1) && (mxGetM(OFFSET_EACH) != 1)) {#ifdef MATLAB_MEX_FILE mexErrMsgTxt("The offset must be a vector");#endif } if ((mxGetN(OFFSET_EACH) * (mxGetM(OFFSET_EACH))) != ((mxGetN(DIVIDER_EACH) * (mxGetM(DIVIDER_EACH))))) {#ifdef MATLAB_MEX_FILE mexErrMsgTxt("Divider and Offset must have the same length");#endif } dividerSize = mxGetN(DIVIDER_EACH) * mxGetM(DIVIDER_EACH); ssSetNumContStates( S, 0); ssSetNumDiscStates( S, 0); ssSetNumInputs( S, 0); ssSetNumOutputs( S, dividerSize); ssSetDirectFeedThrough(S, 0); ssSetNumInputArgs( S, NUM_ARGS); ssSetNumSampleTimes( S, dividerSize); ssSetNumRWork( S, 4*dividerSize+2); /* store the timing */ ssSetNumIWork( S, dividerSize); /* store the last time access. */ ssSetNumPWork( S, 0); } else {#ifdef MATLAB_MEX_FILE char err_msg[256]; sprintf(err_msg, "Wrong number of input arguments passed to S-function MEX-file.\n %d input arguments were passed in when expecting %d input arguments.\n", ssGetNumArgs(S) + 4, NUM_ARGS + 4); mexErrMsgTxt(err_msg);#endif }}/* * mdlInitializeSampleTimes - initializes the array of sample times stored in * the SimStruct associated with this S-Function. */static void mdlInitializeSampleTimes(S) SimStruct *S;{ double sampleTime, offsetTime, tmp; int i, dividerSize, adj; int *reverse = ssGetIWork(S); sampleTime = mxGetPr(SAMPLE_TIME)[0]; dividerSize = mxGetN(DIVIDER_EACH) * mxGetM(DIVIDER_EACH); for (i=0; i < dividerSize; i++) { offsetTime = mxGetPr(OFFSET_EACH)[i]; tmp = sampleTime/2./mxGetPr(DIVIDER_EACH)[i]; ssSetSampleTimeEvent(S, i, tmp); adj = (int)(offsetTime / tmp); tmp = offsetTime - ((double)adj) * tmp; ssSetOffsetTimeEvent(S, i, tmp);/* if (tmp != offsetTime - ((double)((int)(offsetTime/tmp/2))) * tmp *2) { reverse[i] = 1; } else { reverse[i] = 0; } */ }}/* * mdlInitializeConditions - initializes the states for the S-Function */static void mdlInitializeConditions(x0, S) double *x0; SimStruct *S;{ int dividerSize = mxGetN(DIVIDER_EACH) * mxGetM(DIVIDER_EACH); double *hit_base = ssGetRWork(S); double *next_hit = ssGetRWork(S) + 1; double *last_value = ssGetRWork(S) + dividerSize + 1; double *increment = ssGetRWork(S) + dividerSize * 2 + 1; double *adj_offset = ssGetRWork(S) + dividerSize * 3 + 1; double *tolerance = ssGetRWork(S) + dividerSize * 4 + 1; int *reverse = ssGetIWork(S); double sampleTime, offsetTime, offsetMin, tmp, tol; int i, adj; offsetMin = mxGetPr(OFFSET_EACH)[0]; sampleTime = mxGetPr(SAMPLE_TIME)[0]; /* * Initialize the last_accs to all zeros. */ tol = sampleTime; for (i = 0; i < dividerSize; i++) { *last_value++ = 0.; offsetTime = mxGetPr(OFFSET_EACH)[i]; offsetMin = (offsetMin < offsetTime) ? offsetMin : offsetTime; next_hit[i] = offsetTime; tmp = sampleTime/2./mxGetPr(DIVIDER_EACH)[i]; increment[i] = tmp; tol = (tol < tmp) ? tol : tmp; adj = (int)(offsetTime / tmp); tmp = offsetTime - ((double)adj) * tmp; if (tmp != offsetTime - ((double)((int)(offsetTime/tmp/2))) * tmp *2) { reverse[i] = 1; } else { reverse[i] = 0; }#ifdef MATLAB_MEX_FILE if (0) { char err_msg[255]; sprintf(err_msg, "reverse[%d]=%d; ", i, reverse[i]); mexPrintf(err_msg); }#endif adj_offset[i] = tmp; if (tmp > 0) tol = (tol < tmp) ? tol : tmp; }#ifdef MATLAB_MEX_FILE if (0) { char err_msg[255]; sprintf(err_msg, "\n"); mexPrintf(err_msg); }#endif *hit_base = offsetMin + sampleTime; *hit_base = sampleTime; *tolerance = tol / 100;}/* * mdlOutputs - computes the outputs of the S-Function */static void mdlOutputs(y, x, u, S, tid) double *y, *x, *u; SimStruct *S; int tid;{ int dividerSize = mxGetN(DIVIDER_EACH) * mxGetM(DIVIDER_EACH); double *hit_base = ssGetRWork(S); double *next_hit = ssGetRWork(S) + 1; double *last_value = ssGetRWork(S) + dividerSize + 1; double *increment = ssGetRWork(S) + dividerSize * 2 + 1; double *adj_offset = ssGetRWork(S) + dividerSize * 3 + 1; double *tolerance = ssGetRWork(S) + dividerSize * 4 + 1; int *reverse = ssGetIWork(S); double time_clock, tol; int i; tol = *tolerance; time_clock = ssGetT(S) + tol; for (i = 0; i < dividerSize; i++) { if (time_clock >= next_hit[i]) { int num; double sampleTime; sampleTime = mxGetPr(SAMPLE_TIME)[0]; num = (int)((time_clock - *hit_base - adj_offset[i] - sampleTime) / increment[i]); num = num%2; if (num) last_value[i] = 1.; else last_value[i] = 0.;#ifdef MATLAB_MEX_FILE if (0) { char err_msg[255]; sprintf(err_msg, "reverse[%d]=%d; last_value=%d; ", i, reverse[i], (int)last_value[i]); mexPrintf(err_msg); }#endif if (reverse[i]) last_value[i] = ((int)last_value[i] + 1) % 2;#ifdef MATLAB_MEX_FILE if (0) { char err_msg[255]; sprintf(err_msg, "new_last_value=%d;\n ", (int)last_value[i]); mexPrintf(err_msg); }#endif next_hit[i] = next_hit[i] + increment[i]; } y[i] = last_value[i]; } /* sprintf(err_msg, "\n "); mexPrintf(err_msg); for (i = 0; i < dividerSize; i++) { sprintf(err_msg, "output_y[%d]= %f, ", i, y[i]); mexPrintf(err_msg); } */ /* adjust the "current hit" every sample cycle. */ if (time_clock > *hit_base){ double sampleTime; sampleTime = mxGetPr(SAMPLE_TIME)[0]; for (i = 0; i < dividerSize; i++) { if (time_clock > mxGetPr(OFFSET_EACH)[i]) { if (adj_offset[i] <= 0) { next_hit[i] = *hit_base + increment[i]; } else { next_hit[i] = *hit_base + adj_offset[i]; } } } *hit_base = *hit_base + sampleTime; } }/* * mdlUpdate - computes the discrete states of the S-Function */static void mdlUpdate(x, u, S, tid) double *x, *u; SimStruct *S; int tid;{}/* * mdlDerivatives - computes the derivatives of the S-Function */static void mdlDerivatives(dx, x, u, S, tid) double *dx, *x, *u; SimStruct *S; int tid;{}/* * mdlTerminate - called at termination of model execution. */static void mdlTerminate(S) SimStruct *S;{}#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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -