Main MRPT website > C++ reference
MRPT logo
CLogOddsGridMap2D.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 CLogOddsGridMap2D_H
00030 #define CLogOddsGridMap2D_H
00031 
00032 #include <mrpt/utils/utils_defs.h>
00033 
00034 namespace mrpt
00035 {
00036         namespace slam
00037         {
00038                 namespace detail
00039                 {
00040                         template <typename TCELL> struct logoddscell_traits;
00041                         // Specializations:
00042                         template <> struct logoddscell_traits<int8_t>
00043                         {
00044                                 static const int8_t CELLTYPE_MIN  = -127; // In mrpt <0.9.4 was -128 (!) - This is to make it compatible with all architectures.
00045                                 static const int8_t CELLTYPE_MAX  = 127;
00046                                 static const int8_t P2LTABLE_SIZE = CELLTYPE_MAX;
00047                                 static const size_t LOGODDS_LUT_ENTRIES = 1<<8;
00048                         };
00049                         template <> struct logoddscell_traits<int16_t>
00050                         {
00051                                 static const int16_t CELLTYPE_MIN  = -32767; // In mrpt <0.9.4 was -32768 (!).
00052                                 static const int16_t CELLTYPE_MAX  = 32767;
00053                                 static const int16_t P2LTABLE_SIZE = CELLTYPE_MAX;
00054                                 static const size_t  LOGODDS_LUT_ENTRIES = 1<<16;
00055                         };
00056                 }
00057 
00058                 /** A generic provider of log-odds grid-map maintainance functions.
00059                   *  Map cells must be type TCELL, which can be only:
00060                   *             - int8_t or
00061                   *             - int16_t
00062                   *
00063                   *  \sa CLogOddsGridMapLUT, See derived classes for usage examples.
00064                   * \ingroup mrpt_maps_grp
00065                   */
00066                 template <typename TCELL>
00067                 struct CLogOddsGridMap2D : public detail::logoddscell_traits<TCELL>
00068                 {
00069                         typedef TCELL cell_t; //!< The type of cells
00070                         typedef detail::logoddscell_traits<TCELL>  traits_t;
00071 
00072                         /** Performs the Bayesian fusion of a new observation of a cell, without checking for grid limits nor updateInfoChangeOnly.
00073                           * This method increases the "occupancy-ness" of a cell, managing possible saturation.
00074                           *  \param x Cell index in X axis.
00075                           *  \param y Cell index in Y axis.
00076                           *  \param logodd_obs Observation of the cell, in log-odd form as transformed by p2l.
00077                           *  \param thres  This must be CELLTYPE_MIN+logodd_obs
00078                           * \sa updateCell, updateCell_fast_free
00079                          */
00080                         inline static void  updateCell_fast_occupied(
00081                                 const unsigned  x,
00082                                 const unsigned  y,
00083                                 const cell_t    logodd_obs,
00084                                 const cell_t  thres,
00085                                 cell_t          *mapArray,
00086                                 const unsigned  _size_x)
00087                         {
00088                                 cell_t *theCell = mapArray + (x+y*_size_x);
00089                                 if (*theCell > thres )
00090                                                 *theCell -= logodd_obs;
00091                                 else    *theCell = traits_t::CELLTYPE_MIN;
00092                         }
00093 
00094                         /** Performs the Bayesian fusion of a new observation of a cell, without checking for grid limits nor updateInfoChangeOnly.
00095                           * This method increases the "occupancy-ness" of a cell, managing possible saturation.
00096                           *  \param theCell The cell to modify
00097                           *  \param logodd_obs Observation of the cell, in log-odd form as transformed by p2l.
00098                           *  \param thres  This must be CELLTYPE_MIN+logodd_obs
00099                           * \sa updateCell, updateCell_fast_free
00100                          */
00101                         inline static void  updateCell_fast_occupied(
00102                                 cell_t          *theCell,
00103                                 const cell_t    logodd_obs,
00104                                 const cell_t  thres )
00105                         {
00106                                 if (*theCell > thres )
00107                                                 *theCell -= logodd_obs;
00108                                 else    *theCell = traits_t::CELLTYPE_MIN;
00109                         }
00110 
00111                         /** Performs the Bayesian fusion of a new observation of a cell, without checking for grid limits nor updateInfoChangeOnly.
00112                           * This method increases the "free-ness" of a cell, managing possible saturation.
00113                           *  \param x Cell index in X axis.
00114                           *  \param y Cell index in Y axis.
00115                           *  \param logodd_obs Observation of the cell, in log-odd form as transformed by p2l.
00116                           *  \param thres  This must be CELLTYPE_MAX-logodd_obs
00117                           * \sa updateCell_fast_occupied
00118                          */
00119                         inline static void  updateCell_fast_free(
00120                                 const unsigned  x,
00121                                 const unsigned  y,
00122                                 const cell_t    logodd_obs,
00123                                 const cell_t  thres,
00124                                 cell_t          *mapArray,
00125                                 const unsigned  _size_x)
00126                         {
00127                                 cell_t *theCell = mapArray + (x+y*_size_x);
00128                                 if (*theCell < thres )
00129                                                 *theCell += logodd_obs;
00130                                 else    *theCell = traits_t::CELLTYPE_MAX;
00131                         }
00132 
00133                         /** Performs the Bayesian fusion of a new observation of a cell, without checking for grid limits nor updateInfoChangeOnly.
00134                           * This method increases the "free-ness" of a cell, managing possible saturation.
00135                           *  \param x Cell index in X axis.
00136                           *  \param y Cell index in Y axis.
00137                           *  \param logodd_obs Observation of the cell, in log-odd form as transformed by p2l.
00138                           *  \param thres  This must be CELLTYPE_MAX-logodd_obs
00139                           * \sa updateCell_fast_occupied
00140                          */
00141                         inline static void  updateCell_fast_free(
00142                                 cell_t          *theCell,
00143                                 const cell_t    logodd_obs,
00144                                 const cell_t  thres)
00145                         {
00146                                 if (*theCell < thres )
00147                                                 *theCell += logodd_obs;
00148                                 else    *theCell = traits_t::CELLTYPE_MAX;
00149                         }
00150 
00151                 };  // end of CLogOddsGridMap2D
00152 
00153                 /** One static instance of this struct should exist in any class implementing CLogOddsGridMap2D to hold the Look-up-tables (LUTs) for log-odss Bayesian update.
00154                   *  Map cells must be type TCELL, which can be only:
00155                   *             - int8_t or
00156                   *             - int16_t
00157                   *
00158                   *  \sa CLogOddsGridMap2D, see derived classes for usage examples.
00159                   * \ingroup mrpt_maps_grp
00160                   */
00161                 template <typename TCELL>
00162                 struct CLogOddsGridMapLUT : public detail::logoddscell_traits<TCELL>
00163                 {
00164                         typedef TCELL cell_t; //!< The type of
00165                         typedef detail::logoddscell_traits<TCELL>  traits_t;
00166 
00167                         /** A lookup table to compute occupancy probabilities in [0,1] from integer log-odds values in the cells, using \f$ p(m_{xy}) = \frac{1}{1+exp(-log_odd)} \f$.
00168                           */
00169                         std::vector<float>    logoddsTable;
00170 
00171                         /** A lookup table to compute occupancy probabilities in the range [0,255] from integer log-odds values in the cells, using \f$ p(m_{xy}) = \frac{1}{1+exp(-log_odd)} \f$.
00172                           *  This is used to speed-up conversions to grayscale images.
00173                           */
00174                         std::vector<uint8_t>   logoddsTable_255;
00175 
00176                         /** A lookup table for passing from float to log-odds as cell_t. */
00177                         std::vector<cell_t>    p2lTable;
00178 
00179                         /** Constructor: computes all the required stuff. */
00180                         CLogOddsGridMapLUT()
00181                         {
00182                                 MRPT_START
00183 
00184                                 // The factor for converting log2-odds into integers:
00185                                 static const double LOGODD_K  = 16;
00186                                 static const double LOGODD_K_INV = 1.0/LOGODD_K;
00187 
00188                                 logoddsTable.resize( traits_t::LOGODDS_LUT_ENTRIES );
00189                                 logoddsTable_255.resize( traits_t::LOGODDS_LUT_ENTRIES );
00190                                 for (int i=traits_t::CELLTYPE_MIN;i<=traits_t::CELLTYPE_MAX;i++)
00191                                 {
00192                                         float f = 1.0f / (1.0f + exp( - i * LOGODD_K_INV ) );
00193                                         unsigned int idx =  -traits_t::CELLTYPE_MIN+i;
00194                                         logoddsTable[idx] = f;
00195                                         logoddsTable_255[idx] = (uint8_t)(f*255.0f);
00196                                 }
00197 
00198                                 // Build the p2lTable as well:
00199                                 p2lTable.resize( traits_t::P2LTABLE_SIZE+1 );
00200                                 double K = 1.0 / traits_t::P2LTABLE_SIZE;
00201                                 for (int j=0;j<=traits_t::P2LTABLE_SIZE;j++)
00202                                 {
00203                                         double p = j*K;
00204                                         if (p==0)
00205                                                 p=1e-14;
00206                                         else if (p==1)
00207                                                 p=1-1e-14;
00208 
00209                                         double logodd = log(p)-log(1-p);
00210                                         int   L = round(logodd * LOGODD_K);
00211                                         if (L>traits_t::CELLTYPE_MAX)
00212                                                 L=traits_t::CELLTYPE_MAX;
00213                                         else if (L<traits_t::CELLTYPE_MIN)
00214                                                 L=traits_t::CELLTYPE_MIN;
00215                                         p2lTable[j] = L;
00216                                 }
00217 
00218                                 MRPT_END
00219                         }
00220 
00221                         /** Scales an integer representation of the log-odd into a real valued probability in [0,1], using p=exp(l)/(1+exp(l))
00222                           */
00223                         inline float l2p(const cell_t l)
00224                         {
00225                                 if (l<traits_t::CELLTYPE_MIN)   
00226                                      return logoddsTable[ 0 ];  // This is needed since min can be -127 and int8_t can be -128.
00227                                 else return logoddsTable[ -traits_t::CELLTYPE_MIN+l ];
00228                         }
00229 
00230                         /** Scales an integer representation of the log-odd into a linear scale [0,255], using p=exp(l)/(1+exp(l))
00231                           */
00232                         inline uint8_t l2p_255(const cell_t l)
00233                         {
00234                                 if (l<traits_t::CELLTYPE_MIN)   
00235                                      return logoddsTable_255[ 0 ]; // This is needed since min can be -127 and int8_t can be -128.
00236                                 else return logoddsTable_255[ -traits_t::CELLTYPE_MIN+l ];
00237                         }
00238 
00239                         /** Scales a real valued probability in [0,1] to an integer representation of: log(p)-log(1-p)  in the valid range of cell_t.
00240                           */
00241                         inline cell_t p2l(const float p)
00242                         {
00243                                 return p2lTable[ static_cast<unsigned int>(p * traits_t::P2LTABLE_SIZE) ];
00244                         }
00245 
00246                 }; // end of CLogOddsGridMap2D
00247 
00248         } // End of namespace
00249 } // End of namespace
00250 
00251 #endif



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