00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "model.h"
00030 #include "grt.h"
00031
00032 #ifndef RT_MALLOC
00033 # error "grt_malloc_main.c require RT_MALLOC to be defined"
00034 #endif
00035
00036
00037
00038
00039 #ifdef __cplusplus
00040
00041 extern "C" {
00042
00043 #endif
00044
00045 extern RT_MODEL *MODEL(void);
00046
00047 #ifdef __cplusplus
00048
00049 }
00050 #endif
00051
00052 #if NCSTATES > 0
00053 #ifdef __cplusplus
00054
00055 extern "C" {
00056
00057 #endif
00058 extern void rt_ODECreateIntegrationData(RTWSolverInfo *si);
00059 extern void rt_ODEUpdateContinuousStates(RTWSolverInfo *si);
00060 # if defined(RT_MALLOC)
00061 extern void rt_ODEDestroyIntegrationData(RTWSolverInfo *si);
00062 # endif
00063 #ifdef __cplusplus
00064
00065 }
00066 #endif
00067 #else
00068 # define rt_ODECreateIntegrationData(si) \
00069 rtsiSetSolverName(si, "FixedStepDiscrete");
00070 # define rt_ODEUpdateContinuousStates(si) \
00071 rtsiSetT(si,rtsiGetSolverStopTime(si))
00072 #endif
00073
00074
00075
00076
00077
00078
00079 const char *RT_MEMORY_ALLOCATION_ERROR = "memory allocation error";
00080
00081
00082
00083
00084
00085 #ifdef EXT_MODE
00086 # define rtExtModeSingleTaskUpload(S) \
00087 { \
00088 int stIdx; \
00089 rtExtModeUploadCheckTrigger(rtmGetNumSampleTimes(S)); \
00090 for (stIdx=0; stIdx<NUMST; stIdx++) { \
00091 if (rtmIsSampleHit(S, stIdx, 0 )) { \
00092 rtExtModeUpload(stIdx,rtmGetTaskTime(S,stIdx)); \
00093 } \
00094 } \
00095 }
00096 #else
00097 # define rtExtModeSingleTaskUpload(S)
00098 #endif
00099
00100
00101
00102
00103
00104 namespace rosrtw {
00105
00106 #if !defined(MULTITASKING)
00107
00108
00109
00110
00111
00112
00113
00114
00115 void Model::rt_OneStep(RT_MODEL *S)
00116 {
00117 real_T tnext;
00118
00119
00120
00121
00122 if (GBLbuf.isrOverrun++) {
00123 GBLbuf.stopExecutionFlag = 1;
00124 return;
00125 }
00126
00127
00128
00129
00130 if (rtmGetErrorStatus(S) != NULL) {
00131 GBLbuf.stopExecutionFlag = 1;
00132 return;
00133 }
00134
00135
00136
00137 tnext = rt_SimGetNextSampleHit(rtmGetTimingData(S),
00138 rtmGetNumSampleTimes(S));
00139 rtsiSetSolverStopTime(rtmGetRTWSolverInfo(S),tnext);
00140
00141 rtmiOutputs(rtmGetRTWRTModelMethodsInfo(S),0);
00142
00143 rtExtModeSingleTaskUpload(S);
00144
00145 GBLbuf.errmsg = rt_UpdateTXYLogVars(rtmGetRTWLogInfo(S),
00146 rtmGetTPtr(S));
00147 if (GBLbuf.errmsg != NULL) {
00148 GBLbuf.stopExecutionFlag = 1;
00149 return;
00150 }
00151
00152 rtmiUpdate(rtmGetRTWRTModelMethodsInfo(S),0);
00153
00154 rt_SimUpdateDiscreteTaskSampleHits(rtmGetNumSampleTimes(S),
00155 rtmGetTimingData(S),
00156 rtmGetSampleHitPtr(S),
00157 rtmGetTPtr(S));
00158
00159 if (rtmGetSampleTime(S,0) == CONTINUOUS_SAMPLE_TIME) {
00160 rt_ODEUpdateContinuousStates(rtmGetRTWSolverInfo(S));
00161 }
00162
00163 GBLbuf.isrOverrun--;
00164
00165 rtExtModeCheckEndTrigger();
00166
00167 }
00168
00169 #else
00170
00171 # if TID01EQ == 1
00172 # define FIRST_TID 1
00173 # else
00174 # define FIRST_TID 0
00175 # endif
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 void Model::rt_OneStep(RT_MODEL *S)
00194 {
00195 int_T i;
00196 real_T tnext;
00197 int_T *sampleHit = rtmGetSampleHitPtr(S);
00198
00199
00200
00201
00202 if (GBLbuf.isrOverrun++) {
00203 GBLbuf.stopExecutionFlag = 1;
00204 return;
00205 }
00206
00207
00208
00209
00210 if (rtmGetErrorStatus(S) != NULL) {
00211 GBLbuf.stopExecutionFlag = 1;
00212 return;
00213 }
00214
00215
00216
00217
00218
00219 tnext = rt_SimUpdateDiscreteEvents(rtmGetNumSampleTimes(S),
00220 rtmGetTimingData(S),
00221 rtmGetSampleHitPtr(S),
00222 rtmGetPerTaskSampleHitsPtr(S));
00223 rtsiSetSolverStopTime(rtmGetRTWSolverInfo(S),tnext);
00224 for (i=FIRST_TID+1; i < NUMST; i++) {
00225 if (sampleHit[i] && GBLbuf.eventFlags[i]++) {
00226 GBLbuf.isrOverrun--;
00227 GBLbuf.overrunFlags[i]++;
00228 GBLbuf.stopExecutionFlag=1;
00229 return;
00230 }
00231 }
00232
00233
00234
00235
00236
00237 rtmiOutputs(rtmGetRTWRTModelMethodsInfo(S),FIRST_TID);
00238
00239 rtExtModeUploadCheckTrigger(rtmGetNumSampleTimes(S));
00240 rtExtModeUpload(FIRST_TID,rtmGetTaskTime(S, FIRST_TID));
00241
00242 GBLbuf.errmsg = rt_UpdateTXYLogVars(rtmGetRTWLogInfo(S),
00243 rtmGetTPtr(S));
00244 if (GBLbuf.errmsg != NULL) {
00245 GBLbuf.stopExecutionFlag = 1;
00246 return;
00247 }
00248
00249 rtmiUpdate(rtmGetRTWRTModelMethodsInfo(S),FIRST_TID);
00250
00251 if (rtmGetSampleTime(S,0) == CONTINUOUS_SAMPLE_TIME) {
00252 rt_ODEUpdateContinuousStates(rtmGetRTWSolverInfo(S));
00253 }
00254 else {
00255 rt_SimUpdateDiscreteTaskTime(rtmGetTPtr(S),
00256 rtmGetTimingData(S),0);
00257 }
00258
00259 #if FIRST_TID == 1
00260 rt_SimUpdateDiscreteTaskTime(rtmGetTPtr(S),
00261 rtmGetTimingData(S),1);
00262 #endif
00263
00264
00265
00266
00267
00268
00269 GBLbuf.isrOverrun--;
00270
00271
00272
00273
00274
00275 for (i=FIRST_TID+1; i<NUMST; i++) {
00276
00277 if (GBLbuf.overrunFlags[i]) return;
00278
00279 if (GBLbuf.eventFlags[i]) {
00280 GBLbuf.overrunFlags[i]++;
00281
00282 rtmiOutputs(rtmGetRTWRTModelMethodsInfo(S),i);
00283
00284 rtExtModeUpload(i, rtmGetTaskTime(S,i));
00285
00286 rtmiUpdate(rtmGetRTWRTModelMethodsInfo(S),i);
00287
00288 rt_SimUpdateDiscreteTaskTime(rtmGetTPtr(S),
00289 rtmGetTimingData(S),i);
00290
00291
00292 GBLbuf.overrunFlags[i]--;
00293 GBLbuf.eventFlags[i]--;
00294 }
00295 }
00296
00297 rtExtModeCheckEndTrigger();
00298
00299 }
00300
00301 #endif
00302
00303
00304
00305
00306
00307 bool Model::initialize()
00308 {
00309 if (is_initialized) return false;
00310
00311
00312
00313
00314 S = MODEL();
00315 if (S == NULL) {
00316 (void)fprintf(stderr,"Memory allocation error during model "
00317 "registration");
00318
00319 terminate();
00320 return false;
00321 }
00322
00323 if (rtmGetErrorStatus(S) != NULL) {
00324 (void)fprintf(stderr,"Error during model registration: %s\n",
00325 rtmGetErrorStatus(S));
00326 rtmiTerminate(rtmGetRTWRTModelMethodsInfo(S));
00327
00328 terminate();
00329 return false;
00330 }
00331
00332 if (finaltime >= 0.0 || finaltime == RUN_FOREVER) rtmSetTFinal(S,finaltime);
00333
00334 rtmiInitializeSizes(rtmGetRTWRTModelMethodsInfo(S));
00335 rtmiInitializeSampleTimes(rtmGetRTWRTModelMethodsInfo(S));
00336
00337 const char *status = 0;
00338 status = rt_SimInitTimingEngine(rtmGetNumSampleTimes(S),
00339 rtmGetStepSize(S),
00340 rtmGetSampleTimePtr(S),
00341 rtmGetOffsetTimePtr(S),
00342 rtmGetSampleHitPtr(S),
00343 rtmGetSampleTimeTaskIDPtr(S),
00344 rtmGetTStart(S),
00345 &rtmGetSimTimeStep(S),
00346 &rtmGetTimingData(S));
00347
00348 if (status != NULL) {
00349 (void)fprintf(stderr,
00350 "Failed to initialize sample time engine: %s\n", status);
00351
00352 terminate();
00353 return false;
00354 }
00355 rt_ODECreateIntegrationData(rtmGetRTWSolverInfo(S));
00356 #if NCSTATES > 0
00357 if(rtmGetErrorStatus(S) != NULL) {
00358 (void)fprintf(stderr, "Error creating integration data.\n");
00359 rt_ODEDestroyIntegrationData(rtmGetRTWSolverInfo(S));
00360 rtmiTerminate(rtmGetRTWRTModelMethodsInfo(S));
00361
00362 terminate();
00363 return false;
00364 }
00365 #endif
00366
00367 GBLbuf.errmsg = rt_StartDataLogging(rtmGetRTWLogInfo(S),
00368 rtmGetTFinal(S),
00369 rtmGetStepSize(S),
00370 &rtmGetErrorStatus(S));
00371 if (GBLbuf.errmsg != NULL) {
00372 (void)fprintf(stderr,"Error starting data logging: %s\n",GBLbuf.errmsg);
00373 terminate();
00374 return false;
00375 }
00376
00377 rtExtModeCheckInit(rtmGetNumSampleTimes(S));
00378 rtExtModeWaitForStartPkt(rtmGetRTWExtModeInfo(S),
00379 rtmGetNumSampleTimes(S),
00380 (boolean_T *)&rtmGetStopRequested(S));
00381
00382 (void)printf("\n** starting the model **\n");
00383
00384 rtmiStart(rtmGetRTWRTModelMethodsInfo(S));
00385 if (rtmGetErrorStatus(S) != NULL) {
00386 GBLbuf.stopExecutionFlag = 1;
00387 }
00388
00389 is_initialized = true;
00390 return true;
00391 }
00392
00393 void Model::loop()
00394 {
00395 if (!is_initialized) return;
00396
00397
00398
00399
00400
00401
00402 if (rtmGetTFinal(S) == RUN_FOREVER) {
00403 printf ("\n**May run forever. Model stop time set to infinity.**\n");
00404 }
00405
00406 while(isRunning()) step();
00407 }
00408
00409
00410 bool Model::isRunning()
00411 {
00412 return (!GBLbuf.stopExecutionFlag &&
00413 (rtmGetTFinal(S) == RUN_FOREVER ||
00414 rtmGetTFinal(S)-rtmGetT(S) > rtmGetT(S)*DBL_EPSILON));
00415 }
00416
00417 void Model::step()
00418 {
00419 rtExtModePauseIfNeeded(rtmGetRTWExtModeInfo(S),
00420 rtmGetNumSampleTimes(S),
00421 (boolean_T *)&rtmGetStopRequested(S));
00422
00423 if (rtmGetStopRequested(S)) return;
00424
00425 rtExtModeOneStep(rtmGetRTWExtModeInfo(S),
00426 rtmGetNumSampleTimes(S),
00427 (boolean_T *)&rtmGetStopRequested(S));
00428
00429 rt_OneStep(S);
00430 }
00431
00432 void Model::terminate()
00433 {
00434 if (!is_initialized) return;
00435
00436 if (!GBLbuf.stopExecutionFlag && !rtmGetStopRequested(S)) {
00437
00438 rtExtModeOneStep(rtmGetRTWExtModeInfo(S),
00439 rtmGetNumSampleTimes(S),
00440 (boolean_T *)&rtmGetStopRequested(S));
00441
00442
00443 rt_OneStep(S);
00444 }
00445
00446
00447
00448
00449 rt_StopDataLogging(MATFILE,rtmGetRTWLogInfo(S));
00450 rtExtModeShutdown(rtmGetNumSampleTimes(S));
00451
00452 if (GBLbuf.errmsg) {
00453 (void)fprintf(stderr,"%s\n",GBLbuf.errmsg);
00454
00455 }
00456
00457 if (GBLbuf.isrOverrun) {
00458 (void)fprintf(stderr,
00459 "%s: ISR overrun - base sampling rate is too fast\n",
00460 QUOTE(MODEL));
00461
00462 }
00463
00464 if (rtmGetErrorStatus(S) != NULL) {
00465 (void)fprintf(stderr,"%s\n", rtmGetErrorStatus(S));
00466
00467 }
00468 #ifdef MULTITASKING
00469 else {
00470 int_T i;
00471 for (i=1; i<NUMST; i++) {
00472 if (GBLbuf.overrunFlags[i]) {
00473 (void)fprintf(stderr,
00474 "%s ISR overrun - sampling rate is too fast for "
00475 "sample time index %d\n", QUOTE(MODEL), i);
00476
00477 }
00478 }
00479 }
00480 #endif
00481
00482
00483 rt_SimDestroyTimingEngine(rtmGetTimingData(S));
00484 #if NCSTATES > 0
00485
00486 rt_ODEDestroyIntegrationData(rtmGetRTWSolverInfo(S));
00487 #endif
00488
00489 rtmiTerminate(rtmGetRTWRTModelMethodsInfo(S));
00490
00491 is_initialized = false;
00492 }
00493
00494 }