simple_particle_filter.h
Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2015, JSK Lab
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *********************************************************************/
00035 
00036 
00037 #ifndef JSK_PCL_ROS_ROS_COLLABORATIVE_PARTICLE_FILTER_H_
00038 #define JSK_PCL_ROS_ROS_COLLABORATIVE_PARTICLE_FILTER_H_
00039 
00040 #include <pcl/tracking/particle_filter.h>
00041 #include <pcl/tracking/impl/particle_filter.hpp>
00042 
00043 namespace pcl
00044 {
00045   namespace tracking
00046   {
00047         // Particle filter class which is friendly collaborative with ROS programs.
00048     // Default behavior is same to the ParticleFilterTracker but you can customize
00049     // the behavior from outer of the class.
00050     template <typename PointInT, typename StateT>
00051     class ROSCollaborativeParticleFilterTracker: public ParticleFilterTracker<PointInT, StateT>
00052     {
00053     public:
00054       using Tracker<PointInT, StateT>::input_;
00055       using ParticleFilterTracker<PointInT, StateT>::particles_;
00056       using ParticleFilterTracker<PointInT, StateT>::changed_;
00057       typedef boost::shared_ptr<ROSCollaborativeParticleFilterTracker> Ptr;
00058       typedef typename Tracker<PointInT, StateT>::PointCloudIn PointCloudIn;
00059       typedef typename PointCloudIn::Ptr PointCloudInPtr;
00060       typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr;
00061 
00062       typedef typename Tracker<PointInT, StateT>::PointCloudState PointCloudState;
00063       typedef typename PointCloudState::Ptr PointCloudStatePtr;
00064       typedef typename PointCloudState::ConstPtr PointCloudStateConstPtr;
00065 
00066       typedef PointCoherence<PointInT> Coherence;
00067       typedef boost::shared_ptr< Coherence > CoherencePtr;
00068       typedef boost::shared_ptr< const Coherence > CoherenceConstPtr;
00069 
00070       typedef PointCloudCoherence<PointInT> CloudCoherence;
00071       typedef boost::shared_ptr< CloudCoherence > CloudCoherencePtr;
00072       typedef boost::shared_ptr< const CloudCoherence > CloudCoherenceConstPtr;
00073 
00074       typedef boost::function<StateT (const StateT&)> CustomSampleFunc;
00075       typedef boost::function<void (PointCloudInConstPtr, StateT&)> CustomLikelihoodFunc;
00076       ROSCollaborativeParticleFilterTracker():
00077         ParticleFilterTracker<PointInT, StateT>()
00078       {
00079         motion_ratio_ = 0.0;
00080         changed_ = true;
00081       }
00082 
00083       void setParticles(PointCloudStatePtr particles)
00084       {
00085         particles_ = particles;
00086       }
00087 
00088       void setCustomSampleFunc(CustomSampleFunc f)
00089       {
00090         custom_sample_func_ = f;
00091       }
00092       
00093       void setLikelihoodFunc(CustomLikelihoodFunc f)
00094       {
00095         custom_likelihood_func_ = f;
00096       }
00097       
00098     protected:
00099       bool initCompute()
00100       {
00101         // Do nothing
00102         return true;
00103       }
00104       
00105       void weight()
00106       {
00107         if (!particles_) {
00108           std::cerr << "no particles" << std::endl;
00109         }
00110         if (!input_) {
00111           std::cerr << "no input pointcloud" << std::endl;
00112         }
00113 
00114 #ifdef _OPENMP
00115 #pragma omp parallel for
00116 #endif
00117         for (size_t i = 0; i < particles_->points.size (); i++) {
00118           custom_likelihood_func_ (input_, particles_->points[i]);
00119         }
00120         normalizeWeight();
00121       }
00122       
00123       void 
00124       resample()
00125       {
00126         std::vector<int> a (particles_->points.size ());
00127         std::vector<double> q (particles_->points.size ());
00128         this->genAliasTable (a, q, particles_);
00129   
00130         // memoize the original list of particles
00131         
00132         PointCloudStatePtr origparticles = particles_;
00133         particles_.reset(new PointCloudState());
00134         particles_->points.reserve(origparticles->points.size() + 1); // particle_num_??
00135         // the first particle, it is a just copy of the maximum result
00136         // StateT p = representative_state_;
00137         // particles_->points.push_back (p);
00138   
00139         // with motion
00140         int motion_num = static_cast<int> (particles_->points.size ()) * static_cast<int> (motion_ratio_);
00141         for ( int i = 1; i < motion_num; i++ ) {
00142           int target_particle_index = sampleWithReplacement (a, q);
00143           StateT p = origparticles->points[target_particle_index];
00144           p = custom_sample_func_(p);
00145           p = p + motion_;
00146           particles_->points.push_back (p);
00147         }
00148   
00149         // no motion
00150         for ( int i = motion_num; i < particle_num_; i++ ) {
00151           int target_particle_index = sampleWithReplacement (a, q);
00152           StateT p = origparticles->points[target_particle_index];
00153           // add noise using gaussian
00154           p = custom_sample_func_(p);
00155           particles_->points.push_back (p);
00156         }
00157       }
00158 
00159       bool initParticles(bool)
00160       {
00161         // Do nothing
00162         return true;
00163       }
00164 
00165       void computeTracking()
00166       {
00167         // r->w->u ?
00168         // w->u->r ?
00169         for (int i = 0; i < iteration_num_; i++) {
00170           resample();
00171           weight();
00172           update();
00173         }
00174       }
00175 
00176       void normalizeWeight()
00177       {
00178         double n = 0.0;
00179         for (size_t i = 0; i < particles_->points.size(); i++) {
00180           n = particles_->points[i].weight + n;
00181         }
00182         if (n != 0.0) {
00183           for (size_t i = 0; i < particles_->points.size(); i++) {
00184             particles_->points[i].weight = particles_->points[i].weight / n;
00185           }
00186         }
00187         else {
00188           for (size_t i = 0; i < particles_->points.size(); i++) {
00189             particles_->points[i].weight = 1.0 / particles_->points.size();
00190           }
00191         }
00192       }
00193       
00194       using ParticleFilterTracker<PointInT, StateT>::iteration_num_;
00195       using ParticleFilterTracker<PointInT, StateT>::update;
00196       using ParticleFilterTracker<PointInT, StateT>::representative_state_;
00197       using ParticleFilterTracker<PointInT, StateT>::motion_ratio_;
00198       using ParticleFilterTracker<PointInT, StateT>::particle_num_;
00199       using ParticleFilterTracker<PointInT, StateT>::motion_;
00200       using ParticleFilterTracker<PointInT, StateT>::sampleWithReplacement;
00201       CustomSampleFunc custom_sample_func_;
00202       CustomLikelihoodFunc custom_likelihood_func_;
00203     private:
00204     };
00205   }
00206 }
00207 
00208 #endif


jsk_pcl_ros
Author(s): Yohei Kakiuchi
autogenerated on Sun Oct 8 2017 02:43:50