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://www.mrpt.org/                                |
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          * \ingroup mrpt_hwdrivers_grp
00044          */
00045         namespace hwdrivers
00046         {
00047                 class HWDRIVERS_IMPEXP CGenericSensor;
00048 
00049                 /** A structure for runtime ID class type information in the context of hwdrivers::CGenericSensor.
00050                   */
00051                 struct HWDRIVERS_IMPEXP TSensorClassId
00052                 {
00053                         const char*                     className;                                              //!< Class name
00054                         CGenericSensor*         (*ptrCreateObject)();                   //!< Pointer to class constructor
00055                 };
00056 
00057                 typedef stlplus::smart_ptr<CGenericSensor>      CGenericSensorPtr;
00058 
00059                 /** A generic interface for a wide-variety of sensors designed to be used in the application RawLogGrabber.
00060                   *  Derived classes should be designed with the following execution flow in mind:
00061                   *             - Object constructor
00062                   *             - 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:
00063                   *                     - "process_rate": (Mandatory) The rate in Hertz (Hz) at which the sensor thread should invoke "doProcess".
00064                   *                     - "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.
00065                   *                     - "grab_decimation": (Optional) Grab only 1 out of N observations captured by the sensor (default is 1, i.e. do not decimate).
00066                   *             - CGenericSensor::initialize
00067                   *             - CGenericSensor::doProcess
00068                   *             - CGenericSensor::getObservations
00069                   *
00070                   *  Notice that there are helper methods for managing the internal list of objects (see CGenericSensor::appendObservation).
00071                   *
00072                   *  <b>Class Factory:</b> This is also a factory of derived classes, through the static method CGenericSensor::createSensor
00073                   *
00074                   *
00075                   *  For more details on RawLogGrabber refer to the wiki page:
00076                   *    http://www.mrpt.org/Application:RawLogGrabber
00077                   * \ingroup mrpt_hwdrivers_grp
00078                   */
00079                 class HWDRIVERS_IMPEXP CGenericSensor: public mrpt::utils::CUncopiable
00080                 {
00081                 public:
00082                         virtual const mrpt::hwdrivers::TSensorClassId* GetRuntimeClass() const = 0;
00083 
00084                         typedef std::multimap< mrpt::system::TTimeStamp, mrpt::utils::CSerializablePtr > TListObservations;
00085                         typedef std::pair< mrpt::system::TTimeStamp, mrpt::utils::CSerializablePtr > TListObsPair;
00086 
00087                         /** The current state of the sensor
00088                           * \sa CGenericSensor::getState
00089                           */
00090                         enum TSensorState
00091                         {
00092                                 ssInitializing = 0,
00093                                 ssWorking,
00094                                 ssError
00095                         };
00096 
00097                         /** The current state of the sensor  */
00098                         inline TSensorState getState() const { return m_state; }
00099 
00100                         inline double getProcessRate() const { return m_process_rate; }
00101 
00102                         inline std::string getSensorLabel() const { return m_sensorLabel; }
00103                         inline void setSensorLabel(const std::string& sensorLabel) { m_sensorLabel=sensorLabel; }
00104 
00105                         /** Register a class into the internal list of "CGenericSensor" descendents.
00106                           *  Used internally in the macros DEFINE_GENERIC_SENSOR, etc...
00107                           *
00108                           *  Can be used as "CGenericSensor::registerClass( SENSOR_CLASS_ID(CMySensor) );" if
00109                           *    building custom sensors outside mrpt libraries in user code.
00110                           */
00111                         static void registerClass(const TSensorClassId* pNewClass);
00112 
00113                 private:
00114                         synch::CCriticalSection                 m_csObjList;            //!< The critical section for m_objList
00115                         TListObservations                               m_objList;              //!< The queue of objects to be returned by getObservations
00116 
00117                         /** Used in registerClass */
00118                         static std::map< std::string , const TSensorClassId *>  m_knownClasses;
00119 
00120 
00121                 protected:
00122                         /** @name Common settings to any sensor, loaded in "loadConfig"
00123                             @{ */
00124 
00125                         double  m_process_rate;  //!< See CGenericSensor
00126                         size_t  m_max_queue_len; //!< See CGenericSensor
00127                         size_t  m_grab_decimation;      //!< If set to N>=2, only 1 out of N observations will be saved to m_objList.
00128                         std::string  m_sensorLabel; //!< See CGenericSensor
00129 
00130                         /** @} */
00131 
00132                         size_t  m_grab_decimation_counter; //!< Used when "m_grab_decimation" is enabled
00133 
00134                         TSensorState    m_state;
00135 
00136                         // === Data for off-rawlog file external image directory ====
00137                         //  Only used by a few sensor classes.
00138                         std::string                     m_path_for_external_images; //!< The path where to save off-rawlog images: empty means save images embedded in the rawlog.
00139                         std::string                     m_external_images_format; //!< The extension ("jpg","gif","png",...) that determines the format of images saved externally \sa setPathForExternalImages
00140                         unsigned int            m_external_images_jpeg_quality; //!< For JPEG images, the quality (default=95%).
00141                         // ======================================
00142 
00143                         /** This method must be called by derived classes to enqueue a new observation in the list to be returned by getObservations.
00144                           *  Passed objects must be created in dynamic memory and a smart pointer passed. Example of creation:
00145                           \code
00146                                 CObservationGPSPtr  o = CObservationGPSPtr( new CObservationGPS() );
00147                                 o-> .... // Set data
00148                                 appendObservation(o);
00149                           \endcode
00150                           * If several observations are passed at once in the vector, they'll be considered as a block regarding the grabbing decimation factor.
00151                           */
00152                         void appendObservations( const std::vector<mrpt::utils::CSerializablePtr> &obj);
00153 
00154                         //! Like appendObservations() but for just one observation.
00155                         void appendObservation( const mrpt::utils::CSerializablePtr &obj)
00156                         {
00157                                 appendObservations(std::vector<mrpt::utils::CSerializablePtr>(1, obj));
00158                         }
00159 
00160                         /** Auxiliary structure used for CSerializable runtime class ID support.
00161                           */
00162                         struct CLASSINIT_GENERIC_SENSOR
00163                         {
00164                                 CLASSINIT_GENERIC_SENSOR(const TSensorClassId* pNewClass)
00165                                 {
00166                                         CGenericSensor::registerClass(pNewClass);
00167                                 }
00168                         };
00169 
00170                         /** 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)
00171                           *  \exception This method must throw an exception with a descriptive message if some critical parameter is missing or has an invalid value.
00172                           */
00173                         virtual void  loadConfig_sensorSpecific(
00174                                 const mrpt::utils::CConfigFileBase &configSource,
00175                                 const std::string                       &section ) = 0;
00176 
00177                 public:
00178                         /** Creates a sensor by a name of the class.
00179                           *  Typically the user may want to create a smart pointer around the returned pointer, whis is made with:
00180                           *  \code
00181                           *   CGenericSensorPtr sensor = CGenericSensorPtr( CGenericSensor::createSensor("XXX") );
00182                           *  \endcode
00183                           * \return A pointer to a new class, or NULL if class name is unknown.
00184                           */
00185                         static CGenericSensor* createSensor(const std::string &className);
00186 
00187                         /** Just like createSensor, but returning a smart pointer to the newly created sensor object. */
00188                         static inline CGenericSensorPtr createSensorPtr(const std::string &className)
00189                         {
00190                                 return CGenericSensorPtr(createSensor(className));
00191                         }
00192 
00193                         /** Constructor */
00194                         CGenericSensor( );
00195 
00196                         /** Destructor */
00197                         virtual ~CGenericSensor();
00198 
00199                         /** Loads the generic settings common to any sensor (See CGenericSensor), then call to "loadConfig_sensorSpecific"
00200                           *  \exception This method throws an exception with a descriptive message if some critical parameter is missing or has an invalid value.
00201                           */
00202                         void  loadConfig(
00203                                 const mrpt::utils::CConfigFileBase &configSource,
00204                                 const std::string                       &section );
00205 
00206                         /** This method can or cannot be implemented in the derived class, depending on the need for it.
00207                           *  \exception This method must throw an exception with a descriptive message if some critical error is found.
00208                           */
00209                         virtual void initialize()
00210                         {  }    // Default method does nothing.
00211 
00212                         /** This method will be invoked at a minimum rate of "process_rate" (Hz)
00213                           *  \exception This method must throw an exception with a descriptive message if some critical error is found.
00214                           */
00215                         virtual void doProcess() = 0;
00216 
00217                         /** Returns a list of enqueued objects, emptying it (thread-safe). The objects must be freed by the invoker.
00218                           */
00219                         void getObservations( TListObservations         &lstObjects );
00220 
00221                         /**  Set the path where to save off-rawlog image files (will be ignored in those sensors where this is not applicable).
00222                           *  An  empty string (the default value at construction) means to save images embedded in the rawlog, instead of on separate files.
00223                           * \exception std::exception If the directory doesn't exists and cannot be created.
00224                           */
00225                         virtual void setPathForExternalImages( const std::string &directory ) {
00226                                 // In this base class, the default is to ignore image paths.
00227                         }
00228 
00229                         /**  Set the extension ("jpg","gif","png",...) that determines the format of images saved externally
00230                           *   The default is "jpg".
00231                           * \sa setPathForExternalImages, setExternalImageJPEGQuality
00232                           */
00233                         void setExternalImageFormat( const std::string &ext ) {
00234                                 m_external_images_format = ext;
00235                         }
00236 
00237                         /** The quality of JPEG compression, when external images is enabled and the format is "jpg". \sa setExternalImageFormat */
00238                         void setExternalImageJPEGQuality(const unsigned int quality) {
00239                                 m_external_images_jpeg_quality = quality;
00240                         }
00241                         unsigned int getExternalImageJPEGQuality()const  {
00242                                 return m_external_images_jpeg_quality;
00243                         }
00244 
00245                 }; // end of class
00246 
00247 
00248                 #define SENSOR_CLASS_ID(class_name) \
00249                         static_cast<const mrpt::hwdrivers::TSensorClassId*>(& mrpt::hwdrivers::class_name::class##class_name)
00250 
00251                 #define SENSOR_IS_CLASS( ptrObj, class_name )  (ptrObj->GetRuntimeClass()==SENSOR_CLASS_ID(class_name))
00252 
00253 
00254                 /** This declaration must be inserted in all CGenericSensor classes definition, within the class declaration.
00255                   */
00256                 #define DEFINE_GENERIC_SENSOR(class_name) \
00257                 protected: \
00258                         static mrpt::hwdrivers::CGenericSensor::CLASSINIT_GENERIC_SENSOR _init_##class_name;\
00259                 public: \
00260                         static  mrpt::hwdrivers::TSensorClassId class##class_name; \
00261                         virtual const mrpt::hwdrivers::TSensorClassId* GetRuntimeClass() const; \
00262                         static  mrpt::hwdrivers::CGenericSensor* CreateObject(); \
00263                         static void doRegister() \
00264                         {       CGenericSensor::registerClass( SENSOR_CLASS_ID( class_name ) ); }
00265 
00266                 /** This must be inserted in all CGenericSensor classes implementation files:
00267                   */
00268                 #define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace) \
00269                         mrpt::hwdrivers::CGenericSensor* NameSpace::class_name::CreateObject() \
00270                                 { return static_cast<hwdrivers::CGenericSensor*>( new NameSpace::class_name ); } \
00271                         mrpt::hwdrivers::TSensorClassId NameSpace::class_name::class##class_name = { \
00272                                 #class_name, NameSpace::class_name::CreateObject }; \
00273                         const mrpt::hwdrivers::TSensorClassId* NameSpace::class_name::GetRuntimeClass() const \
00274                                 { return SENSOR_CLASS_ID(class_name); }
00275 
00276 
00277         } // end of namespace
00278 } // end of namespace
00279 
00280 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011