manager.cpp
Go to the documentation of this file.
00001 //
00002 // manager.cpp
00003 //
00004 
00005 #include "manager.hpp"
00006 #include "tools/errorhandler.hpp"
00007 #include "tools/toolbox.hpp"
00008 
00009 // The devices
00010 #include "devices/LD_MRS.hpp"
00011 
00012 // The applications
00013 #include "application/LdmrsApp.hpp"
00014 #include "application/LdmrsSectorChangeApp.hpp"
00015 #include "application/LdmrsFieldApp.hpp"
00016 #include "application/LdmrsNtpTimeApp.hpp"
00017 #include "application/LdmrsScanpointCoordinateApp.hpp"
00018 
00019 using namespace application;
00020 using namespace devices;
00021 
00022 // ****************************************************************************
00023 //     The Manager of the system
00024 // ****************************************************************************
00025 Manager::Manager()
00026         : m_beVerbose(false)
00027         , m_nextSourceId(0)
00028 {
00029         infoMessage("Manager: Starting constructor.", m_beVerbose);
00030         
00031         // Max. size of the device-data-buffer
00032         m_sourceBuffer.setLimit(5000000);
00033         
00034         infoMessage("Manager: Constructor done.", m_beVerbose);
00035 }
00036 
00037 //
00038 // Destructor.
00039 // Close all applications and devices.
00040 //
00041 Manager::~Manager()
00042 {
00043         infoMessage("~Manager(): Destructor called.", m_beVerbose);
00044         
00045         stopAllDevices();
00046 
00047         // Delete all applications
00048         while (m_appList.size() > 0)
00049         {
00050                 BasicApplication* a;
00051                 a = m_appList.back();
00052                 delete a;
00053                 m_appList.pop_back();
00054         }
00055         
00056         // Delete all devices
00057         while (m_deviceList.size() > 0)
00058         {
00059                 BasicDevice* p;
00060                 p = m_deviceList.back();
00061                 delete p;
00062                 m_deviceList.pop_back();
00063         }
00064 
00065         infoMessage("~Manager(): Destructor is done.", m_beVerbose);
00066 }
00067 
00068 
00069 //
00070 // Provides the next unique ID. Such an ID is set for all devices and all
00071 // applications, to identify data generated by them.
00072 //
00073 UINT16 Manager::getNextSourceId()
00074 {
00075         UINT16 sourceId = m_nextSourceId;
00076         m_nextSourceId++;
00077         
00078         if (m_nextSourceId == 0x0000)
00079         {
00080                 dieWithError("Manager::getNextSourceId(): We are out of source IDs - exiting.");
00081         }
00082         return sourceId;
00083 }
00084 
00085 
00086 //
00087 // Add a new device at runtime.
00088 //
00089 // It would be nice to add an ID-handling, to make the IDs safely unique!
00090 //
00091 bool Manager::addAndRunDevice(Sourcetype deviceType, std::string deviceName, UINT16 wantedId)
00092 {
00093         BasicDevice* device;
00094         
00095         // Device erzeugen
00096         switch (deviceType)
00097         {
00098                 case Sourcetype_LDMRS:
00099                         device = new LDMRS(this);
00100                         break;
00101                 default:
00102                         printError("Manager::addAndRunDevice: Unknown device (Type=" + toString((UINT16)deviceType) +
00103                                                 " , Name=" + deviceName + "). Ignoring this call!");
00104                         return false;
00105         }
00106         return addAndRunDevice(device, deviceName, wantedId);
00107 }
00108 
00109 //
00110 // Add a external created device object.
00111 //
00112 // Note that device needs to be on the heap and will automatically be deleted when the manager is destructed.
00113 //
00114 bool Manager::addAndRunDevice(devices::BasicDevice* device, std::string deviceName, UINT16 wantedId)
00115 {
00116         bool beVerboseHere = true | m_beVerbose;
00117         
00118         // ID erzeugen
00119         UINT16 id = wantedId;
00120         if (id == 0xFFFF)
00121         {
00122                 id = getNextSourceId();
00123         }
00124         device->setSourceId(id);
00125         
00126         // Namen setzen
00127         device->setDeviceName(deviceName);
00128 
00129         // Device speichern
00130         m_deviceList.push_back(device);
00131         
00132         std::string text = "Manager::addAndRunDevice: Created Device of type " +
00133                                                 toString(device->getDevicetype()) +
00134                                                 " with Name " + deviceName +
00135                                                 " under the ID " +
00136                                                 toString(device->getSourceId()) + ". Now initializing the device.";
00137         printInfoMessage(text, beVerboseHere);
00138         
00139         // Device initialisieren
00140         bool result = device->init();
00141         if (result == true)
00142         {
00143                 printInfoMessage("Manager::addAndRunDevice: Device is initialized.", beVerboseHere);
00144         }
00145         else
00146         {
00147                 printError("Manager::addAndRunDevice: Failed to initialize the device, aborting.");
00148                 return false;
00149         }
00150         
00151         // Device starten
00152         result = device->run();
00153         if (result == true)
00154         {
00155                 printInfoMessage("Manager::addAndRunDevice: Device is running.", beVerboseHere);
00156         }
00157         else
00158         {
00159                 printError("Manager::addAndRunDevice: Failed to run device, aborting.");
00160                 return false;
00161         }
00162         
00163         if (m_sourceThread.isRunning() == false)
00164         {
00165                 printInfoMessage("Manager::addAndRunDevice: Added device, now running source thread.", beVerboseHere);
00166                 m_sourceThread.run(this);
00167         }
00168 
00169         printInfoMessage("Manager::addAndRunDevice: All done, leaving.", beVerboseHere);
00170         return result;
00171 }
00172 
00173 //
00174 // Eine neue Applikation dynamisch, d.h. zur Laufzeit, hinzufuegen.
00175 //
00176 // It would be nice to add an ID-handling, to make the IDs safely unique!
00177 //
00178 bool Manager::addApplication(Sourcetype appType, std::string appName, UINT16 wantedId)
00179 {
00180         BasicApplication* app;
00181         
00182         // Device erzeugen
00183         switch (appType)
00184         {
00185                 case Sourcetype_MrsApp:
00186                         app = new LdmrsApp(this);
00187                         break;
00188                 case Sourcetype_MrsFieldApp:
00189                         app = new LdmrsFieldApp(this);
00190                         break;
00191                 case Sourcetype_MrsChangeApp:
00192                         app = new LdmrsSectorChangeApp(this);
00193                         break;
00194                 case Sourcetype_MrsNtpTimeApp:
00195                         app = new LdmrsNtpTimeApp(this);
00196                         break;
00197                 case Sourcetype_MrsScanpointCoordinateApp:
00198                         app = new LdmrsScanpointCoordinateApp(this);
00199                         break;
00200                 default:
00201                         printError("Manager::addApplication: Unknown application (Type=" + toString((UINT16)appType) +
00202                                                 " , Name=" + appName + "). Ignoring this call!");
00203                         return false;
00204         }
00205         
00206         // Namen setzen
00207         app->setApplicationName(appName);
00208 
00209         return addApplication(app, wantedId);
00210 }
00211 
00212 bool Manager::addApplication(BasicApplication *app, UINT16 wantedId)
00213 {
00214         // ID erzeugen
00215         UINT16 id = wantedId;
00216         if (id == 0xFFFF)
00217         {
00218                 id = getNextSourceId();
00219         }
00220         app->setSourceId(id);
00221 
00222         // Device speichern
00223         m_appList.push_back(app);
00224         
00225         std::string text = "Manager::addApplication: Created application " +
00226                                                 toString(app->getApplicationType()) +
00227                                                 " with Name " + app->getApplicationName() +
00228                                                 " under the ID " +
00229                                                 toString(app->getSourceId()) + ". Now running the device.";
00230         printInfoMessage(text, m_beVerbose);
00231         
00232         return true;
00233 }
00234 
00235 
00236 
00240 bool Manager::runAllDevices()
00241 {
00242         std::string text;
00243 
00244         for (UINT32 i=0; i<m_deviceList.size(); i++)
00245         {
00246                 BasicDevice* device;
00247                 device = m_deviceList.at(i);
00248                 
00249                 text = "Manager: Running device with ID " + toString(device->getSourceId()) + ".";
00250                 infoMessage(text, m_beVerbose);
00251         
00252                 device->run();
00253         }
00254 
00255         // Start the data distribution
00256         if (m_sourceThread.isRunning() == false)
00257         {
00258                 m_sourceThread.run(this);
00259         }
00260         
00261         return true;
00262 }
00263 
00264 
00265 //
00266 // Stop!
00267 //
00268 void Manager::stopAllDevices()
00269 {
00270         std::string text;
00271         
00272         for (UINT32 i=0; i<m_deviceList.size(); i++)
00273         {
00274                 BasicDevice* device;
00275                 device = m_deviceList.at(i);
00276                 
00277                 text = "Manager::stopAllDevices: Stopping device with ID " + toString(device->getSourceId()) + ".";
00278                 infoMessage(text, m_beVerbose);
00279                 
00280                 device->stop();
00281 
00282                 infoMessage("Manager::stopAllDevices: Device stopped.", m_beVerbose);
00283         }
00284 }
00285 
00286 //
00287 // Receiver for data from the devices. The data is forwarded to the applications.
00288 //
00289 // Note: In the buffer, only the data pointers are stored!
00290 //
00291 void Manager::setDeviceData(BasicData* data)
00292 {
00293         // Hier in einen Puffer schreiben!
00294         ScopedLock lock(&m_sourceBufferMutex);  // Wg. der folgenden Textmeldung. Der Puffer selber ist sicher...
00295         bool result = m_sourceBuffer.pushData(data);
00296         if (result == true)
00297         {
00298                 // Datum wurde hinzugefuegt
00299                 if (m_beVerbose == true)
00300                 {
00301                         std::string text;
00302                         text = "Manager::setDeviceData(): Added data. Device data buffer size is now " +
00303                                 toString(m_sourceBuffer.getBufferSize()) + " Elements (" + toString(m_sourceBuffer.getUsedBytes()) + " bytes).";
00304                         infoMessage(text, m_beVerbose);
00305                 }
00306         }
00307         else
00308         {
00309                 // Datum konnte nicht hinzugefuegt werden
00310                 std::string text;
00311                 text = "Manager::setDeviceData(): Failed to add data. Device data buffer size is currently " +
00312                            toString(m_sourceBuffer.getBufferSize()) + " Elements (" + toString(m_sourceBuffer.getUsedBytes()) +
00313                            " bytes), and the buffer refused to add " + toString(data->getUsedMemory()) + " bytes.";
00314                 printWarning(text);
00315                 
00316                 // Datum loeschen!
00317                 delete data;
00318                 return;
00319         }
00320 }
00321 
00333 void Manager::sourceThreadFunction(bool& endThread, UINT16& waitTimeMs)
00334 {
00335         infoMessage("Manager: sourceThreadFunction() called.", m_beVerbose);
00336         
00337         //
00338         // Pruefe, ob Daten verteilt werden muessen
00339         //
00340         // Hole den Zeiger auf die naechsten Daten im Puffer, falls welche da sind.
00341         // Zugriffsschutz hier nicht erforderlich, da der Buffer selber Thread-Safe ist.
00342         BasicData* data = NULL;
00343         data = m_sourceBuffer.popData();
00344         
00345         // Verteile die Daten, falls welche da waren
00346         if (data != NULL)
00347         {
00348                 // DEBUG
00349                 if (m_beVerbose == true)
00350                 {
00351                         std::string text;
00352                         text = "Manager::sourceThreadFunction(): Popped a dataset of type " + toString(data->getDatatype()) + 
00353                                         ", created from Source-ID " + toString(data->getSourceId()) + ".";
00354                         infoMessage(text, m_beVerbose);
00355                 }
00356                 
00357 
00358                 // Einfach an jede Applikation verteilen
00359                 for (UINT32 i=0; i<m_appList.size(); i++)
00360                 {
00361                         BasicApplication* a;
00362                         a = m_appList.at(i);
00363                         a->setData(*data);
00364                 }
00365                 
00366                 // Datensatz wird nicht mehr benoetigt, loeschen
00367                 delete data;
00368                 data = NULL;
00369         }
00370 
00371         //
00372         // Naechsten Aufruf vorbereiten
00373         //
00374         endThread = false;
00375         if (m_sourceBuffer.getBufferSize() > 0)
00376         {
00377                 // Es sind bereits jetzt neue Daten da, also nur kurz unterbrechen
00378                 waitTimeMs = 0;
00379 //              infoMessage("Source fill level: " + toString(m_sourceBuffer.getBufferSize()) + ".", true);
00380         }
00381         else
00382         {
00383                 // Es sind aktuell keine weiteren Daten da, also ruhig etwas laenger schlafen
00384                 waitTimeMs = 2;
00385         }
00386 }
00387 
00388 //
00389 // Get a pointer to the device identified by its ID.
00390 // Returns NULL if no such device could be found.
00391 //
00392 devices::BasicDevice* Manager::getDeviceById(UINT32 id)
00393 {
00394         devices::BasicDevice* device = NULL;
00395 
00396         for (DeviceList::iterator iter = m_deviceList.begin(); iter != m_deviceList.end(); ++iter)
00397         {
00398                 if ((*iter)->getSourceId() == id)
00399                 {
00400                         device = *iter;
00401                         break;
00402                 }
00403         }
00404 
00405         return device;
00406 }
00407 
00408 //
00409 // Get a pointer to the first device of the given type.
00410 // Returns NULL if no such device could be found.
00411 //
00412 devices::BasicDevice* Manager::getFirstDeviceByType(Sourcetype type)
00413 {
00414         devices::BasicDevice* device = NULL;
00415 
00416         for (DeviceList::iterator iter = m_deviceList.begin(); iter != m_deviceList.end(); ++iter)
00417         {
00418                 if ((*iter)->getDevicetype() == type)
00419                 {
00420                         device = *iter;
00421                         break;
00422                 }
00423         }
00424 
00425         return device;
00426 }
00427 


libsick_ldmrs
Author(s): SICK AG , Martin Günther , Jochen Sprickerhof
autogenerated on Thu Jun 6 2019 21:02:36