| |
libFAUDES
Sections
Index
|
sp_dplpexecutor.cppGo 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