Main MRPT website > C++ reference
MRPT logo
CGenericSensor.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 
29 #ifndef CGenericSensor_H
30 #define CGenericSensor_H
31 
33 #include <mrpt/slam/CObservation.h>
34 #include <mrpt/synch.h>
35 #include <mrpt/system/threads.h>
36 
38 
39 
40 namespace mrpt
41 {
42  /** Contains classes for various device interfaces.
43  * \ingroup mrpt_hwdrivers_grp
44  */
45  namespace hwdrivers
46  {
48 
49  /** A structure for runtime ID class type information in the context of hwdrivers::CGenericSensor.
50  */
52  {
53  const char* className; //!< Class name
54  CGenericSensor* (*ptrCreateObject)(); //!< Pointer to class constructor
55  };
56 
58 
59  /** A generic interface for a wide-variety of sensors designed to be used in the application RawLogGrabber.
60  * Derived classes should be designed with the following execution flow in mind:
61  * - Object constructor
62  * - 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:
63  * - "process_rate": (Mandatory) The rate in Hertz (Hz) at which the sensor thread should invoke "doProcess".
64  * - "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.
65  * - "grab_decimation": (Optional) Grab only 1 out of N observations captured by the sensor (default is 1, i.e. do not decimate).
66  * - CGenericSensor::initialize
67  * - CGenericSensor::doProcess
68  * - CGenericSensor::getObservations
69  *
70  * Notice that there are helper methods for managing the internal list of objects (see CGenericSensor::appendObservation).
71  *
72  * <b>Class Factory:</b> This is also a factory of derived classes, through the static method CGenericSensor::createSensor
73  *
74  *
75  * For more details on RawLogGrabber refer to the wiki page:
76  * http://www.mrpt.org/Application:RawLogGrabber
77  * \ingroup mrpt_hwdrivers_grp
78  */
80  {
81  public:
82  virtual const mrpt::hwdrivers::TSensorClassId* GetRuntimeClass() const = 0;
83 
84  typedef std::multimap< mrpt::system::TTimeStamp, mrpt::utils::CSerializablePtr > TListObservations;
85  typedef std::pair< mrpt::system::TTimeStamp, mrpt::utils::CSerializablePtr > TListObsPair;
86 
87  /** The current state of the sensor
88  * \sa CGenericSensor::getState
89  */
91  {
92  ssInitializing = 0,
94  ssError
95  };
96 
97  /** The current state of the sensor */
98  inline TSensorState getState() const { return m_state; }
99 
100  inline double getProcessRate() const { return m_process_rate; }
101 
102  inline std::string getSensorLabel() const { return m_sensorLabel; }
103  inline void setSensorLabel(const std::string& sensorLabel) { m_sensorLabel=sensorLabel; }
104 
105  /** Register a class into the internal list of "CGenericSensor" descendents.
106  * Used internally in the macros DEFINE_GENERIC_SENSOR, etc...
107  *
108  * Can be used as "CGenericSensor::registerClass( SENSOR_CLASS_ID(CMySensor) );" if
109  * building custom sensors outside mrpt libraries in user code.
110  */
111  static void registerClass(const TSensorClassId* pNewClass);
112 
113  private:
114  synch::CCriticalSection m_csObjList; //!< The critical section for m_objList
115  TListObservations m_objList; //!< The queue of objects to be returned by getObservations
116 
117  /** Used in registerClass */
118  static std::map< std::string , const TSensorClassId *> m_knownClasses;
119 
120 
121  protected:
122  /** @name Common settings to any sensor, loaded in "loadConfig"
123  @{ */
124 
125  double m_process_rate; //!< See CGenericSensor
126  size_t m_max_queue_len; //!< See CGenericSensor
127  size_t m_grab_decimation; //!< If set to N>=2, only 1 out of N observations will be saved to m_objList.
128  std::string m_sensorLabel; //!< See CGenericSensor
129 
130  /** @} */
131 
132  size_t m_grab_decimation_counter; //!< Used when "m_grab_decimation" is enabled
133 
135 
136  // === Data for off-rawlog file external image directory ====
137  // Only used by a few sensor classes.
138  std::string m_path_for_external_images; //!< The path where to save off-rawlog images: empty means save images embedded in the rawlog.
139  std::string m_external_images_format; //!< The extension ("jpg","gif","png",...) that determines the format of images saved externally \sa setPathForExternalImages
140  unsigned int m_external_images_jpeg_quality; //!< For JPEG images, the quality (default=95%).
141  // ======================================
142 
143  /** This method must be called by derived classes to enqueue a new observation in the list to be returned by getObservations.
144  * Passed objects must be created in dynamic memory and a smart pointer passed. Example of creation:
145  \code
146  CObservationGPSPtr o = CObservationGPSPtr( new CObservationGPS() );
147  o-> .... // Set data
148  appendObservation(o);
149  \endcode
150  * If several observations are passed at once in the vector, they'll be considered as a block regarding the grabbing decimation factor.
151  */
152  void appendObservations( const std::vector<mrpt::utils::CSerializablePtr> &obj);
153 
154  //! Like appendObservations() but for just one observation.
155  void appendObservation( const mrpt::utils::CSerializablePtr &obj)
156  {
157  appendObservations(std::vector<mrpt::utils::CSerializablePtr>(1, obj));
158  }
159 
160  /** Auxiliary structure used for CSerializable runtime class ID support.
161  */
163  {
165  {
167  }
168  };
169 
170  /** 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)
171  * \exception This method must throw an exception with a descriptive message if some critical parameter is missing or has an invalid value.
172  */
173  virtual void loadConfig_sensorSpecific(
174  const mrpt::utils::CConfigFileBase &configSource,
175  const std::string &section ) = 0;
176 
177  public:
178  /** Creates a sensor by a name of the class.
179  * Typically the user may want to create a smart pointer around the returned pointer, whis is made with:
180  * \code
181  * CGenericSensorPtr sensor = CGenericSensorPtr( CGenericSensor::createSensor("XXX") );
182  * \endcode
183  * \return A pointer to a new class, or NULL if class name is unknown.
184  */
185  static CGenericSensor* createSensor(const std::string &className);
186 
187  /** Just like createSensor, but returning a smart pointer to the newly created sensor object. */
188  static inline CGenericSensorPtr createSensorPtr(const std::string &className)
189  {
190  return CGenericSensorPtr(createSensor(className));
191  }
192 
193  /** Constructor */
194  CGenericSensor( );
195 
196  /** Destructor */
197  virtual ~CGenericSensor();
198 
199  /** Loads the generic settings common to any sensor (See CGenericSensor), then call to "loadConfig_sensorSpecific"
200  * \exception This method throws an exception with a descriptive message if some critical parameter is missing or has an invalid value.
201  */
202  void loadConfig(
203  const mrpt::utils::CConfigFileBase &configSource,
204  const std::string &section );
205 
206  /** This method can or cannot be implemented in the derived class, depending on the need for it.
207  * \exception This method must throw an exception with a descriptive message if some critical error is found.
208  */
209  virtual void initialize()
210  { } // Default method does nothing.
211 
212  /** This method will be invoked at a minimum rate of "process_rate" (Hz)
213  * \exception This method must throw an exception with a descriptive message if some critical error is found.
214  */
215  virtual void doProcess() = 0;
216 
217  /** Returns a list of enqueued objects, emptying it (thread-safe). The objects must be freed by the invoker.
218  */
219  void getObservations( TListObservations &lstObjects );
220 
221  /** Set the path where to save off-rawlog image files (will be ignored in those sensors where this is not applicable).
222  * An empty string (the default value at construction) means to save images embedded in the rawlog, instead of on separate files.
223  * \exception std::exception If the directory doesn't exists and cannot be created.
224  */
225  virtual void setPathForExternalImages( const std::string &directory ) {
226  // In this base class, the default is to ignore image paths.
227  }
228 
229  /** Set the extension ("jpg","gif","png",...) that determines the format of images saved externally
230  * The default is "jpg".
231  * \sa setPathForExternalImages, setExternalImageJPEGQuality
232  */
233  void setExternalImageFormat( const std::string &ext ) {
234  m_external_images_format = ext;
235  }
236 
237  /** The quality of JPEG compression, when external images is enabled and the format is "jpg". \sa setExternalImageFormat */
238  void setExternalImageJPEGQuality(const unsigned int quality) {
239  m_external_images_jpeg_quality = quality;
240  }
241  unsigned int getExternalImageJPEGQuality()const {
242  return m_external_images_jpeg_quality;
243  }
244 
245  }; // end of class
246 
247 
248  #define SENSOR_CLASS_ID(class_name) \
249  static_cast<const mrpt::hwdrivers::TSensorClassId*>(& mrpt::hwdrivers::class_name::class##class_name)
250 
251  #define SENSOR_IS_CLASS( ptrObj, class_name ) (ptrObj->GetRuntimeClass()==SENSOR_CLASS_ID(class_name))
252 
253 
254  /** This declaration must be inserted in all CGenericSensor classes definition, within the class declaration.
255  */
256  #define DEFINE_GENERIC_SENSOR(class_name) \
257  protected: \
258  static mrpt::hwdrivers::CGenericSensor::CLASSINIT_GENERIC_SENSOR _init_##class_name;\
259  public: \
260  static mrpt::hwdrivers::TSensorClassId class##class_name; \
261  virtual const mrpt::hwdrivers::TSensorClassId* GetRuntimeClass() const; \
262  static mrpt::hwdrivers::CGenericSensor* CreateObject(); \
263  static void doRegister() \
264  { CGenericSensor::registerClass( SENSOR_CLASS_ID( class_name ) ); }
265 
266  /** This must be inserted in all CGenericSensor classes implementation files:
267  */
268  #define IMPLEMENTS_GENERIC_SENSOR(class_name, NameSpace) \
269  mrpt::hwdrivers::CGenericSensor* NameSpace::class_name::CreateObject() \
270  { return static_cast<hwdrivers::CGenericSensor*>( new NameSpace::class_name ); } \
271  mrpt::hwdrivers::TSensorClassId NameSpace::class_name::class##class_name = { \
272  #class_name, NameSpace::class_name::CreateObject }; \
273  const mrpt::hwdrivers::TSensorClassId* NameSpace::class_name::GetRuntimeClass() const \
274  { return SENSOR_CLASS_ID(class_name); }
275 
276 
277  } // end of namespace
278 } // end of namespace
279 
280 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013