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" {
00014 #endif // defined within this scope
00015
00016
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
00027 #define PW_TRAJECTORY_IDX 0
00028 #define TRAJECTORY_OBJECT(S) ((Trajectory *)ssGetPWork(S)[PW_TRAJECTORY_IDX])
00029
00030
00031
00032
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
00041
00042
00043 #define MDL_CHECK_PARAMETERS
00044 #if defined(MDL_CHECK_PARAMETERS) && defined(MATLAB_MEX_FILE)
00045
00046
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
00076
00077
00078
00079
00080 static void mdlInitializeSizes(SimStruct *S)
00081 {
00082
00083
00084 ssSetNumSFcnParams(S, 3);
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;
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);
00112 ssSetNumModes(S, 0);
00113 ssSetNumNonsampledZCs(S, 0);
00114
00115 ssSetOptions(S, 0);
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
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
00135 #if defined(MDL_START)
00136
00137
00138
00139
00140
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
00161
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
00180
00181
00182
00183
00184
00185
00186
00187 static void mdlOutputs(SimStruct *S, int_T tid)
00188 {
00189
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
00202
00203 UNUSED_ARG(tid);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 static void mdlTerminate(SimStruct *S)
00213 {
00214 delete TRAJECTORY_OBJECT(S);
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224 #ifdef MATLAB_MEX_FILE
00225 #include "simulink.c"
00226 #else
00227 #include "cg_sfun.h"
00228 #endif
00229
00230 #ifdef __cplusplus
00231 }
00232 #endif