sf_trgen.cc

00001 #include <list>
00002 #include <math.h>
00003 #include <exception>
00004 #include <typeinfo>
00005 #include <iterator>
00006 #include <trgen.h>
00007 
00008 #define S_FUNCTION_LEVEL 2
00009 #define S_FUNCTION_NAME  sf_trgen
00010 #include "simstruc.h"
00011 
00012 #ifdef __cplusplus
00013 extern "C" { // use the C fcn-call standard for all functions  
00014 #endif       // defined within this scope                     
00015 
00016 // Dialog parameters
00017 #define DP_PATH_IDX 0
00018 #define PATH_PARAM(S) (ssGetSFcnParam(S,DP_PATH_IDX))
00019 
00020 #define DP_INITPOS_IDX 1
00021 #define INITPOS_PARAM(S) (ssGetSFcnParam(S,DP_INITPOS_IDX))
00022 
00023 #define DP_TRAJECTORY_CONSTRAINTS_IDX 2
00024 #define TRAJECTORY_CONSTRAINTS_PARAM(S) (ssGetSFcnParam(S,DP_TRAJECTORY_CONSTRAINTS_IDX))
00025 
00026 // Work vectors
00027 #define PW_TRAJECTORY_IDX 0
00028 #define TRAJECTORY_OBJECT(S) ((Trajectory *)ssGetPWork(S)[PW_TRAJECTORY_IDX])
00029 
00030 /*
00031  * Need to include simstruc.h for the definition of the SimStruct and
00032  * its associated macro definitions.
00033  */
00034 #include "simstruc.h"
00035 
00036 #define IS_PARAM_DOUBLE(pVal) (mxIsNumeric(pVal) && !mxIsLogical(pVal) &&\
00037 !mxIsEmpty(pVal) && !mxIsSparse(pVal) && !mxIsComplex(pVal) && mxIsDouble(pVal))
00038 
00039 /*====================*
00040  * S-function methods *
00041  *====================*/
00042 
00043 #define MDL_CHECK_PARAMETERS
00044 #if defined(MDL_CHECK_PARAMETERS)  && defined(MATLAB_MEX_FILE)
00045 /*
00046  * Check to make sure that each parameter is 1-d and positive
00047  */
00048 static void mdlCheckParameters(SimStruct *S)
00049 {
00050 
00051     const mxArray *pPath = PATH_PARAM(S);
00052     const mxArray *initpos = INITPOS_PARAM(S);
00053     const mxArray *wc = TRAJECTORY_CONSTRAINTS_PARAM(S);
00054 
00055     if (mxGetM(pPath) != 2) {
00056         ssSetErrorStatus(S, "Parameter to S-function must be a two row array");
00057         return;
00058     }
00059     if (mxGetN(pPath) < 1) {
00060         ssSetErrorStatus(S, "Parameter to S-function must have at least one points (columns)");
00061         return;
00062     }
00063     if (mxGetN(initpos)*mxGetM(initpos) != 3) {
00064         ssSetErrorStatus(S, "The third parameter (initpos) must have three elements.");
00065         return;
00066     }
00067     if (mxGetN(wc)*mxGetM(wc) != 6) {
00068         ssSetErrorStatus(S, "The fourth parameter (constraints) must have six elements.");
00069         return;
00070     }
00071 }
00072 #endif
00073 
00074 
00075 /* Function: mdlInitializeSizes ===============================================
00076  * Abstract:
00077  *    The sizes information is used by Simulink to determine the S-function
00078  *    block's characteristics (number of inputs, outputs, states, etc.).
00079  */
00080 static void mdlInitializeSizes(SimStruct *S)
00081 {
00082     /* See sfuntmpl.doc for more details on the macros below */
00083 
00084     ssSetNumSFcnParams(S, 3);  /* Number of expected parameters */
00085 #if defined(MATLAB_MEX_FILE)
00086     if (ssGetNumSFcnParams(S) == ssGetSFcnParamsCount(S)) {
00087         mdlCheckParameters(S);
00088         if (ssGetErrorStatus(S) != NULL) {
00089             return;
00090         }
00091     } else {
00092         return; /* Parameter mismatch will be reported by Simulink */
00093     }
00094 #endif
00095     ssSetSFcnParamTunable(S, DP_PATH_IDX, 1);
00096     ssSetSFcnParamTunable(S, DP_INITPOS_IDX, 0);
00097     ssSetSFcnParamTunable(S, DP_TRAJECTORY_CONSTRAINTS_IDX, 0);
00098 
00099     ssSetNumContStates(S, 0);
00100     ssSetNumDiscStates(S, 0);
00101 
00102     if (!ssSetNumInputPorts(S, 0)) return;
00103     
00104     if (!ssSetNumOutputPorts(S, 1)) return;
00105     ssSetOutputPortWidth(S, 0, 5);
00106 
00107 
00108     ssSetNumSampleTimes(S, 1);
00109     ssSetNumRWork(S, 0);
00110     ssSetNumIWork(S, 0);
00111     ssSetNumPWork(S, 1); // reserve element in the pointers vector
00112     ssSetNumModes(S, 0); // to store a C++ object
00113     ssSetNumNonsampledZCs(S, 0);
00114 
00115     ssSetOptions(S, 0);
00116 }
00117 
00118 
00119 
00120 /* Function: mdlInitializeSampleTimes =========================================
00121  * Abstract:
00122  *    This function is used to specify the sample time(s) for your
00123  *    S-function. You must register the same number of sample times as
00124  *    specified in ssSetNumSampleTimes.
00125  */
00126 static void mdlInitializeSampleTimes(SimStruct *S)
00127 {
00128     ssSetSampleTime(S, 0, 0.05);
00129     ssSetOffsetTime(S, 0, 0.0);
00130     ssSetModelReferenceSampleTimeDefaultInheritance(S);
00131 }
00132 
00133 
00134 #define MDL_START  /* Change to #undef to remove function */
00135 #if defined(MDL_START) 
00136   /* Function: mdlStart =======================================================
00137    * Abstract:
00138    *    This function is called once at start of model execution. If you
00139    *    have states that should be initialized once, this is the place
00140    *    to do it.
00141    */
00142   static void mdlStart(SimStruct *S)
00143   {
00144       const double *initpos = mxGetPr(INITPOS_PARAM(S));
00145       const double *wc = mxGetPr(TRAJECTORY_CONSTRAINTS_PARAM(S));
00146       Pos initPos;
00147       TrajectoryConstraints trajectoryConstraints;
00148       Trajectory *trajectory;
00149       initPos.x = initpos[0];
00150       initPos.y = initpos[1];
00151       initPos.phi = initpos[2];
00152       trajectoryConstraints.maxv = wc[0];
00153       trajectoryConstraints.maxomega = wc[1];
00154       trajectoryConstraints.maxangacc = wc[2];
00155       trajectoryConstraints.maxacc = wc[3];
00156       trajectoryConstraints.maxcenacc = wc[4];
00157       trajectoryConstraints.maxe = wc[5];
00158       trajectory = new Trajectory(trajectoryConstraints);
00159       trajectory->finalHeading = (double)90.0/180*M_PI;
00160       //ssGetPWork(S)[PW_REG_IDX] = (void*)new PosRegCmu(); // store new C++ object in the
00161                                                  // pointers vector
00162 
00163       ssGetPWork(S)[PW_TRAJECTORY_IDX] = (void*)trajectory;
00164       
00165       double *path = mxGetPr(PATH_PARAM(S));
00166       for (unsigned i=0; i<mxGetN(PATH_PARAM(S)); i++) {
00167           trajectory->addPoint(path[2*i], path[2*i+1]);
00168           if (i>0) {
00169               char cmd[300];
00170               sprintf(cmd, "plot([%g %g], [%g %g], '--bo')",
00171                       path[2*i-2], path[2*i], path[2*i-1], path[2*i+1]);
00172               mexEvalString(cmd);
00173           }
00174       }
00175 
00176       trajectory->prepare(initPos);
00177       trajectory->plot("-m");
00178   }
00179 #endif /*  MDL_START */
00180 
00181 
00182 /* Function: mdlOutputs =======================================================
00183  * Abstract:
00184  *    In this function, you compute the outputs of your S-function
00185  *    block. Generally outputs are placed in the output vector, ssGetY(S).
00186  */
00187 static void mdlOutputs(SimStruct *S, int_T tid)
00188 {
00189     //PosRegCmu *reg = REG_OBJECT(S);   // retrieve C++ object from
00190     real_T  *y = ssGetOutputPortRealSignal(S,0); 
00191     Trajectory *trajectory = TRAJECTORY_OBJECT(S);
00192     Pos rp;
00193     
00194     trajectory->getRefPos(ssGetT(S), rp);
00195     y[0] = rp.x;
00196     y[1] = rp.y;
00197     y[2] = rp.phi;
00198     y[3] = rp.v;
00199     y[4] = rp.omega;
00200 
00201     //ssPrintf("%g %g %g %g %g\n", y[0], y[1], y[2], y[3], y[4]);
00202 
00203     UNUSED_ARG(tid);
00204 }                                                
00205 
00206 /* Function: mdlTerminate =====================================================
00207  * Abstract:
00208  *    In this function, you should perform any actions that are necessary
00209  *    at the termination of a simulation.  For example, if memory was
00210  *    allocated in mdlStart, this is the place to free it.
00211  */
00212 static void mdlTerminate(SimStruct *S)
00213 {
00214     delete TRAJECTORY_OBJECT(S);
00215 }                                              // function
00216 /*======================================================*
00217  * See sfuntmpl.doc for the optional S-function methods *
00218  *======================================================*/
00219 
00220 /*=============================*
00221  * Required S-function trailer *
00222  *=============================*/
00223 
00224 #ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
00225 #include "simulink.c"      /* MEX-file interface mechanism */
00226 #else
00227 #include "cg_sfun.h"       /* Code generation registration function */
00228 #endif
00229 
00230 #ifdef __cplusplus
00231 } // end of extern "C" scope
00232 #endif

Generated on Thu Sep 13 11:28:28 2007 for DCE-Eurobot by  doxygen 1.5.3