libFAUDES

Sections

Index

iop_xdevice.cpp

Go 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