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 §ion ) = 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 §ion ); 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 |