libFAUDES

Sections

Index

sp_dplpexecutor.cpp

Go to the documentation of this file.
00001 /** @file sp_dplpexecutor.cpp Executor with IO device  */
00002 
00003 /* 
00004    FAU Discrete Event Systems Library (libfaudes)
00005 
00006    Copyright (C) 2008  Thomas Moor
00007 
00008 */
00009 
00010 
00011 // load configuration
00012 #include "corefaudes.h"
00013 
00014 
00015 #include "sp_dplpexecutor.h"
00016 #include <iostream>
00017 
00018 namespace faudes {
00019 
00020 // constructor
00021 DeviceExecutor::DeviceExecutor(void) : ProposingExecutor() , pDevice(0) { 
00022   mMaxSyncGap=10*tpTime::Step;
00023   mSyncMode=0x0;
00024 }
00025 
00026 // cdestructor
00027 DeviceExecutor::~DeviceExecutor(void) { 
00028 }
00029 
00030 // set io device
00031 void DeviceExecutor::Devicep(vDevice* dev) {
00032   pDevice=dev;
00033   mSyncError=false;
00034 #ifdef FAUDES_PLUGIN_IODEVICE
00035   if(!dev) return;
00036   pDevice->Reset();
00037   Reset();
00038 #endif
00039 }
00040 
00041 // start the device
00042 void DeviceExecutor::DeviceStart(void) {
00043 #ifdef FAUDES_PLUGIN_IODEVICE
00044   if(!pDevice) return;
00045   pDevice->Start();
00046 #endif
00047 }
00048 
00049 // stop the device
00050 void DeviceExecutor::DeviceStop(void) {
00051 #ifdef FAUDES_PLUGIN_IODEVICE
00052   if(!pDevice) return;
00053   pDevice->Stop();
00054 #endif
00055 }
00056 
00057 // clear static data
00058 void DeviceExecutor::Clear(void){
00059   Reset();
00060   ProposingExecutor::Clear();
00061 }
00062 
00063 // clear dynamic data
00064 void DeviceExecutor::Reset(long int seed){
00065   FD_DS("DeviceExecutor::Reset()");
00066 #ifdef FAUDES_PLUGIN_IODEVICE
00067   // reset the device
00068   if(pDevice) pDevice->Reset();
00069   // overwrite sensor attributes 
00070   if(pDevice) {
00071     SimPriorityEventAttribute neverpa;
00072     neverpa.mPriority=-9999; // todo: have a never-priority                                      
00073     SimEventAttribute never;
00074     never.Priority(neverpa);
00075     EventSet::Iterator eit=pDevice->Sensors().Begin();
00076     for(;eit!=pDevice->Sensors().End(); eit++) {
00077       if(Alphabet().Exists(*eit)) EventAttribute(*eit,never);
00078     }
00079   }
00080 #endif
00081   // call base
00082   ProposingExecutor::Reset(seed);
00083   mSyncError=false;
00084   FD_DS("DeviceExecutor::Reset(): done");
00085 }
00086 
00087 //ExecuteEvent
00088 bool DeviceExecutor::ExecuteEvent(Idx event){
00089   FD_DS("DeviceExecutor::ExecuteEvent(): "<< EventName(event));
00090   /*
00091 #ifdef FAUDES_PLUGIN_IODEVICE
00092   // sync time
00093   if(pDevice) SyncStep(0);
00094 #endif
00095   */
00096   // execute event
00097   bool res=ProposingExecutor::ExecuteEvent(event);
00098   /*
00099 #ifdef FAUDES_PLUGIN_IODEVICE
00100   // pass on to callbacks
00101   if(res && pDevice) pDevice->WriteActuator(event);
00102 #endif
00103   */
00104   // report
00105   return res;
00106 }
00107 
00108 
00109 //SyncTime()
00110 bool DeviceExecutor::SyncTime(void){
00111 
00112   // no plugin, no run
00113 #ifndef FAUDES_PLUGIN_IODEVICE
00114   return false;
00115 #else
00116 
00117   // no device, no run
00118   if(!pDevice) return false;
00119 
00120   // figure situation
00121   tpTime::Type devNow=pDevice->CurrentTime();
00122   tpTime::Type genNow=CurrentTime();
00123   tpTime::Type syncTime=devNow-genNow;
00124   tpTime::Type propTime=ProposeNextTransition().Time;
00125 
00126   // report
00127   FD_DS_SYNC("DeviceExecutor::SyncTime(): device time " << devNow << " gen time " << genNow);
00128 
00129   // time sync: no chance since generator is ahead
00130   if(mSyncMode & SyncStrictTime)
00131   if(syncTime < -mMaxSyncGap) {
00132     FD_DS_SYNC("DeviceExecutor::SyncTime(): sync error: gen time ahead");
00133     mSyncError=true;
00134     pDevice->Reset();
00135     return false;
00136   }
00137 
00138   // time sync: check whether proposal allows for sync
00139   if(mSyncMode & SyncStrictTime)
00140   if(syncTime - mMaxSyncGap > propTime || propTime==tpTime::UnDef) {
00141     FD_DS_SYNC("DeviceExecutor::SyncTime(): sync error: cannot sync enough time");
00142     mSyncError=true;
00143     pDevice->Reset();
00144     return false;
00145   }
00146 
00147   // fix undef time (aka deadlock)
00148   // note: this is pointless, since the executor will not recover
00149   if(propTime==tpTime::UnDef) propTime=tpTime::Max;
00150  
00151   // adjust by proposal
00152   if(syncTime > propTime) {
00153     FD_DS_SYNC("DeviceExecutor::SyncTime(): adjust by proposal");
00154     syncTime=propTime;
00155   }
00156 
00157   // time sync: pass generator time 
00158   FD_DS_SYNC("DeviceExecutor::SyncTime(): generator to pass " << syncTime);
00159   if(!ProposingExecutor::ExecuteTime(syncTime)) {
00160     tpTime::Type maxsync=EnabledTime().UB();
00161     if(maxsync >= syncTime-mMaxSyncGap) {
00162       syncTime=maxsync;
00163     }
00164     FD_DS_SYNC("DeviceExecutor::SyncTime(): retry: generator to pass " << syncTime);
00165     if(!ProposingExecutor::ExecuteTime(syncTime)) 
00166     if(mSyncMode & SyncStrictTime) {
00167       FD_DS_SYNC("DeviceExecutor::SyncTime(): exec error");
00168       mSyncError=true;
00169       pDevice->Reset();
00170       return false;
00171     }
00172   };
00173 
00174   // done
00175   FD_DS_SYNC("DeviceExecutor::SyncTime(): ok: device time " << 
00176     pDevice->CurrentTime() << " gen time " << CurrentTime());
00177   return true;
00178 
00179 #endif
00180 }
00181 
00182 
00183 //SyncEvents()
00184 Idx DeviceExecutor::SyncEvents(void){
00185 
00186   // no plugin, no run
00187 #ifndef FAUDES_PLUGIN_IODEVICE
00188   return 0;
00189 #else
00190 
00191   // no device, no run
00192   if(!pDevice) return 0;
00193 
00194   // ignore alien hardware event
00195   if(Idx sev=pDevice->PeekSensor()) {
00196     if(!ParallelExecutor::Alphabet().Exists(sev)) {
00197       FD_DS_SYNC("DeviceExecutor::SyncEvents(): sensor event " << EStr(sev) << "ignored");
00198       pDevice->ReadSensor();
00199     }
00200   }
00201 
00202   // get and execute hardware events, if accepted
00203   if(Idx sev=pDevice->PeekSensor()) {
00204     if(EnabledEvents().Exists(sev)) {
00205       pDevice->ReadSensor();
00206       ProposingExecutor::ExecuteEvent(sev);
00207       FD_DS_SYNC("DeviceExecutor::SyncEvents(): sensor event " << EStr(sev) << " accepted");
00208       return sev;
00209     }
00210     FD_DS_SYNC("DeviceExecutor::SyncEvents(): sensor event " << EStr(sev) << " postponed");
00211   }
00212 
00213   // check and execute scheduled event
00214   const TimedEvent& proposedTrans=ProposeNextTransition();
00215   if(proposedTrans.Time==0 && proposedTrans.Event!=0) {
00216     FD_DS_SYNC("DeviceExecutor::SyncEvents(): scheduled event: " << EventName(proposedTrans.Event));
00217     ProposingExecutor::ExecuteEvent(proposedTrans.Event);
00218     if(pDevice->Actuators().Exists(proposedTrans.Event))
00219       pDevice->WriteActuator(proposedTrans.Event);
00220     FD_DS_SYNC("DeviceExecutor::SyncEvents(): scheduled event: execueted");
00221     return proposedTrans.Event; 
00222   }
00223 
00224   // get and execute hardware events
00225   if(Idx sev=pDevice->ReadSensor()) {
00226     bool exec = ProposingExecutor::ExecuteEvent(sev);
00227     if(!exec && (mSyncMode & SyncStrictEvents)) {
00228       FD_DS_SYNC("DeviceExecutor::SyncEvents(): sync error: invalid sensor event");
00229       mSyncError=true;
00230       pDevice->Reset();
00231     }
00232     return (exec ? sev : 0);
00233   }
00234 
00235 
00236   FD_DS_SYNC("DeviceExecutor::SyncEvents(): no events ready");
00237   return 0;
00238 
00239 #endif
00240 }
00241 
00242 //SyncWait()
00243 bool DeviceExecutor::SyncWait(tpTime::Type duration){
00244 
00245   // no plugin, no run
00246 #ifndef FAUDES_PLUGIN_IODEVICE
00247   return false;
00248 #else
00249 
00250   // no device, no run
00251   if(!pDevice) return false;
00252 
00253   // report
00254   FD_DS_SYNC("DeviceExecutor::SyncWait(): sleep " << tpTime::Str(duration) );
00255 
00256   // adjust
00257   const TimedEvent& proposedTrans=ProposeNextTransition();
00258   if(proposedTrans.Time<duration) duration=proposedTrans.Time;
00259   if(duration <0) duration=0;
00260 
00261   // report
00262   FD_DS_SYNC("DeviceExecutor::SyncWait(): adjusted by proposal: " << tpTime::Str(duration) );
00263 
00264   // doit
00265   bool res=pDevice->WaitSensors(duration);
00266 
00267   // done
00268   return res;
00269 
00270 #endif // io plugin
00271 }
00272 
00273 
00274 //SyncWaitMs()
00275 bool DeviceExecutor::SyncWaitMs(int durationms) {
00276 
00277   // no plugin, no run
00278 #ifndef FAUDES_PLUGIN_IODEVICE
00279   return false;
00280 #else
00281 
00282   // no device, no run
00283   if(!pDevice) return false;
00284 
00285   // report
00286   FD_DS_SYNC("DeviceExecutor::SyncWaitMs(): sleep " << durationms );
00287 
00288   // adjust
00289   const TimedEvent& proposedTrans=ProposeNextTransition();
00290   if(proposedTrans.Time*pDevice->TimeScale() <durationms) durationms=proposedTrans.Time *pDevice->TimeScale();
00291   if(durationms <0) durationms=0;
00292 
00293   // report
00294   FD_DS_SYNC("DeviceExecutor::SyncWaitMs(): adjusted by proposal: " << durationms );
00295 
00296   // doit
00297   bool res=pDevice->WaitSensorsMs(durationms);
00298 
00299   // done
00300   return res;
00301 
00302 #endif // io plugin
00303 }
00304 
00305 
00306 //SyncStep(duartion)
00307 Idx DeviceExecutor::SyncStep(tpTime::Type duration){
00308   FD_DS_SYNC("DeviceExecutor::SyncStep("<< tpTime::Str(duration) << ")");
00309 
00310   // no plugin, no run
00311 #ifndef FAUDES_PLUGIN_IODEVICE
00312   return 0;
00313 #else
00314 
00315   // no device, no run
00316   if(!pDevice) return 0;
00317 
00318   // result
00319   Idx res=0;
00320 
00321   // doit
00322   if(!SyncTime()) return res;
00323   if((res=SyncEvents())!=0) return res;
00324   if(!SyncWait(duration)) return res;
00325   if(!SyncTime()) return res;
00326   res=SyncEvents();
00327 
00328   // done  
00329   return res;
00330 
00331 #endif // io plugin
00332 }
00333 
00334 //SyncRun(duartion)
00335 bool DeviceExecutor::SyncRun(tpTime::Type duration){
00336   FD_DS_SYNC("DeviceExecutor::SyncRun("<< tpTime::Str(duration) << ")");
00337 
00338   // prepare
00339   tpTime::Type genNow=CurrentTime();
00340   tpTime::Type genStop=genNow+duration;
00341   tpTime::Type genLeft=genStop-genNow;
00342   if(duration==tpTime::Max) {
00343     genStop=tpTime::Max;
00344     genLeft=tpTime::Max;
00345   }
00346 
00347   // loop time
00348   while(genLeft>0) {
00349     // step
00350     if(SyncStep(genLeft)==0) return false;
00351     // update
00352     genNow=CurrentTime();
00353     genLeft=genStop-genNow;
00354     if(duration==tpTime::Max) genLeft=tpTime::Max;
00355   }
00356   // done
00357   return true;
00358 }
00359 
00360 } // namespace
00361 

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6