Main MRPT website > C++ reference
MRPT logo
CRandomFieldGridMap2D.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 CRandomFieldGridMap2D_H
30 #define CRandomFieldGridMap2D_H
31 
33 #include <mrpt/utils/CImage.h>
35 #include <mrpt/math/CMatrixD.h>
37 #include <mrpt/slam/CMetricMap.h>
38 
39 #include <mrpt/maps/link_pragmas.h>
40 
41 namespace mrpt
42 {
43 namespace slam
44 {
45  using namespace mrpt::utils;
46  using namespace mrpt::poses;
47  using namespace mrpt::math;
48 
50 
51  // Pragma defined to ensure no structure packing: since we'll serialize TRandomFieldCell to streams, we want it not to depend on compiler options, etc.
52 #pragma pack(push,1)
53 
54  /** The contents of each cell in a CRandomFieldGridMap2D map.
55  * \ingroup mrpt_maps_grp
56  **/
58  {
59  /** Constructor */
60  TRandomFieldCell(double kfmean_dm_mean = 1e-20, double kfstd_dmmeanw = 0) :
61  kf_mean (kfmean_dm_mean),
62  kf_std (kfstd_dmmeanw),
63  dmv_var_mean (0),
64  last_updated(mrpt::system::now()),
65  updated_std (kfstd_dmmeanw)
66  { }
67 
68  // *Note*: Use unions to share memory between data fields, since only a set
69  // of the variables will be used for each mapping strategy.
70  // You can access to a "TRandomFieldCell *cell" like: cell->kf_mean, cell->kf_std, etc..
71  // but accessing cell->kf_mean would also modify (i.e. ARE the same memory slot) cell->dm_mean, for example.
72 
73  // Note 2: If the number of type of fields are changed in the future,
74  // *PLEASE* also update the writeToStream() and readFromStream() methods!!
75 
76  union
77  {
78  double kf_mean; //!< [KF-methods only] The mean value of this cell
79  double dm_mean; //!< [Kernel-methods only] The cumulative weighted readings of this cell
80 
81  };
82  union
83  {
84  double kf_std; //!< [KF-methods only] The standard deviation value of this cell
85  double dm_mean_w; //!< [Kernel-methods only] The cumulative weights (concentration = alpha * dm_mean / dm_mean_w + (1-alpha)*r0 )
86  };
87 
88  double dmv_var_mean; //!< [Kernel DM-V only] The cumulative weighted variance of this cell
89 
90  TTimeStamp last_updated; //!< [Dynamic maps only] The timestamp of the last time the cell was updated
91  double updated_std; //!< [Dynamic maps only] The std cell value that was updated (to be used in the Forgetting_curve
92  };
93 #pragma pack(pop)
94 
95  /** CRandomFieldGridMap2D represents a 2D grid map where each cell is associated one real-valued property which is estimated by this map, either
96  * as a simple value or as a probility distribution (for each cell).
97  *
98  * There are a number of methods available to build the gas grid-map, depending on the value of
99  * "TMapRepresentation maptype" passed in the constructor.
100  *
101  * The following papers describe the mapping alternatives implemented here:
102  * - mrKernelDM: A kernel-based method:
103  * "Building gas concentration gridmaps with a mobile robot", Lilienthal, A. and Duckett, T., Robotics and Autonomous Systems, v.48, 2004.
104  *
105  * - mrKernelDMV: A kernel-based method:
106  * "A Statistical Approach to Gas Distribution Modelling with Mobile Robots--The Kernel DM+ V Algorithm"
107  * , Lilienthal, A.J. and Reggente, M. and Trincavelli, M. and Blanco, J.L. and Gonzalez, J., IROS 2009.
108  *
109  * Note that this class is virtual, since derived classes still have to implement:
110  * - mrpt::slam::CMetricMap::computeObservationLikelihood()
111  * - mrpt::slam::CMetricMap::internal_insertObservation()
112  * - Serialization methods: writeToStream() and readFromStream()
113  *
114  * \sa mrpt::slam::CGasConcentrationGridMap2D, mrpt::slam::CWirelessPowerGridMap2D, mrpt::slam::CMetricMap, mrpt::utils::CDynamicGrid, The application icp-slam, mrpt::slam::CMultiMetricMap
115  * \ingroup mrpt_maps_grp
116  */
117  class CRandomFieldGridMap2D : public CMetricMap, public utils::CDynamicGrid<TRandomFieldCell>
118  {
120 
121  // This must be added to any CSerializable derived class:
123  public:
124 
125  /** Calls the base CMetricMap::clear
126  * Declared here to avoid ambiguity between the two clear() in both base classes.
127  */
128  inline void clear() { CMetricMap::clear(); }
129 
130  // This method is just used for the ::saveToTextFile() method in base class.
131  float cell2float(const TRandomFieldCell& c) const
132  {
133  return c.kf_mean;
134  }
135 
136  /** The type of map representation to be used.
137  */
139  {
140  mrKernelDM = 0, //
141  mrAchim = 0, // Another alias for "mrKernelDM", for backward compatibility
144  mrKernelDMV
145  };
146 
147  /** Constructor
148  */
150  TMapRepresentation mapType = mrAchim,
151  float x_min = -2,
152  float x_max = 2,
153  float y_min = -2,
154  float y_max = 2,
155  float resolution = 0.1
156  );
157 
158  /** Destructor */
159  virtual ~CRandomFieldGridMap2D();
160 
161  /** Returns true if the map is empty/no observation has been inserted (in this class it always return false,
162  * unless redefined otherwise in base classes)
163  */
164  virtual bool isEmpty() const;
165 
166 
167  /** Save the current map as a graphical file (BMP,PNG,...).
168  * The file format will be derived from the file extension (see CImage::saveToFile )
169  * It depends on the map representation model:
170  * mrAchim: Each pixel is the ratio \f$ \sum{\frac{wR}{w}} \f$
171  * mrKalmanFilter: Each pixel is the mean value of the Gaussian that represents each cell.
172  *
173  * \sa \a getAsBitmapFile()
174  */
175  virtual void saveAsBitmapFile(const std::string &filName) const;
176 
177  /** Returns an image just as described in \a saveAsBitmapFile */
178  virtual void getAsBitmapFile(mrpt::utils::CImage &out_img) const;
179 
180  /** Parameters common to any derived class.
181  * Derived classes should derive a new struct from this one, plus "public utils::CLoadableOptions",
182  * and call the internal_* methods where appropiate to deal with the variables declared here.
183  * Derived classes instantions of their "TInsertionOptions" MUST set the pointer "m_insertOptions_common" upon construction.
184  */
186  {
187  TInsertionOptionsCommon(); //!< Default values loader
188 
189  /** See utils::CLoadableOptions */
190  void internal_loadFromConfigFile_common(
191  const mrpt::utils::CConfigFileBase &source,
192  const std::string &section);
193 
194  void internal_dumpToTextStream_common(CStream &out) const; //!< See utils::CLoadableOptions
195 
196  /** @name Kernel methods (mrKernelDM, mrKernelDMV)
197  @{ */
198  float sigma; //!< The sigma of the "Parzen"-kernel Gaussian
199  float cutoffRadius; //!< The cutoff radius for updating cells.
200  float R_min,R_max; //!< Limits for normalization of sensor readings.
201  double dm_sigma_omega; //!< [DM/DM+V methods] The scaling parameter for the confidence "alpha" values (see the IROS 2009 paper; see CRandomFieldGridMap2D) */
202  /** @} */
203 
204  /** @name Kalman-filter methods (mrKalmanFilter, mrKalmanApproximate)
205  @{ */
206  float KF_covSigma; //!< The "sigma" for the initial covariance value between cells (in meters).
207  float KF_initialCellStd; //!< The initial standard deviation of each cell's concentration (will be stored both at each cell's structure and in the covariance matrix as variances in the diagonal) (in normalized concentration units).
208  float KF_observationModelNoise; //!< The sensor model noise (in normalized concentration units).
209  float KF_defaultCellMeanValue; //!< The default value for the mean of cells' concentration.
210  uint16_t KF_W_size; //!< [mrKalmanApproximate] The size of the window of neighbor cells.
211  /** @} */
212  };
213 
214  /** Changes the size of the grid, maintaining previous contents.
215  * \sa setSize
216  */
217  virtual void resize( float new_x_min,
218  float new_x_max,
219  float new_y_min,
220  float new_y_max,
221  const TRandomFieldCell& defaultValueNewCells,
222  float additionalMarginMeters = 1.0f );
223 
224  /** Computes the ratio in [0,1] of correspondences between "this" and the "otherMap" map, whose 6D pose relative to "this" is "otherMapPose"
225  * In the case of a multi-metric map, this returns the average between the maps. This method always return 0 for grid maps.
226  * \param otherMap [IN] The other map to compute the matching with.
227  * \param otherMapPose [IN] The 6D pose of the other map as seen from "this".
228  * \param minDistForCorr [IN] The minimum distance between 2 non-probabilistic map elements for counting them as a correspondence.
229  * \param minMahaDistForCorr [IN] The minimum Mahalanobis distance between 2 probabilistic map elements for counting them as a correspondence.
230  *
231  * \return The matching ratio [0,1]
232  * \sa computeMatchingWith2D
233  */
234  float compute3DMatchingRatio(
235  const CMetricMap *otherMap,
236  const CPose3D &otherMapPose,
237  float minDistForCorr = 0.10f,
238  float minMahaDistForCorr = 2.0f
239  ) const;
240 
241 
242  /** The implementation in this class just calls all the corresponding method of the contained metric maps.
243  */
244  virtual void saveMetricMapRepresentationToFile(
245  const std::string &filNamePrefix
246  ) const;
247 
248  /** Save a matlab ".m" file which represents as 3D surfaces the mean and a given confidence level for the concentration of each cell.
249  * This method can only be called in a KF map model.
250  * \sa getAsMatlab3DGraphScript
251  */
252  virtual void saveAsMatlab3DGraph(const std::string &filName) const;
253 
254  /** Return a large text block with a MATLAB script to plot the contents of this map \sa saveAsMatlab3DGraph
255  * This method can only be called in a KF map model.
256  */
257  void getAsMatlab3DGraphScript(std::string &out_script) const;
258 
259  /** Returns a 3D object representing the map (mean).
260  */
261  virtual void getAs3DObject ( mrpt::opengl::CSetOfObjectsPtr &outObj ) const;
262 
263  /** Returns two 3D objects representing the mean and variance maps.
264  */
265  virtual void getAs3DObject ( mrpt::opengl::CSetOfObjectsPtr &meanObj, mrpt::opengl::CSetOfObjectsPtr &varObj ) const;
266 
267  /** Return the type of the random-field grid map, according to parameters passed on construction.
268  */
269  TMapRepresentation getMapType();
270 
271  /** Returns the prediction of the measurement at some (x,y) coordinates, and its certainty (in the form of the expected variance).
272  * This methods is implemented differently for the different gas map types.
273  */
274  virtual void predictMeasurement(
275  const double &x,
276  const double &y,
277  double &out_predict_response,
278  double &out_predict_response_variance );
279 
280  /** Return the mean and covariance vector of the full Kalman filter estimate (works for all KF-based methods). */
281  void getMeanAndCov( vector_double &out_means, CMatrixDouble &out_cov) const;
282 
283  protected:
284  /** Common options to all random-field grid maps: pointer that is set to the derived-class instance of "insertOptions" upon construction of this class. */
286 
287  /** Get the part of the options common to all CRandomFieldGridMap2D classes */
288  virtual CRandomFieldGridMap2D::TInsertionOptionsCommon* getCommonInsertOptions() = 0;
289 
290  /** The map representation type of this map, as passed in the constructor */
292 
293  CMatrixD m_cov; //!< The whole covariance matrix, used for the Kalman Filter map representation.
294 
295  /** The compressed band diagonal matrix for the KF2 implementation.
296  * The format is a Nx(W^2+2W+1) matrix, one row per cell in the grid map with the
297  * cross-covariances between each cell and half of the window around it in the grid.
298  */
300  mutable bool m_hasToRecoverMeanAndCov; //!< Only for the KF2 implementation.
301 
302  /** @name Auxiliary vars for DM & DM+V methods
303  @{ */
305  std::vector<float> m_DM_gaussWindow;
306  double m_average_normreadings_mean, m_average_normreadings_var;
308  /** @} */
309 
310  /** The implementation of "insertObservation" for Achim Lilienthal's map models DM & DM+V.
311  * \param normReading Is a [0,1] normalized concentration reading.
312  * \param sensorPose Is the sensor pose on the robot
313  * \param is_DMV = false -> map type is Kernel DM; true -> map type is DM+V
314  */
315  void insertObservation_KernelDM_DMV(
316  float normReading,
317  const CPose3D &sensorPose,
318  bool is_DMV );
319 
320  /** The implementation of "insertObservation" for the (whole) Kalman Filter map model.
321  * \param normReading Is a [0,1] normalized concentration reading.
322  * \param sensorPose Is the sensor pose
323  */
324  void insertObservation_KF(
325  float normReading,
326  const CPose3D &sensorPose );
327 
328  /** The implementation of "insertObservation" for the Efficient Kalman Filter map model.
329  * \param normReading Is a [0,1] normalized concentration reading.
330  * \param sensorPose Is the sensor pose
331  */
332  void insertObservation_KF2(
333  float normReading,
334  const CPose3D &sensorPose );
335 
336  /** Computes the average cell concentration, or the overall average value if it has never been observed */
337  double computeMeanCellValue_DM_DMV (const TRandomFieldCell *cell ) const;
338 
339  /** Computes the estimated variance of the cell concentration, or the overall average variance if it has never been observed */
340  double computeVarCellValue_DM_DMV (const TRandomFieldCell *cell ) const;
341 
342  /** In the KF2 implementation, takes the auxiliary matrices and from them update the cells' mean and std values.
343  * \sa m_hasToRecoverMeanAndCov
344  */
345  void recoverMeanAndCov() const;
346 
347  /** Erase all the contents of the map */
348  virtual void internal_clear();
349 
350  };
351 
352 
353  } // End of namespace
354 
355 
356  // Specializations MUST occur at the same namespace:
357  namespace utils
358  {
359  template <>
361  {
363  static void fill(bimap<enum_t,std::string> &m_map)
364  {
365  m_map.insert(slam::CRandomFieldGridMap2D::mrKernelDM, "mrKernelDM");
366  m_map.insert(slam::CRandomFieldGridMap2D::mrKalmanFilter, "mrKalmanFilter");
367  m_map.insert(slam::CRandomFieldGridMap2D::mrKalmanApproximate, "mrKalmanApproximate");
368  m_map.insert(slam::CRandomFieldGridMap2D::mrKernelDMV, "mrKernelDMV");
369  }
370  };
371  } // End of namespace
372 } // End of namespace
373 
374 #endif



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