particle_filter_tracking.h
Go to the documentation of this file.
00001 // -*- mode: C++ -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2013, Yuto Inagaki and 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 #ifndef JSK_PCL_ROS_PARTICLE_FILTER_TRACKING_H_
00037 #define JSK_PCL_ROS_PARTICLE_FILTER_TRACKING_H_
00038 
00039 // ros
00040 #include <ros/ros.h>
00041 #include <ros/names.h>
00042 #include <sensor_msgs/PointCloud2.h>
00043 #include <visualization_msgs/Marker.h>
00044 #include <tf/transform_broadcaster.h>
00045 #include <tf_conversions/tf_eigen.h>
00046 #include <jsk_recognition_utils/pcl_conversion_util.h>
00047 #include <jsk_topic_tools/connection_based_nodelet.h>
00048 #include <jsk_recognition_utils/tf_listener_singleton.h>
00049 #include <boost/circular_buffer.hpp>
00050 // pcl
00051 #include <pcl/point_types.h>
00052 #include <pcl/common/centroid.h>
00053 #include <pcl/common/transforms.h>
00054 
00055 #include <pcl/search/pcl_search.h>
00056 #include <pcl/common/transforms.h>
00057 
00058 #include <pcl/tracking/tracking.h>
00059 #include <pcl/tracking/particle_filter.h>
00060 #include <pcl/tracking/kld_adaptive_particle_filter_omp.h>
00061 #include <pcl/tracking/particle_filter_omp.h>
00062 #include <pcl/tracking/coherence.h>
00063 #include <pcl/tracking/distance_coherence.h>
00064 #include <pcl/tracking/hsv_color_coherence.h>
00065 #include <pcl/tracking/approx_nearest_pair_point_cloud_coherence.h>
00066 #include <pcl/tracking/nearest_pair_point_cloud_coherence.h>
00067 
00068 #include <jsk_recognition_msgs/SetPointCloud2.h>
00069 #include <jsk_pcl_ros/ParticleFilterTrackingConfig.h>
00070 #include <jsk_recognition_msgs/BoundingBox.h>
00071 
00072 #include <dynamic_reconfigure/server.h>
00073 #include <message_filters/subscriber.h>
00074 #include <message_filters/time_synchronizer.h>
00075 #include <message_filters/synchronizer.h>
00076 
00077 #include <pcl/tracking/particle_filter.h>
00078 #include <pcl/tracking/impl/tracking.hpp>
00079 #include <pcl/tracking/impl/particle_filter.hpp>
00080 #include <jsk_recognition_utils/time_util.h>
00081 #include <std_msgs/Float32.h>
00082 #include <jsk_recognition_utils/pcl_util.h>
00083 #include <visualization_msgs/MarkerArray.h>
00084 #include <jsk_recognition_msgs/TrackerStatus.h>
00085 // This namespace follows PCL coding style
00086 namespace pcl
00087 {
00088   namespace tracking
00089   {
00090     // hack pcl::tracking
00091     // original tracker assumes that the number of reference points is smaller
00092     // than the number of input.
00093     // ReversedParticleFilterTracker assumues that the number of reference
00094     // points is greater than the number of input.
00095     // So we need to change:
00096     //   1) transform input pointcloud during weight phase with inverse of each particles
00097     //      particle should keep meaning the pose of reference for simplicity.
00098     template <typename PointInT, typename StateT>
00099     class ReversedParticleFilterTracker: public ParticleFilterTracker<PointInT, StateT>
00100     {
00101     public:
00102       using Tracker<PointInT, StateT>::tracker_name_;
00103       using Tracker<PointInT, StateT>::search_;
00104       using Tracker<PointInT, StateT>::input_;
00105       using Tracker<PointInT, StateT>::indices_;
00106       using Tracker<PointInT, StateT>::getClassName;
00107       using ParticleFilterTracker<PointInT, StateT>::particles_;
00108       using ParticleFilterTracker<PointInT, StateT>::change_detector_;
00109       using ParticleFilterTracker<PointInT, StateT>::change_counter_;
00110       using ParticleFilterTracker<PointInT, StateT>::change_detector_resolution_;
00111       using ParticleFilterTracker<PointInT, StateT>::change_detector_interval_;
00112       using ParticleFilterTracker<PointInT, StateT>::use_change_detector_;
00113       using ParticleFilterTracker<PointInT, StateT>::alpha_;
00114       using ParticleFilterTracker<PointInT, StateT>::changed_;
00115       using ParticleFilterTracker<PointInT, StateT>::ref_;
00116       using ParticleFilterTracker<PointInT, StateT>::coherence_;
00117       using ParticleFilterTracker<PointInT, StateT>::use_normal_;
00118       using ParticleFilterTracker<PointInT, StateT>::particle_num_;
00119       using ParticleFilterTracker<PointInT, StateT>::change_detector_filter_;
00120       using ParticleFilterTracker<PointInT, StateT>::transed_reference_vector_;
00121       //using ParticleFilterTracker<PointInT, StateT>::calcLikelihood;
00122       using ParticleFilterTracker<PointInT, StateT>::normalizeWeight;
00123       using ParticleFilterTracker<PointInT, StateT>::initParticles;
00124       using ParticleFilterTracker<PointInT, StateT>::normalizeParticleWeight;
00125       using ParticleFilterTracker<PointInT, StateT>::calcBoundingBox;
00126 
00127       typedef Tracker<PointInT, StateT> BaseClass;
00128       
00129       typedef typename Tracker<PointInT, StateT>::PointCloudIn PointCloudIn;
00130       typedef typename PointCloudIn::Ptr PointCloudInPtr;
00131       typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr;
00132 
00133       typedef typename Tracker<PointInT, StateT>::PointCloudState PointCloudState;
00134       typedef typename PointCloudState::Ptr PointCloudStatePtr;
00135       typedef typename PointCloudState::ConstPtr PointCloudStateConstPtr;
00136 
00137       typedef PointCoherence<PointInT> Coherence;
00138       typedef boost::shared_ptr< Coherence > CoherencePtr;
00139       typedef boost::shared_ptr< const Coherence > CoherenceConstPtr;
00140 
00141       typedef PointCloudCoherence<PointInT> CloudCoherence;
00142       typedef boost::shared_ptr< CloudCoherence > CloudCoherencePtr;
00143       typedef boost::shared_ptr< const CloudCoherence > CloudCoherenceConstPtr;
00144 
00145       // call initCompute only if reference pointcloud is updated
00146       inline void
00147       setReferenceCloud (const PointCloudInConstPtr &ref)
00148       {
00149         ref_ = ref;
00150         if (coherence_) {
00151           coherence_->setTargetCloud (ref_);
00152           coherence_->initCompute ();
00153         }
00154         else {
00155           PCL_ERROR("coherence_ is not yet available!");
00156         }
00157       }
00158 
00159 
00160     protected:
00161       std::vector<PointCloudInPtr> transed_input_vector_;
00162       
00163       virtual bool initCompute()
00164       {
00165         if (!Tracker<PointInT, StateT>::initCompute ())
00166         {
00167           PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
00168           return (false);
00169         }
00170         
00171         // allocate pointclouds in transed_input_vector_ instead of transed_reference_vector_
00172         if (transed_input_vector_.empty ())
00173         {
00174           //std::cout << "initializing " << particle_num_ << " input" << std::endl;
00175           // only one time allocation
00176           transed_input_vector_.resize (particle_num_ + 1);
00177           for (int i = 0; i < particle_num_ + 1; i++)
00178           {
00179             transed_input_vector_[i] = PointCloudInPtr (new PointCloudIn ());
00180           }
00181         }
00182 
00183         // set reference instead of input
00184         // if (coherence_) {
00185         //   coherence_->setTargetCloud (ref_);
00186         // }
00187           
00188         if (!change_detector_)
00189           change_detector_ = boost::shared_ptr<pcl::octree::OctreePointCloudChangeDetector<PointInT> >(new pcl::octree::OctreePointCloudChangeDetector<PointInT> (change_detector_resolution_));
00190           
00191         if (!particles_ || particles_->points.empty ())
00192           initParticles (true);
00193         return (true);
00194       }
00195 
00196       // only is computation without normal supported
00197       void computeTransformedPointCloudWithoutNormal
00198       (const StateT& hypothesis, PointCloudIn &cloud)
00199         {
00200           const Eigen::Affine3f trans = this->toEigenMatrix (hypothesis);
00201           // destructively assigns to cloud
00202           pcl::transformPointCloud<PointInT> (*input_, cloud, trans);
00203         }
00204 
00205       
00206       virtual void weight()
00207       {
00208         changed_ = true;
00209         if (!use_normal_)
00210         {
00211           for (size_t i = 0; i < particles_->points.size (); i++)
00212           {
00213             //std::cout << "processing " << i << " particle: " << particles_->points[i].weight << std::endl;
00214             // compute `inverse` of particle
00215             StateT inverse_particle;
00216             Eigen::Affine3f trans = particles_->points[i].toEigenMatrix();
00217             Eigen::Affine3f inverse_trans = trans.inverse();
00218             inverse_particle = StateT::toState(inverse_trans);
00219             computeTransformedPointCloudWithoutNormal (inverse_particle, *transed_input_vector_[i]);
00220             IndicesPtr indices;
00221             coherence_->compute (transed_input_vector_[i], indices, particles_->points[i].weight);
00222           }
00223         }
00224         else
00225         {
00226           for (size_t i = 0; i < particles_->points.size (); i++)
00227           {
00228             StateT inverse_particle;
00229             Eigen::Affine3f trans = particles_->points[i].toEigenMatrix();
00230             Eigen::Affine3f inverse_trans = trans.inverse();
00231             inverse_particle = StateT::toState(inverse_trans);
00232             IndicesPtr indices (new std::vector<int>);
00233             this->computeTransformedPointCloudWithNormal (inverse_particle, *indices, *transed_input_vector_[i]);
00234             coherence_->compute (transed_input_vector_[i], indices, particles_->points[i].weight);
00235           }
00236         }
00237   
00238         normalizeWeight ();
00239         
00240       }
00241     private:
00242     };
00243     
00244     template <typename PointInT, typename StateT>
00245     class ReversedParticleFilterOMPTracker: public ReversedParticleFilterTracker<PointInT, StateT>
00246     {
00247     public:
00248       using Tracker<PointInT, StateT>::tracker_name_;
00249       using Tracker<PointInT, StateT>::search_;
00250       using Tracker<PointInT, StateT>::input_;
00251       using Tracker<PointInT, StateT>::indices_;
00252       using Tracker<PointInT, StateT>::getClassName;
00253       using ParticleFilterTracker<PointInT, StateT>::particles_;
00254       using ParticleFilterTracker<PointInT, StateT>::change_detector_;
00255       using ParticleFilterTracker<PointInT, StateT>::change_counter_;
00256       using ParticleFilterTracker<PointInT, StateT>::change_detector_resolution_;
00257       using ParticleFilterTracker<PointInT, StateT>::change_detector_interval_;
00258       using ParticleFilterTracker<PointInT, StateT>::use_change_detector_;
00259       using ParticleFilterTracker<PointInT, StateT>::alpha_;
00260       using ParticleFilterTracker<PointInT, StateT>::changed_;
00261       using ParticleFilterTracker<PointInT, StateT>::ref_;
00262       using ParticleFilterTracker<PointInT, StateT>::coherence_;
00263       using ParticleFilterTracker<PointInT, StateT>::use_normal_;
00264       using ParticleFilterTracker<PointInT, StateT>::particle_num_;
00265       using ParticleFilterTracker<PointInT, StateT>::change_detector_filter_;
00266       using ParticleFilterTracker<PointInT, StateT>::transed_reference_vector_;
00267       //using ParticleFilterTracker<PointInT, StateT>::calcLikelihood;
00268       using ParticleFilterTracker<PointInT, StateT>::normalizeWeight;
00269       using ParticleFilterTracker<PointInT, StateT>::initParticles;
00270       using ParticleFilterTracker<PointInT, StateT>::normalizeParticleWeight;
00271       using ParticleFilterTracker<PointInT, StateT>::calcBoundingBox;
00272 
00273       typedef Tracker<PointInT, StateT> BaseClass;
00274       
00275       typedef typename Tracker<PointInT, StateT>::PointCloudIn PointCloudIn;
00276       typedef typename PointCloudIn::Ptr PointCloudInPtr;
00277       typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr;
00278 
00279       typedef typename Tracker<PointInT, StateT>::PointCloudState PointCloudState;
00280       typedef typename PointCloudState::Ptr PointCloudStatePtr;
00281       typedef typename PointCloudState::ConstPtr PointCloudStateConstPtr;
00282 
00283       typedef PointCoherence<PointInT> Coherence;
00284       typedef boost::shared_ptr< Coherence > CoherencePtr;
00285       typedef boost::shared_ptr< const Coherence > CoherenceConstPtr;
00286 
00287       typedef PointCloudCoherence<PointInT> CloudCoherence;
00288       typedef boost::shared_ptr< CloudCoherence > CloudCoherencePtr;
00289       typedef boost::shared_ptr< const CloudCoherence > CloudCoherenceConstPtr;
00290       using ReversedParticleFilterTracker<PointInT, StateT>::transed_input_vector_;
00291     protected:
00292 
00293       unsigned int threads_;
00294       
00295     public:
00296       ReversedParticleFilterOMPTracker (unsigned int nr_threads = 0)
00297         : ReversedParticleFilterTracker<PointInT, StateT> ()
00298         , threads_ (nr_threads)
00299       {
00300         tracker_name_ = "ReversedParticleFilterOMPTracker";
00301       }
00302 
00303       inline void
00304       setNumberOfThreads (unsigned int nr_threads = 0) { threads_ = nr_threads; }
00305 
00306     protected:
00307       
00308       virtual void weight()
00309       {
00310         changed_ = true;
00311         if (!use_normal_)
00312         {
00313 #ifdef _OPENMP
00314 #pragma omp parallel for num_threads(threads_)
00315 #endif
00316           for (size_t i = 0; i < particles_->points.size (); i++)
00317           {
00318             //std::cout << "processing " << i << " particle: " << particles_->points[i].weight << std::endl;
00319             // compute `inverse` of particle
00320             StateT inverse_particle;
00321             Eigen::Affine3f trans = particles_->points[i].toEigenMatrix();
00322             Eigen::Affine3f inverse_trans = trans.inverse();
00323             inverse_particle = StateT::toState(inverse_trans);
00324             this->computeTransformedPointCloudWithoutNormal (inverse_particle, *transed_input_vector_[i]);
00325             //computeTransformedPointCloudWithoutNormal (particles_->points[i], *transed_input_vector_[i]);
00326             IndicesPtr indices;
00327             coherence_->compute (transed_input_vector_[i], indices, particles_->points[i].weight);
00328             //std::cout << "processing " << i << " particle: " << particles_->points[i].weight << std::endl;
00329             //std::cout << inverse_particle << std::endl;
00330           }
00331         }
00332         else
00333         {
00334 #ifdef _OPENMP
00335 #pragma omp parallel for num_threads(threads_)
00336 #endif
00337           for (size_t i = 0; i < particles_->points.size (); i++)
00338           {
00339             StateT inverse_particle;
00340             Eigen::Affine3f trans = particles_->points[i].toEigenMatrix();
00341             Eigen::Affine3f inverse_trans = trans.inverse();
00342             inverse_particle = StateT::toState(inverse_trans);
00343             IndicesPtr indices (new std::vector<int>);
00344             this->computeTransformedPointCloudWithNormal (inverse_particle, *indices, *transed_input_vector_[i]);
00345             coherence_->compute (transed_input_vector_[i], indices, particles_->points[i].weight);
00346           }
00347         }
00348   
00349         normalizeWeight ();
00350         for (size_t i = 0; i < particles_->points.size (); i++)
00351         {
00352           //std::cout << "normalized " << i << " particle: " << particles_->points[i].weight << std::endl;
00353         }
00354       }
00355     private:
00356     };
00357 
00358     template <typename PointInT>
00359     class CachedApproxNearestPairPointCloudCoherence: public ApproxNearestPairPointCloudCoherence<PointInT>
00360     {
00361     public:
00362       typedef typename ApproxNearestPairPointCloudCoherence<PointInT>::PointCoherencePtr PointCoherencePtr;
00363       typedef typename ApproxNearestPairPointCloudCoherence<PointInT>::PointCloudInConstPtr PointCloudInConstPtr;
00364       //using NearestPairPointCloudCoherence<PointInT>::search_;
00365       using ApproxNearestPairPointCloudCoherence<PointInT>::maximum_distance_;
00366       using ApproxNearestPairPointCloudCoherence<PointInT>::target_input_;
00367       using ApproxNearestPairPointCloudCoherence<PointInT>::point_coherences_;
00368       using ApproxNearestPairPointCloudCoherence<PointInT>::coherence_name_;
00369       using ApproxNearestPairPointCloudCoherence<PointInT>::new_target_;
00370       using ApproxNearestPairPointCloudCoherence<PointInT>::getClassName;
00371       using ApproxNearestPairPointCloudCoherence<PointInT>::search_;
00372       
00374       CachedApproxNearestPairPointCloudCoherence (const double bin_x,
00375                                                   const double bin_y,
00376                                                   const double bin_z) : 
00377         ApproxNearestPairPointCloudCoherence<PointInT> (),
00378         bin_x_(bin_x), bin_y_(bin_y), bin_z_(bin_z)
00379       {
00380         coherence_name_ = "CachedApproxNearestPairPointCloudCoherence";
00381       }
00382       
00383     protected:
00385       virtual void
00386       computeCoherence (const PointCloudInConstPtr &cloud, const IndicesConstPtr &indices, float &w_j)
00387       {
00388         boost::mutex::scoped_lock lock(cache_mutex_);
00389         double val = 0.0;
00390         //for (size_t i = 0; i < indices->size (); i++)
00391         for (size_t i = 0; i < cloud->points.size (); i++)
00392         {
00393           PointInT input_point = cloud->points[i];
00394           int xi, yi, zi;
00395           computeBin(input_point.getVector3fMap(), xi, yi, zi);
00396           int k_index;
00397           if (checkCache(xi, yi, zi)) {
00398             k_index = getCachedIndex(xi, yi, zi);
00399           }
00400           else {
00401             float k_distance = 0.0; // dummy
00402             search_->approxNearestSearch(input_point, k_index, k_distance);
00403             registerCache(k_index, xi, yi, zi);
00404           }
00405           PointInT target_point = target_input_->points[k_index];
00406           float dist = (target_point.getVector3fMap() - input_point.getVector3fMap()).norm();
00407           if (dist < maximum_distance_)
00408           {
00409             double coherence_val = 1.0;
00410             for (size_t i = 0; i < point_coherences_.size (); i++)
00411             {
00412               PointCoherencePtr coherence = point_coherences_[i];  
00413               double w = coherence->compute (input_point, target_point);
00414               coherence_val *= w;
00415             }
00416             val += coherence_val;
00417           }
00418         }
00419         w_j = - static_cast<float> (val);
00420         //ROS_INFO("hit: %d", counter);
00421       }
00422 
00423       virtual void computeBin(
00424         const Eigen::Vector3f& p, int& xi, int& yi, int& zi)
00425       {
00426         xi = (int)(p[0]/bin_x_);
00427         yi = (int)(p[1]/bin_y_);
00428         zi = (int)(p[2]/bin_z_);
00429       }
00430       
00431       virtual void registerCache(int k_index, int bin_x, int bin_y, int bin_z)
00432       {
00433         //boost::mutex::scoped_lock lock(cache_mutex_);
00434         if (cache_.find(bin_x) == cache_.end()) {
00435           cache_[bin_x] = std::map<int, std::map<int, int> >();
00436         }
00437         if (cache_[bin_x].find(bin_y) == cache_[bin_x].end()) {
00438           cache_[bin_x][bin_y] = std::map<int, int>();
00439         }
00440         cache_[bin_x][bin_y][bin_z] = k_index;
00441       }
00442       
00443       virtual int getCachedIndex(int bin_x, int bin_y, int bin_z)
00444       {
00445         //boost::mutex::scoped_lock lock(cache_mutex_);
00446         return cache_[bin_x][bin_y][bin_z];
00447       }
00448       
00449       virtual bool checkCache(int bin_x, int bin_y, int bin_z)
00450       {
00451         //boost::mutex::scoped_lock lock(cache_mutex_);
00452         if (cache_.find(bin_x) == cache_.end()) {
00453           return false;
00454         }
00455         else {
00456           if (cache_[bin_x].find(bin_y) == cache_[bin_x].end()) {
00457             return false;
00458           }
00459           else {
00460             if (cache_[bin_x][bin_y].find(bin_z) == cache_[bin_x][bin_y].end()) {
00461               return false;
00462             }
00463             else {
00464               return true;
00465             }
00466           }
00467         }
00468       }
00469       
00470       virtual void clearCache()
00471       {
00472         boost::mutex::scoped_lock lock(cache_mutex_);
00473         cache_ = CacheMap();
00474       }
00475 
00476       virtual bool initCompute()
00477       {
00478         if (!ApproxNearestPairPointCloudCoherence<PointInT>::initCompute ())
00479         {
00480           PCL_ERROR ("[pcl::%s::initCompute] PointCloudCoherence::Init failed.\n", getClassName ().c_str ());
00481           //deinitCompute ();
00482           return false;
00483         }
00484         clearCache();
00485         return true;
00486       }
00487       
00488       //typename boost::shared_ptr<pcl::search::Octree<PointInT> > search_;
00489       typedef std::map<int, std::map<int, std::map<int, int> > > CacheMap;
00490       CacheMap cache_;
00491       boost::mutex cache_mutex_;
00492       double bin_x_;
00493       double bin_y_;
00494       double bin_z_;
00495       
00496     };
00497 
00498     
00499     template <typename PointInT>
00500     class OrganizedNearestPairPointCloudCoherence: public NearestPairPointCloudCoherence<PointInT>
00501     {
00502     public:
00503       using NearestPairPointCloudCoherence<PointInT>::target_input_;
00504       using NearestPairPointCloudCoherence<PointInT>::new_target_;
00505       using NearestPairPointCloudCoherence<PointInT>::getClassName;
00506       typename boost::shared_ptr<pcl::search::OrganizedNeighbor<PointInT> > search_;
00507     protected:
00508       virtual bool initCompute ()
00509       {
00510         if (!PointCloudCoherence<PointInT>::initCompute ())
00511         {
00512           PCL_ERROR ("[pcl::%s::initCompute] PointCloudCoherence::Init failed.\n", getClassName ().c_str ());
00513           //deinitCompute ();
00514           return (false);
00515         }
00516         
00517         // initialize tree
00518         if (!search_)
00519           search_.reset (new pcl::search::OrganizedNeighbor<PointInT> (false));
00520         
00521         if (new_target_ && target_input_)
00522         {
00523           search_->setInputCloud (target_input_);
00524           if (!search_->isValid())
00525             return false;
00526           new_target_ = false;
00527         }
00528       
00529         return true;
00530       }
00531     };
00532   }  
00533 }
00534 
00535 using namespace pcl::tracking;
00536 namespace jsk_pcl_ros
00537 {
00538   class ParticleFilterTracking: public jsk_topic_tools::ConnectionBasedNodelet
00539   {
00540   public:
00541     typedef pcl::PointXYZRGB PointT;
00542     typedef ParticleFilterTrackingConfig Config;
00543     typedef message_filters::sync_policies::ExactTime<
00544       sensor_msgs::PointCloud2,
00545       jsk_recognition_msgs::BoundingBox > SyncPolicy;
00546     typedef message_filters::sync_policies::ExactTime<
00547       sensor_msgs::PointCloud2,
00548       sensor_msgs::PointCloud2 > SyncChangePolicy;
00549     typedef ParticleFilterTracker<PointT, ParticleXYZRPY>::PointCloudStatePtr
00550     PointCloudStatePtr;
00551     ParticleFilterTracking(): timer_(10), distance_error_buffer_(100), angle_error_buffer_(100), no_move_buffer_(10) {}
00552   protected:
00553     pcl::PointCloud<PointT>::Ptr cloud_pass_;
00554     pcl::PointCloud<PointT>::Ptr cloud_pass_downsampled_;
00555     pcl::PointCloud<PointT>::Ptr target_cloud_;
00556 
00557     //boost::shared_ptr<ParticleFilterTracker<PointT, ParticleXYZRPY> > tracker_;
00558     boost::shared_ptr<KLDAdaptiveParticleFilterOMPTracker<PointT, ParticleXYZRPY> > tracker_;
00559     boost::shared_ptr<ReversedParticleFilterOMPTracker<PointT, ParticleXYZRPY> > reversed_tracker_;
00560     //boost::shared_ptr<ReversedParticleFilterTracker<PointT, ParticleXYZRPY> > reversed_tracker_;
00561     boost::mutex mtx_;
00562     bool new_cloud_;
00563     bool track_target_set_;
00564     bool align_box_;
00565     bool change_frame_;
00566     std::string frame_id_;
00567     std::string base_frame_id_;
00568     std::string track_target_name_;
00569     ros::Time stamp_;
00570     ros::Time prev_stamp_;
00571     tf::Transform reference_transform_;
00572 
00573     ros::Subscriber sub_;
00574     ros::Subscriber sub_update_model_;
00575     ros::Subscriber sub_update_with_marker_model_;
00576     ros::Publisher pub_latest_time_;
00577     ros::Publisher pub_average_time_;
00578     ros::Publisher pub_rms_distance_;
00579     ros::Publisher pub_rms_angle_;
00580     ros::Publisher pub_velocity_;
00581     ros::Publisher pub_velocity_norm_;
00582     ros::Publisher pub_no_move_;
00583     ros::Publisher pub_no_move_raw_;
00584     ros::Publisher pub_skipped_;
00585     ros::Publisher pub_change_cloud_marker_;
00586     ros::Publisher pub_tracker_status_;
00587     jsk_recognition_utils::WallDurationTimer timer_;
00588     Eigen::Affine3f initial_pose_;
00589     boost::circular_buffer<double> distance_error_buffer_;
00590     boost::circular_buffer<double> angle_error_buffer_;
00591 
00592     jsk_recognition_utils::SeriesedBoolean no_move_buffer_;
00593     message_filters::Subscriber<sensor_msgs::PointCloud2> sub_input_;
00594     message_filters::Subscriber<jsk_recognition_msgs::BoundingBox> sub_box_;
00595     message_filters::Subscriber<sensor_msgs::PointCloud2> sub_input_cloud_;
00596     message_filters::Subscriber<sensor_msgs::PointCloud2> sub_change_cloud_;
00597     boost::shared_ptr<message_filters::Synchronizer<SyncPolicy> > sync_;
00598     boost::shared_ptr<message_filters::Synchronizer<SyncChangePolicy> > change_sync_;
00599     ros::Publisher particle_publisher_;
00600     ros::Publisher track_result_publisher_;
00601     ros::Publisher pose_stamped_publisher_;
00602     ros::ServiceServer renew_model_srv_;
00603     boost::shared_ptr <dynamic_reconfigure::Server<Config> > srv_;
00604     tf::TransformListener* listener_;
00605     
00607     // parameters
00609     bool use_change_detection_;
00610     int max_particle_num_;
00611     double delta_;
00612     double epsilon_;
00613     int iteration_num_;
00614     double resample_likelihood_thr_;
00615     ParticleXYZRPY bin_size_;
00616     ParticleXYZRPY prev_result_;
00617     int counter_;
00618     std::vector<double> default_step_covariance_;
00619     bool reversed_;
00620     bool not_use_reference_centroid_;
00621     bool not_publish_tf_;
00622     int marker_to_pointcloud_sampling_nums_;
00623     double static_velocity_thr_;
00624     double change_cloud_near_threshold_;
00625     virtual void config_callback(Config &config, uint32_t level);
00626     virtual void publish_particles();
00627     virtual void publish_result();
00628     virtual std::string reference_frame_id();
00629     virtual void reset_tracking_target_model(
00630       const pcl::PointCloud<PointT>::ConstPtr &new_target_cloud);
00631     virtual tf::Transform change_pointcloud_frame(
00632       pcl::PointCloud<PointT>::Ptr cloud);
00633     virtual double rms(boost::circular_buffer<double>& buffer) {
00634       double res = 0.0;
00635       for (size_t i = 0; i < buffer.size(); i++) {
00636         res += buffer[i] * buffer[i];
00637       }
00638       return sqrt(res / buffer.size());
00639     }
00640     virtual void cloud_cb(const sensor_msgs::PointCloud2 &pc);
00641     virtual void cloud_change_cb(const sensor_msgs::PointCloud2::ConstPtr &pc, const sensor_msgs::PointCloud2::ConstPtr &chnage_cloud);
00642     virtual bool renew_model_cb(
00643       jsk_recognition_msgs::SetPointCloud2::Request &req,
00644       jsk_recognition_msgs::SetPointCloud2::Response &response);
00645     virtual void renew_model_with_box_topic_cb(
00646       const sensor_msgs::PointCloud2::ConstPtr &pc_ptr,
00647       const jsk_recognition_msgs::BoundingBox::ConstPtr &bb_ptr);
00648     virtual void renew_model_topic_cb(const sensor_msgs::PointCloud2 &pc);
00649     virtual void renew_model_with_marker_topic_cb(const visualization_msgs::Marker &marker);
00650 
00651     virtual void publish_tracker_status(const std_msgs::Header& header,
00652                                         const bool is_tracking);
00653 
00654     
00656     // Wrap particle filter methods
00658     virtual void tracker_set_trans(const Eigen::Affine3f& trans);
00659     virtual void tracker_set_step_noise_covariance(
00660       const std::vector<double>& covariance);
00661     virtual void tracker_set_initial_noise_covariance(
00662       const std::vector<double>& covariance);
00663     virtual void tracker_set_initial_noise_mean(
00664       const std::vector<double>& mean);
00665     virtual void tracker_set_iteration_num(const int num);
00666     virtual void tracker_set_particle_num(const int num);
00667     virtual void tracker_set_resample_likelihood_thr(double thr);
00668     virtual void tracker_set_use_normal(bool use_normal);
00669     virtual void tracker_set_cloud_coherence(
00670       ApproxNearestPairPointCloudCoherence<PointT>::Ptr coherence);
00671     virtual void tracker_set_maximum_particle_num(int num);
00672     virtual void tracker_set_delta(double delta);
00673     virtual void tracker_set_epsilon(double epsilon);
00674     virtual void tracker_set_bin_size(const ParticleXYZRPY bin_size);
00675     virtual ParticleFilterTracker<PointT, ParticleXYZRPY>::PointCloudStatePtr
00676     tracker_get_particles();
00677     virtual ParticleXYZRPY tracker_get_result();
00678     virtual Eigen::Affine3f tracker_to_eigen_matrix(
00679       const ParticleXYZRPY& result);
00680     virtual pcl::PointCloud<PointT>::ConstPtr tracker_get_reference_cloud();
00681     virtual void tracker_set_reference_cloud(pcl::PointCloud<PointT>::Ptr ref);
00682     virtual void tracker_reset_tracking();
00683     virtual void tracker_set_input_cloud(pcl::PointCloud<PointT>::Ptr input);
00684     virtual void tracker_compute();
00685 
00686     virtual void subscribe() {}
00687     virtual void unsubscribe() {}    
00688     
00689   private:
00690     virtual void onInit();
00691 
00692   };
00693 }
00694 
00695 #endif


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