|
libFAUDES
Sections
Index
|
iop_xdevice.cppGo to the documentation of this file.00001 /** @file iop_xdevice.cpp Device container with vDevice interface */ 00002 00003 /* 00004 FAU Discrete Event Systems Library (libfaudes) 00005 00006 Copyright (C) 2008, Thomas Moor 00007 Exclusive copyright is granted to Klaus Schmidt 00008 00009 */ 00010 00011 00012 00013 #include "iop_xdevice.h" 00014 #include "sys/time.h" 00015 //#include "iop_simplenet.h" 00016 //#include "iop_comedi.h" 00017 00018 namespace faudes { 00019 00020 /* 00021 ********************************************** 00022 ********************************************** 00023 ********************************************** 00024 00025 implementation: xDevice 00026 00027 ********************************************** 00028 ********************************************** 00029 ********************************************** 00030 */ 00031 00032 //constructor 00033 xDevice::xDevice(void) : vDevice() { 00034 FD_DHV("xDevice(" << mName << ")::xDevice()"); 00035 mName="IoDevices"; 00036 // have appropriate default label 00037 mDefaultLabel="DeviceContainer"; 00038 } 00039 00040 // destructor 00041 xDevice::~xDevice(void) { 00042 FD_DHV("xDevice(" << mName << ")::~xDevice()"); 00043 // loop to free devices. 00044 Iterator dit; 00045 for(dit=Begin();dit!=End();dit++){ 00046 delete (*dit); 00047 } 00048 } 00049 00050 //FromTokenReader(rTr) 00051 xDevice* xDevice::FromTokenReader(TokenReader& rTr) { 00052 // construct from token reader 00053 FD_DHV("xDevice::FromTokenReader()"); 00054 // allocate 00055 xDevice* dev=new xDevice(); 00056 // read 00057 dev->DoRead(rTr); 00058 return dev; 00059 } 00060 00061 //FromFile(rFilename) 00062 xDevice* xDevice::FromFile(const std::string& rFileName) { 00063 // construct from file 00064 FD_DHV("xDevice()::FromFile(" << rFileName <<")"); 00065 // peek first token 00066 TokenReader tr(rFileName); 00067 return FromTokenReader(tr); 00068 } 00069 00070 00071 //Status(void) 00072 xDevice::DeviceState xDevice::Status(void){ 00073 00074 FD_DHV("xDevice(" << mName << ")::Status() "); 00075 //prepare result 00076 xDevice::DeviceState res; 00077 //vector to store states of all devices integrated in xdevice 00078 std::vector<xDevice::DeviceState> states; 00079 //vector iterator 00080 std::vector<DeviceState>::iterator vit; 00081 vit = states.begin(); 00082 //device iterator 00083 iterator dit; 00084 //identify device state 00085 for(dit=Begin();dit!=End();dit++){ 00086 //get state of current device and insert it in vector 00087 states.push_back((DeviceState)(*dit)->Status()); 00088 //make sure it isnt the first entry 00089 if(vit != states.begin()){ 00090 //if current entry doesnt equal previous 00091 //decide depending on last command 00092 if (*vit!=*vit--){ 00093 //if last command was start: "StartUp" 00094 if(lastCommandWasStart){ 00095 res = StartUp; 00096 break; 00097 } 00098 //if last command was stop: "ShutDown" 00099 if(!lastCommandWasStart){ 00100 res = ShutDown; 00101 break; 00102 } 00103 } 00104 } 00105 //move on to next device 00106 vit++; 00107 } 00108 //if for-loop finished all entries of vector "states" are equal 00109 res = *states.begin(); 00110 return res; 00111 } 00112 00113 // Start(void) 00114 void xDevice::Start(void) { 00115 00116 FD_DHV("xDevice(" << mName <<")::Start()"); 00117 // start implies reset 00118 Reset(); 00119 //start all existing devices 00120 Iterator dit; 00121 for(dit = Begin();dit!=End();dit++){ 00122 (*dit)->Start(); 00123 } 00124 //remember this command 00125 lastCommandWasStart = true; 00126 } 00127 00128 // Stop(void) 00129 void xDevice::Stop(void) { 00130 00131 FD_DHV("xDevice(" << mName <<")::Stop()"); 00132 // xDevice Reset 00133 Reset(); 00134 // stop all existing devices 00135 Iterator dit; 00136 for(dit=Begin();dit!=End();dit++){ 00137 (*dit)->Stop(); 00138 } 00139 //remember this command 00140 lastCommandWasStart = false; 00141 } 00142 00143 // Reset(void) 00144 void xDevice::Reset(void){ 00145 //clear dynamic data 00146 00147 FD_DHV("xDevice(" << mName <<")::Reset()"); 00148 // device-iterator 00149 Iterator dit; 00150 for(dit=Begin();dit!=End();dit++){ 00151 (*dit)->Reset(); 00152 } 00153 // call base to reset time and fifo 00154 vDevice::Reset(); 00155 } 00156 00157 // Clear(void) 00158 void xDevice::Clear(void){ 00159 //clear static data 00160 00161 FD_DHV("xDevice(" << mName << ")::Clear()"); 00162 // Stop running devices 00163 Stop(); 00164 // device-iterator 00165 Iterator dit; 00166 // and clear all devices 00167 for(dit=Begin();dit!=End();dit++){ 00168 (*dit)->Clear(); 00169 } 00170 // destroy existing data 00171 for(dit=Begin();dit!=End();dit++){ 00172 delete (*dit); 00173 } 00174 // compile with empty containers 00175 Compile(); 00176 } 00177 00178 // Insert(vDevice*) 00179 void xDevice::Insert(vDevice* device){ 00180 00181 FD_DHV("xDevice("<<mName<<")::Insert(" << device << "):" << device->Name()); 00182 // insert any vdevice, but no xdevice 00183 if(dynamic_cast<xDevice*>(device)) { 00184 std::stringstream errstr; 00185 errstr << "Attempt to insert xDevice into xDevice"; 00186 throw Exception("xDevice::Compile", errstr.str(), 550); 00187 } 00188 // add to mDevices 00189 mDevices.push_back(device); 00190 // and update compiled data 00191 Compile(); 00192 } 00193 00194 //Insert(rFilename) 00195 void xDevice::Insert(const std::string& rFileName){ 00196 //inserts a device by filename 00197 00198 FD_DHV("xDevice("<<mName<<")::Insert(rFileName)"); 00199 //read device 00200 vDevice* pdev = vDevice::FromFile(rFileName); 00201 //insert device 00202 Insert(pdev); 00203 //and remember its name 00204 mDeviceNames.push_back(rFileName); 00205 } 00206 00207 00208 // Compile(void) 00209 void xDevice::Compile(void) { 00210 //build up internal data-structures 00211 00212 FD_DHV("xDevice("<<mName<<")::Compile()"); 00213 Stop(); 00214 // build up (event-idx,int)-map and memorize all existing events 00215 // prepare containers 00216 mSensors.Clear(); 00217 mActuators.Clear(); 00218 mSensorToDevice.clear(); 00219 mActuatorToDevice.clear(); 00220 // temporary container 00221 EventSet tmpSenEvents; 00222 EventSet tmpActEvents; 00223 // event-iterator 00224 EventSet::Iterator eit; 00225 // device-iterator 00226 Iterator dit; 00227 // helper 00228 int j; 00229 // iterate over existing devices 00230 for(dit=Begin(), j=0; dit!=End(); dit++,j++){ 00231 // get events by Index 00232 tmpSenEvents = (*dit)->Sensors(); 00233 tmpActEvents = (*dit)->Actuators(); 00234 //insert actuator-events in map 00235 for(eit=tmpActEvents.Begin();eit!=tmpActEvents.End();eit++){ 00236 // test if actual event already exists in map 00237 if(mActuators.Exists(*eit)){ 00238 //throw exeption 00239 std::stringstream errstr; 00240 errstr << "Event already exists!"; 00241 throw Exception("xDevice()::Compile", errstr.str(), 550); 00242 } 00243 mActuatorToDevice[*eit] = j; 00244 } 00245 // memorize events 00246 mSensors.InsertSet(tmpSenEvents); 00247 mActuators.InsertSet(tmpActEvents); 00248 // tell the device which mutex/condition-pair to use 00249 (*dit)->UseCondition(pWaitMutex,pWaitCondition); 00250 (*dit)->UseBuffer(pBufferMutex,pSensorBuffer); 00251 }//end iteration over existing devices 00252 // set time scale from first device 00253 if(Size()!=0) (*Begin())->TimeScale(mTimeScale); 00254 } 00255 00256 00257 //Configure(event,attr) 00258 void xDevice::Configure(Idx event, const AttributeDeviceEvent& attr){ 00259 (void) event; (void) attr; 00260 // cannot do vDevice style configuration of events 00261 00262 FD_DHV("xDevice("<<mName<<")::Configure(Idx,attr): "); 00263 std::stringstream errstr; 00264 errstr << "Attempt to configure xDevice by event"; 00265 throw Exception("xDevice::Configure(Idx,attr)", errstr.str(), 550); 00266 } 00267 00268 //Configure(rEvents) 00269 void xDevice::Configure(const EventSet& rEvents){ 00270 (void) rEvents; 00271 // cannot do vDevice style configuration of events 00272 00273 FD_DHV("xDevice("<<mName<<")::Configure(rEvents)"); 00274 std::stringstream errstr; 00275 errstr << "Attempt to configure xDevice by events"; 00276 throw Exception("xDevice::Configure", errstr.str(), 550); 00277 } 00278 00279 00280 //CurrentTime(void) 00281 tpTime::Type xDevice::CurrentTime(void) { 00282 00283 FD_DHV("xDevice("<<mName<<"): CurrentTime() "); 00284 // throw exception if there is no device 00285 if(Size()==0) { 00286 std::stringstream errstr; 00287 errstr << "xDevice owns no device!"; 00288 throw Exception("xDevice::CurrentTime", errstr.str(),550); 00289 } 00290 // ask first device 00291 return (*Begin())->CurrentTime(); 00292 } 00293 00294 00295 //CurrentTime(void) 00296 long int xDevice::CurrentTimeMs(void) { 00297 //debug flag: say hello 00298 FD_DHV("xDevice("<<mName<<")::CurrentTimeMs() "); 00299 // throw exception if there is no device 00300 if(Size()==0) { 00301 std::stringstream errstr; 00302 errstr << "xDevice owns no device!"; 00303 throw Exception("xDevice::CurrentTimeMs", errstr.str(),550); 00304 } 00305 // ask first device 00306 return (*Begin())->CurrentTimeMs(); 00307 } 00308 00309 //CurrentTime(now) 00310 void xDevice::CurrentTime(tpTime::Type now) { 00311 //debug flag: say hello 00312 FD_DHV("xDevice("<<mName<<")::CurrentTime("<<now<<") "); 00313 // tell first device if such 00314 if(Size()!=0) (*Begin())->CurrentTime(now); 00315 } 00316 00317 //CurrentTimeMs(now) 00318 void xDevice::CurrentTimeMs(long int nowms) { 00319 //debug flag: say hello 00320 00321 FD_DHV("xDevice("<<mName<<")::CurrentTimeMs("<<nowms<<") "); 00322 // tell first device if such 00323 if(Size()!=0) (*Begin())->CurrentTimeMs(nowms); 00324 } 00325 00326 //DoWrite(rTr,rLabel) 00327 void xDevice::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00328 (void) rTw; 00329 00330 FD_DHV("xDevice("<<mName<<")::DoWrite()"); 00331 // build output-file depending on mDevices 00332 std::string label=rLabel; 00333 if(label=="") label = mDefaultLabel; 00334 // Write label "DeviceContainer" if no label specified 00335 rTw.WriteBegin(label); 00336 // define device-iterator 00337 Iterator dit; 00338 //iterate over all devices 00339 for(Idx i=0; i<Size(); i++) { 00340 //if device was read from an extra file 00341 if(mDeviceNames.at(i) != ""){ 00342 //write path to TokenWriter 00343 FD_DH("xDevice("<<mName<<")::DoWrite(): "<<mDeviceNames.at(i)); 00344 rTw.WriteString(mDeviceNames.at(i)); //TODO: relativ path-names 00345 } 00346 //else device was directly read from base-config-file 00347 else if(mDeviceNames.at(i) == ""){ 00348 //write configuration 00349 FD_DH("xDevice("<<mName<<")::DoWrite(): "<<mDeviceNames.at(i)); 00350 (mDevices.at(i))->Write(rTw); 00351 } 00352 } 00353 rTw.WriteEnd(label); 00354 } 00355 00356 00357 // ResetRequest() 00358 bool xDevice::ResetRequest(void) { 00359 bool res=false; 00360 Iterator dit; 00361 for(dit=Begin();dit!=End();dit++){ 00362 res = res | (*dit)->ResetRequest(); 00363 } 00364 return res; 00365 } 00366 00367 //DoRead(rTr,rLabel) 00368 void xDevice::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00369 (void) rLabel; (void) pContext; 00370 00371 FD_DHV("xDevice("<<mName<<")::DoRead()"); 00372 //prepare token 00373 Token token; 00374 //prepare string 00375 std::string filename = ""; //to store filename 00376 std::string dirname = ""; //to store directory 00377 std::string path; //to store absolut path 00378 // have default section 00379 std::string label = rLabel; 00380 if(label=="") label = mDefaultLabel; 00381 // find section "Devices" 00382 rTr.SeekBegin(label); 00383 // call base for preface 00384 vDevice::DoReadPreface(rTr,"",pContext); 00385 // find section "Devices" 00386 rTr.SeekBegin("Devices"); 00387 // fill mDevices with devices specified in given file 00388 while(!rTr.Eos("Devices")){ 00389 //peek token 00390 rTr.Peek(token); 00391 // if Token is a String we assume its the name of a file containing a device 00392 if(token.Type()==Token::String) { 00393 //read Token 00394 rTr.Get(token); 00395 //import filename 00396 filename = token.StringValue(); 00397 //build up path to base-file 00398 if(rTr.SourceMode()==TokenReader::File) dirname = ExtractDirectory(rTr.FileName()); 00399 //build up path to specified file 00400 path = dirname.append(filename); 00401 //insert device 00402 Insert(path); 00403 00404 continue; 00405 } 00406 // if its not a file it has to be a device 00407 else if(token.Type()==Token::Begin) { 00408 // read device 00409 vDevice* devp = vDevice::FromTokenReader(rTr); 00410 // insert device mDevices 00411 Insert(devp); 00412 //remember that devices was read directly from base-configfile 00413 mDeviceNames.push_back(""); 00414 } 00415 00416 } 00417 rTr.SeekEnd("Devices"); 00418 rTr.SeekEnd(label); 00419 } 00420 00421 00422 // WriteActuator(Idx) 00423 void xDevice::WriteActuator(Idx actuator){ 00424 00425 FD_DHV("xDevice("<<mName<<")::WriteActuator()"); 00426 // identify corresponding device(if idx is unique) 00427 int didx = mActuatorToDevice[actuator]; 00428 FD_DH("xDevice("<<mName<<")::WriteActuator(): " << actuator << " to " << didx); 00429 mDevices.at(didx)->WriteActuator(actuator); 00430 } 00431 00432 00433 } // name space 00434 00435 |
libFAUDES 2.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3