00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define BOOST_PARAMETER_MAX_ARITY 7
00036
00037 #include <jsk_topic_tools/log_utils.h>
00038 #include "jsk_pcl_ros/particle_filter_tracking.h"
00039 #include <pcl/tracking/impl/distance_coherence.hpp>
00040 #include <pcl/tracking/impl/approx_nearest_pair_point_cloud_coherence.hpp>
00041 #include <pluginlib/class_list_macros.h>
00042 #include <jsk_topic_tools/rosparam_utils.h>
00043 #include <geometry_msgs/TwistStamped.h>
00044 #include <std_msgs/Bool.h>
00045 #include <pcl/kdtree/kdtree_flann.h>
00046
00047 using namespace pcl::tracking;
00048
00049 namespace jsk_pcl_ros
00050 {
00051
00052 void ParticleFilterTracking::onInit(void)
00053 {
00054 pcl::console::setVerbosityLevel(pcl::console::L_ERROR);
00055
00056 ConnectionBasedNodelet::onInit();
00057
00058 track_target_set_ = false;
00059 new_cloud_ = false;
00060
00061 default_step_covariance_.resize(6);
00062
00063 srv_ = boost::make_shared <dynamic_reconfigure::Server<Config> >(*pnh_);
00064 dynamic_reconfigure::Server<Config>::CallbackType f =
00065 boost::bind(&ParticleFilterTracking::config_callback, this, _1, _2);
00066 srv_->setCallback(f);
00067
00068 int particle_num;
00069 pnh_->param("particle_num", particle_num, max_particle_num_ - 1);
00070 bool use_normal;
00071 pnh_->param("use_normal", use_normal, false);
00072 bool use_hsv;
00073 pnh_->param("use_hsv", use_hsv, true);
00074 pnh_->param("track_target_name", track_target_name_,
00075 std::string("track_result"));
00076 std::vector<double> initial_noise_covariance(6, 0.00001);
00077 jsk_topic_tools::readVectorParameter(
00078 *pnh_, "initial_noise_covariance",
00079 initial_noise_covariance);
00080 std::vector<double> default_initial_mean(6, 0.0);
00081 jsk_topic_tools::readVectorParameter(
00082 *pnh_, "default_initial_mean", default_initial_mean);
00083
00084
00085 double octree_resolution = 0.01;
00086 pnh_->getParam("octree_resolution", octree_resolution);
00087 pnh_->param("align_box", align_box_, false);
00088 pnh_->param("BASE_FRAME_ID", base_frame_id_, std::string("NONE"));
00089 if (base_frame_id_.compare("NONE") != 0) {
00090 listener_ = jsk_recognition_utils::TfListenerSingleton::getInstance();
00091 }
00092 target_cloud_.reset(new pcl::PointCloud<PointT>());
00093 pnh_->param("not_use_reference_centroid", not_use_reference_centroid_,
00094 false);
00095 pnh_->param("not_publish_tf", not_publish_tf_, false);
00096 pnh_->param("reversed", reversed_, false);
00097
00098 int thread_nr;
00099 pnh_->param("thread_nr", thread_nr, omp_get_num_procs());
00100
00101 if (!reversed_) {
00102 boost::shared_ptr<KLDAdaptiveParticleFilterOMPTracker<PointT, ParticleXYZRPY> > tracker
00103 (new KLDAdaptiveParticleFilterOMPTracker<PointT, ParticleXYZRPY>(thread_nr));
00104 tracker->setMaximumParticleNum(max_particle_num_);
00105 tracker->setDelta(delta_);
00106 tracker->setEpsilon(epsilon_);
00107 tracker->setBinSize(bin_size_);
00108 tracker_ = tracker;
00109 }
00110 else {
00111 boost::shared_ptr<ReversedParticleFilterOMPTracker<PointT, ParticleXYZRPY> > tracker
00112 (new ReversedParticleFilterOMPTracker<PointT, ParticleXYZRPY>(thread_nr));
00113
00114
00115 reversed_tracker_ = tracker;
00116 }
00117 tracker_set_trans(Eigen::Affine3f::Identity());
00118 tracker_set_step_noise_covariance(default_step_covariance_);
00119 tracker_set_initial_noise_covariance(initial_noise_covariance);
00120 tracker_set_initial_noise_mean(default_initial_mean);
00121 tracker_set_iteration_num(iteration_num_);
00122 tracker_set_particle_num(particle_num);
00123 tracker_set_resample_likelihood_thr(resample_likelihood_thr_);
00124 tracker_set_use_normal(use_normal);
00125
00126
00127 bool enable_cache;
00128 bool enable_organized;
00129 pnh_->param("enable_cache", enable_cache, false);
00130 pnh_->param("enable_organized", enable_organized, false);
00131 ApproxNearestPairPointCloudCoherence<PointT>::Ptr coherence;
00132 if (enable_cache) {
00133 double cache_bin_size_x, cache_bin_size_y, cache_bin_size_z;
00134 pnh_->param("cache_size_x", cache_bin_size_x, 0.01);
00135 pnh_->param("cache_size_y", cache_bin_size_y, 0.01);
00136 pnh_->param("cache_size_z", cache_bin_size_z, 0.01);
00137 coherence.reset(new CachedApproxNearestPairPointCloudCoherence<PointT>(
00138 cache_bin_size_x, cache_bin_size_y, cache_bin_size_z));
00139 }else if(enable_organized){
00140 coherence.reset(new OrganizedNearestPairPointCloudCoherence<PointT>());
00141 }
00142 else {
00143 coherence.reset(new ApproxNearestPairPointCloudCoherence<PointT>());
00144 }
00145
00146
00147 boost::shared_ptr<DistanceCoherence<PointT> >
00148 distance_coherence(new DistanceCoherence<PointT>);
00149 coherence->addPointCoherence(distance_coherence);
00150
00151
00152 if (use_hsv) {
00153 boost::shared_ptr<HSVColorCoherence<PointT> > hsv_color_coherence
00154 = boost::shared_ptr<HSVColorCoherence<PointT> >(new HSVColorCoherence<PointT>());
00155 coherence->addPointCoherence(hsv_color_coherence);
00156 }
00157
00158 boost::shared_ptr<pcl::search::Octree<PointT> > search
00159 (new pcl::search::Octree<PointT>(octree_resolution));
00160
00161 coherence->setSearchMethod(search);
00162 double max_distance;
00163 pnh_->param("max_distance", max_distance, 0.01);
00164 coherence->setMaximumDistance(max_distance);
00165 pnh_->param("use_change_detection", use_change_detection_, false);
00166 tracker_set_cloud_coherence(coherence);
00167
00168
00169 particle_publisher_ = pnh_->advertise<sensor_msgs::PointCloud2>(
00170 "particle", 1);
00171 track_result_publisher_ = pnh_->advertise<sensor_msgs::PointCloud2>(
00172 "track_result", 1);
00173 pose_stamped_publisher_ = pnh_->advertise<geometry_msgs::PoseStamped>(
00174 "track_result_pose", 1);
00175 pub_latest_time_ = pnh_->advertise<std_msgs::Float32>(
00176 "output/latest_time", 1);
00177 pub_average_time_ = pnh_->advertise<std_msgs::Float32>(
00178 "output/average_time", 1);
00179 pub_rms_angle_ = pnh_->advertise<std_msgs::Float32>(
00180 "output/rms_angle_error", 1);
00181 pub_rms_distance_ = pnh_->advertise<std_msgs::Float32>(
00182 "output/rms_distance_error", 1);
00183 pub_velocity_ = pnh_->advertise<geometry_msgs::TwistStamped>(
00184 "output/velocity", 1);
00185 pub_velocity_norm_ = pnh_->advertise<std_msgs::Float32>(
00186 "output/velocity_norm", 1);
00187 pub_no_move_raw_ = pnh_->advertise<std_msgs::Bool>(
00188 "output/no_move_raw", 1);
00189 pub_no_move_ = pnh_->advertise<std_msgs::Bool>(
00190 "output/no_move", 1);
00191 pub_skipped_ = pnh_->advertise<std_msgs::Bool>(
00192 "output/skipped", 1);
00193
00194 if (use_change_detection_) {
00195 pub_change_cloud_marker_ = pnh_->advertise<visualization_msgs::MarkerArray>(
00196 "output/change_marker", 1);
00197 pub_tracker_status_ = pnh_->advertise<jsk_recognition_msgs::TrackerStatus>(
00198 "output/tracker_status", 1);
00199 sub_input_cloud_.subscribe(*pnh_, "input", 4);
00200 sub_change_cloud_.subscribe(*pnh_, "input_change", 4);
00201 change_sync_ = boost::make_shared<message_filters::Synchronizer<SyncChangePolicy> >(100);
00202 change_sync_->connectInput(sub_input_cloud_, sub_change_cloud_);
00203 change_sync_->registerCallback(
00204 boost::bind(
00205 &ParticleFilterTracking::cloud_change_cb,
00206 this, _1, _2));
00207 }
00208 else {
00209 sub_ = pnh_->subscribe("input", 1, &ParticleFilterTracking::cloud_cb,this);
00210 }
00211 if (align_box_) {
00212 sub_input_.subscribe(*pnh_, "renew_model", 1);
00213 sub_box_.subscribe(*pnh_, "renew_box", 1);
00214 sync_ = boost::make_shared<message_filters::Synchronizer<SyncPolicy> >(100);
00215 sync_->connectInput(sub_input_, sub_box_);
00216 sync_->registerCallback(
00217 boost::bind(
00218 &ParticleFilterTracking::renew_model_with_box_topic_cb,
00219 this, _1, _2));
00220 }
00221 else {
00222 sub_update_model_ = pnh_->subscribe(
00223 "renew_model", 1, &ParticleFilterTracking::renew_model_topic_cb,this);
00224 sub_update_with_marker_model_
00225 = pnh_->subscribe("renew_model_with_marker", 1, &ParticleFilterTracking::renew_model_with_marker_topic_cb, this);
00226 }
00227
00228 pnh_->param("marker_to_pointcloud_sampling_nums", marker_to_pointcloud_sampling_nums_, 10000);
00229 renew_model_srv_
00230 = pnh_->advertiseService(
00231 "renew_model", &ParticleFilterTracking::renew_model_cb, this);
00232
00233 onInitPostProcess();
00234 }
00235
00236 void ParticleFilterTracking::config_callback(Config &config, uint32_t level)
00237 {
00238 boost::mutex::scoped_lock lock(mtx_);
00239 max_particle_num_ = config.max_particle_num;
00240 iteration_num_ = config.iteration_num;
00241 resample_likelihood_thr_ = config.resample_likelihood_thr;
00242 delta_ = config.delta;
00243 epsilon_ = config.epsilon;
00244 bin_size_.x = config.bin_size_x;
00245 bin_size_.y = config.bin_size_y;
00246 bin_size_.z = config.bin_size_z;
00247 bin_size_.roll = config.bin_size_roll;
00248 bin_size_.pitch = config.bin_size_pitch;
00249 bin_size_.yaw = config.bin_size_yaw;
00250 default_step_covariance_[0] = config.default_step_covariance_x;
00251 default_step_covariance_[1] = config.default_step_covariance_y;
00252 default_step_covariance_[2] = config.default_step_covariance_z;
00253 default_step_covariance_[3] = config.default_step_covariance_roll;
00254 default_step_covariance_[4] = config.default_step_covariance_pitch;
00255 default_step_covariance_[5] = config.default_step_covariance_yaw;
00256 static_velocity_thr_ = config.static_velocity_thr;
00257 change_cloud_near_threshold_ = config.change_cloud_near_thr;
00258 if (tracker_ || reversed_tracker_)
00259 {
00260 NODELET_INFO("update tracker parameter");
00261 tracker_set_step_noise_covariance(default_step_covariance_);
00262 tracker_set_iteration_num(iteration_num_);
00263 tracker_set_resample_likelihood_thr(resample_likelihood_thr_);
00264 tracker_set_maximum_particle_num(max_particle_num_);
00265 tracker_set_delta(delta_);
00266 tracker_set_epsilon(epsilon_);
00267 tracker_set_bin_size(bin_size_);
00268 }
00269 }
00270
00271
00272 void ParticleFilterTracking::publish_particles()
00273 {
00274 PointCloudStatePtr particles = tracker_get_particles();
00275 if (particles && new_cloud_ && particle_publisher_.getNumSubscribers()) {
00276
00277 pcl::PointCloud<pcl::PointXYZ>::Ptr particle_cloud
00278 (new pcl::PointCloud<pcl::PointXYZ>());
00279 for (size_t i = 0; i < particles->points.size(); i++)
00280 {
00281 pcl::PointXYZ point;
00282 point.x = particles->points[i].x;
00283 point.y = particles->points[i].y;
00284 point.z = particles->points[i].z;
00285 particle_cloud->points.push_back(point);
00286 }
00287
00288 sensor_msgs::PointCloud2 particle_pointcloud2;
00289 pcl::toROSMsg(*particle_cloud, particle_pointcloud2);
00290 particle_pointcloud2.header.frame_id = reference_frame_id();
00291 particle_pointcloud2.header.stamp = stamp_;
00292 particle_publisher_.publish(particle_pointcloud2);
00293 }
00294 }
00295
00296 void ParticleFilterTracking::publish_result()
00297 {
00298 ParticleXYZRPY result = tracker_get_result();
00299 Eigen::Affine3f transformation = tracker_to_eigen_matrix(result);
00300
00301
00302 tf::Transform tfTransformation;
00303 tf::transformEigenToTF((Eigen::Affine3d) transformation, tfTransformation);
00304
00305 if (!not_publish_tf_) {
00306 static tf::TransformBroadcaster tfBroadcaster;
00307 tfBroadcaster.sendTransform(tf::StampedTransform(
00308 tfTransformation, stamp_,
00309 reference_frame_id(), track_target_name_));
00310 }
00311
00312 geometry_msgs::PoseStamped result_pose_stamped;
00313 result_pose_stamped.header.frame_id = reference_frame_id();
00314 result_pose_stamped.header.stamp = stamp_;
00315 tf::Quaternion q;
00316 tf::poseTFToMsg(tfTransformation, result_pose_stamped.pose);
00317 pose_stamped_publisher_.publish(result_pose_stamped);
00318
00319 pcl::PointCloud<PointT>::Ptr result_cloud
00320 (new pcl::PointCloud<PointT>());
00321 pcl::transformPointCloud<PointT>(
00322 *(tracker_get_reference_cloud()), *result_cloud, transformation);
00323 sensor_msgs::PointCloud2 result_pointcloud2;
00324 pcl::toROSMsg(*result_cloud, result_pointcloud2);
00325 result_pointcloud2.header.frame_id = reference_frame_id();
00326 result_pointcloud2.header.stamp = stamp_;
00327 track_result_publisher_.publish(result_pointcloud2);
00328
00329 if (counter_ > 0) {
00330 geometry_msgs::TwistStamped twist;
00331 twist.header.frame_id = reference_frame_id();
00332 twist.header.stamp = stamp_;
00333 double dt = (stamp_ - prev_stamp_).toSec();
00334 twist.twist.linear.x = (result.x - prev_result_.x) / dt;
00335 twist.twist.linear.y = (result.y - prev_result_.y) / dt;
00336 twist.twist.linear.z = (result.z - prev_result_.z) / dt;
00337 twist.twist.angular.x = (result.roll - prev_result_.roll) / dt;
00338 twist.twist.angular.y = (result.pitch - prev_result_.pitch) / dt;
00339 twist.twist.angular.z = (result.yaw - prev_result_.yaw) / dt;
00340 pub_velocity_.publish(twist);
00341 Eigen::Vector3f vel(twist.twist.linear.x, twist.twist.linear.y, twist.twist.linear.z);
00342 std_msgs::Float32 velocity_norm;
00343 velocity_norm.data = vel.norm();
00344 pub_velocity_norm_.publish(velocity_norm);
00345 bool is_static = vel.norm() < static_velocity_thr_;
00346 no_move_buffer_.addValue(is_static);
00347 std_msgs::Bool no_move_raw, no_move;
00348 no_move_raw.data = is_static;
00349 no_move.data = no_move_buffer_.isAllTrueFilled();
00350 pub_no_move_.publish(no_move);
00351 pub_no_move_raw_.publish(no_move_raw);
00352 }
00353
00354 Eigen::Affine3f diff_trans = transformation.inverse() * initial_pose_;
00355 double distance_error = Eigen::Vector3f(diff_trans.translation()).norm();
00356 double angle_error = Eigen::AngleAxisf(diff_trans.rotation()).angle();
00357 distance_error_buffer_.push_back(distance_error);
00358 angle_error_buffer_.push_back(angle_error);
00359 double distance_rms = rms(distance_error_buffer_);
00360 double angle_rms = rms(angle_error_buffer_);
00361 std_msgs::Float32 ros_distance_rms, ros_angle_rms;
00362 ros_distance_rms.data = distance_rms;
00363 ros_angle_rms.data = angle_rms;
00364 pub_rms_distance_.publish(ros_distance_rms);
00365 pub_rms_angle_.publish(ros_angle_rms);
00366 prev_result_ = result;
00367 prev_stamp_ = stamp_;
00368 ++counter_;
00369 }
00370
00371 std::string ParticleFilterTracking::reference_frame_id()
00372 {
00373 if (base_frame_id_.compare("NONE") == 0) {
00374 return frame_id_;
00375 }
00376 else {
00377 return base_frame_id_;
00378 }
00379 }
00380
00381 void ParticleFilterTracking::reset_tracking_target_model(
00382 const pcl::PointCloud<PointT>::ConstPtr &recieved_target_cloud)
00383 {
00384 pcl::PointCloud<PointT>::Ptr new_target_cloud(new pcl::PointCloud<PointT>);
00385 std::vector<int> indices;
00386 new_target_cloud->is_dense = false;
00387 pcl::removeNaNFromPointCloud(
00388 *recieved_target_cloud, *new_target_cloud, indices);
00389
00390 if (base_frame_id_.compare("NONE") != 0) {
00391 tf::Transform transform_result
00392 = change_pointcloud_frame(new_target_cloud);
00393 reference_transform_ = transform_result * reference_transform_;;
00394 }
00395
00396 if (!recieved_target_cloud->points.empty()) {
00397
00398 Eigen::Affine3f trans = Eigen::Affine3f::Identity();
00399 pcl::PointCloud<PointT>::Ptr transed_ref(new pcl::PointCloud<PointT>);
00400 if (!align_box_) {
00401 if (!not_use_reference_centroid_) {
00402 Eigen::Vector4f c;
00403 pcl::compute3DCentroid(*new_target_cloud, c);
00404 trans.translation().matrix() = Eigen::Vector3f(c[0], c[1], c[2]);
00405 }
00406 }
00407 else {
00408 Eigen::Affine3d trans_3d = Eigen::Affine3d::Identity();
00409 tf::transformTFToEigen(reference_transform_, trans_3d);
00410 trans = (Eigen::Affine3f) trans_3d;
00411 }
00412 pcl::transformPointCloud(*new_target_cloud, *transed_ref, trans.inverse());
00413
00414 {
00415 boost::mutex::scoped_lock lock(mtx_);
00416 tracker_set_reference_cloud(transed_ref);
00417 tracker_set_trans(trans);
00418 tracker_reset_tracking();
00419 initial_pose_ = Eigen::Affine3f(trans);
00420 }
00421 track_target_set_ = true;
00422 NODELET_INFO("RESET TARGET MODEL");
00423 }
00424 else {
00425 track_target_set_ = false;
00426 NODELET_ERROR("TARGET MODEL POINTS SIZE IS 0 !! Stop TRACKING");
00427 }
00428 }
00429
00430 tf::Transform ParticleFilterTracking::change_pointcloud_frame(
00431 pcl::PointCloud<PointT>::Ptr cloud)
00432 {
00433 tf::Transform tfTransformation;
00434 tf::StampedTransform tfTransformationStamped;
00435 ros::Time now = ros::Time::now();
00436 try {
00437 listener_->waitForTransform(base_frame_id_, frame_id_, now,
00438 ros::Duration(2.0));
00439 listener_->lookupTransform(base_frame_id_, frame_id_, now,
00440 tfTransformationStamped);
00441
00442 }
00443 catch(tf::TransformException ex) {
00444 NODELET_ERROR("%s",ex.what());
00445 tfTransformation = tf::Transform(tf::Quaternion(0, 0, 0, 1));
00446 }
00447 tfTransformation = tf::Transform(tfTransformationStamped.getBasis(),
00448 tfTransformationStamped.getOrigin());
00449 Eigen::Affine3f trans; Eigen::Affine3d trans_3d;
00450 tf::transformTFToEigen(tfTransformation, trans_3d);
00451 trans = (Eigen::Affine3f) trans_3d;
00452 pcl::transformPointCloud(*cloud, *cloud, trans);
00453 return tfTransformation;
00454 }
00455
00456 void ParticleFilterTracking::publish_tracker_status(const std_msgs::Header& header,
00457 const bool is_tracking)
00458 {
00459 jsk_recognition_msgs::TrackerStatus tracker_status;
00460 tracker_status.header = header;
00461 tracker_status.is_tracking = is_tracking;
00462 pub_tracker_status_.publish(tracker_status);
00463 }
00464
00465 void ParticleFilterTracking::cloud_change_cb(const sensor_msgs::PointCloud2::ConstPtr &pc_msg,
00466 const sensor_msgs::PointCloud2::ConstPtr &change_cloud_msg)
00467 {
00468 if (no_move_buffer_.isAllTrueFilled()) {
00469 jsk_recognition_utils::ScopedWallDurationReporter r
00470 = timer_.reporter(pub_latest_time_, pub_average_time_);
00471
00472 pcl::PointCloud<pcl::PointXYZRGB>::Ptr change_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
00473 pcl::fromROSMsg(*change_cloud_msg, *change_cloud);
00474 if (change_cloud->points.size() == 0) {
00475 stamp_ = pc_msg->header.stamp;
00476 publish_result();
00477 publish_tracker_status(pc_msg->header, false);
00478 return;
00479 }
00480 pcl::KdTreeFLANN<pcl::PointXYZRGB> kdtree;
00481 kdtree.setInputCloud(change_cloud);
00482 std::vector<int> k_indices;
00483 std::vector<float> k_sqr_distances;
00484 pcl::PointXYZRGB p;
00485 p.x = prev_result_.x;
00486 p.y = prev_result_.y;
00487 p.z = prev_result_.z;
00488 if (kdtree.radiusSearch(p, change_cloud_near_threshold_, k_indices, k_sqr_distances, 1) > 0) {
00489 NODELET_INFO("change detection triggered!");
00490
00491 cloud_cb(*pc_msg);
00492 r.setIsEnabled(false);
00493 no_move_buffer_.clear();
00494 publish_tracker_status(pc_msg->header, true);
00495 }
00496 else {
00497
00498 stamp_ = pc_msg->header.stamp;
00499 publish_result();
00500 publish_tracker_status(pc_msg->header, false);
00501 }
00502 }
00503 else {
00504 publish_tracker_status(pc_msg->header, true);
00505 cloud_cb(*pc_msg);
00506 }
00507 }
00508
00509
00510 void ParticleFilterTracking::cloud_cb(const sensor_msgs::PointCloud2 &pc)
00511 {
00512 if (track_target_set_) {
00513 pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>());
00514 frame_id_ = pc.header.frame_id;
00515 stamp_ = pc.header.stamp;
00516 std::vector<int> indices;
00517 pcl::fromROSMsg(pc, *cloud);
00518 cloud->is_dense = false;
00519 {
00520 jsk_recognition_utils::ScopedWallDurationReporter r
00521 = timer_.reporter(pub_latest_time_, pub_average_time_);
00522 pcl::removeNaNFromPointCloud(*cloud, *cloud, indices);
00523 if (base_frame_id_.compare("NONE")!=0) {
00524 change_pointcloud_frame(cloud);
00525 }
00526 cloud_pass_downsampled_.reset(new pcl::PointCloud<PointT>);
00527 pcl::copyPointCloud(*cloud, *cloud_pass_downsampled_);
00528 if (!cloud_pass_downsampled_->points.empty()) {
00529 boost::mutex::scoped_lock lock(mtx_);
00530 tracker_set_input_cloud(cloud_pass_downsampled_);
00531 tracker_compute();
00532 publish_particles();
00533 publish_result();
00534 }
00535 new_cloud_ = true;
00536 }
00537 }
00538 }
00539
00540 void ParticleFilterTracking::renew_model_topic_cb(
00541 const sensor_msgs::PointCloud2 &pc)
00542 {
00543 pcl::PointCloud<PointT>::Ptr new_target_cloud
00544 (new pcl::PointCloud<PointT>());
00545 pcl::fromROSMsg(pc, *new_target_cloud);
00546 frame_id_ = pc.header.frame_id;
00547 reset_tracking_target_model(new_target_cloud);
00548 }
00549
00550 void ParticleFilterTracking::renew_model_with_marker_topic_cb(const visualization_msgs::Marker &marker)
00551 {
00552 if(marker.type == visualization_msgs::Marker::TRIANGLE_LIST && !marker.points.empty()){
00553 ROS_INFO("Reset Tracker Model with renew_model_with_marker_topic_cb");
00554 pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
00555 jsk_recognition_utils::markerMsgToPointCloud(marker,
00556 marker_to_pointcloud_sampling_nums_,
00557 *cloud
00558 );
00559
00560 Eigen::Affine3f trans;
00561 tf::poseMsgToEigen(marker.pose, trans);
00562 pcl::transformPointCloud(*cloud, *cloud, trans);
00563
00564 frame_id_ = marker.header.frame_id;
00565 reset_tracking_target_model(cloud);
00566 }else{
00567 ROS_ERROR(" Marker Models type is not TRIANGLE ");
00568 ROS_ERROR(" OR ");
00569 ROS_ERROR(" Marker Points is empty ");
00570 }
00571 }
00572
00573 void ParticleFilterTracking::renew_model_with_box_topic_cb(
00574 const sensor_msgs::PointCloud2::ConstPtr &pc_ptr,
00575 const jsk_recognition_msgs::BoundingBox::ConstPtr &bb_ptr)
00576 {
00577 pcl::PointCloud<PointT>::Ptr new_target_cloud
00578 (new pcl::PointCloud<PointT>());
00579 pcl::fromROSMsg(*pc_ptr, *new_target_cloud);
00580 frame_id_ = pc_ptr->header.frame_id;
00581 tf::poseMsgToTF(bb_ptr->pose, reference_transform_);
00582 reset_tracking_target_model(new_target_cloud);
00583 }
00584
00585 bool ParticleFilterTracking::renew_model_cb(
00586 jsk_recognition_msgs::SetPointCloud2::Request &req,
00587 jsk_recognition_msgs::SetPointCloud2::Response &res)
00588 {
00589 pcl::PointCloud<PointT>::Ptr new_target_cloud(new pcl::PointCloud<PointT>());
00590 pcl::fromROSMsg(req.cloud, *new_target_cloud);
00591 frame_id_ = req.cloud.header.frame_id;
00592 reset_tracking_target_model(new_target_cloud);
00593 return true;
00594 }
00595
00596 void ParticleFilterTracking::tracker_set_trans(
00597 const Eigen::Affine3f& trans)
00598 {
00599 Eigen::Vector3f pos = trans.translation();
00600 NODELET_INFO("trans: [%f, %f, %f]", pos[0], pos[1], pos[2]);
00601 if (reversed_) {
00602 reversed_tracker_->setTrans(trans);
00603 }
00604 else {
00605 tracker_->setTrans(trans);
00606 }
00607 }
00608
00609 void ParticleFilterTracking::tracker_set_step_noise_covariance(
00610 const std::vector<double>& covariance)
00611 {
00612 if (reversed_) {
00613 reversed_tracker_->setStepNoiseCovariance(covariance);
00614 }
00615 else {
00616 tracker_->setStepNoiseCovariance(covariance);
00617 }
00618 }
00619
00620 void ParticleFilterTracking::tracker_set_initial_noise_covariance(
00621 const std::vector<double>& covariance)
00622 {
00623 if (reversed_) {
00624 reversed_tracker_->setInitialNoiseCovariance(covariance);
00625 }
00626 else {
00627 tracker_->setInitialNoiseCovariance(covariance);
00628 }
00629 }
00630
00631 void ParticleFilterTracking::tracker_set_initial_noise_mean(
00632 const std::vector<double>& mean)
00633 {
00634 if (reversed_) {
00635 reversed_tracker_->setInitialNoiseMean(mean);
00636 }
00637 else {
00638 tracker_->setInitialNoiseMean(mean);
00639 }
00640 }
00641
00642 void ParticleFilterTracking::tracker_set_iteration_num(const int num)
00643 {
00644 if (reversed_) {
00645 reversed_tracker_->setIterationNum(num);
00646 }
00647 else {
00648 tracker_->setIterationNum(num);
00649 }
00650 }
00651
00652 void ParticleFilterTracking::tracker_set_particle_num(const int num)
00653 {
00654 if (reversed_) {
00655 reversed_tracker_->setParticleNum(num);
00656 }
00657 else {
00658 tracker_->setParticleNum(num);
00659 }
00660 }
00661
00662 void ParticleFilterTracking::tracker_set_resample_likelihood_thr(double thr)
00663 {
00664 if (reversed_) {
00665 reversed_tracker_->setResampleLikelihoodThr(thr);
00666 }
00667 else {
00668 tracker_->setResampleLikelihoodThr(thr);
00669 }
00670 }
00671
00672 void ParticleFilterTracking::tracker_set_use_normal(bool use_normal)
00673 {
00674 if (reversed_) {
00675 reversed_tracker_->setUseNormal(use_normal);
00676 }
00677 else {
00678 tracker_->setUseNormal(use_normal);
00679 }
00680 }
00681
00682 void ParticleFilterTracking::tracker_set_cloud_coherence(
00683 ApproxNearestPairPointCloudCoherence<PointT>::Ptr coherence)
00684 {
00685 if (reversed_) {
00686 reversed_tracker_->setCloudCoherence(coherence);
00687 }
00688 else {
00689 tracker_->setCloudCoherence(coherence);
00690 }
00691 }
00692
00693 void ParticleFilterTracking::tracker_set_maximum_particle_num(int num)
00694 {
00695 if (!reversed_) {
00696 tracker_->setMaximumParticleNum(num);
00697 }
00698 }
00699
00700 void ParticleFilterTracking::tracker_set_delta(double delta)
00701 {
00702 if (!reversed_) {
00703 tracker_->setDelta(delta);
00704 }
00705 }
00706
00707 void ParticleFilterTracking::tracker_set_epsilon(double epsilon)
00708 {
00709 if (!reversed_) {
00710 tracker_->setEpsilon(epsilon);
00711 }
00712 }
00713
00714 void ParticleFilterTracking::tracker_set_bin_size(
00715 const ParticleXYZRPY bin_size)
00716 {
00717 if (!reversed_) {
00718 tracker_->setBinSize(bin_size);
00719 }
00720 }
00721
00722 ParticleFilterTracking::PointCloudStatePtr
00723 ParticleFilterTracking::tracker_get_particles()
00724 {
00725 if (!reversed_) {
00726 return tracker_->getParticles();
00727 }
00728 else {
00729 return reversed_tracker_->getParticles();
00730 }
00731 }
00732
00733 ParticleXYZRPY ParticleFilterTracking::tracker_get_result()
00734 {
00735 if (!reversed_) {
00736 return tracker_->getResult();
00737 }
00738 else {
00739 return reversed_tracker_->getResult();
00740 }
00741 }
00742
00743 Eigen::Affine3f ParticleFilterTracking::tracker_to_eigen_matrix(
00744 const ParticleXYZRPY& result)
00745 {
00746 if (!reversed_) {
00747 return tracker_->toEigenMatrix(result);
00748 }
00749 else {
00750 return reversed_tracker_->toEigenMatrix(result);
00751 }
00752 }
00753
00754 pcl::PointCloud<ParticleFilterTracking::PointT>::ConstPtr
00755 ParticleFilterTracking::tracker_get_reference_cloud()
00756 {
00757 if (!reversed_) {
00758 return tracker_->getReferenceCloud();
00759 }
00760 else {
00761 return reversed_tracker_->getReferenceCloud();
00762 }
00763 }
00764
00765 void ParticleFilterTracking::tracker_set_reference_cloud(
00766 pcl::PointCloud<PointT>::Ptr ref)
00767 {
00768 if (!reversed_) {
00769 tracker_->setReferenceCloud(ref);
00770 }
00771 else {
00772 reversed_tracker_->setReferenceCloud(ref);
00773 }
00774 counter_ = 0;
00775 no_move_buffer_.clear();
00776 }
00777
00778 void ParticleFilterTracking::tracker_reset_tracking()
00779 {
00780 if (!reversed_) {
00781 tracker_->resetTracking();
00782 }
00783 else {
00784 reversed_tracker_->resetTracking();
00785 }
00786 }
00787
00788 void ParticleFilterTracking::tracker_set_input_cloud(
00789 pcl::PointCloud<PointT>::Ptr input)
00790 {
00791 if (!reversed_) {
00792 tracker_->setInputCloud(input);
00793 }
00794 else {
00795 reversed_tracker_->setInputCloud(input);
00796 }
00797 }
00798 void ParticleFilterTracking::tracker_compute()
00799 {
00800 if (!reversed_) {
00801 tracker_->compute();
00802 }
00803 else {
00804 reversed_tracker_->compute();
00805 }
00806 }
00807 }
00808
00809 PLUGINLIB_EXPORT_CLASS (jsk_pcl_ros::ParticleFilterTracking, nodelet::Nodelet);