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 CRandomFieldGridMap2D_H 00030 #define CRandomFieldGridMap2D_H 00031 00032 #include <mrpt/utils/CDynamicGrid.h> 00033 #include <mrpt/utils/CImage.h> 00034 #include <mrpt/utils/CSerializable.h> 00035 #include <mrpt/math/CMatrixD.h> 00036 #include <mrpt/utils/CLoadableOptions.h> 00037 #include <mrpt/slam/CMetricMap.h> 00038 00039 #include <mrpt/maps/link_pragmas.h> 00040 00041 namespace mrpt 00042 { 00043 namespace slam 00044 { 00045 using namespace mrpt::utils; 00046 using namespace mrpt::poses; 00047 using namespace mrpt::math; 00048 00049 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE( CRandomFieldGridMap2D , CMetricMap, MAPS_IMPEXP ) 00050 00051 // Pragma defined to ensure no structure packing: since we'll serialize TRandomFieldCell to streams, we want it not to depend on compiler options, etc. 00052 #pragma pack(push,1) 00053 00054 /** The contents of each cell in a CRandomFieldGridMap2D map. 00055 * \ingroup mrpt_maps_grp 00056 **/ 00057 struct MAPS_IMPEXP TRandomFieldCell 00058 { 00059 /** Constructor */ 00060 TRandomFieldCell(double kfmean_dm_mean = 1e-20, double kfstd_dmmeanw = 0) : 00061 kf_mean (kfmean_dm_mean), 00062 kf_std (kfstd_dmmeanw), 00063 dmv_var_mean (0) 00064 { } 00065 00066 // *Note*: Use unions to share memory between data fields, since only a set 00067 // of the variables will be used for each mapping strategy. 00068 // You can access to a "TRandomFieldCell *cell" like: cell->kf_mean, cell->kf_std, etc.. 00069 // but accessing cell->kf_mean would also modify (i.e. ARE the same memory slot) cell->dm_mean, for example. 00070 00071 // Note 2: If the number of type of fields are changed in the future, 00072 // *PLEASE* also update the writeToStream() and readFromStream() methods!! 00073 00074 union 00075 { 00076 double kf_mean; //!< [KF-methods only] The mean value of this cell 00077 double dm_mean; //!< [Kernel-methods only] The cumulative weighted readings of this cell 00078 00079 }; 00080 union 00081 { 00082 double kf_std; //!< [KF-methods only] The standard deviation value of this cell 00083 double dm_mean_w; //!< [Kernel-methods only] The cumulative weights (concentration = alpha * dm_mean / dm_mean_w + (1-alpha)*r0 ) 00084 }; 00085 00086 double dmv_var_mean; //!< [Kernel DM-V only] The cumulative weighted variance of this cell 00087 }; 00088 #pragma pack(pop) 00089 00090 /** CRandomFieldGridMap2D represents a 2D grid map where each cell is associated one real-valued property which is estimated by this map, either 00091 * as a simple value or as a probility distribution (for each cell). 00092 * 00093 * There are a number of methods available to build the gas grid-map, depending on the value of 00094 * "TMapRepresentation maptype" passed in the constructor. 00095 * 00096 * The following papers describe the mapping alternatives implemented here: 00097 * - mrKernelDM: A kernel-based method: 00098 * "Building gas concentration gridmaps with a mobile robot", Lilienthal, A. and Duckett, T., Robotics and Autonomous Systems, v.48, 2004. 00099 * 00100 * - mrKernelDMV: A kernel-based method: 00101 * "A Statistical Approach to Gas Distribution Modelling with Mobile Robots--The Kernel DM+ V Algorithm" 00102 * , Lilienthal, A.J. and Reggente, M. and Trincavelli, M. and Blanco, J.L. and Gonzalez, J., IROS 2009. 00103 * 00104 * Note that this class is virtual, since derived classes still have to implement: 00105 * - mrpt::slam::CMetricMap::computeObservationLikelihood() 00106 * - mrpt::slam::CMetricMap::internal_insertObservation() 00107 * - Serialization methods: writeToStream() and readFromStream() 00108 * 00109 * \sa mrpt::slam::CGasConcentrationGridMap2D, mrpt::slam::CWirelessPowerGridMap2D, mrpt::slam::CMetricMap, mrpt::utils::CDynamicGrid, The application icp-slam, mrpt::slam::CMultiMetricMap 00110 * \ingroup mrpt_maps_grp 00111 */ 00112 class CRandomFieldGridMap2D : public CMetricMap, public utils::CDynamicGrid<TRandomFieldCell> 00113 { 00114 typedef utils::CDynamicGrid<TRandomFieldCell> BASE; 00115 00116 // This must be added to any CSerializable derived class: 00117 DEFINE_VIRTUAL_SERIALIZABLE( CRandomFieldGridMap2D ) 00118 public: 00119 00120 /** Calls the base CMetricMap::clear 00121 * Declared here to avoid ambiguity between the two clear() in both base classes. 00122 */ 00123 inline void clear() { CMetricMap::clear(); } 00124 00125 // This method is just used for the ::saveToTextFile() method in base class. 00126 float cell2float(const TRandomFieldCell& c) const 00127 { 00128 return c.kf_mean; 00129 } 00130 00131 /** The type of map representation to be used. 00132 */ 00133 enum TMapRepresentation 00134 { 00135 mrKernelDM = 0, // 00136 mrAchim = 0, // Another alias for "mrKernelDM", for backward compatibility 00137 mrKalmanFilter, 00138 mrKalmanApproximate, 00139 mrKernelDMV 00140 }; 00141 00142 /** Constructor 00143 */ 00144 CRandomFieldGridMap2D( 00145 TMapRepresentation mapType = mrAchim, 00146 float x_min = -2, 00147 float x_max = 2, 00148 float y_min = -2, 00149 float y_max = 2, 00150 float resolution = 0.1 00151 ); 00152 00153 /** Destructor */ 00154 virtual ~CRandomFieldGridMap2D(); 00155 00156 /** Returns true if the map is empty/no observation has been inserted (in this class it always return false, 00157 * unless redefined otherwise in base classes) 00158 */ 00159 virtual bool isEmpty() const; 00160 00161 00162 /** Save the current map as a graphical file (BMP,PNG,...). 00163 * The file format will be derived from the file extension (see CImage::saveToFile ) 00164 * It depends on the map representation model: 00165 * mrAchim: Each pixel is the ratio \f$ \sum{\frac{wR}{w}} \f$ 00166 * mrKalmanFilter: Each pixel is the mean value of the Gaussian that represents each cell. 00167 * 00168 * \sa \a getAsBitmapFile() 00169 */ 00170 virtual void saveAsBitmapFile(const std::string &filName) const; 00171 00172 /** Returns an image just as described in \a saveAsBitmapFile */ 00173 virtual void getAsBitmapFile(mrpt::utils::CImage &out_img) const; 00174 00175 /** Parameters common to any derived class. 00176 * Derived classes should derive a new struct from this one, plus "public utils::CLoadableOptions", 00177 * and call the internal_* methods where appropiate to deal with the variables declared here. 00178 * Derived classes instantions of their "TInsertionOptions" MUST set the pointer "m_insertOptions_common" upon construction. 00179 */ 00180 struct MAPS_IMPEXP TInsertionOptionsCommon 00181 { 00182 TInsertionOptionsCommon(); //!< Default values loader 00183 00184 /** See utils::CLoadableOptions */ 00185 void internal_loadFromConfigFile_common( 00186 const mrpt::utils::CConfigFileBase &source, 00187 const std::string §ion); 00188 00189 void internal_dumpToTextStream_common(CStream &out) const; //!< See utils::CLoadableOptions 00190 00191 /** @name Kernel methods (mrKernelDM, mrKernelDMV) 00192 @{ */ 00193 float sigma; //!< The sigma of the "Parzen"-kernel Gaussian 00194 float cutoffRadius; //!< The cutoff radius for updating cells. 00195 float R_min,R_max; //!< Limits for normalization of sensor readings. 00196 double dm_sigma_omega; //!< [DM/DM+V methods] The scaling parameter for the confidence "alpha" values (see the IROS 2009 paper; see CRandomFieldGridMap2D) */ 00197 /** @} */ 00198 00199 /** @name Kalman-filter methods (mrKalmanFilter, mrKalmanApproximate) 00200 @{ */ 00201 float KF_covSigma; //!< The "sigma" for the initial covariance value between cells (in meters). 00202 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). 00203 float KF_observationModelNoise; //!< The sensor model noise (in normalized concentration units). 00204 float KF_defaultCellMeanValue; //!< The default value for the mean of cells' concentration. 00205 uint16_t KF_W_size; //!< [mrKalmanApproximate] The size of the window of neighbor cells. 00206 /** @} */ 00207 }; 00208 00209 /** Changes the size of the grid, maintaining previous contents. 00210 * \sa setSize 00211 */ 00212 virtual void resize( float new_x_min, 00213 float new_x_max, 00214 float new_y_min, 00215 float new_y_max, 00216 const TRandomFieldCell& defaultValueNewCells, 00217 float additionalMarginMeters = 1.0f ); 00218 00219 /** Computes the ratio in [0,1] of correspondences between "this" and the "otherMap" map, whose 6D pose relative to "this" is "otherMapPose" 00220 * In the case of a multi-metric map, this returns the average between the maps. This method always return 0 for grid maps. 00221 * \param otherMap [IN] The other map to compute the matching with. 00222 * \param otherMapPose [IN] The 6D pose of the other map as seen from "this". 00223 * \param minDistForCorr [IN] The minimum distance between 2 non-probabilistic map elements for counting them as a correspondence. 00224 * \param minMahaDistForCorr [IN] The minimum Mahalanobis distance between 2 probabilistic map elements for counting them as a correspondence. 00225 * 00226 * \return The matching ratio [0,1] 00227 * \sa computeMatchingWith2D 00228 */ 00229 float compute3DMatchingRatio( 00230 const CMetricMap *otherMap, 00231 const CPose3D &otherMapPose, 00232 float minDistForCorr = 0.10f, 00233 float minMahaDistForCorr = 2.0f 00234 ) const; 00235 00236 00237 /** The implementation in this class just calls all the corresponding method of the contained metric maps. 00238 */ 00239 virtual void saveMetricMapRepresentationToFile( 00240 const std::string &filNamePrefix 00241 ) const; 00242 00243 /** Save a matlab ".m" file which represents as 3D surfaces the mean and a given confidence level for the concentration of each cell. 00244 * This method can only be called in a KF map model. 00245 * \sa getAsMatlab3DGraphScript 00246 */ 00247 virtual void saveAsMatlab3DGraph(const std::string &filName) const; 00248 00249 /** Return a large text block with a MATLAB script to plot the contents of this map \sa saveAsMatlab3DGraph 00250 * This method can only be called in a KF map model. 00251 */ 00252 void getAsMatlab3DGraphScript(std::string &out_script) const; 00253 00254 /** Returns a 3D object representing the map. 00255 */ 00256 virtual void getAs3DObject ( mrpt::opengl::CSetOfObjectsPtr &outObj ) const; 00257 00258 /** Return the type of the random-field grid map, according to parameters passed on construction. 00259 */ 00260 TMapRepresentation getMapType(); 00261 00262 /** Returns the prediction of the measurement at some (x,y) coordinates, and its certainty (in the form of the expected variance). 00263 * This methods is implemented differently for the different gas map types. 00264 */ 00265 virtual void predictMeasurement( 00266 const double &x, 00267 const double &y, 00268 double &out_predict_response, 00269 double &out_predict_response_variance ); 00270 00271 /** Return the mean and covariance vector of the full Kalman filter estimate (works for all KF-based methods). */ 00272 void getMeanAndCov( vector_double &out_means, CMatrixDouble &out_cov) const; 00273 00274 protected: 00275 /** Common options to all random-field grid maps: pointer that is set to the derived-class instance of "insertOptions" upon construction of this class. */ 00276 TInsertionOptionsCommon * m_insertOptions_common; 00277 00278 /** Get the part of the options common to all CRandomFieldGridMap2D classes */ 00279 virtual CRandomFieldGridMap2D::TInsertionOptionsCommon* getCommonInsertOptions() = 0; 00280 00281 /** The map representation type of this map, as passed in the constructor */ 00282 TMapRepresentation m_mapType; 00283 00284 CMatrixD m_cov; //!< The whole covariance matrix, used for the Kalman Filter map representation. 00285 00286 /** The compressed band diagonal matrix for the KF2 implementation. 00287 * The format is a Nx(W^2+2W+1) matrix, one row per cell in the grid map with the 00288 * cross-covariances between each cell and half of the window around it in the grid. 00289 */ 00290 CMatrixD m_stackedCov; 00291 mutable bool m_hasToRecoverMeanAndCov; //!< Only for the KF2 implementation. 00292 00293 /** @name Auxiliary vars for DM & DM+V methods 00294 @{ */ 00295 float m_DM_lastCutOff; 00296 std::vector<float> m_DM_gaussWindow; 00297 double m_average_normreadings_mean, m_average_normreadings_var; 00298 size_t m_average_normreadings_count; 00299 /** @} */ 00300 00301 /** The implementation of "insertObservation" for Achim Lilienthal's map models DM & DM+V. 00302 * \param normReading Is a [0,1] normalized concentration reading. 00303 * \param sensorPose Is the sensor pose on the robot 00304 * \param is_DMV = false -> map type is Kernel DM; true -> map type is DM+V 00305 */ 00306 void insertObservation_KernelDM_DMV( 00307 float normReading, 00308 const CPose3D &sensorPose, 00309 bool is_DMV ); 00310 00311 /** The implementation of "insertObservation" for the (whole) Kalman Filter map model. 00312 * \param normReading Is a [0,1] normalized concentration reading. 00313 * \param sensorPose Is the sensor pose 00314 */ 00315 void insertObservation_KF( 00316 float normReading, 00317 const CPose3D &sensorPose ); 00318 00319 /** The implementation of "insertObservation" for the Efficient Kalman Filter map model. 00320 * \param normReading Is a [0,1] normalized concentration reading. 00321 * \param sensorPose Is the sensor pose 00322 */ 00323 void insertObservation_KF2( 00324 float normReading, 00325 const CPose3D &sensorPose ); 00326 00327 /** Computes the average cell concentration, or the overall average value if it has never been observed */ 00328 double computeMeanCellValue_DM_DMV (const TRandomFieldCell *cell ) const; 00329 00330 /** Computes the estimated variance of the cell concentration, or the overall average variance if it has never been observed */ 00331 double computeVarCellValue_DM_DMV (const TRandomFieldCell *cell ) const; 00332 00333 /** In the KF2 implementation, takes the auxiliary matrices and from them update the cells' mean and std values. 00334 * \sa m_hasToRecoverMeanAndCov 00335 */ 00336 void recoverMeanAndCov() const; 00337 00338 /** Erase all the contents of the map */ 00339 virtual void internal_clear(); 00340 00341 }; 00342 00343 00344 } // End of namespace 00345 00346 00347 // Specializations MUST occur at the same namespace: 00348 namespace utils 00349 { 00350 template <> 00351 struct TEnumTypeFiller<slam::CRandomFieldGridMap2D::TMapRepresentation> 00352 { 00353 typedef slam::CRandomFieldGridMap2D::TMapRepresentation enum_t; 00354 static void fill(bimap<enum_t,std::string> &m_map) 00355 { 00356 m_map.insert(slam::CRandomFieldGridMap2D::mrKernelDM, "mrKernelDM"); 00357 m_map.insert(slam::CRandomFieldGridMap2D::mrKalmanFilter, "mrKalmanFilter"); 00358 m_map.insert(slam::CRandomFieldGridMap2D::mrKalmanApproximate, "mrKalmanApproximate"); 00359 m_map.insert(slam::CRandomFieldGridMap2D::mrKernelDMV, "mrKernelDMV"); 00360 } 00361 }; 00362 } // End of namespace 00363 } // End of namespace 00364 00365 #endif
| Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011 |