Main MRPT website > C++ reference
MRPT logo

CGenericSensor.h

Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                   http://mrpt.sourceforge.net/                            |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 
00029 #ifndef CGenericSensor_H
00030 #define CGenericSensor_H
00031 
00032 #include <mrpt/utils/CConfigFileBase.h>
00033 #include <mrpt/slam/CObservation.h>
00034 #include <mrpt/synch.h>
00035 #include <mrpt/system/threads.h>
00036 
00037 #include <mrpt/hwdrivers/link_pragmas.h>
00038 
00039 
00040 namespace mrpt
00041 {
00042         /**   Contains classes for various device interfaces.
00043          */
00044         namespace hwdrivers
00045         {
00046                 class HWDRIVERS_IMPEXP CGenericSensor;
00047 
00048                 /** A structure for runtime ID class type information in the context of hwdrivers::CGenericSensor.
00049                   */
00050                 struct HWDRIVERS_IMPEXP TSensorClassId
00051                 {
00052                         const char*                     className;                                              //!< Class name
00053                         CGenericSensor*         (*ptrCreateObject)();                   //!< Pointer to class constructor
00054                 };
00055 
00056                 typedef stlplus::smart_ptr<CGenericSensor>      CGenericSensorPtr;
00057 
00058                 /** A generic interface for a wide-variety of sensors designed to be used in the application RawLogGrabber.
00059                   *  Derived classes should be designed with the following execution flow in mind:
00060                   *             - Object constructor
00061                   *             - CGenericSensor::loadConfig: The following parameters are common to all sensors in rawlog-grabber (they are automatically loaded by rawlog-grabber) - see each class documentation for additional parameters:
00062                   *                     - "process_rate": (Mandatory) The rate in Hertz (Hz) at which the sensor thread should invoke "doProcess".
00063                   *                     - "max_queue_len": (Optional) The maximum number of objects in the observations queue (default is 200). If overflow occurs, an error message will be issued at run-time.
00064                   *                     - "grab_decimation": (Optional) Grab only 1 out of N observations captured by the sensor (default is 1, i.e. do not decimate).
00065                   *             - CGenericSensor::initialize
00066                   *             - CGenericSensor::doProcess
00067                   *             - CGenericSensor::getObservations
00068                   *
00069                   *  Notice that there are helper methods for managing the internal list of objects (see CGenericSensor::appendObservation).
00070                   *
00071                   *  <b>Class Factory:</b> This is also a factory of derived classes, through the static method CGenericSensor::createSensor
00072                   *
00073                   *
00074                   *  For more details on RawLogGrabber refer to the wiki page:
00075                   *    http://www.mrpt.org/Application:RawLogGrabber
00076                   */
00077                 class HWDRIVERS_IMPEXP CGenericSensor: public mrpt::utils::CUncopiable
00078                 {
00079                 public:
00080                         virtual const mrpt::hwdrivers::TSensorClassId* GetRuntimeClass() const = 0;
00081 
00082                         typedef std::multimap< mrpt::system::TTimeStamp, mrpt::utils::CSerializablePtr > TListObservations;
00083                         typedef std::pair< mrpt::system::TTimeStamp, mrpt::utils::CSerializablePtr > TListObsPair;
00084 
00085                         /** The current state of the sensor
00086                           * \sa CGenericSensor::getState
00087                           */
00088                         enum TSensorState
00089                         {
00090                                 ssInitializing = 0,
00091                                 ssWorking,
00092                                 ssError
00093                         };
00094 
00095                         /** The current state of the sensor  */
00096                         inline TSensorState getState() const { return m_state; }
00097 
00098                         inline double getProcessRate() const { return m_process_rate; }
00099 
00100                         inline std::string getSensorLabel() const { return m_sensorLabel; }
00101                         inline void setSensorLabel(const std::string& sensorLabel) { m_sensorLabel=sensorLabel; }
00102 
00103                         /** Register a class into the internal list of "CGenericSensor" descendents.
00104                           *  Used internally in the macros DEFINE_GENERIC_SENSOR, etc...
00105                           *
00106                           *  Can be used as "CGenericSensor::registerClass( SENSOR_CLASS_ID(CMySensor) );" if
00107                           *    building custom sensors outside mrpt libraries in user code.
00108                           */
00109                         static void registerClass(const TSensorClassId* pNewClass);
00110 
00111                 private:
00112                         synch::CCriticalSection                 m_csObjList;            //!< The critical section for m_objList
00113                         TListObservations                               m_objList;              //!< The queue of objects to be returned by getObservations
00114 
00115                         /** Used in registerClass */
00116                         static std::map< std::string , const TSensorClassId *>  m_knownClasses;
00117 
00118 
00119                 protected:
00120                         /** @name Common settings to any sensor, loaded in "loadConfig"
00121                             @{ */
00122 
00123                         double  m_process_rate;  //!< See CGenericSensor
00124                         size_t  m_max_queue_len; //!< See CGenericSensor
00125                         size_t  m_grab_decimation;      //!< If set to N>=2, only 1 out of N observations will be saved to m_objList.
00126                         std::string  m_sensorLabel; //!< See CGenericSensor
00127 
00128                         /** @} */
00129 
00130                         size_t  m_grab_decimation_counter; //!< Used when "m_grab_decimation" is enabled
00131 
00132                         TSensorState    m_state;
00133 
00134                         // === Data for off-rawlog file external image directory ====
00135                         //  Only used by a few sensor classes.
00136                         std::string                     m_path_for_external_images; //!< The path where to save off-rawlog images: empty means save images embedded in the rawlog.
00137                         std::string                     m_external_images_format; //!< The extension ("jpg","gif","png",...) that determines the format of images saved externally \sa setPathForExternalImages
00138                         unsigned int            m_external_images_jpeg_quality; //!< For JPEG images, the quality (default=95%).
00139                         // ======================================
00140 
00141                         /** This method must be called by derived classes to enqueue a new observation in the list to be returned by getObservations.
00142                           *  Passed objects must be created in dynamic memory and a smart pointer passed. Example of creation:
00143                           \code
00144                                 CObservationGPSPtr  o = CObservationGPSPtr( new CObservationGPS() );
00145                                 o-> .... // Set data
00146                                 appendObservation(o);
00147                           \endcode
00148                           * If several observations are passed at once in the vector, they'll be considered as a block regarding the grabbing decimation factor.
00149                           */
00150                         void appendObservations( const std::vector<mrpt::utils::CSerializablePtr> &obj);
00151 
00152                         //! Like appendObservations() but for just one observation.
00153                         void appendObservation( const mrpt::utils::CSerializablePtr &obj)
00154                         {
00155                                 appendObservations(std::vector<mrpt::utils::CSerializablePtr>(1, obj));
00156                         }
00157 
00158                         /** Auxiliary structure used for CSerializable runtime class ID support.
00159                           */
00160                         struct CLASSINIT_GENERIC_SENSOR
00161                         {
00162                                 CLASSINIT_GENERIC_SENSOR(const TSensorClassId* pNewClass)
00163                                 {
00164                                         CGenericSensor::registerClass(pNewClass);
00165                                 }
00166                         };
00167 
00168                         /** Loads specific configuration for the device from a given source of configuration parameters, for example, an ".ini" file, loading from the section "[iniSection]" (see utils::CConfigFileBase and derived classes)
00169                           *  \exception This method must throw an exception with a descriptive message if some critical parameter is missing or has an invalid value.
00170                           */
00171                         virtual void  loadConfig_sensorSpecific(
00172                                 const mrpt::utils::CConfigFileBase &configSource,
00173                                 const std::string                       &section ) = 0;
00174 
00175                 public:
00176                         /** Creates a sensor by a name of the class.
00177                           *  Typically the user may want to create a smart pointer around the returned pointer, whis is made with:
00178                           *  \code
00179                           *   CGenericSensorPtr sensor = CGenericSensorPtr( CGenericSensor::createSensor("XXX") );
00180                           *  \endcode
00181                           * \return A pointer to a new class, or NULL if class name is unknown.
00182                           */
00183                         static CGenericSensor* createSensor(const std::string &className);
00184 
00185                         /** Just like createSensor, but returning a smart pointer to the newly created sensor object. */
00186                         static inline CGenericSensorPtr createSensorPtr(const std::string &className)
00187                         {
00188                                 return CGenericSensorPtr(createSensor(className));
00189                         }
00190 
00191                         /** Constructor */
00192                         CGenericSensor( );
00193 
00194                         /** Destructor */
00195                         virtual ~CGenericSensor();
00196 
00197                         /** Loads the generic settings common to any sensor (See CGenericSensor), then call to "loadConfig_sensorSpecific"
00198                           *  \exception This method throws an exception with a descriptive message if some critical parameter is missing or has an invalid value.
00199                           */
00200                         void  loadConfig(
00201                                 const mrpt::utils::CConfigFileBase &configSource,
00202                                 const std::string                       &section );
00203 
00204                         /** This method can or cannot be implemented in the derived class, depending on the need for it.
00205                           *  \exception This method must throw an exception with a descriptive message if some critical error is found.
00206                           */
00207                         virtual void initialize()
00208                         {  }    // Default method does nothing.
00209 
00210                         /** This method will be invoked at a minimum rate of "process_rate" (Hz)
00211                           *  \exception This method must throw an exception with a descriptive message if some critical error is found.
00212                           */
00213                         virtual void doProcess() = 0;
00214 
00215                         /** Returns a list of enqueued objects, emptying it (thread-safe). The objects must be freed by the invoker.
00216                           */
00217                         void getObservations( TListObservations         &lstObjects );
00218 
00219                         /**  Set the path where to save off-rawlog image files (will be ignored in those sensors where this is not applicable).
00220                           *  An  empty string (the default value at construction) means to save images embedded in the rawlog, instead of on separate files.
00221                           * \exception std::exception If the directory doesn't exists and cannot be created.
00222                           */
00223                         virtual void setPathForExternalImages( const std::string &directory ) {
00224                                 // In this base class, the default is to ignore image paths.
00225                         }
00226 
00227                         /**  Set the extension ("jpg","gif","png",...) that determines the format of images saved externally
00228                           *   The default is "jpg".
00229                           * \sa setPathForExternalImages, setExternalImageJPEGQuality
00230                           */
00231                         void setExternalImageFormat( const std::string &ext ) {
00232                                 m_external_images_format = ext;
00233                         }
00234 
00235                         /** The quality of JPEG compression, when external images is enabled and the format is "jpg". \sa setExternalImageFormat */
00236                         void setExternalImageJPEGQuality(const unsigned int quality) {
00237                                 m_external_images_jpeg_quality = quality;
00238                         }
00239                         unsigned int getExternalImageJPEGQuality()const  {
00240                                 return m_external_images_jpeg_quality;
00241                         }
00242 
00243                 }; // end of class
00244 
00245 
00246                 #define SENSOR_CLASS_ID(class_name) \
00247                         static_cast<const mrpt::hwdrivers::TSensorClassId*>(& mrpt::hwdrivers::class_name::class##class_name)
00248 
00249                 #define SENSOR_IS_CLASS( ptrObj, class_name )  (ptrObj->GetRuntimeClass()==SENSOR_CLASS_ID(class_name))
00250 
00251 
00252                 /** This declaration must be inserted in all CGenericSensor classes definition, within the class declaration.
00253                   */
00254                 #define DEFINE_GENERIC_SENSOR(class_name) \
00255                 protected: \
00256                         static mrpt::hwdrivers::CGenericSensor::CLASSINIT_GENERIC_SENSOR _init_##class_name;\
00257                 public: \
00258                         static  mrpt::hwdrivers::TSensorClassId class##class_name; \
00259                         virtual const mrpt::hwdrivers::TSensorClassId* GetRuntimeClass() const; \
00260                         static  mrpt::hwdrivers::CGenericSensor* CreateObject(); \
00261                         static void doRegister() \
00262                         {       CGenericSensor::registerClass( SENSOR_CLASS_ID( class_name ) ); }
00263 
00264                 /** This must be inserted in all CGenericSensor classes implementation files:
00265                   */
00266                 #define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace) \
00267                         mrpt::hwdrivers::CGenericSensor* NameSpace::class_name::CreateObject() \
00268                                 { return static_cast<hwdrivers::CGenericSensor*>( new NameSpace::class_name ); } \
00269                         mrpt::hwdrivers::TSensorClassId NameSpace::class_name::class##class_name = { \
00270                                 #class_name, NameSpace::class_name::CreateObject }; \
00271                         const mrpt::hwdrivers::TSensorClassId* NameSpace::class_name::GetRuntimeClass() const \
00272                                 { return SENSOR_CLASS_ID(class_name); }
00273 
00274 
00275         } // end of namespace
00276 } // end of namespace
00277 
00278 #endif



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:40:17 UTC 2011