36 #ifndef JSK_PCL_ROS_PARTICLE_FILTER_TRACKING_H_ 37 #define JSK_PCL_ROS_PARTICLE_FILTER_TRACKING_H_ 42 #include <sensor_msgs/PointCloud2.h> 43 #include <visualization_msgs/Marker.h> 49 #include <boost/circular_buffer.hpp> 51 #include <pcl/point_types.h> 52 #include <pcl/common/centroid.h> 53 #include <pcl/common/transforms.h> 55 #include <pcl/search/pcl_search.h> 56 #include <pcl/common/transforms.h> 58 #include <pcl/tracking/tracking.h> 59 #include <pcl/tracking/particle_filter.h> 60 #include <pcl/tracking/kld_adaptive_particle_filter_omp.h> 61 #include <pcl/tracking/particle_filter_omp.h> 62 #include <pcl/tracking/coherence.h> 63 #include <pcl/tracking/distance_coherence.h> 64 #include <pcl/tracking/hsv_color_coherence.h> 65 #include <pcl/tracking/approx_nearest_pair_point_cloud_coherence.h> 66 #include <pcl/tracking/nearest_pair_point_cloud_coherence.h> 68 #include <jsk_recognition_msgs/SetPointCloud2.h> 69 #include <jsk_pcl_ros/ParticleFilterTrackingConfig.h> 70 #include <jsk_recognition_msgs/BoundingBox.h> 72 #include <dynamic_reconfigure/server.h> 77 #include <pcl/tracking/particle_filter.h> 78 #include <pcl/tracking/impl/tracking.hpp> 79 #include <pcl/tracking/impl/particle_filter.hpp> 81 #include <std_msgs/Float32.h> 83 #include <visualization_msgs/MarkerArray.h> 84 #include <jsk_recognition_msgs/TrackerStatus.h> 98 template <
typename Po
intInT,
typename StateT>
102 using Tracker<PointInT, StateT>::tracker_name_;
103 using Tracker<PointInT, StateT>::search_;
104 using Tracker<PointInT, StateT>::input_;
105 using Tracker<PointInT, StateT>::indices_;
106 using Tracker<PointInT, StateT>::getClassName;
107 using ParticleFilterTracker<PointInT, StateT>::particles_;
108 using ParticleFilterTracker<PointInT, StateT>::change_detector_;
109 using ParticleFilterTracker<PointInT, StateT>::change_counter_;
110 using ParticleFilterTracker<PointInT, StateT>::change_detector_resolution_;
111 using ParticleFilterTracker<PointInT, StateT>::change_detector_interval_;
112 using ParticleFilterTracker<PointInT, StateT>::use_change_detector_;
113 using ParticleFilterTracker<PointInT, StateT>::alpha_;
114 using ParticleFilterTracker<PointInT, StateT>::changed_;
115 using ParticleFilterTracker<PointInT, StateT>::ref_;
116 using ParticleFilterTracker<PointInT, StateT>::coherence_;
117 using ParticleFilterTracker<PointInT, StateT>::use_normal_;
118 using ParticleFilterTracker<PointInT, StateT>::particle_num_;
119 using ParticleFilterTracker<PointInT, StateT>::change_detector_filter_;
120 using ParticleFilterTracker<PointInT, StateT>::transed_reference_vector_;
122 using ParticleFilterTracker<PointInT, StateT>::normalizeWeight;
123 using ParticleFilterTracker<PointInT, StateT>::initParticles;
124 using ParticleFilterTracker<PointInT, StateT>::normalizeParticleWeight;
125 using ParticleFilterTracker<PointInT, StateT>::calcBoundingBox;
151 coherence_->setTargetCloud (ref_);
152 coherence_->initCompute ();
155 PCL_ERROR(
"coherence_ is not yet available!");
165 if (!Tracker<PointInT, StateT>::initCompute ())
167 PCL_ERROR (
"[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
172 if (transed_input_vector_.empty ())
176 transed_input_vector_.resize (particle_num_ + 1);
177 for (
int i = 0; i < particle_num_ + 1; i++)
188 if (!change_detector_)
191 if (!particles_ || particles_->points.empty ())
192 initParticles (
true);
198 (
const StateT& hypothesis, PointCloudIn &cloud)
200 const Eigen::Affine3f trans = this->toEigenMatrix (hypothesis);
202 pcl::transformPointCloud<PointInT> (*input_, cloud, trans);
211 for (
size_t i = 0; i < particles_->points.size (); i++)
215 StateT inverse_particle;
216 Eigen::Affine3f trans = particles_->points[i].toEigenMatrix();
217 Eigen::Affine3f inverse_trans = trans.inverse();
218 inverse_particle = StateT::toState(inverse_trans);
221 coherence_->compute (transed_input_vector_[i], indices, particles_->points[i].weight);
226 for (
size_t i = 0; i < particles_->points.size (); i++)
228 StateT inverse_particle;
229 Eigen::Affine3f trans = particles_->points[i].toEigenMatrix();
230 Eigen::Affine3f inverse_trans = trans.inverse();
231 inverse_particle = StateT::toState(inverse_trans);
232 IndicesPtr indices (
new std::vector<int>);
233 this->computeTransformedPointCloudWithNormal (inverse_particle, *indices, *transed_input_vector_[i]);
234 coherence_->compute (transed_input_vector_[i], indices, particles_->points[i].weight);
244 template <
typename Po
intInT,
typename StateT>
248 using Tracker<PointInT, StateT>::tracker_name_;
249 using Tracker<PointInT, StateT>::search_;
250 using Tracker<PointInT, StateT>::input_;
251 using Tracker<PointInT, StateT>::indices_;
252 using Tracker<PointInT, StateT>::getClassName;
253 using ParticleFilterTracker<PointInT, StateT>::particles_;
254 using ParticleFilterTracker<PointInT, StateT>::change_detector_;
255 using ParticleFilterTracker<PointInT, StateT>::change_counter_;
256 using ParticleFilterTracker<PointInT, StateT>::change_detector_resolution_;
257 using ParticleFilterTracker<PointInT, StateT>::change_detector_interval_;
258 using ParticleFilterTracker<PointInT, StateT>::use_change_detector_;
259 using ParticleFilterTracker<PointInT, StateT>::alpha_;
260 using ParticleFilterTracker<PointInT, StateT>::changed_;
261 using ParticleFilterTracker<PointInT, StateT>::ref_;
262 using ParticleFilterTracker<PointInT, StateT>::coherence_;
263 using ParticleFilterTracker<PointInT, StateT>::use_normal_;
264 using ParticleFilterTracker<PointInT, StateT>::particle_num_;
265 using ParticleFilterTracker<PointInT, StateT>::change_detector_filter_;
266 using ParticleFilterTracker<PointInT, StateT>::transed_reference_vector_;
268 using ParticleFilterTracker<PointInT, StateT>::normalizeWeight;
269 using ParticleFilterTracker<PointInT, StateT>::initParticles;
270 using ParticleFilterTracker<PointInT, StateT>::normalizeParticleWeight;
271 using ParticleFilterTracker<PointInT, StateT>::calcBoundingBox;
298 , threads_ (nr_threads)
300 tracker_name_ =
"ReversedParticleFilterOMPTracker";
314 #pragma omp parallel for num_threads(threads_) 316 for (
size_t i = 0; i < particles_->points.size (); i++)
320 StateT inverse_particle;
321 Eigen::Affine3f trans = particles_->points[i].toEigenMatrix();
322 Eigen::Affine3f inverse_trans = trans.inverse();
323 inverse_particle = StateT::toState(inverse_trans);
327 coherence_->compute (transed_input_vector_[i], indices, particles_->points[i].weight);
335 #pragma omp parallel for num_threads(threads_) 337 for (
size_t i = 0; i < particles_->points.size (); i++)
339 StateT inverse_particle;
340 Eigen::Affine3f trans = particles_->points[i].toEigenMatrix();
341 Eigen::Affine3f inverse_trans = trans.inverse();
342 inverse_particle = StateT::toState(inverse_trans);
343 IndicesPtr indices (
new std::vector<int>);
344 this->computeTransformedPointCloudWithNormal (inverse_particle, *indices, *transed_input_vector_[i]);
345 coherence_->compute (transed_input_vector_[i], indices, particles_->points[i].weight);
350 for (
size_t i = 0; i < particles_->points.size (); i++)
358 template <
typename Po
intInT>
362 typedef typename ApproxNearestPairPointCloudCoherence<PointInT>::PointCoherencePtr
PointCoherencePtr;
365 using ApproxNearestPairPointCloudCoherence<PointInT>::maximum_distance_;
366 using ApproxNearestPairPointCloudCoherence<PointInT>::target_input_;
367 using ApproxNearestPairPointCloudCoherence<PointInT>::point_coherences_;
368 using ApproxNearestPairPointCloudCoherence<PointInT>::coherence_name_;
369 using ApproxNearestPairPointCloudCoherence<PointInT>::new_target_;
370 using ApproxNearestPairPointCloudCoherence<PointInT>::getClassName;
371 using ApproxNearestPairPointCloudCoherence<PointInT>::search_;
376 const double bin_z) :
377 ApproxNearestPairPointCloudCoherence<PointInT> (),
378 bin_x_(bin_x), bin_y_(bin_y), bin_z_(bin_z)
380 coherence_name_ =
"CachedApproxNearestPairPointCloudCoherence";
386 computeCoherence (
const PointCloudInConstPtr &cloud,
const IndicesConstPtr &indices,
float &w_j)
388 boost::mutex::scoped_lock
lock(cache_mutex_);
391 for (
size_t i = 0; i < cloud->points.size (); i++)
393 PointInT input_point = cloud->points[i];
395 computeBin(input_point.getVector3fMap(), xi, yi, zi);
397 if (checkCache(xi, yi, zi)) {
398 k_index = getCachedIndex(xi, yi, zi);
401 float k_distance = 0.0;
402 search_->approxNearestSearch(input_point, k_index, k_distance);
403 registerCache(k_index, xi, yi, zi);
405 PointInT target_point = target_input_->points[k_index];
406 float dist = (target_point.getVector3fMap() - input_point.getVector3fMap()).norm();
407 if (dist < maximum_distance_)
409 double coherence_val = 1.0;
410 for (
size_t i = 0; i < point_coherences_.size (); i++)
412 PointCoherencePtr coherence = point_coherences_[i];
413 double w = coherence->compute (input_point, target_point);
416 val += coherence_val;
419 w_j = -
static_cast<float> (val);
424 const Eigen::Vector3f& p,
int& xi,
int& yi,
int& zi)
426 xi = (int)(p[0]/bin_x_);
427 yi = (int)(p[1]/bin_y_);
428 zi = (int)(p[2]/bin_z_);
434 if (cache_.find(bin_x) == cache_.end()) {
435 cache_[bin_x] = std::map<int, std::map<int, int> >();
437 if (cache_[bin_x].find(bin_y) == cache_[bin_x].end()) {
438 cache_[bin_x][bin_y] = std::map<int, int>();
440 cache_[bin_x][bin_y][bin_z] = k_index;
446 return cache_[bin_x][bin_y][bin_z];
452 if (cache_.find(bin_x) == cache_.end()) {
456 if (cache_[bin_x].find(bin_y) == cache_[bin_x].end()) {
460 if (cache_[bin_x][bin_y].find(bin_z) == cache_[bin_x][bin_y].end()) {
472 boost::mutex::scoped_lock
lock(cache_mutex_);
478 if (!ApproxNearestPairPointCloudCoherence<PointInT>::initCompute ())
480 PCL_ERROR (
"[pcl::%s::initCompute] PointCloudCoherence::Init failed.\n", getClassName ().c_str ());
489 typedef std::map<int, std::map<int, std::map<int, int> > >
CacheMap;
499 template <
typename Po
intInT>
503 using NearestPairPointCloudCoherence<PointInT>::target_input_;
504 using NearestPairPointCloudCoherence<PointInT>::new_target_;
505 using NearestPairPointCloudCoherence<PointInT>::getClassName;
510 if (!PointCloudCoherence<PointInT>::initCompute ())
512 PCL_ERROR (
"[pcl::%s::initCompute] PointCloudCoherence::Init failed.\n", getClassName ().c_str ());
519 search_.reset (
new pcl::search::OrganizedNeighbor<PointInT> (
false));
521 if (new_target_ && target_input_)
523 search_->setInputCloud (target_input_);
524 if (!search_->isValid())
542 typedef ParticleFilterTrackingConfig
Config;
544 sensor_msgs::PointCloud2,
547 sensor_msgs::PointCloud2,
549 typedef ParticleFilterTracker<PointT, ParticleXYZRPY>::PointCloudStatePtr
626 virtual void publish_particles();
627 virtual void publish_result();
628 virtual std::string reference_frame_id();
629 virtual void reset_tracking_target_model(
630 const pcl::PointCloud<PointT>::ConstPtr &new_target_cloud);
632 pcl::PointCloud<PointT>::Ptr cloud);
633 virtual double rms(boost::circular_buffer<double>& buffer) {
635 for (
size_t i = 0; i < buffer.size(); i++) {
636 res += buffer[i] * buffer[i];
638 return sqrt(res / buffer.size());
640 virtual void cloud_cb(
const sensor_msgs::PointCloud2 &pc);
641 virtual void cloud_change_cb(
const sensor_msgs::PointCloud2::ConstPtr &pc,
const sensor_msgs::PointCloud2::ConstPtr &chnage_cloud);
642 virtual bool renew_model_cb(
643 jsk_recognition_msgs::SetPointCloud2::Request &
req,
644 jsk_recognition_msgs::SetPointCloud2::Response &response);
645 virtual void renew_model_with_box_topic_cb(
646 const sensor_msgs::PointCloud2::ConstPtr &pc_ptr,
647 const jsk_recognition_msgs::BoundingBox::ConstPtr &bb_ptr);
648 virtual void renew_model_topic_cb(
const sensor_msgs::PointCloud2 &pc);
649 virtual void renew_model_with_marker_topic_cb(
const visualization_msgs::Marker &
marker);
651 virtual void publish_tracker_status(
const std_msgs::Header&
header,
652 const bool is_tracking);
658 virtual void tracker_set_trans(
const Eigen::Affine3f& trans);
659 virtual void tracker_set_step_noise_covariance(
660 const std::vector<double>& covariance);
661 virtual void tracker_set_initial_noise_covariance(
662 const std::vector<double>& covariance);
663 virtual void tracker_set_initial_noise_mean(
664 const std::vector<double>&
mean);
665 virtual void tracker_set_iteration_num(
const int num);
666 virtual void tracker_set_particle_num(
const int num);
667 virtual void tracker_set_resample_likelihood_thr(
double thr);
668 virtual void tracker_set_use_normal(
bool use_normal);
669 virtual void tracker_set_cloud_coherence(
670 ApproxNearestPairPointCloudCoherence<PointT>::Ptr coherence);
671 virtual void tracker_set_maximum_particle_num(
int num);
672 virtual void tracker_set_delta(
double delta);
673 virtual void tracker_set_epsilon(
double epsilon);
674 virtual void tracker_set_bin_size(
const ParticleXYZRPY bin_size);
675 virtual ParticleFilterTracker<PointT, ParticleXYZRPY>::PointCloudStatePtr
676 tracker_get_particles();
677 virtual ParticleXYZRPY tracker_get_result();
678 virtual Eigen::Affine3f tracker_to_eigen_matrix(
679 const ParticleXYZRPY&
result);
680 virtual pcl::PointCloud<PointT>::ConstPtr tracker_get_reference_cloud();
681 virtual void tracker_set_reference_cloud(pcl::PointCloud<PointT>::Ptr ref);
682 virtual void tracker_reset_tracking();
683 virtual void tracker_set_input_cloud(pcl::PointCloud<PointT>::Ptr input);
684 virtual void tracker_compute();
690 virtual void onInit();
ParticleFilterTracker< PointT, ParticleXYZRPY >::PointCloudStatePtr PointCloudStatePtr
ros::Publisher pub_no_move_
PointCloudCoherence< PointInT > CloudCoherence
void setNumberOfThreads(unsigned int nr_threads=0)
ros::Publisher pub_rms_distance_
virtual void computeCoherence(const PointCloudInConstPtr &cloud, const IndicesConstPtr &indices, float &w_j)
compute the nearest pairs and compute coherence using point_coherences_
void setReferenceCloud(const PointCloudInConstPtr &ref)
PointCloudIn::Ptr PointCloudInPtr
boost::shared_ptr< ReversedParticleFilterOMPTracker< PointT, ParticleXYZRPY > > reversed_tracker_
ros::Publisher track_result_publisher_
bool not_use_reference_centroid_
boost::shared_ptr< dynamic_reconfigure::Server< Config > > srv_
jsk_recognition_utils::WallDurationTimer timer_
Tracker< PointInT, StateT > BaseClass
boost::shared_ptr< const CloudCoherence > CloudCoherenceConstPtr
pcl::PointCloud< PointT >::Ptr cloud_pass_downsampled_
PointCloudIn::ConstPtr PointCloudInConstPtr
std::map< int, std::map< int, std::map< int, int > > > CacheMap
double static_velocity_thr_
virtual bool initCompute()
boost::shared_ptr< const Coherence > CoherenceConstPtr
virtual bool initCompute()
ros::Subscriber sub_update_with_marker_model_
PointCloudState::Ptr PointCloudStatePtr
ros::Publisher pub_rms_angle_
jsk_recognition_utils::SeriesedBoolean no_move_buffer_
PointCloudState::ConstPtr PointCloudStateConstPtr
boost::circular_buffer< double > distance_error_buffer_
virtual double rms(boost::circular_buffer< double > &buffer)
virtual void registerCache(int k_index, int bin_x, int bin_y, int bin_z)
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_input_
bool use_change_detection_
double resample_likelihood_thr_
ros::ServiceServer renew_model_srv_
boost::shared_ptr< message_filters::Synchronizer< SyncChangePolicy > > change_sync_
PointCloudState::ConstPtr PointCloudStateConstPtr
ros::Publisher pub_latest_time_
virtual int getCachedIndex(int bin_x, int bin_y, int bin_z)
boost::shared_ptr< CloudCoherence > CloudCoherencePtr
ParticleFilterTrackingConfig Config
pcl::PointCloud< PointT >::Ptr target_cloud_
virtual bool initCompute()
boost::shared_ptr< pcl::search::OrganizedNeighbor< PointInT > > search_
std::string base_frame_id_
tf::TransformListener * listener_
Tracker< PointInT, StateT > BaseClass
double change_cloud_near_threshold_
std::vector< double > default_step_covariance_
message_filters::sync_policies::ExactTime< sensor_msgs::PointCloud2, jsk_recognition_msgs::BoundingBox > SyncPolicy
PointCloudIn::Ptr PointCloudInPtr
Tracker< PointInT, StateT >::PointCloudState PointCloudState
std::string track_target_name_
virtual void clearCache()
boost::shared_ptr< const Coherence > CoherenceConstPtr
PointCloudCoherence< PointInT > CloudCoherence
pcl::PointCloud< PointT >::Ptr cloud_pass_
PointCoherence< PointInT > Coherence
ApproxNearestPairPointCloudCoherence< PointInT >::PointCoherencePtr PointCoherencePtr
ros::Publisher pose_stamped_publisher_
boost::shared_ptr< const CloudCoherence > CloudCoherenceConstPtr
std::vector< PointCloudInPtr > transed_input_vector_
PointCloudState::Ptr PointCloudStatePtr
boost::mutex cache_mutex_
ParticleXYZRPY prev_result_
tf::Transform reference_transform_
int marker_to_pointcloud_sampling_nums_
CachedApproxNearestPairPointCloudCoherence(const double bin_x, const double bin_y, const double bin_z)
empty constructor
ros::Publisher pub_no_move_raw_
boost::shared_ptr< KLDAdaptiveParticleFilterOMPTracker< PointT, ParticleXYZRPY > > tracker_
boost::circular_buffer< double > angle_error_buffer_
Tracker< PointInT, StateT >::PointCloudState PointCloudState
boost::mutex mutex
global mutex.
virtual void unsubscribe()
PointCloudIn::ConstPtr PointCloudInConstPtr
virtual void computeBin(const Eigen::Vector3f &p, int &xi, int &yi, int &zi)
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_change_cloud_
ApproxNearestPairPointCloudCoherence< PointInT >::PointCloudInConstPtr PointCloudInConstPtr
void computeTransformedPointCloudWithoutNormal(const StateT &hypothesis, PointCloudIn &cloud)
ros::Publisher particle_publisher_
virtual bool checkCache(int bin_x, int bin_y, int bin_z)
boost::shared_ptr< Coherence > CoherencePtr
boost::shared_ptr< message_filters::Synchronizer< SyncPolicy > > sync_
ros::Publisher pub_skipped_
boost::shared_ptr< CloudCoherence > CloudCoherencePtr
message_filters::sync_policies::ExactTime< sensor_msgs::PointCloud2, sensor_msgs::PointCloud2 > SyncChangePolicy
ros::Publisher pub_velocity_norm_
message_filters::Subscriber< jsk_recognition_msgs::BoundingBox > sub_box_
ReversedParticleFilterOMPTracker(unsigned int nr_threads=0)
Eigen::Affine3f initial_pose_
Tracker< PointInT, StateT >::PointCloudIn PointCloudIn
message_filters::Subscriber< sensor_msgs::PointCloud2 > sub_input_cloud_
ros::Publisher pub_average_time_
Tracker< PointInT, StateT >::PointCloudIn PointCloudIn
PointCoherence< PointInT > Coherence
ros::Publisher pub_velocity_
ros::Subscriber sub_update_model_
boost::shared_ptr< Coherence > CoherencePtr
ros::Publisher pub_change_cloud_marker_
ros::Publisher pub_tracker_status_