Main MRPT website > C++ reference
MRPT logo
CParticleFilterCapable.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 #ifndef CPARTICLEFILTERCAPABLE_H
00029 #define CPARTICLEFILTERCAPABLE_H
00030 
00031 #include <mrpt/utils/utils_defs.h>
00032 #include <mrpt/bayes/CParticleFilter.h>
00033 
00034 namespace mrpt
00035 {
00036 namespace bayes
00037 {
00038         #define INVALID_LIKELIHOOD_VALUE  (-1e300)   // An invalid log-likelihood value, used to signal non-initialized likelihood variables.
00039 
00040         /** This virtual class defines the interface that any particles based PDF class must implement in order to be executed by a mrpt::bayes::CParticleFilter.
00041          *
00042          * See the <a href="http://www.mrpt.org/Particle_Filter_Tutorial" >Particle Filter tutorial</a> explaining how to use the particle filter-related classes.
00043          * \sa CParticleFilter, CParticleFilterData
00044          * \ingroup mrpt_base_grp
00045          */
00046         class BASE_IMPEXP CParticleFilterCapable
00047         {
00048                 friend class CParticleFilter;
00049 
00050         private:
00051                 static const unsigned PARTICLE_FILTER_CAPABLE_FAST_DRAW_BINS;
00052 
00053         public:
00054 
00055                 CParticleFilterCapable() : m_fastDrawAuxiliary()
00056                 { }
00057 
00058 
00059         /** Virtual destructor
00060           */
00061         virtual ~CParticleFilterCapable()
00062                 {
00063                 }
00064 
00065                 /** A callback function type for evaluating the probability of m_particles of being selected, used in "fastDrawSample".
00066                   *  The default evaluator function "defaultEvaluator" simply returns the particle weight.
00067                   * \param index This is the index of the particle its probability is being computed.
00068                   * \param action The value of this is the parameter passed to "prepareFastDrawSample"
00069                   * \param observation The value of this is the parameter passed to "prepareFastDrawSample"
00070                   *  The action and the observation are declared as "void*" for a greater flexibility.
00071                   * \sa prepareFastDrawSample
00072                   */
00073                 typedef double ( *TParticleProbabilityEvaluator) (
00074                         const bayes::CParticleFilter::TParticleFilterOptions &PF_options,
00075                         const CParticleFilterCapable    *obj,
00076                         size_t                                  index,
00077                         const void      * action,
00078                         const void      * observation );
00079 
00080                 /** The default evaluator function, which simply returns the particle weight.
00081                   *  The action and the observation are declared as "void*" for a greater flexibility.
00082                   * \sa prepareFastDrawSample
00083                   */
00084                 static double  defaultEvaluator(
00085                         const bayes::CParticleFilter::TParticleFilterOptions &PF_options,
00086                         const CParticleFilterCapable    *obj,
00087                         size_t                          index,
00088                         const void      * action,
00089                         const void      * observation )
00090                 {
00091                         MRPT_UNUSED_PARAM(action); MRPT_UNUSED_PARAM(observation);
00092                         return obj->getW(index);
00093                 }
00094 
00095                 /** Prepares data structures for calling fastDrawSample method next.
00096                   *  This method must be called once before using "fastDrawSample" (calling this more than once has no effect, but it takes time for nothing!)
00097                   *  The behavior depends on the configuration of the PF (see CParticleFilter::TParticleFilterOptions):
00098                   *             - <b>DYNAMIC SAMPLE SIZE=NO</b>: In this case this method fills out an internal array (m_fastDrawAuxiliary.alreadyDrawnIndexes) with
00099                   *                     the random indexes generated according to the selected resample scheme in TParticleFilterOptions. Those indexes are
00100                   *                     read sequentially by subsequent calls to fastDrawSample.
00101                   *             - <b>DYNAMIC SAMPLE SIZE=YES</b>: Then:
00102                   *                     - If TParticleFilterOptions.resamplingMethod = prMultinomial, the internal buffers will be filled out (m_fastDrawAuxiliary.CDF, CDF_indexes & PDF) and
00103                   *                             then fastDrawSample can be called an arbitrary number of times to generate random indexes.
00104                   *                     - For the rest of resampling algorithms, an exception will be raised since they are not appropriate for a dynamic (unknown in advance) number of particles.
00105                   *
00106                   * The function pointed by "partEvaluator" should take into account the particle filter algorithm selected in "m_PFAlgorithm".
00107                   * If called without arguments (defaultEvaluator), the default behavior is to draw samples with a probability proportional to their current weights.
00108                   *  The action and the observation are declared as "void*" for a greater flexibility.
00109                   *  For a more detailed information see the <a href="http://www.mrpt.org/Particle_Filters" >Particle Filter tutorial</a>.
00110                   *  Custom supplied "partEvaluator" functions must take into account the previous particle weight, i.e. multiplying the current observation likelihood by the weights.
00111                   * \sa fastDrawSample
00112                   */
00113                 void  prepareFastDrawSample(
00114                         const bayes::CParticleFilter::TParticleFilterOptions &PF_options,
00115                         TParticleProbabilityEvaluator partEvaluator = defaultEvaluator,
00116                         const void      * action = NULL,
00117                         const void      * observation = NULL
00118                         ) const;
00119 
00120                 /** Draws a random sample from the particle filter, in such a way that each particle has a probability proportional to its weight (in the standard PF algorithm).
00121                   *   This method can be used to generate a variable number of m_particles when resampling: to vary the number of m_particles in the filter.
00122                   *   See prepareFastDrawSample for more information, or the <a href="http://www.mrpt.org/Particle_Filters" >Particle Filter tutorial</a>.
00123                   *
00124                   * NOTES:
00125                   *             - You MUST call "prepareFastDrawSample" ONCE before calling this method. That method must be called after modifying the particle filter (executing one step, resampling, etc...)
00126                   *             - This method returns ONE index for the selected ("drawn") particle, in the range [0,M-1]
00127                   *             - You do not need to call "normalizeWeights" before calling this.
00128                   * \sa prepareFastDrawSample
00129                   */
00130                 size_t  fastDrawSample( const bayes::CParticleFilter::TParticleFilterOptions &PF_options  ) const;
00131 
00132                 /** Access to i'th particle (logarithm) weight, where first one is index 0.
00133                  */
00134                 virtual double  getW(size_t i) const = 0;
00135 
00136                 /** Modifies i'th particle (logarithm) weight, where first one is index 0.
00137                  */
00138                 virtual void  setW(size_t i, double w) = 0;
00139 
00140                 /** Get the m_particles count.
00141                  */
00142                 virtual size_t particlesCount() const = 0;
00143 
00144                 /** Performs the prediction stage of the Particle Filter.
00145                  *  This method simply selects the appropiate protected method according to the particle filter algorithm to run.
00146                  * \sa prediction_and_update_pfStandardProposal,prediction_and_update_pfAuxiliaryPFStandard,prediction_and_update_pfOptimalProposal,prediction_and_update_pfAuxiliaryPFOptimal
00147                  */
00148                 void  prediction_and_update(
00149                         const mrpt::slam::CActionCollection     * action,
00150                         const mrpt::slam::CSensoryFrame         * observation,
00151                         const bayes::CParticleFilter::TParticleFilterOptions &PF_options
00152                          );
00153 
00154                 /**  Performs the substitution for internal use of resample in particle filter algorithm, don't call it directly.
00155                  *  \param indx The indices of current m_particles to be saved as the new m_particles set.
00156                  */
00157                 virtual void  performSubstitution( const std::vector<size_t> &indx) = 0;
00158 
00159                 /** Normalize the (logarithmic) weights, such as the maximum weight is zero.
00160                  * \param out_max_log_w If provided, will return with the maximum log_w before normalizing, such as new_weights = old_weights - max_log_w.
00161                  * \return The max/min ratio of weights ("dynamic range")
00162                  */
00163                 virtual double  normalizeWeights( double *out_max_log_w = NULL ) =0;
00164 
00165                 /** Returns the normalized ESS (Estimated Sample Size), in the range [0,1].
00166                   *  Note that you do NOT need to normalize the weights before calling this.
00167                  */
00168                 virtual double ESS() = 0;
00169 
00170                 /** Performs a resample of the m_particles, using the method selected in the constructor.
00171                   * After computing the surviving samples, this method internally calls "performSubstitution" to actually perform the particle replacement.
00172                   * This method is called automatically by CParticleFilter::execute, andshould not be invoked manually normally.
00173                   * To just obtaining the sequence of resampled indexes from a sequence of weights, use "resample"
00174                   * \sa resample
00175                   */
00176                 void  performResampling( const bayes::CParticleFilter::TParticleFilterOptions &PF_options );
00177 
00178                 /** A static method to perform the computation of the samples resulting from resampling a given set of particles, given their logarithmic weights, and a resampling method.
00179                   * It returns the sequence of indexes from the resampling. The number of output samples is the same than the input population.
00180                   *  This generic method just computes these indexes, to actually perform a resampling in a particle filter object, call performResampling
00181                   * \sa performResampling
00182                   */
00183                 static void computeResampling(
00184                         CParticleFilter::TParticleResamplingAlgorithm   method,
00185                         const vector_double     &in_logWeights,
00186                         std::vector<size_t>                     &out_indexes
00187                         );
00188 
00189                 /** A static method to compute the linear, normalized (the sum the unity) weights from log-weights.
00190                   * \sa performResampling
00191                   */
00192                 static void log2linearWeights(
00193                         const vector_double     &in_logWeights,
00194                         vector_double           &out_linWeights );
00195 
00196 
00197         protected:
00198                 /** Performs the particle filter prediction/update stages for the algorithm "pfStandardProposal" (if not implemented in heritated class, it will raise a 'non-implemented' exception).
00199                  * \sa prediction_and_update
00200                  */
00201                 virtual void  prediction_and_update_pfStandardProposal(
00202                         const mrpt::slam::CActionCollection     * action,
00203                         const mrpt::slam::CSensoryFrame         * observation,
00204                         const bayes::CParticleFilter::TParticleFilterOptions &PF_options );
00205                 /** Performs the particle filter prediction/update stages for the algorithm "pfAuxiliaryPFStandard" (if not implemented in heritated class, it will raise a 'non-implemented' exception).
00206                  * \sa prediction_and_update
00207                  */
00208                 virtual void  prediction_and_update_pfAuxiliaryPFStandard(
00209                         const mrpt::slam::CActionCollection     * action,
00210                         const mrpt::slam::CSensoryFrame         * observation,
00211                         const bayes::CParticleFilter::TParticleFilterOptions &PF_options );
00212                 /** Performs the particle filter prediction/update stages for the algorithm "pfOptimalProposal" (if not implemented in heritated class, it will raise a 'non-implemented' exception).
00213                  * \sa prediction_and_update
00214                  */
00215                 virtual void  prediction_and_update_pfOptimalProposal(
00216                         const mrpt::slam::CActionCollection     * action,
00217                         const mrpt::slam::CSensoryFrame         * observation,
00218                         const bayes::CParticleFilter::TParticleFilterOptions &PF_options );
00219                 /** Performs the particle filter prediction/update stages for the algorithm "pfAuxiliaryPFOptimal" (if not implemented in heritated class, it will raise a 'non-implemented' exception).
00220                  * \sa prediction_and_update
00221                  */
00222                 virtual void  prediction_and_update_pfAuxiliaryPFOptimal(
00223                         const mrpt::slam::CActionCollection     * action,
00224                         const mrpt::slam::CSensoryFrame         * observation,
00225                         const bayes::CParticleFilter::TParticleFilterOptions &PF_options );
00226 
00227                 /** Auxiliary vectors, see CParticleFilterCapable::prepareFastDrawSample for more information
00228                   */
00229                 struct BASE_IMPEXP TFastDrawAuxVars
00230                 {
00231                         TFastDrawAuxVars() :
00232                                 CDF(),
00233                                 CDF_indexes(),
00234                                 PDF(),
00235                                 alreadyDrawnIndexes(),
00236                                 alreadyDrawnNextOne(0)
00237                         { }
00238 
00239                         vector_double   CDF;
00240                         vector_uint             CDF_indexes;
00241                         vector_double   PDF;
00242 
00243                         vector_uint             alreadyDrawnIndexes;
00244                         size_t                  alreadyDrawnNextOne;
00245                 };
00246 
00247                 /** Auxiliary vectors, see CParticleFilterCapable::prepareFastDrawSample for more information
00248                   */
00249                 mutable TFastDrawAuxVars        m_fastDrawAuxiliary;
00250 
00251         }; // End of class def.
00252 
00253         } // end namespace
00254 } // end namespace
00255 #endif



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