FeatureTrackerNode.cpp
Go to the documentation of this file.
00001 #include "feature_tracker/FeatureTrackerNode.h"
00002 #include <pcl/conversions.h>
00003 #include <rosbag/bag.h>
00004 #include <rosbag/view.h>
00005 #include <boost/foreach.hpp>
00006 #include <tf/tfMessage.h>
00007 #include <tf/transform_broadcaster.h>
00008 #include <tf/transform_listener.h>
00009 #include <geometry_msgs/TransformStamped.h>
00010 
00011 #include <rosgraph_msgs/Clock.h>
00012 
00013 #include <std_msgs/Float64.h>
00014 
00015 #include "feature_tracker/PointFeatureTracker.h"
00016 
00017 #include <unistd.h>
00018 
00019 #include <pcl_conversions/pcl_conversions.h>
00020 
00021 #if ROS_VERSION_MINIMUM(1, 11, 1) // if current ros version is >= 1.10.1 (hydro)
00022 #else
00023 #include "feature_tracker/pcl_conversions_indigo.h"
00024 #endif
00025 
00026 #define LINES_OF_TERMINAL_FT 4
00027 
00028 using namespace omip;
00029 
00030 FeatureTrackerNode::FeatureTrackerNode() :
00031     RecursiveEstimatorNodeInterface(1),
00032     _image_transport(this->_measurements_node_handle),
00033     _synchronizer(NULL),
00034     _data_from_bag(false),
00035     _ci_initialized(false),
00036     _subscribe_to_pc(false),
00037     _publishing_depth_edges_img(false),
00038     _publishing_tracked_feats_img(false),
00039     _publishing_rgb_img(false),
00040     _publishing_depth_img(false),
00041     _publishing_tracked_feats_with_pred_msk_img(false),
00042     _publishing_full_pc(false),
00043     _publishing_predicting_msk_img(false),
00044     _publishing_tracking_msk_img(false),
00045     _publishing_detecting_msk_img(false),
00046     _publishing_predicted_and_past_feats_img(false),
00047     _republishing_predicted_feat_locs(false),
00048     _advance_frame_min_wait_time(0.0),
00049     _sensor_fps(0.0),
00050     _loop_period_ns(0.0),
00051     _processing_factor(0),
00052     _advance_frame_mechanism(0),
00053     _advance_frame_max_wait_time(60.),
00054     _advance_sub_returned_true(false),
00055     _attention_to_motion(false),
00056     _occlusion_mask_positive(true)
00057 {
00058     this->_namespace = std::string("feature_tracker");
00059 
00060     this->_ReadParameters();
00061     
00062     this->_SubscribeAndAdvertiseTopics();
00063     
00064     this->_InitializeVariables();
00065 }
00066 
00067 FeatureTrackerNode::~FeatureTrackerNode()
00068 {  
00069 }
00070 
00071 void FeatureTrackerNode::measurementCallback(const sensor_msgs::PointCloud2ConstPtr& full_pc_msg,
00072                                              const sensor_msgs::ImageConstPtr &depth_image_msg,
00073                                              const sensor_msgs::ImageConstPtr &rgb_image_msg)
00074 {
00075     // Pass the full RGBD point cloud
00076     PointCloudPCL temp_cloud;
00077     pcl::fromROSMsg(*full_pc_msg, temp_cloud);
00078     this->_full_rgbd_pc = boost::make_shared<const PointCloudPCL>(temp_cloud);
00079     this->_re_filter->setFullRGBDPC(this->_full_rgbd_pc);
00080 
00081     // Call the reduced callback, so that we don't duplicate code
00082     this->measurementCallback(depth_image_msg, rgb_image_msg);
00083 }
00084 
00085 void FeatureTrackerNode::measurementCallback(const sensor_msgs::ImageConstPtr &depth_image_msg,
00086                                              const sensor_msgs::ImageConstPtr &rgb_image_msg)
00087 {
00088     ros::Time first = ros::Time::now();
00089 
00090     // Set the current time to be the time of the depth image
00091     ros::Time current_measurement_time = depth_image_msg->header.stamp;
00092 
00093     ros::Duration time_between_meas;
00094 
00095     // If we are in the first iteration the prev meas time is zero and we don't check for the elapsed time
00096     if(this->_previous_measurement_time.toSec() != 0.)
00097     {
00098         // Measure the time interval between the previous measurement and the current measurement
00099         time_between_meas = current_measurement_time - this->_previous_measurement_time;
00100 
00101         // The time interval between frames is the inverse of the max_framerate
00102         double period_between_frames = 1.0/this->_sensor_fps;
00103 
00104         // The number of frames elapsed is the time elapsed divided by the period between frames
00105         int frames_between_meas = round((time_between_meas.toSec())/period_between_frames);
00106 
00107         // Processing fps: ignore (this->_processing_factor - 1) frames and process one. This gives effectively the desired processing fps: _sensor_fps/_processing_factor
00108         if( frames_between_meas < this->_processing_factor )
00109         {
00110             return;
00111         }
00112         else if(frames_between_meas == this->_processing_factor )
00113         {
00114             ROS_INFO("  0 frames lost. Processing at %d fps.", (int)this->_sensor_fps);
00115         }
00116         else if(frames_between_meas > this->_processing_factor)
00117         {
00118             // We show this message if we have lost frames
00119             ROS_ERROR("%3d frames lost! Consider setting a lower frame rate." , frames_between_meas - this->_processing_factor);
00120         }
00121     }
00122 
00123     // Get the time of the current measurement (reference time from depth maps channel)
00124     this->_current_measurement_time = current_measurement_time;
00125 
00126     // Create an ft_measurement object and pass it to the RE
00127     this->_cv_ptr_depth = cv_bridge::toCvCopy(depth_image_msg);
00128     this->_cv_ptr_rgb = cv_bridge::toCvCopy(rgb_image_msg);
00129     ft_measurement_t latest_measurement = ft_measurement_t( this->_cv_ptr_rgb, this->_cv_ptr_depth);
00130 
00131     this->_re_filter->setMeasurement(latest_measurement, (double)this->_current_measurement_time.toNSec());
00132 
00133     // Predict next RE state
00134     this->_re_filter->predictState(this->_loop_period_ns);
00135 
00136     // Predict next measurement based on the predicted state
00137     this->_re_filter->predictMeasurement();
00138 
00139     //TOBETESTED: We do not jump the first frame because we need to detect features
00140     // Use the predicted measurement and the received measurement to correct the state
00141     this->_re_filter->correctState();
00142 
00143     // Publish the obtained new state
00144     this->_publishState();
00145     
00146     // Publish additional stuff
00147     this->PublishRGBImg();
00148     this->PublishDepthImg();
00149     this->PublishDepthEdgesImg();
00150     this->PublishTrackedFeaturesImg();
00151     this->PublishTrackedFeaturesWithPredictionMaskImg();
00152     this->PublishDetectingMaskImg();
00153     this->PublishTrackingMaskImg();
00154     this->PublishPredictedAndLastFeaturesImg();
00155     this->PublishPredictionMaskImg();
00156 
00157     this->RepublishPredictedFeatLocation();
00158 
00159     if(this->_publishing_full_pc && this->_subscribe_to_pc)
00160     {
00161         this->PublishFullRGBDPC();
00162     }
00163     
00164 
00165     if (this->_data_from_bag)
00166     {
00167         static int advanced_frame_number = 0;
00168         switch(this->_advance_frame_mechanism)
00169         {
00170         case 0://0 -> Automatically advancing, no waiting
00171         {
00172             usleep((int)(this->_advance_frame_min_wait_time));
00173         }
00174             break;
00175         case 1://1 -> Manually advancing
00176         {
00177             std::cout << "Press enter to process the next frame" << std::endl;
00178             getchar();
00179         }
00180             break;
00181         case 2://2 -> Wait for signal from Shape Reconstruction
00182         case 3://3 -> Wait for signal from Shape Tracker
00183         {
00184 
00185             double max_time = _advance_frame_max_wait_time; //(seconds)
00186 
00187             if (max_time < 0) {
00188                 std::cout << "WARNING: no time limit, waiting forever" << std::endl;
00189                 max_time = std::numeric_limits<double>::max();
00190             }
00191 
00192             std::cout << "Waiting for advance response in FTracker" ;
00193 
00194             double wait_time=0.;
00195             while(advanced_frame_number > 0 && !this->_advance_sub_returned_true && wait_time < max_time && this->_active)
00196             {
00197                 usleep(1e5);
00198                 printf(" (%4.1fs)", wait_time);
00199                 wait_time += 0.1;
00200             }
00201             if (wait_time >= max_time) {
00202                 std::cout << " Exceeded time limit " << max_time ;
00203             } else {
00204                 std::cout << " Refinement received in FTracker" ;
00205             }
00206             this->_advance_sub_returned_true = false;
00207         }
00208             break;
00209         }
00210         advanced_frame_number++;
00211         std::cout << ". Reading frame " << advanced_frame_number << std::endl;
00212     }
00213 
00214     //After processing, the time stamp of the current measurement becomes the previous time
00215     this->_previous_measurement_time = this->_current_measurement_time;
00216 
00217     ros::Time last = ros::Time::now();
00218     ROS_WARN_STREAM("Time between meas: " << time_between_meas.toSec()*1000 << " ms");
00219     ROS_WARN_STREAM("Total meas processing time: " << (last-first).toSec()*1000 << " ms");
00220 }
00221 
00222 void FeatureTrackerNode::statePredictionCallback(const boost::shared_ptr<ft_state_ros_t const> &predicted_locations_pc)
00223 {
00224     //convert dataset
00225     FeatureCloudPCLwc temp_cloud;
00226     pcl::fromROSMsg(*predicted_locations_pc, temp_cloud);
00227     this->_predicted_locations_pc = boost::make_shared<FeatureCloudPCLwc>(temp_cloud);
00228 
00229     this->_re_filter->addPredictedState(this->_predicted_locations_pc, (double)predicted_locations_pc->header.stamp.toNSec());
00230 }
00231 
00232 void FeatureTrackerNode::DynamicReconfigureCallback(feature_tracker::FeatureTrackerDynReconfConfig &config, uint32_t level)
00233 {
00234     // Set class variables to new values. They should match what is input at the dynamic reconfigure GUI.
00235     this->_publishing_depth_edges_img = config.pub_depth_edges_img;
00236     this->_publishing_tracked_feats_img = config.pub_tracked_feats_img;
00237     this->_publishing_rgb_img = config.pub_rgb_img;
00238     this->_publishing_depth_img = config.pub_depth_img;
00239     this->_publishing_tracked_feats_with_pred_msk_img = config.pub_tracked_feats_with_pred_mask_img;
00240     //this->_publishing_full_pc = config.pub_full_pc;
00241     this->_publishing_predicting_msk_img = config.pub_predicting_msk_img;
00242     this->_publishing_tracking_msk_img = config.pub_tracking_msk_img;
00243     this->_publishing_detecting_msk_img = config.pub_detecting_msk_img;
00244     this->_publishing_predicted_and_past_feats_img = config.pub_predicted_and_past_feats_img;
00245 
00246     this->_republishing_predicted_feat_locs = config.repub_predicted_feat_locs;
00247 
00248     this->_advance_frame_min_wait_time = 1e6*(config.advance_frame_min_wait_time);
00249     if(this->_re_filter)
00250     {
00251         this->_re_filter->setDynamicReconfigureValues(config);
00252     }
00253 }
00254 
00255 void FeatureTrackerNode::ReadRosBag()
00256 {
00257     rosbag::Bag bag;
00258     ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadRosBag", "Reading rosbag: " <<this->_bag_file_name);
00259     bag.open(this->_bag_file_name, rosbag::bagmode::Read);
00260 
00261     std::vector<std::string> topics;
00262     topics.push_back(this->_full_rgbd_pc_topic);
00263     topics.push_back(this->_depth_img_topic);
00264     topics.push_back(this->_rgb_img_topic);
00265     topics.push_back(this->_occlusion_mask_img_topic);
00266     topics.push_back(this->_ci_topic);
00267     topics.push_back("/tf");
00268 
00269     ROS_DEBUG_STREAM_NAMED( "FeatureTrackerNode.ReadRosBag",
00270                             "Topics: " << this->_full_rgbd_pc_topic << std::endl
00271                             << this->_depth_img_topic << std::endl
00272                             << this->_rgb_img_topic << std::endl
00273                             << this->_occlusion_mask_img_topic << std::endl
00274                             << this->_ci_topic);
00275 
00276     rosbag::View view(bag, rosbag::TopicQuery(topics));
00277 
00278     int messages_counter = 0;
00279     rosgraph_msgs::Clock time_now_msg;
00280 
00281     // When we read a rosbag we use the time of the bag
00282     // We get the time from the messages and we publish it, so that the rest of the ROS system gets the time of the bag
00283     ros::Time time_now;
00284     BOOST_FOREACH(rosbag::MessageInstance const m, view)
00285     {
00286         if(!this->_active)
00287             break;
00288 
00289         if (m.getTopic() == this->_full_rgbd_pc_topic || ("/" + m.getTopic() == this->_full_rgbd_pc_topic))
00290         {
00291             sensor_msgs::PointCloud2::ConstPtr points_pc = m.instantiate<sensor_msgs::PointCloud2>();
00292             if (points_pc != NULL )
00293             {
00294                 if(this->_subscribe_to_pc)
00295                 {
00296                     this->_bag_full_rgbd_pc_sub.newMessage(points_pc);
00297                 }
00298                 time_now = points_pc->header.stamp;
00299             }
00300             this->_camera_info_pub.publish(this->_camera_info_msg);
00301             this->_camera_info_pub2.publish(this->_camera_info_msg);
00302         }
00303 
00304         if (m.getTopic() == this->_occlusion_mask_img_topic || ("/" + m.getTopic() == this->_occlusion_mask_img_topic))
00305         {
00306             sensor_msgs::Image::Ptr occlusion_mask = m.instantiate<sensor_msgs::Image>();
00307             if (occlusion_mask != NULL)
00308             {
00309                 time_now = occlusion_mask->header.stamp;
00310                 this->OcclusionMaskImgCallback(occlusion_mask);
00311             }
00312         }
00313 
00314         if (m.getTopic() == this->_depth_img_topic || ("/" + m.getTopic() == this->_depth_img_topic))
00315         {
00316             sensor_msgs::Image::Ptr depth_img =  m.instantiate<sensor_msgs::Image>();
00317             if (depth_img != NULL)
00318             {
00319                 time_now = depth_img->header.stamp;
00320                 this->_bag_depth_img_sub.newMessage(depth_img);
00321             }
00322         }
00323 
00324         if (m.getTopic() == this->_rgb_img_topic || ("/" + m.getTopic() == this->_rgb_img_topic))
00325         {
00326             sensor_msgs::Image::Ptr rgb_img = m.instantiate<sensor_msgs::Image>();
00327             if (rgb_img != NULL)
00328             {
00329                 time_now = rgb_img->header.stamp;
00330                 this->_bag_rgb_img_sub.newMessage(rgb_img);
00331             }
00332 
00333             // Spin here the queue of the measurements
00334             if (ros::ok())
00335             {
00336                 this->_measurements_queue->callAvailable(ros::WallDuration(0.0));
00337             }
00338         }
00339 
00340         if ((m.getTopic() == this->_ci_topic || ("/" + m.getTopic() == this->_ci_topic)) && !this->_ci_initialized)
00341         {
00342             sensor_msgs::CameraInfo::ConstPtr ci_msg = m.instantiate<sensor_msgs::CameraInfo>();
00343             if (ci_msg != NULL)
00344             {
00345                 time_now = ci_msg->header.stamp;
00346                 this->_camera_info_msg = sensor_msgs::CameraInfo(*ci_msg);
00347                 this->_re_filter->setCameraInfoMsg(&this->_camera_info_msg);
00348                 this->_ci_initialized = true;
00349             }
00350         }
00351 
00352 
00353         static tf::TransformBroadcaster br;
00354         static bool first_ee_tf = true;
00355 
00356         if ((m.getTopic() == "/tf" || ("/" + m.getTopic() == "/tf")))
00357         {
00358             tf::tfMessage::Ptr tf_msg = m.instantiate<tf::tfMessage>();
00359             if (tf_msg != NULL)
00360             {
00361                 time_now = tf_msg->transforms.at(0).header.stamp;
00362                 for(int tf_transforms_idx = 0; tf_transforms_idx < tf_msg->transforms.size() ; tf_transforms_idx++)
00363                 {
00364                     geometry_msgs::TransformStamped transform = tf_msg->transforms.at(tf_transforms_idx);
00365                     if(transform.child_frame_id == "/ee")
00366                     {
00367                         if(first_ee_tf)
00368                         {
00369                             tf::StampedTransform cam_link_to_camera_rgb_optical_frame;
00370 
00371                             tf::Vector3 translation = tf::Vector3(0.000, 0.020, 0.000);
00372                             cam_link_to_camera_rgb_optical_frame.setOrigin(translation);
00373                             tf::Quaternion rotation = tf::createQuaternionFromRPY(0.,0.0,-M_PI_2);
00374                             cam_link_to_camera_rgb_optical_frame.setRotation(rotation);
00375 
00376                             tf::transformMsgToTF(transform.transform, this->_initial_ee_tf);
00377                             this->_initial_ee_tf =  this->_initial_ee_tf * cam_link_to_camera_rgb_optical_frame;
00378                             first_ee_tf = false;
00379                         }
00380 
00381                         //transform.header.stamp = ros::Time::now();
00382                         br.sendTransform(transform);
00383 
00384                         geometry_msgs::TransformStamped initial_tf;
00385                         tf::transformTFToMsg(this->_initial_ee_tf, initial_tf.transform);
00386                         initial_tf.header = transform.header;
00387                         initial_tf.child_frame_id = "initial_transform";
00388                         br.sendTransform(initial_tf);
00389                     }
00390                 }
00391             }
00392         }
00393 
00394         time_now_msg.clock = time_now;
00395         this->_time_repub.publish(time_now_msg);
00396 
00397         messages_counter++;
00398     }
00399 
00400     if(this->_active)
00401     {
00402         ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadRosBag", "End of the rosbag.");
00403     }
00404     bag.close();    
00405     this->_shutdown_publisher.publish(std_msgs::Empty());
00406 }
00407 
00408 void FeatureTrackerNode::OcclusionMaskImgCallback(const sensor_msgs::ImageConstPtr &occlusion_mask_img)
00409 {
00410     this->_cv_ptr_occlusion_msk = cv_bridge::toCvCopy(occlusion_mask_img, "mono8");
00411     this->_re_filter->setOcclusionMaskImg(this->_cv_ptr_occlusion_msk);
00412 }
00413 
00414 void FeatureTrackerNode::PublishRGBImg()
00415 {
00416     if(this->_publishing_rgb_img)
00417     {
00418         cv_bridge::CvImagePtr rgb_img = this->_re_filter->getRGBImg();
00419         if(rgb_img)
00420         {
00421             rgb_img->header.frame_id = "camera_rgb_optical_frame";
00422             rgb_img->header.stamp = this->_current_measurement_time;
00423             this->_rgb_img_pub.publish(rgb_img->toImageMsg());
00424         }
00425     }
00426 }
00427 
00428 void FeatureTrackerNode::PublishDepthImg()
00429 {
00430     if(this->_publishing_depth_img)
00431     {
00432         cv_bridge::CvImagePtr depth_img = this->_re_filter->getDepthImg();
00433         if(depth_img)
00434         {
00435             depth_img->header.frame_id = "camera_rgb_optical_frame";
00436             depth_img->header.stamp = this->_current_measurement_time;
00437             this->_depth_img_pub.publish(depth_img->toImageMsg());
00438         }
00439     }
00440 }
00441 
00442 void FeatureTrackerNode::PublishFullRGBDPC()
00443 {
00444     if(this->_publishing_full_pc && this->_subscribe_to_pc)
00445     {
00446         sensor_msgs::PointCloud2 full_rgbd_pc_ros;
00447         pcl::toROSMsg(*(this->_full_rgbd_pc), full_rgbd_pc_ros);
00448         full_rgbd_pc_ros.header.stamp = this->_current_measurement_time;
00449         full_rgbd_pc_ros.header.frame_id = "camera_rgb_optical_frame";
00450         this->_full_rgbd_pc_repub.publish(full_rgbd_pc_ros);
00451     }
00452 }
00453 
00454 void FeatureTrackerNode::PublishTrackedFeaturesImg()
00455 {
00456     if(this->_publishing_tracked_feats_img)
00457     {
00458         cv_bridge::CvImagePtr tracked_features_img = this->_re_filter->getTrackedFeaturesImg();
00459         tracked_features_img->header.frame_id = "camera_rgb_optical_frame";
00460         tracked_features_img->header.stamp = this->_current_measurement_time;
00461         this->_tracked_feats_img_pub.publish(tracked_features_img->toImageMsg());
00462     }
00463 }
00464 
00465 void FeatureTrackerNode::PublishTrackedFeaturesWithPredictionMaskImg()
00466 {
00467     if(this->_publishing_tracked_feats_with_pred_msk_img)
00468     {
00469         cv_bridge::CvImagePtr tracked_features_with_pm_img = this->_re_filter
00470                 ->getTrackedFeaturesWithPredictionMaskImg();
00471         tracked_features_with_pm_img->header.frame_id = "camera_rgb_optical_frame";
00472         tracked_features_with_pm_img->header.stamp = this->_current_measurement_time;
00473         this->_tracked_feats_with_pm_img_pub.publish(tracked_features_with_pm_img->toImageMsg());
00474     }
00475 }
00476 
00477 void FeatureTrackerNode::PublishDepthEdgesImg()
00478 {
00479     if(this->_publishing_depth_edges_img)
00480     {
00481         cv_bridge::CvImagePtr depth_edges_img = this->_re_filter
00482                 ->getDepthEdgesImg();
00483         depth_edges_img->header.frame_id = "camera_rgb_optical_frame";
00484         depth_edges_img->header.stamp = this->_current_measurement_time;
00485         this->_depth_edges_img_pub.publish(depth_edges_img->toImageMsg());
00486     }
00487 }
00488 
00489 void FeatureTrackerNode::PublishPredictionMaskImg()
00490 {
00491     if(this->_publishing_predicting_msk_img)
00492     {
00493         cv_bridge::CvImagePtr predicting_mask_img = this->_re_filter->getPredictingMaskImg();
00494         predicting_mask_img->header.frame_id = "camera_rgb_optical_frame";
00495         predicting_mask_img->header.stamp = this->_current_measurement_time;
00496         this->_prediction_mask_img_pub.publish(predicting_mask_img->toImageMsg());
00497     }
00498 }
00499 
00500 void FeatureTrackerNode::PublishTrackingMaskImg()
00501 {
00502     if(this->_publishing_tracking_msk_img)
00503     {
00504         cv_bridge::CvImagePtr tracking_mask_img = this->_re_filter->getTrackingMaskImg();
00505         tracking_mask_img->header.frame_id = "camera_rgb_optical_frame";
00506         tracking_mask_img->header.stamp = this->_current_measurement_time;
00507         this->_tracking_mask_img_pub.publish(tracking_mask_img->toImageMsg());
00508     }
00509 }
00510 
00511 void FeatureTrackerNode::PublishDetectingMaskImg()
00512 {
00513     if(this->_publishing_detecting_msk_img)
00514     {
00515         cv_bridge::CvImagePtr detecting_mask_img = this->_re_filter->getDetectingMaskImg();
00516         detecting_mask_img->header.frame_id = "camera_rgb_optical_frame";
00517         detecting_mask_img->header.stamp = this->_current_measurement_time;
00518         this->_detecting_mask_img_pub.publish(detecting_mask_img->toImageMsg());
00519     }
00520 }
00521 
00522 void FeatureTrackerNode::PublishPredictedAndLastFeaturesImg()
00523 {
00524     if(this->_publishing_predicted_and_past_feats_img)
00525     {
00526         cv_bridge::CvImagePtr predicted_and_last_feats_img = this->_re_filter->getPredictedAndLastFeaturesImg();
00527         predicted_and_last_feats_img->header.frame_id = "camera_rgb_optical_frame";
00528         predicted_and_last_feats_img->header.stamp = this->_current_measurement_time;
00529         this->_predicted_and_past_feats_img_pub.publish(predicted_and_last_feats_img->toImageMsg());
00530     }
00531 }
00532 
00533 void FeatureTrackerNode::RepublishPredictedFeatLocation()
00534 {
00535     if(this->_republishing_predicted_feat_locs && this->_predicted_locations_pc)
00536     {
00537         //convert dataset
00538         sensor_msgs::PointCloud2 temp_cloud;
00539         pcl::toROSMsg(*this->_predicted_locations_pc, temp_cloud);
00540         temp_cloud.header.stamp = this->_current_measurement_time;
00541         temp_cloud.header.frame_id = "camera_rgb_optical_frame";
00542         _pred_feat_locs_repub.publish(temp_cloud);
00543     }
00544 }
00545 
00546 void FeatureTrackerNode::_publishState() const
00547 {
00548     ft_state_t tracked_features_pc = this->_re_filter->getState();
00549 
00550     sensor_msgs::PointCloud2 tracked_features_pc_ros;
00551     pcl::toROSMsg(*tracked_features_pc, tracked_features_pc_ros);
00552     tracked_features_pc_ros.header.stamp = this->_current_measurement_time;
00553     tracked_features_pc_ros.header.frame_id = "camera_rgb_optical_frame";
00554 
00555     this->_state_publisher.publish(tracked_features_pc_ros);
00556 }
00557 
00558 void FeatureTrackerNode::_publishPredictedMeasurement() const
00559 {
00560     ROS_ERROR_STREAM_NAMED("FeatureTrackerNode._publishPredictedMeasurement", "FeatureTrackerNode::_publishPredictedMeasurement has not been implemented for the Feature Tracker. It could publish the predicted 2D location of the features using both generative models: the internal model (no motion between frames) and the model that uses the higher RE level (velocity of the features");
00561 }
00562 
00563 void FeatureTrackerNode::_ReadParameters()
00564 {
00565     this->getROSParameter<bool>(this->_namespace  + std::string("/data_from_bag"),this->_data_from_bag);
00566     this->getROSParameter<std::string>(this->_namespace  + std::string("/ft_type"),this->_tracker_type);
00567     this->getROSParameter<std::string>(this->_namespace  + std::string("/bag_file"),this->_bag_file_name);
00568     this->getROSParameter<std::string>(this->_namespace + std::string("/rgbd_pc_topic"),this->_full_rgbd_pc_topic);
00569     this->getROSParameter<std::string>(this->_namespace + std::string("/depth_img_topic"),this->_depth_img_topic);
00570     this->getROSParameter<std::string>(this->_namespace + std::string("/rgb_img_topic"),this->_rgb_img_topic);
00571     this->getROSParameter<std::string>(this->_namespace + std::string("/camera_info_topic"),this->_ci_topic);
00572 
00573     this->getROSParameter<bool>(this->_namespace + std::string("/pub_depth_edges_img"),this->_publishing_depth_edges_img, false);
00574     this->getROSParameter<bool>(this->_namespace + std::string("/pub_rgb_img"),this->_publishing_rgb_img, false);
00575     this->getROSParameter<bool>(this->_namespace + std::string("/pub_depth_img"),this->_publishing_depth_img, false);
00576     this->getROSParameter<bool>(this->_namespace + std::string("/pub_tracked_feats_img"),this->_publishing_tracked_feats_img, false);
00577     this->getROSParameter<bool>(this->_namespace + std::string("/pub_tracked_feats_with_pred_mask_img"),this->_publishing_tracked_feats_with_pred_msk_img, false);
00578     this->getROSParameter<bool>(this->_namespace + std::string("/pub_predicting_msk_img"),this->_publishing_predicting_msk_img, false);
00579     this->getROSParameter<bool>(this->_namespace + std::string("/pub_tracking_msk_img"),this->_publishing_tracking_msk_img, false);
00580     this->getROSParameter<bool>(this->_namespace + std::string("/pub_detecting_msk_img"),this->_publishing_detecting_msk_img, false);
00581     this->getROSParameter<bool>(this->_namespace + std::string("/pub_predicted_and_past_feats_img"),this->_publishing_predicted_and_past_feats_img, false);
00582 
00583     this->getROSParameter<bool>(this->_namespace + std::string("/repub_predicted_feat_locs"),this->_republishing_predicted_feat_locs, false);
00584 
00585     this->getROSParameter<bool>(this->_namespace + std::string("/attention_to_motion"),this->_attention_to_motion);
00586 
00587 
00588     this->getROSParameter<bool>(this->_namespace + std::string("/subscribe_to_pc"),this->_subscribe_to_pc);
00589     this->getROSParameter<bool>(this->_namespace + std::string("/pub_full_pc"),this->_publishing_full_pc);
00590 
00591     this->getROSParameter<int>(this->_namespace + std::string("/advance_frame_mechanism"),this->_advance_frame_mechanism);
00592     this->getROSParameter<double>(this->_namespace + std::string("/advance_frame_max_wait_time"),this->_advance_frame_max_wait_time, 60.);
00593     this->getROSParameter<double>(this->_namespace + std::string("/advance_frame_min_wait_time"),this->_advance_frame_min_wait_time, -1);
00594 
00595     this->_advance_frame_min_wait_time *= 1e6;
00596 
00597     this->getROSParameter<std::string>(this->_namespace + std::string("/selfocclusionfilter_img_topic"),this->_occlusion_mask_img_topic);
00598     this->_predicted_locations_pc_topic = std::string(this->_namespace + "/predicted_measurement");
00599     this->getROSParameter<bool>(this->_namespace + std::string("/selfocclusionfilter_positive"),this->_occlusion_mask_positive);
00600 
00601     this->getROSParameter<double>(std::string("/omip/sensor_fps"), this->_sensor_fps);
00602     this->getROSParameter<int>(std::string("/omip/processing_factor"), this->_processing_factor);
00603     this->_loop_period_ns = 1e9/(this->_sensor_fps/(double)this->_processing_factor);
00604 
00605     // Defined also in feature_tracker_cfg.yaml
00606     std::map<int, std::string > mechanism_codes;
00607     mechanism_codes[0] = std::string("Automatically advancing, no waiting");
00608     mechanism_codes[1] = std::string("Manually advancing");
00609     mechanism_codes[2] = std::string("Wait for signal from Shape Reconstruction");
00610     mechanism_codes[3] = std::string("Wait for signal from Shape Tracker");
00611 
00612     if(this->_data_from_bag)
00613     {
00614         ROS_ERROR_STREAM_NAMED("FeatureTrackerNode.ReadParameters","Reading a rosbag!");
00615         ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadParameters",
00616                                "FeatureTrackerNode Parameters: " <<
00617                                "\n\tRosbag file: " << this->_bag_file_name <<
00618                                "\n\tType of advancing mechanism: " << mechanism_codes[this->_advance_frame_mechanism] <<
00619                                "\n\tMaximum time to wait for the signal to advance a frame (only used if advance_frame_mechanism is 2 or 3): " << this->_advance_frame_max_wait_time <<
00620                                "\n\tMinimum time to wait to advance a frame (only used if advance_frame_mechanism is 0): " << this->_advance_frame_min_wait_time/1e6 <<
00621                                "\n\tSubscribe to point cloud topic: " << this->_subscribe_to_pc <<
00622                                "\n\tSensor framerate: " << this->_sensor_fps << " fps (" << 1.f/this->_sensor_fps << " s)");
00623     }else{
00624         ROS_ERROR_STREAM_NAMED("FeatureTrackerNode.ReadParameters","Data from sensor!");
00625         ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadParameters",
00626                                "FeatureTrackerNode Parameters: " <<
00627                                "\n\tSubscribe to point cloud topic: " << this->_subscribe_to_pc <<
00628                                "\n\tSensor framerate: " << this->_sensor_fps << " fps (" << 1.f/this->_sensor_fps << " s)");
00629     }
00630 
00631 
00632     if(this->_subscribe_to_pc)
00633     {
00634         ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadParameters",
00635                                "FeatureTrackerNode subscribes to these topics: " <<
00636                                "\n\t" << this->_full_rgbd_pc_topic <<
00637                                "\n\t" << this->_depth_img_topic <<
00638                                "\n\t" << this->_rgb_img_topic <<
00639                                "\n\t" << this->_ci_topic <<
00640                                "\n\t" << this->_occlusion_mask_img_topic);
00641     }else{
00642         ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadParameters",
00643                                "FeatureTrackerNode subscribes to these topics: " <<
00644                                "\n\t" << this->_depth_img_topic <<
00645                                "\n\t" << this->_rgb_img_topic <<
00646                                "\n\t" << this->_ci_topic <<
00647                                "\n\t" << this->_occlusion_mask_img_topic);
00648     }
00649 }
00650 
00651 void FeatureTrackerNode::_InitializeVariables()
00652 {
00653     if (this->_tracker_type == std::string("PointFeatureTracker"))
00654     {
00655         this->_re_filter = new PointFeatureTracker(this->_loop_period_ns,
00656                                                   this->_subscribe_to_pc,
00657                                                   this->_namespace);
00658         ((PointFeatureTracker*)this->_re_filter)->setSelfOcclusionPositive(_occlusion_mask_positive);
00659     }
00660     else
00661     {
00662         ROS_ERROR_STREAM_NAMED( "FeatureTrackerNode.getROSParameter",
00663                                 "This type of Visual Tracker (" << this->_tracker_type << ") is not defined");
00664         throw(std::string(
00665                     "[FeatureTrackerNode::getROSParameter] This type of Visual Tracker is not defined"));
00666     }
00667 
00668     //Set the previous time to zero
00669     this->_previous_measurement_time.fromSec(0.);
00670 
00671     // Get the CameraInfo message from the sensor (when not reading from a bag)
00672     if (!this->_data_from_bag)
00673     {
00674         // Waits a second to read one camera_info message from the camera driver, if not, returns an empty vector
00675         sensor_msgs::CameraInfoConstPtr camera_info = ros::topic::waitForMessage<
00676                 sensor_msgs::CameraInfo>(this->_ci_topic, this->_measurements_node_handle,
00677                                          ros::Duration(2.0));
00678         if (camera_info)
00679         {
00680             this->_camera_info_msg = sensor_msgs::CameraInfo(*camera_info);
00681             this->_re_filter->setCameraInfoMsg(&this->_camera_info_msg);
00682             this->_ci_initialized = true;
00683             this->_camera_info_pub2.publish(this->_camera_info_msg);
00684         }
00685         else
00686         {
00687             ROS_ERROR_NAMED(
00688                         "FeatureTrackerNode.getROSParameter",
00689                         "CameraInfo message could not get read. Using default values to initialize the camera info!");
00690             this->_camera_info_msg.width = 640;
00691             this->_camera_info_msg.height = 480;
00692             this->_camera_info_msg.distortion_model = std::string("plumb_bob");
00693             for(int i=0; i<5; i++)
00694                 this->_camera_info_msg.D.push_back(0.0);
00695             this->_camera_info_msg.K[0] = 520;
00696             this->_camera_info_msg.K[2] = 320;
00697             this->_camera_info_msg.K[4] = 520;
00698             this->_camera_info_msg.K[5] = 240;
00699             this->_camera_info_msg.K[8] = 1;
00700             this->_camera_info_msg.R[0] = 1;
00701             this->_camera_info_msg.R[4] = 1;
00702             this->_camera_info_msg.R[8] = 1;
00703             this->_camera_info_msg.P[0] = 520;
00704             this->_camera_info_msg.P[2] = 320;
00705             this->_camera_info_msg.P[5] = 520;
00706             this->_camera_info_msg.P[6] = 240;
00707             this->_camera_info_msg.P[10] = 1;
00708             this->_re_filter->setCameraInfoMsg(&this->_camera_info_msg);
00709             this->_ci_initialized = false;
00710             this->_camera_info_pub2.publish(this->_camera_info_msg);
00711         }
00712     }
00713 }
00714 
00715 void FeatureTrackerNode::_SubscribeAndAdvertiseTopics()
00716 {
00717     // Setup the callback for the dynamic reconfigure
00718     this->_dr_callback = boost::bind(&FeatureTrackerNode::DynamicReconfigureCallback, this, _1, _2);
00719 
00720     //this->_dr_srv = new dynamic_reconfigure::Server<feature_tracker::feature_tracker_paramsConfig>();
00721     this->_dr_srv.setCallback(this->_dr_callback);
00722 
00723     // If we get the data from the kinect
00724     if (!this->_data_from_bag)
00725     {
00726         this->_depth_img_sub.subscribe(this->_measurements_node_handle, this->_depth_img_topic, 10);
00727         this->_rgb_img_sub.subscribe(this->_measurements_node_handle, this->_rgb_img_topic, 10);
00728         
00729         if (this->_subscribe_to_pc)
00730         {
00731             ROS_ERROR_STREAM_NAMED("FeatureTrackerNode._SubscribeAndAdvertiseTopics", "Using the HEAVY synchronization in FT (depth maps, RGB images and point clouds).");
00732             this->_full_rgbd_pc_sub.subscribe(this->_measurements_node_handle, this->_full_rgbd_pc_topic, 1);
00733             this->_synchronizer = new message_filters::Synchronizer<FTrackerSyncPolicy>(FTrackerSyncPolicy(1), this->_full_rgbd_pc_sub,
00734                                                                                         this->_depth_img_sub, this->_rgb_img_sub);
00735         }
00736         else
00737         {
00738             ROS_ERROR_STREAM_NAMED("FeatureTrackerNode._SubscribeAndAdvertiseTopics", "Using the LIGHT synchronization in FT (depth maps and RGB images).");
00739             this->_light_synchronizer = new message_filters::Synchronizer<FTrackerLightSyncPolicy>(FTrackerLightSyncPolicy(10),
00740                                                                                                    this->_depth_img_sub, this->_rgb_img_sub);
00741         }
00742     }
00743     // If we get the data from a bag
00744     else
00745     {
00746         this->_time_repub = this->_measurements_node_handle.advertise<rosgraph_msgs::Clock>("clock", 100);
00747         if (this->_subscribe_to_pc)
00748         {
00749             this->_synchronizer =new message_filters::Synchronizer<FTrackerSyncPolicy>(FTrackerSyncPolicy(10),
00750                                                                                        this->_bag_full_rgbd_pc_sub,
00751                                                                                        this->_bag_depth_img_sub,
00752                                                                                        this->_bag_rgb_img_sub);
00753         }
00754         else
00755         {
00756             this->_light_synchronizer = new message_filters::Synchronizer<FTrackerLightSyncPolicy>(FTrackerLightSyncPolicy(10),
00757                                                                                                    this->_bag_depth_img_sub,
00758                                                                                                    this->_bag_rgb_img_sub);
00759         }
00760     }
00761     
00762     if (this->_subscribe_to_pc)
00763     {
00764         this->_synchronizer->registerCallback(boost::bind(&FeatureTrackerNode::measurementCallback, this, _1, _2, _3));
00765     }
00766     else
00767     {
00768         this->_light_synchronizer->registerCallback(boost::bind(&FeatureTrackerNode::measurementCallback, this, _1, _2));
00769     }
00770     
00771     this->_occlusion_mask_img_sub = this->_measurements_node_handle.subscribe(this->_occlusion_mask_img_topic, 1,
00772                                                                               &FeatureTrackerNode::OcclusionMaskImgCallback, this);
00773     
00774     this->_state_prediction_subscriber = this->_state_prediction_node_handles.at(0).subscribe(
00775                 this->_predicted_locations_pc_topic,1,&FeatureTrackerNode::statePredictionCallback, this);
00776     
00777     this->_state_publisher = this->_measurements_node_handle.advertise<ft_state_ros_t>(this->_namespace + "/state", 100);
00778     this->_rgb_img_pub = this->_image_transport.advertise(this->_namespace + "/rgb_img", 100);
00779     this->_depth_img_pub = this->_image_transport.advertise(this->_namespace + "/depth_img", 100);
00780     this->_tracked_feats_img_pub = this->_image_transport.advertise(this->_namespace + "/tracked_feats_img", 100);
00781     this->_tracked_feats_with_pm_img_pub = this->_image_transport.advertise(this->_namespace + "/tracked_feats_with_pm_img", 100);
00782     this->_depth_edges_img_pub = this->_image_transport.advertise(this->_namespace + "/depth_edges_img", 100);
00783     this->_tracking_mask_img_pub = this->_image_transport.advertise(this->_namespace + "/tracking_mask_img", 100);
00784     this->_detecting_mask_img_pub = this->_image_transport.advertise(this->_namespace + "/detecting_mask_img", 100);
00785     this->_predicted_and_past_feats_img_pub = this->_image_transport.advertise(this->_namespace + "/pred_and_past_feats_img", 100);
00786     this->_prediction_mask_img_pub = this->_image_transport.advertise(this->_namespace + "/predicting_msk_img", 100);
00787     this->_camera_info_pub2 =this->_measurements_node_handle.advertise<sensor_msgs::CameraInfo>(this->_namespace + "/camera_info",100);
00788 
00789     this->_pred_feat_locs_repub = this->_measurements_node_handle.advertise<ft_state_ros_t>(this->_namespace + "/pred_feat_locs_repub" ,100);
00790 
00791     this->_camera_info_pub =this->_measurements_node_handle.advertise<sensor_msgs::CameraInfo>(this->_ci_topic,100);
00792     
00793     if(this->_data_from_bag )
00794     {
00795         this->_full_rgbd_pc_repub = this->_measurements_node_handle.advertise<sensor_msgs::PointCloud2>("camera/depth_registered/points",100);
00796         this->_tf_repub = this->_measurements_node_handle.advertise<tf::tfMessage>("tf",100);
00797         this->_shutdown_publisher = this->_measurements_node_handle.advertise<std_msgs::Empty>("/omip/shutdown",100);
00798     }
00799 
00800 
00801     // Wait for refinements of the pose coming from a shape tracker node
00802     if(this->_advance_frame_mechanism == 2)
00803     {
00804         ROS_INFO("Waiting for ShapeReconstruction to advance");
00805         this->_advance_sub = this->_state_prediction_node_handles.at(0).subscribe("segmentation_info_msg", 1,
00806                                                                                   &FeatureTrackerNode::AdvanceBagCallbackFromShapeReconstruction, this);
00807     }else if(this->_advance_frame_mechanism == 3){
00808         ROS_INFO("Waiting for ShapeTracker to advance");
00809         this->_advance_sub = this->_state_prediction_node_handles.at(0).subscribe("/shape_tracker/state", 1,
00810                                                                                   &FeatureTrackerNode::AdvanceBagCallbackFromShapeTracker, this);
00811     }
00812 }
00813 
00814 void FeatureTrackerNode::AdvanceBagCallbackFromShapeReconstruction(const boost::shared_ptr<std_msgs::Bool const> &flag)
00815 {
00816     ROS_DEBUG_STREAM("Advance flag from ShapeReconstruction received in FeatureTracker!");
00817     this->_advance_sub_returned_true = true;
00818 }
00819 
00820 void FeatureTrackerNode::AdvanceBagCallbackFromShapeTracker(const boost::shared_ptr<omip_msgs::ShapeTrackerStates const> &st_states)
00821 {
00822     ROS_DEBUG_STREAM("Advance flag from ShapeTracker received in FeatureTracker!");
00823     this->_advance_sub_returned_true = true;
00824 }
00825 
00826 void FeatureTrackerNode::run()
00827 {
00828     if (this->_data_from_bag)
00829     {
00830         for(int idx = 0; idx < this->_num_external_state_predictors; idx++)
00831         {
00832             // Create a thread that spins on the callback queue of the predictions
00833             this->_state_predictor_listener_threads.push_back(new boost::thread(boost::bind(&RecursiveEstimatorNodeInterface::spinStatePredictorQueue, this, idx)));
00834         }
00835         this->ReadRosBag();
00836     }else{
00837         RecursiveEstimatorNodeInterface::run();
00838     }
00839 }
00840 
00841 // Main program
00842 int main(int argc, char** argv)
00843 {
00844     ros::init(argc, argv, "feature_tracker");
00845     FeatureTrackerNode ft_node;
00846 
00847     bool press_enter_to_start = false;
00848     ft_node.getROSParameter<bool>("/omip/press_enter_to_start", press_enter_to_start);
00849     if(press_enter_to_start)
00850     {
00851         std::cout << "************************************************************************" << std::endl;
00852         std::cout << "Press enter to start Online Interactive Perception" << std::endl;
00853         std::cout << "************************************************************************" << std::endl;
00854         getchar();
00855     }else{
00856         std::cout << "Starting Online Interactive Perception" << std::endl;
00857     }
00858 
00859     ft_node.run();
00860     
00861     return (0);
00862 }


feature_tracker
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:26:39