sp_dplpexecutor.cpp

Go to the documentation of this file.
00001 
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 }
00024 
00025 // cdestructor
00026 DeviceExecutor::~DeviceExecutor(void) { 
00027 }
00028 
00029 // set io device
00030 void DeviceExecutor::Devicep(vDevice* dev) {
00031   pDevice=dev;
00032   mSyncError=false;
00033 #ifdef FAUDES_PLUGIN_IODEVICE
00034   if(!dev) return;
00035   pDevice->Reset();
00036 #endif
00037 }
00038 
00039 // start the device
00040 void DeviceExecutor::DeviceStart(void) {
00041 #ifdef FAUDES_PLUGIN_IODEVICE
00042   if(!pDevice) return;
00043   pDevice->Start();
00044 #endif
00045 }
00046 
00047 // stop the device
00048 void DeviceExecutor::DeviceStop(void) {
00049 #ifdef FAUDES_PLUGIN_IODEVICE
00050   if(!pDevice) return;
00051   pDevice->Stop();
00052 #endif
00053 }
00054 
00055 // clear static data
00056 void DeviceExecutor::Clear(void){
00057   Reset();
00058   ProposingExecutor::Clear();
00059 }
00060 
00061 // clear dynamic data
00062 void DeviceExecutor::Reset(long int seed){
00063 #ifdef FAUDES_PLUGIN_IODEVICE
00064   if(pDevice) pDevice->Reset();
00065 #endif
00066   ProposingExecutor::Reset(seed);
00067   mSyncError=false;
00068 }
00069 
00070 //ExecuteEvent
00071 bool DeviceExecutor::ExecuteEvent(Idx event){
00072   FD_DS("DeviceExecutor::ExecuteEvent(): "<< EventName(event));
00073   /*
00074 #ifdef FAUDES_PLUGIN_IODEVICE
00075   // sync time
00076   if(pDevice) SyncStep(0);
00077 #endif
00078   */
00079   // execute event
00080   bool res=ProposingExecutor::ExecuteEvent(event);
00081   /*
00082 #ifdef FAUDES_PLUGIN_IODEVICE
00083   // pass on to callbacks
00084   if(res && pDevice) pDevice->WriteActuator(event);
00085 #endif
00086   */
00087   // report
00088   return res;
00089 }
00090 
00091 
00092 //SyncTime()
00093 bool DeviceExecutor::SyncTime(void){
00094 
00095   // no plugin, no run
00096 #ifndef FAUDES_PLUGIN_IODEVICE
00097   return false;
00098 #else
00099 
00100   // no device, no run
00101   if(!pDevice) return false;
00102 
00103   // figure situation
00104   tpTime::Type devNow=pDevice->CurrentTime();
00105   tpTime::Type genNow=CurrentTime();
00106   tpTime::Type syncTime=devNow-genNow;
00107   tpTime::Type propTime=ProposeNextTransition().Time;
00108 
00109   // report
00110   FD_DS_SYNC("DeviceExecutor::SyncTime(): device time " << devNow << " gen time " << genNow);
00111 
00112   // time sync: no chance since generator is ahead
00113   if(syncTime < -mMaxSyncGap) {
00114     FD_DS_SYNC("DeviceExecutor::SyncTime(): sync error: gen time ahead");
00115     mSyncError=true;
00116     pDevice->Reset();
00117     return false;
00118   }
00119 
00120   // time sync: check whether proposal allows for sync
00121   if(syncTime - mMaxSyncGap > propTime || propTime==tpTime::UnDef) {
00122     FD_DS_SYNC("DeviceExecutor::SyncTime(): sync error: cannot sync enough time");
00123     mSyncError=true;
00124     pDevice->Reset();
00125     return false;
00126   }
00127  
00128   // adjust by proposal
00129   if(syncTime > propTime) {
00130     FD_DS_SYNC("DeviceExecutor::SyncTime(): adjust by proposal");
00131     syncTime=propTime;
00132   }
00133 
00134   // time sync: pass generator time 
00135   FD_DS_SYNC("DeviceExecutor::SyncTime(): generator to pass " << syncTime);
00136   if(!ProposingExecutor::ExecuteTime(syncTime)) {
00137     tpTime::Type maxsync=EnabledTime().UB();
00138     if(maxsync >= syncTime-mMaxSyncGap) {
00139       syncTime=maxsync;
00140     }
00141     FD_DS_SYNC("DeviceExecutor::SyncTime(): retry: generator to pass " << syncTime);
00142     if(!ProposingExecutor::ExecuteTime(syncTime)) {
00143       FD_DS_SYNC("DeviceExecutor::SyncTime(): exec error");
00144       mSyncError=true;
00145       pDevice->Reset();
00146       return false;
00147     }
00148   };
00149 
00150   // done
00151   FD_DS_SYNC("DeviceExecutor::SyncTime(): ok");
00152   return true;
00153 
00154 #endif
00155 }
00156 
00157 
00158 //SyncEvents()
00159 Idx DeviceExecutor::SyncEvents(void){
00160 
00161   // no plugin, no run
00162 #ifndef FAUDES_PLUGIN_IODEVICE
00163   return 0;
00164 #else
00165 
00166   // no device, no run
00167   if(!pDevice) return 0;
00168 
00169 
00170   // check and execute scheduled event
00171   const TimedEvent& proposedTrans=ProposeNextTransition();
00172   if(proposedTrans.Time==0 && proposedTrans.Event!=0) {
00173     FD_DS_SYNC("DeviceExecutor::SyncEvents(): scheduled event: " << EventName(proposedTrans.Event));
00174     ProposingExecutor::ExecuteEvent(proposedTrans.Event);
00175     if(pDevice->Actuators().Exists(proposedTrans.Event))
00176       pDevice->WriteActuator(proposedTrans.Event);
00177     FD_DS_SYNC("DeviceExecutor::SyncEvents(): scheduled event: ok");
00178     return proposedTrans.Event; 
00179   }
00180 
00181   // get and execute hardware events
00182   if(Idx sev=pDevice->ReadSensor()) {
00183     FD_DS_SYNC("DeviceExecutor::SyncEvents(): sensor event " << EStr(sev));
00184     if(!ProposingExecutor::ExecuteEvent(sev)) {
00185       FD_DS_SYNC("DeviceExecutor::SyncEvents(): sync error: invalid sensor event");
00186       mSyncError=true;
00187       pDevice->Reset();
00188       return 0;
00189     }
00190     return sev;
00191   }
00192 
00193 
00194   FD_DS_SYNC("DeviceExecutor::SyncEvents(): no events ready");
00195   return 0;
00196 
00197 #endif
00198 }
00199 
00200 //SyncWait()
00201 bool DeviceExecutor::SyncWait(tpTime::Type duration){
00202 
00203   // no plugin, no run
00204 #ifndef FAUDES_PLUGIN_IODEVICE
00205   return false;
00206 #else
00207 
00208   // no device, no run
00209   if(!pDevice) return false;
00210 
00211   // report
00212   FD_DS_SYNC("DeviceExecutor::SyncWait(): sleep " << tpTime::Str(duration) );
00213 
00214   // adjust
00215   const TimedEvent& proposedTrans=ProposeNextTransition();
00216   if(proposedTrans.Time<duration) duration=proposedTrans.Time;
00217   if(duration <0) duration=0;
00218 
00219   // report
00220   FD_DS_SYNC("DeviceExecutor::SyncWait(): adjusted by proposal: " << tpTime::Str(duration) );
00221 
00222   // doit
00223   bool res=pDevice->WaitSensors(duration);
00224 
00225   // done
00226   return res;
00227 
00228 #endif // io plugin
00229 }
00230 
00231 
00232 //SyncStep(duartion)
00233 Idx DeviceExecutor::SyncStep(tpTime::Type duration){
00234   FD_DS_SYNC("DeviceExecutor::SyncStep("<< tpTime::Str(duration) << ")");
00235 
00236   // no plugin, no run
00237 #ifndef FAUDES_PLUGIN_IODEVICE
00238   return 0;
00239 #else
00240 
00241   // no device, no run
00242   if(!pDevice) return 0;
00243 
00244   // result
00245   Idx res=0;
00246 
00247   // doit
00248   if(!SyncTime()) return res;
00249   if((res=SyncEvents())!=0) return res;
00250   if(!SyncWait(duration)) return res;
00251   if(!SyncTime()) return res;
00252   res=SyncEvents();
00253 
00254   // done  
00255   return res;
00256 
00257 #endif // io plugin
00258 }
00259 
00260 //SyncRun(duartion)
00261 bool DeviceExecutor::SyncRun(tpTime::Type duration){
00262   FD_DS_SYNC("DeviceExecutor::SyncRun("<< tpTime::Str(duration) << ")");
00263 
00264   // prepare
00265   tpTime::Type genNow=CurrentTime();
00266   tpTime::Type genStop=genNow+duration;
00267   tpTime::Type genLeft=genStop-genNow;
00268   if(duration==tpTime::Max) {
00269     genStop=tpTime::Max;
00270     genLeft=tpTime::Max;
00271   }
00272 
00273   // loop time
00274   while(genLeft>0) {
00275     // step
00276     if(SyncStep(genLeft)==0) return false;
00277     // update
00278     genNow=CurrentTime();
00279     genLeft=genStop-genNow;
00280     if(duration==tpTime::Max) genLeft=tpTime::Max;
00281   }
00282   // done
00283   return true;
00284 }
00285 
00286 } // namespace
00287 

Generated on Mon Nov 10 08:13:15 2008 for libFAUDES 2.11v by  doxygen 1.4.4