FeatureTrackerNode.cpp
Go to the documentation of this file.
2 #include <pcl/conversions.h>
3 #include <rosbag/bag.h>
4 #include <rosbag/view.h>
5 #include <boost/foreach.hpp>
6 #include <tf/tfMessage.h>
9 #include <geometry_msgs/TransformStamped.h>
10 
11 #include <rosgraph_msgs/Clock.h>
12 
13 #include <std_msgs/Float64.h>
14 
16 
17 #include <unistd.h>
18 
20 
21 #if ROS_VERSION_MINIMUM(1, 11, 1) // if current ros version is >= 1.10.1 (hydro)
22 #else
24 #endif
25 
26 #define LINES_OF_TERMINAL_FT 4
27 
28 using namespace omip;
29 
32  _image_transport(this->_measurements_node_handle),
33  _synchronizer(NULL),
34  _data_from_bag(false),
35  _ci_initialized(false),
36  _subscribe_to_pc(false),
37  _publishing_depth_edges_img(false),
38  _publishing_tracked_feats_img(false),
39  _publishing_rgb_img(false),
40  _publishing_depth_img(false),
41  _publishing_tracked_feats_with_pred_msk_img(false),
42  _publishing_full_pc(false),
43  _publishing_predicting_msk_img(false),
44  _publishing_tracking_msk_img(false),
45  _publishing_detecting_msk_img(false),
46  _publishing_predicted_and_past_feats_img(false),
47  _republishing_predicted_feat_locs(false),
48  _advance_frame_min_wait_time(0.0),
49  _sensor_fps(0.0),
50  _loop_period_ns(0.0),
51  _processing_factor(0),
52  _advance_frame_mechanism(0),
53  _advance_frame_max_wait_time(60.),
54  _advance_sub_returned_true(false),
55  _attention_to_motion(false),
56  _occlusion_mask_positive(true)
57 {
58  this->_namespace = std::string("feature_tracker");
59 
60  this->_ReadParameters();
61 
63 
64  this->_InitializeVariables();
65 }
66 
68 {
69 }
70 
71 void FeatureTrackerNode::measurementCallback(const sensor_msgs::PointCloud2ConstPtr& full_pc_msg,
72  const sensor_msgs::ImageConstPtr &depth_image_msg,
73  const sensor_msgs::ImageConstPtr &rgb_image_msg)
74 {
75  // Pass the full RGBD point cloud
76  PointCloudPCL temp_cloud;
77  pcl::fromROSMsg(*full_pc_msg, temp_cloud);
78  this->_full_rgbd_pc = boost::make_shared<const PointCloudPCL>(temp_cloud);
79  this->_re_filter->setFullRGBDPC(this->_full_rgbd_pc);
80 
81  // Call the reduced callback, so that we don't duplicate code
82  this->measurementCallback(depth_image_msg, rgb_image_msg);
83 }
84 
85 void FeatureTrackerNode::measurementCallback(const sensor_msgs::ImageConstPtr &depth_image_msg,
86  const sensor_msgs::ImageConstPtr &rgb_image_msg)
87 {
88  ros::Time first = ros::Time::now();
89 
90  // Set the current time to be the time of the depth image
91  ros::Time current_measurement_time = depth_image_msg->header.stamp;
92 
93  ros::Duration time_between_meas;
94 
95  // If we are in the first iteration the prev meas time is zero and we don't check for the elapsed time
96  if(this->_previous_measurement_time.toSec() != 0.)
97  {
98  // Measure the time interval between the previous measurement and the current measurement
99  time_between_meas = current_measurement_time - this->_previous_measurement_time;
100 
101  // The time interval between frames is the inverse of the max_framerate
102  double period_between_frames = 1.0/this->_sensor_fps;
103 
104  // The number of frames elapsed is the time elapsed divided by the period between frames
105  int frames_between_meas = round((time_between_meas.toSec())/period_between_frames);
106 
107  // Processing fps: ignore (this->_processing_factor - 1) frames and process one. This gives effectively the desired processing fps: _sensor_fps/_processing_factor
108  if( frames_between_meas < this->_processing_factor )
109  {
110  return;
111  }
112  else if(frames_between_meas == this->_processing_factor )
113  {
114  ROS_INFO(" 0 frames lost. Processing at %d fps.", (int)this->_sensor_fps);
115  }
116  else if(frames_between_meas > this->_processing_factor)
117  {
118  // We show this message if we have lost frames
119  ROS_ERROR("%3d frames lost! Consider setting a lower frame rate." , frames_between_meas - this->_processing_factor);
120  }
121  }
122 
123  // Get the time of the current measurement (reference time from depth maps channel)
124  this->_current_measurement_time = current_measurement_time;
125 
126  // Create an ft_measurement object and pass it to the RE
127  this->_cv_ptr_depth = cv_bridge::toCvCopy(depth_image_msg);
128  this->_cv_ptr_rgb = cv_bridge::toCvCopy(rgb_image_msg);
129  ft_measurement_t latest_measurement = ft_measurement_t( this->_cv_ptr_rgb, this->_cv_ptr_depth);
130 
131  this->_re_filter->setMeasurement(latest_measurement, (double)this->_current_measurement_time.toNSec());
132 
133  // Predict next RE state
134  this->_re_filter->predictState(this->_loop_period_ns);
135 
136  // Predict next measurement based on the predicted state
137  this->_re_filter->predictMeasurement();
138 
139  //TOBETESTED: We do not jump the first frame because we need to detect features
140  // Use the predicted measurement and the received measurement to correct the state
141  this->_re_filter->correctState();
142 
143  // Publish the obtained new state
144  this->_publishState();
145 
146  // Publish additional stuff
147  this->PublishRGBImg();
148  this->PublishDepthImg();
149  this->PublishDepthEdgesImg();
152  this->PublishDetectingMaskImg();
153  this->PublishTrackingMaskImg();
155  this->PublishPredictionMaskImg();
156 
158 
159  if(this->_publishing_full_pc && this->_subscribe_to_pc)
160  {
161  this->PublishFullRGBDPC();
162  }
163 
164 
165  if (this->_data_from_bag)
166  {
167  static int advanced_frame_number = 0;
168  switch(this->_advance_frame_mechanism)
169  {
170  case 0://0 -> Automatically advancing, no waiting
171  {
172  usleep((int)(this->_advance_frame_min_wait_time));
173  }
174  break;
175  case 1://1 -> Manually advancing
176  {
177  std::cout << "Press enter to process the next frame" << std::endl;
178  getchar();
179  }
180  break;
181  case 2://2 -> Wait for signal from Shape Reconstruction
182  case 3://3 -> Wait for signal from Shape Tracker
183  {
184 
185  double max_time = _advance_frame_max_wait_time; //(seconds)
186 
187  if (max_time < 0) {
188  std::cout << "WARNING: no time limit, waiting forever" << std::endl;
189  max_time = std::numeric_limits<double>::max();
190  }
191 
192  std::cout << "Waiting for advance response in FTracker" ;
193 
194  double wait_time=0.;
195  while(advanced_frame_number > 0 && !this->_advance_sub_returned_true && wait_time < max_time && this->_active)
196  {
197  usleep(1e5);
198  printf(" (%4.1fs)", wait_time);
199  wait_time += 0.1;
200  }
201  if (wait_time >= max_time) {
202  std::cout << " Exceeded time limit " << max_time ;
203  } else {
204  std::cout << " Refinement received in FTracker" ;
205  }
206  this->_advance_sub_returned_true = false;
207  }
208  break;
209  }
210  advanced_frame_number++;
211  std::cout << ". Reading frame " << advanced_frame_number << std::endl;
212  }
213 
214  //After processing, the time stamp of the current measurement becomes the previous time
216 
217  ros::Time last = ros::Time::now();
218  ROS_WARN_STREAM("Time between meas: " << time_between_meas.toSec()*1000 << " ms");
219  ROS_WARN_STREAM("Total meas processing time: " << (last-first).toSec()*1000 << " ms");
220 }
221 
223 {
224  //convert dataset
225  FeatureCloudPCLwc temp_cloud;
226  pcl::fromROSMsg(*predicted_locations_pc, temp_cloud);
227  this->_predicted_locations_pc = boost::make_shared<FeatureCloudPCLwc>(temp_cloud);
228 
229  this->_re_filter->addPredictedState(this->_predicted_locations_pc, (double)predicted_locations_pc->header.stamp.toNSec());
230 }
231 
232 void FeatureTrackerNode::DynamicReconfigureCallback(feature_tracker::FeatureTrackerDynReconfConfig &config, uint32_t level)
233 {
234  // Set class variables to new values. They should match what is input at the dynamic reconfigure GUI.
235  this->_publishing_depth_edges_img = config.pub_depth_edges_img;
236  this->_publishing_tracked_feats_img = config.pub_tracked_feats_img;
237  this->_publishing_rgb_img = config.pub_rgb_img;
238  this->_publishing_depth_img = config.pub_depth_img;
239  this->_publishing_tracked_feats_with_pred_msk_img = config.pub_tracked_feats_with_pred_mask_img;
240  //this->_publishing_full_pc = config.pub_full_pc;
241  this->_publishing_predicting_msk_img = config.pub_predicting_msk_img;
242  this->_publishing_tracking_msk_img = config.pub_tracking_msk_img;
243  this->_publishing_detecting_msk_img = config.pub_detecting_msk_img;
244  this->_publishing_predicted_and_past_feats_img = config.pub_predicted_and_past_feats_img;
245 
246  this->_republishing_predicted_feat_locs = config.repub_predicted_feat_locs;
247 
248  this->_advance_frame_min_wait_time = 1e6*(config.advance_frame_min_wait_time);
249  if(this->_re_filter)
250  {
251  this->_re_filter->setDynamicReconfigureValues(config);
252  }
253 }
254 
256 {
257  rosbag::Bag bag;
258  ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadRosBag", "Reading rosbag: " <<this->_bag_file_name);
260 
261  std::vector<std::string> topics;
262  topics.push_back(this->_full_rgbd_pc_topic);
263  topics.push_back(this->_depth_img_topic);
264  topics.push_back(this->_rgb_img_topic);
265  topics.push_back(this->_occlusion_mask_img_topic);
266  topics.push_back(this->_ci_topic);
267  topics.push_back("/tf");
268 
269  ROS_DEBUG_STREAM_NAMED( "FeatureTrackerNode.ReadRosBag",
270  "Topics: " << this->_full_rgbd_pc_topic << std::endl
271  << this->_depth_img_topic << std::endl
272  << this->_rgb_img_topic << std::endl
273  << this->_occlusion_mask_img_topic << std::endl
274  << this->_ci_topic);
275 
276  rosbag::View view(bag, rosbag::TopicQuery(topics));
277 
278  int messages_counter = 0;
279  rosgraph_msgs::Clock time_now_msg;
280 
281  // When we read a rosbag we use the time of the bag
282  // 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
283  ros::Time time_now;
284  BOOST_FOREACH(rosbag::MessageInstance const m, view)
285  {
286  if(!this->_active)
287  break;
288 
289  if (m.getTopic() == this->_full_rgbd_pc_topic || ("/" + m.getTopic() == this->_full_rgbd_pc_topic))
290  {
291  sensor_msgs::PointCloud2::ConstPtr points_pc = m.instantiate<sensor_msgs::PointCloud2>();
292  if (points_pc != NULL )
293  {
294  if(this->_subscribe_to_pc)
295  {
296  this->_bag_full_rgbd_pc_sub.newMessage(points_pc);
297  }
298  time_now = points_pc->header.stamp;
299  }
302  }
303 
304  if (m.getTopic() == this->_occlusion_mask_img_topic || ("/" + m.getTopic() == this->_occlusion_mask_img_topic))
305  {
306  sensor_msgs::Image::Ptr occlusion_mask = m.instantiate<sensor_msgs::Image>();
307  if (occlusion_mask != NULL)
308  {
309  time_now = occlusion_mask->header.stamp;
310  this->OcclusionMaskImgCallback(occlusion_mask);
311  }
312  }
313 
314  if (m.getTopic() == this->_depth_img_topic || ("/" + m.getTopic() == this->_depth_img_topic))
315  {
316  sensor_msgs::Image::Ptr depth_img = m.instantiate<sensor_msgs::Image>();
317  if (depth_img != NULL)
318  {
319  time_now = depth_img->header.stamp;
320  this->_bag_depth_img_sub.newMessage(depth_img);
321  }
322  }
323 
324  if (m.getTopic() == this->_rgb_img_topic || ("/" + m.getTopic() == this->_rgb_img_topic))
325  {
326  sensor_msgs::Image::Ptr rgb_img = m.instantiate<sensor_msgs::Image>();
327  if (rgb_img != NULL)
328  {
329  time_now = rgb_img->header.stamp;
330  this->_bag_rgb_img_sub.newMessage(rgb_img);
331  }
332 
333  // Spin here the queue of the measurements
334  if (ros::ok())
335  {
337  }
338  }
339 
340  if ((m.getTopic() == this->_ci_topic || ("/" + m.getTopic() == this->_ci_topic)) && !this->_ci_initialized)
341  {
342  sensor_msgs::CameraInfo::ConstPtr ci_msg = m.instantiate<sensor_msgs::CameraInfo>();
343  if (ci_msg != NULL)
344  {
345  time_now = ci_msg->header.stamp;
346  this->_camera_info_msg = sensor_msgs::CameraInfo(*ci_msg);
347  this->_re_filter->setCameraInfoMsg(&this->_camera_info_msg);
348  this->_ci_initialized = true;
349  }
350  }
351 
352 
353  static tf::TransformBroadcaster br;
354  static bool first_ee_tf = true;
355 
356  if ((m.getTopic() == "/tf" || ("/" + m.getTopic() == "/tf")))
357  {
358  tf::tfMessage::Ptr tf_msg = m.instantiate<tf::tfMessage>();
359  if (tf_msg != NULL)
360  {
361  time_now = tf_msg->transforms.at(0).header.stamp;
362  for(int tf_transforms_idx = 0; tf_transforms_idx < tf_msg->transforms.size() ; tf_transforms_idx++)
363  {
364  geometry_msgs::TransformStamped transform = tf_msg->transforms.at(tf_transforms_idx);
365  if(transform.child_frame_id == "/ee")
366  {
367  if(first_ee_tf)
368  {
369  tf::StampedTransform cam_link_to_camera_rgb_optical_frame;
370 
371  tf::Vector3 translation = tf::Vector3(0.000, 0.020, 0.000);
372  cam_link_to_camera_rgb_optical_frame.setOrigin(translation);
373  tf::Quaternion rotation = tf::createQuaternionFromRPY(0.,0.0,-M_PI_2);
374  cam_link_to_camera_rgb_optical_frame.setRotation(rotation);
375 
376  tf::transformMsgToTF(transform.transform, this->_initial_ee_tf);
377  this->_initial_ee_tf = this->_initial_ee_tf * cam_link_to_camera_rgb_optical_frame;
378  first_ee_tf = false;
379  }
380 
381  //transform.header.stamp = ros::Time::now();
382  br.sendTransform(transform);
383 
384  geometry_msgs::TransformStamped initial_tf;
385  tf::transformTFToMsg(this->_initial_ee_tf, initial_tf.transform);
386  initial_tf.header = transform.header;
387  initial_tf.child_frame_id = "initial_transform";
388  br.sendTransform(initial_tf);
389  }
390  }
391  }
392  }
393 
394  time_now_msg.clock = time_now;
395  this->_time_repub.publish(time_now_msg);
396 
397  messages_counter++;
398  }
399 
400  if(this->_active)
401  {
402  ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadRosBag", "End of the rosbag.");
403  }
404  bag.close();
405  this->_shutdown_publisher.publish(std_msgs::Empty());
406 }
407 
408 void FeatureTrackerNode::OcclusionMaskImgCallback(const sensor_msgs::ImageConstPtr &occlusion_mask_img)
409 {
410  this->_cv_ptr_occlusion_msk = cv_bridge::toCvCopy(occlusion_mask_img, "mono8");
411  this->_re_filter->setOcclusionMaskImg(this->_cv_ptr_occlusion_msk);
412 }
413 
415 {
416  if(this->_publishing_rgb_img)
417  {
418  cv_bridge::CvImagePtr rgb_img = this->_re_filter->getRGBImg();
419  if(rgb_img)
420  {
421  rgb_img->header.frame_id = "camera_rgb_optical_frame";
422  rgb_img->header.stamp = this->_current_measurement_time;
423  this->_rgb_img_pub.publish(rgb_img->toImageMsg());
424  }
425  }
426 }
427 
429 {
430  if(this->_publishing_depth_img)
431  {
432  cv_bridge::CvImagePtr depth_img = this->_re_filter->getDepthImg();
433  if(depth_img)
434  {
435  depth_img->header.frame_id = "camera_rgb_optical_frame";
436  depth_img->header.stamp = this->_current_measurement_time;
437  this->_depth_img_pub.publish(depth_img->toImageMsg());
438  }
439  }
440 }
441 
443 {
444  if(this->_publishing_full_pc && this->_subscribe_to_pc)
445  {
446  sensor_msgs::PointCloud2 full_rgbd_pc_ros;
447  pcl::toROSMsg(*(this->_full_rgbd_pc), full_rgbd_pc_ros);
448  full_rgbd_pc_ros.header.stamp = this->_current_measurement_time;
449  full_rgbd_pc_ros.header.frame_id = "camera_rgb_optical_frame";
450  this->_full_rgbd_pc_repub.publish(full_rgbd_pc_ros);
451  }
452 }
453 
455 {
457  {
458  cv_bridge::CvImagePtr tracked_features_img = this->_re_filter->getTrackedFeaturesImg();
459  tracked_features_img->header.frame_id = "camera_rgb_optical_frame";
460  tracked_features_img->header.stamp = this->_current_measurement_time;
461  this->_tracked_feats_img_pub.publish(tracked_features_img->toImageMsg());
462  }
463 }
464 
466 {
468  {
469  cv_bridge::CvImagePtr tracked_features_with_pm_img = this->_re_filter
470  ->getTrackedFeaturesWithPredictionMaskImg();
471  tracked_features_with_pm_img->header.frame_id = "camera_rgb_optical_frame";
472  tracked_features_with_pm_img->header.stamp = this->_current_measurement_time;
473  this->_tracked_feats_with_pm_img_pub.publish(tracked_features_with_pm_img->toImageMsg());
474  }
475 }
476 
478 {
480  {
481  cv_bridge::CvImagePtr depth_edges_img = this->_re_filter
482  ->getDepthEdgesImg();
483  depth_edges_img->header.frame_id = "camera_rgb_optical_frame";
484  depth_edges_img->header.stamp = this->_current_measurement_time;
485  this->_depth_edges_img_pub.publish(depth_edges_img->toImageMsg());
486  }
487 }
488 
490 {
492  {
493  cv_bridge::CvImagePtr predicting_mask_img = this->_re_filter->getPredictingMaskImg();
494  predicting_mask_img->header.frame_id = "camera_rgb_optical_frame";
495  predicting_mask_img->header.stamp = this->_current_measurement_time;
496  this->_prediction_mask_img_pub.publish(predicting_mask_img->toImageMsg());
497  }
498 }
499 
501 {
503  {
504  cv_bridge::CvImagePtr tracking_mask_img = this->_re_filter->getTrackingMaskImg();
505  tracking_mask_img->header.frame_id = "camera_rgb_optical_frame";
506  tracking_mask_img->header.stamp = this->_current_measurement_time;
507  this->_tracking_mask_img_pub.publish(tracking_mask_img->toImageMsg());
508  }
509 }
510 
512 {
514  {
515  cv_bridge::CvImagePtr detecting_mask_img = this->_re_filter->getDetectingMaskImg();
516  detecting_mask_img->header.frame_id = "camera_rgb_optical_frame";
517  detecting_mask_img->header.stamp = this->_current_measurement_time;
518  this->_detecting_mask_img_pub.publish(detecting_mask_img->toImageMsg());
519  }
520 }
521 
523 {
525  {
526  cv_bridge::CvImagePtr predicted_and_last_feats_img = this->_re_filter->getPredictedAndLastFeaturesImg();
527  predicted_and_last_feats_img->header.frame_id = "camera_rgb_optical_frame";
528  predicted_and_last_feats_img->header.stamp = this->_current_measurement_time;
529  this->_predicted_and_past_feats_img_pub.publish(predicted_and_last_feats_img->toImageMsg());
530  }
531 }
532 
534 {
536  {
537  //convert dataset
538  sensor_msgs::PointCloud2 temp_cloud;
539  pcl::toROSMsg(*this->_predicted_locations_pc, temp_cloud);
540  temp_cloud.header.stamp = this->_current_measurement_time;
541  temp_cloud.header.frame_id = "camera_rgb_optical_frame";
542  _pred_feat_locs_repub.publish(temp_cloud);
543  }
544 }
545 
547 {
548  ft_state_t tracked_features_pc = this->_re_filter->getState();
549 
550  sensor_msgs::PointCloud2 tracked_features_pc_ros;
551  pcl::toROSMsg(*tracked_features_pc, tracked_features_pc_ros);
552  tracked_features_pc_ros.header.stamp = this->_current_measurement_time;
553  tracked_features_pc_ros.header.frame_id = "camera_rgb_optical_frame";
554 
555  this->_state_publisher.publish(tracked_features_pc_ros);
556 }
557 
559 {
560  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");
561 }
562 
564 {
565  this->getROSParameter<bool>(this->_namespace + std::string("/data_from_bag"),this->_data_from_bag);
566  this->getROSParameter<std::string>(this->_namespace + std::string("/ft_type"),this->_tracker_type);
567  this->getROSParameter<std::string>(this->_namespace + std::string("/bag_file"),this->_bag_file_name);
568  this->getROSParameter<std::string>(this->_namespace + std::string("/rgbd_pc_topic"),this->_full_rgbd_pc_topic);
569  this->getROSParameter<std::string>(this->_namespace + std::string("/depth_img_topic"),this->_depth_img_topic);
570  this->getROSParameter<std::string>(this->_namespace + std::string("/rgb_img_topic"),this->_rgb_img_topic);
571  this->getROSParameter<std::string>(this->_namespace + std::string("/camera_info_topic"),this->_ci_topic);
572 
573  this->getROSParameter<bool>(this->_namespace + std::string("/pub_depth_edges_img"),this->_publishing_depth_edges_img, false);
574  this->getROSParameter<bool>(this->_namespace + std::string("/pub_rgb_img"),this->_publishing_rgb_img, false);
575  this->getROSParameter<bool>(this->_namespace + std::string("/pub_depth_img"),this->_publishing_depth_img, false);
576  this->getROSParameter<bool>(this->_namespace + std::string("/pub_tracked_feats_img"),this->_publishing_tracked_feats_img, false);
577  this->getROSParameter<bool>(this->_namespace + std::string("/pub_tracked_feats_with_pred_mask_img"),this->_publishing_tracked_feats_with_pred_msk_img, false);
578  this->getROSParameter<bool>(this->_namespace + std::string("/pub_predicting_msk_img"),this->_publishing_predicting_msk_img, false);
579  this->getROSParameter<bool>(this->_namespace + std::string("/pub_tracking_msk_img"),this->_publishing_tracking_msk_img, false);
580  this->getROSParameter<bool>(this->_namespace + std::string("/pub_detecting_msk_img"),this->_publishing_detecting_msk_img, false);
581  this->getROSParameter<bool>(this->_namespace + std::string("/pub_predicted_and_past_feats_img"),this->_publishing_predicted_and_past_feats_img, false);
582 
583  this->getROSParameter<bool>(this->_namespace + std::string("/repub_predicted_feat_locs"),this->_republishing_predicted_feat_locs, false);
584 
585  this->getROSParameter<bool>(this->_namespace + std::string("/attention_to_motion"),this->_attention_to_motion);
586 
587 
588  this->getROSParameter<bool>(this->_namespace + std::string("/subscribe_to_pc"),this->_subscribe_to_pc);
589  this->getROSParameter<bool>(this->_namespace + std::string("/pub_full_pc"),this->_publishing_full_pc);
590 
591  this->getROSParameter<int>(this->_namespace + std::string("/advance_frame_mechanism"),this->_advance_frame_mechanism);
592  this->getROSParameter<double>(this->_namespace + std::string("/advance_frame_max_wait_time"),this->_advance_frame_max_wait_time, 60.);
593  this->getROSParameter<double>(this->_namespace + std::string("/advance_frame_min_wait_time"),this->_advance_frame_min_wait_time, -1);
594 
595  this->_advance_frame_min_wait_time *= 1e6;
596 
597  this->getROSParameter<std::string>(this->_namespace + std::string("/selfocclusionfilter_img_topic"),this->_occlusion_mask_img_topic);
598  this->_predicted_locations_pc_topic = std::string(this->_namespace + "/predicted_measurement");
599  this->getROSParameter<bool>(this->_namespace + std::string("/selfocclusionfilter_positive"),this->_occlusion_mask_positive);
600 
601  this->getROSParameter<double>(std::string("/omip/sensor_fps"), this->_sensor_fps);
602  this->getROSParameter<int>(std::string("/omip/processing_factor"), this->_processing_factor);
603  this->_loop_period_ns = 1e9/(this->_sensor_fps/(double)this->_processing_factor);
604 
605  // Defined also in feature_tracker_cfg.yaml
606  std::map<int, std::string > mechanism_codes;
607  mechanism_codes[0] = std::string("Automatically advancing, no waiting");
608  mechanism_codes[1] = std::string("Manually advancing");
609  mechanism_codes[2] = std::string("Wait for signal from Shape Reconstruction");
610  mechanism_codes[3] = std::string("Wait for signal from Shape Tracker");
611 
612  if(this->_data_from_bag)
613  {
614  ROS_ERROR_STREAM_NAMED("FeatureTrackerNode.ReadParameters","Reading a rosbag!");
615  ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadParameters",
616  "FeatureTrackerNode Parameters: " <<
617  "\n\tRosbag file: " << this->_bag_file_name <<
618  "\n\tType of advancing mechanism: " << mechanism_codes[this->_advance_frame_mechanism] <<
619  "\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 <<
620  "\n\tMinimum time to wait to advance a frame (only used if advance_frame_mechanism is 0): " << this->_advance_frame_min_wait_time/1e6 <<
621  "\n\tSubscribe to point cloud topic: " << this->_subscribe_to_pc <<
622  "\n\tSensor framerate: " << this->_sensor_fps << " fps (" << 1.f/this->_sensor_fps << " s)");
623  }else{
624  ROS_ERROR_STREAM_NAMED("FeatureTrackerNode.ReadParameters","Data from sensor!");
625  ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadParameters",
626  "FeatureTrackerNode Parameters: " <<
627  "\n\tSubscribe to point cloud topic: " << this->_subscribe_to_pc <<
628  "\n\tSensor framerate: " << this->_sensor_fps << " fps (" << 1.f/this->_sensor_fps << " s)");
629  }
630 
631 
632  if(this->_subscribe_to_pc)
633  {
634  ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadParameters",
635  "FeatureTrackerNode subscribes to these topics: " <<
636  "\n\t" << this->_full_rgbd_pc_topic <<
637  "\n\t" << this->_depth_img_topic <<
638  "\n\t" << this->_rgb_img_topic <<
639  "\n\t" << this->_ci_topic <<
640  "\n\t" << this->_occlusion_mask_img_topic);
641  }else{
642  ROS_INFO_STREAM_NAMED( "FeatureTrackerNode.ReadParameters",
643  "FeatureTrackerNode subscribes to these topics: " <<
644  "\n\t" << this->_depth_img_topic <<
645  "\n\t" << this->_rgb_img_topic <<
646  "\n\t" << this->_ci_topic <<
647  "\n\t" << this->_occlusion_mask_img_topic);
648  }
649 }
650 
652 {
653  if (this->_tracker_type == std::string("PointFeatureTracker"))
654  {
656  this->_subscribe_to_pc,
657  this->_namespace);
658  ((PointFeatureTracker*)this->_re_filter)->setSelfOcclusionPositive(_occlusion_mask_positive);
659  }
660  else
661  {
662  ROS_ERROR_STREAM_NAMED( "FeatureTrackerNode.getROSParameter",
663  "This type of Visual Tracker (" << this->_tracker_type << ") is not defined");
664  throw(std::string(
665  "[FeatureTrackerNode::getROSParameter] This type of Visual Tracker is not defined"));
666  }
667 
668  //Set the previous time to zero
670 
671  // Get the CameraInfo message from the sensor (when not reading from a bag)
672  if (!this->_data_from_bag)
673  {
674  // Waits a second to read one camera_info message from the camera driver, if not, returns an empty vector
675  sensor_msgs::CameraInfoConstPtr camera_info = ros::topic::waitForMessage<
676  sensor_msgs::CameraInfo>(this->_ci_topic, this->_measurements_node_handle,
677  ros::Duration(2.0));
678  if (camera_info)
679  {
680  this->_camera_info_msg = sensor_msgs::CameraInfo(*camera_info);
681  this->_re_filter->setCameraInfoMsg(&this->_camera_info_msg);
682  this->_ci_initialized = true;
684  }
685  else
686  {
688  "FeatureTrackerNode.getROSParameter",
689  "CameraInfo message could not get read. Using default values to initialize the camera info!");
690  this->_camera_info_msg.width = 640;
691  this->_camera_info_msg.height = 480;
692  this->_camera_info_msg.distortion_model = std::string("plumb_bob");
693  for(int i=0; i<5; i++)
694  this->_camera_info_msg.D.push_back(0.0);
695  this->_camera_info_msg.K[0] = 520;
696  this->_camera_info_msg.K[2] = 320;
697  this->_camera_info_msg.K[4] = 520;
698  this->_camera_info_msg.K[5] = 240;
699  this->_camera_info_msg.K[8] = 1;
700  this->_camera_info_msg.R[0] = 1;
701  this->_camera_info_msg.R[4] = 1;
702  this->_camera_info_msg.R[8] = 1;
703  this->_camera_info_msg.P[0] = 520;
704  this->_camera_info_msg.P[2] = 320;
705  this->_camera_info_msg.P[5] = 520;
706  this->_camera_info_msg.P[6] = 240;
707  this->_camera_info_msg.P[10] = 1;
708  this->_re_filter->setCameraInfoMsg(&this->_camera_info_msg);
709  this->_ci_initialized = false;
711  }
712  }
713 }
714 
716 {
717  // Setup the callback for the dynamic reconfigure
718  this->_dr_callback = boost::bind(&FeatureTrackerNode::DynamicReconfigureCallback, this, _1, _2);
719 
720  //this->_dr_srv = new dynamic_reconfigure::Server<feature_tracker::feature_tracker_paramsConfig>();
721  this->_dr_srv.setCallback(this->_dr_callback);
722 
723  // If we get the data from the kinect
724  if (!this->_data_from_bag)
725  {
728 
729  if (this->_subscribe_to_pc)
730  {
731  ROS_ERROR_STREAM_NAMED("FeatureTrackerNode._SubscribeAndAdvertiseTopics", "Using the HEAVY synchronization in FT (depth maps, RGB images and point clouds).");
734  this->_depth_img_sub, this->_rgb_img_sub);
735  }
736  else
737  {
738  ROS_ERROR_STREAM_NAMED("FeatureTrackerNode._SubscribeAndAdvertiseTopics", "Using the LIGHT synchronization in FT (depth maps and RGB images).");
740  this->_depth_img_sub, this->_rgb_img_sub);
741  }
742  }
743  // If we get the data from a bag
744  else
745  {
746  this->_time_repub = this->_measurements_node_handle.advertise<rosgraph_msgs::Clock>("clock", 100);
747  if (this->_subscribe_to_pc)
748  {
750  this->_bag_full_rgbd_pc_sub,
751  this->_bag_depth_img_sub,
752  this->_bag_rgb_img_sub);
753  }
754  else
755  {
757  this->_bag_depth_img_sub,
758  this->_bag_rgb_img_sub);
759  }
760  }
761 
762  if (this->_subscribe_to_pc)
763  {
764  this->_synchronizer->registerCallback(boost::bind(&FeatureTrackerNode::measurementCallback, this, _1, _2, _3));
765  }
766  else
767  {
768  this->_light_synchronizer->registerCallback(boost::bind(&FeatureTrackerNode::measurementCallback, this, _1, _2));
769  }
770 
773 
774  this->_state_prediction_subscriber = this->_state_prediction_node_handles.at(0).subscribe(
776 
777  this->_state_publisher = this->_measurements_node_handle.advertise<ft_state_ros_t>(this->_namespace + "/state", 100);
778  this->_rgb_img_pub = this->_image_transport.advertise(this->_namespace + "/rgb_img", 100);
779  this->_depth_img_pub = this->_image_transport.advertise(this->_namespace + "/depth_img", 100);
780  this->_tracked_feats_img_pub = this->_image_transport.advertise(this->_namespace + "/tracked_feats_img", 100);
781  this->_tracked_feats_with_pm_img_pub = this->_image_transport.advertise(this->_namespace + "/tracked_feats_with_pm_img", 100);
782  this->_depth_edges_img_pub = this->_image_transport.advertise(this->_namespace + "/depth_edges_img", 100);
783  this->_tracking_mask_img_pub = this->_image_transport.advertise(this->_namespace + "/tracking_mask_img", 100);
784  this->_detecting_mask_img_pub = this->_image_transport.advertise(this->_namespace + "/detecting_mask_img", 100);
785  this->_predicted_and_past_feats_img_pub = this->_image_transport.advertise(this->_namespace + "/pred_and_past_feats_img", 100);
786  this->_prediction_mask_img_pub = this->_image_transport.advertise(this->_namespace + "/predicting_msk_img", 100);
787  this->_camera_info_pub2 =this->_measurements_node_handle.advertise<sensor_msgs::CameraInfo>(this->_namespace + "/camera_info",100);
788 
789  this->_pred_feat_locs_repub = this->_measurements_node_handle.advertise<ft_state_ros_t>(this->_namespace + "/pred_feat_locs_repub" ,100);
790 
791  this->_camera_info_pub =this->_measurements_node_handle.advertise<sensor_msgs::CameraInfo>(this->_ci_topic,100);
792 
793  if(this->_data_from_bag )
794  {
795  this->_full_rgbd_pc_repub = this->_measurements_node_handle.advertise<sensor_msgs::PointCloud2>("camera/depth_registered/points",100);
796  this->_tf_repub = this->_measurements_node_handle.advertise<tf::tfMessage>("tf",100);
797  this->_shutdown_publisher = this->_measurements_node_handle.advertise<std_msgs::Empty>("/omip/shutdown",100);
798  }
799 
800 
801  // Wait for refinements of the pose coming from a shape tracker node
802  if(this->_advance_frame_mechanism == 2)
803  {
804  ROS_INFO("Waiting for ShapeReconstruction to advance");
805  this->_advance_sub = this->_state_prediction_node_handles.at(0).subscribe("segmentation_info_msg", 1,
807  }else if(this->_advance_frame_mechanism == 3){
808  ROS_INFO("Waiting for ShapeTracker to advance");
809  this->_advance_sub = this->_state_prediction_node_handles.at(0).subscribe("/shape_tracker/state", 1,
811  }
812 }
813 
815 {
816  ROS_DEBUG_STREAM("Advance flag from ShapeReconstruction received in FeatureTracker!");
817  this->_advance_sub_returned_true = true;
818 }
819 
821 {
822  ROS_DEBUG_STREAM("Advance flag from ShapeTracker received in FeatureTracker!");
823  this->_advance_sub_returned_true = true;
824 }
825 
827 {
828  if (this->_data_from_bag)
829  {
830  for(int idx = 0; idx < this->_num_external_state_predictors; idx++)
831  {
832  // Create a thread that spins on the callback queue of the predictions
833  this->_state_predictor_listener_threads.push_back(new boost::thread(boost::bind(&RecursiveEstimatorNodeInterface::spinStatePredictorQueue, this, idx)));
834  }
835  this->ReadRosBag();
836  }else{
838  }
839 }
840 
841 // Main program
842 int main(int argc, char** argv)
843 {
844  ros::init(argc, argv, "feature_tracker");
845  FeatureTrackerNode ft_node;
846 
847  bool press_enter_to_start = false;
848  ft_node.getROSParameter<bool>("/omip/press_enter_to_start", press_enter_to_start);
849  if(press_enter_to_start)
850  {
851  std::cout << "************************************************************************" << std::endl;
852  std::cout << "Press enter to start Online Interactive Perception" << std::endl;
853  std::cout << "************************************************************************" << std::endl;
854  getchar();
855  }else{
856  std::cout << "Starting Online Interactive Perception" << std::endl;
857  }
858 
859  ft_node.run();
860 
861  return (0);
862 }
message_filters::Subscriber< sensor_msgs::PointCloud2 > _full_rgbd_pc_sub
dynamic_reconfigure::Server< feature_tracker::FeatureTrackerDynReconfConfig >::CallbackType _dr_callback
static tf::Quaternion createQuaternionFromRPY(double roll, double pitch, double yaw)
TFSIMD_FORCE_INLINE void setRotation(const Quaternion &q)
void newMessage(const boost::shared_ptr< M const > &msg)
pcl::PointCloud< pcl::PointXYZRGB > PointCloudPCL
virtual void DynamicReconfigureCallback(feature_tracker::FeatureTrackerDynReconfConfig &config, uint32_t level)
Callback for the Dynamic Reconfigure parameters.
std::pair< cv_bridge::CvImagePtr, cv_bridge::CvImagePtr > ft_measurement_t
#define ROS_DEBUG_STREAM_NAMED(name, args)
void publish(const boost::shared_ptr< M > &message) const
message_filters::Subscriber< sensor_msgs::Image > _rgb_img_sub
#define ROS_ERROR_STREAM_NAMED(name, args)
image_transport::Publisher _depth_img_pub
std::string _predicted_locations_pc_topic
void open(std::string const &filename, uint32_t mode=bagmode::Read)
f
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
message_filters::sync_policies::ApproximateTime< sensor_msgs::PointCloud2, sensor_msgs::Image, sensor_msgs::Image > FTrackerSyncPolicy
BagSubscriber< sensor_msgs::Image > _bag_depth_img_sub
ros::Publisher _shutdown_publisher
FeatureCloudPCLwc::Ptr ft_state_t
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
Publisher advertise(const std::string &base_topic, uint32_t queue_size, bool latch=false)
virtual void PublishDepthEdgesImg()
Publish an image with the edges detected on the depth map.
virtual void AdvanceBagCallbackFromShapeReconstruction(const boost::shared_ptr< std_msgs::Bool const > &flag)
void fromROSMsg(const sensor_msgs::PointCloud2 &cloud, pcl::PointCloud< T > &pcl_cloud)
virtual void PublishTrackedFeaturesImg()
Publish an image with the last tracked features on it.
#define ROS_INFO_STREAM_NAMED(name, args)
dynamic_reconfigure::Server< feature_tracker::FeatureTrackerDynReconfConfig > _dr_srv
FeatureCloudPCLwc::Ptr _predicted_locations_pc
virtual void _publishPredictedMeasurement() const
Publish the prediction about the next measurement by this RE level.
void close()
cv_bridge::CvImagePtr _cv_ptr_depth
BagSubscriber< sensor_msgs::Image > _bag_rgb_img_sub
Time & fromSec(double t)
image_transport::Publisher _detecting_mask_img_pub
virtual void RepublishPredictedFeatLocation()
image_transport::Publisher _prediction_mask_img_pub
sensor_msgs::CameraInfo _camera_info_msg
virtual void spinStatePredictorQueue(int state_prediction_queue_idx)
sensor_msgs::PointCloud2 ft_state_ros_t
bool getROSParameter(std::string param_name, T &param_container)
ros::Publisher _full_rgbd_pc_repub
image_transport::Publisher _tracked_feats_with_pm_img_pub
virtual void PublishTrackedFeaturesWithPredictionMaskImg()
Publish an image with the last tracked features together with the mask of the predictions.
virtual void _SubscribeAndAdvertiseTopics()
virtual void _publishState() const
Publish the current state of this RE level.
void publish(const sensor_msgs::Image &message) const
image_transport::Publisher _depth_edges_img_pub
message_filters::Synchronizer< FTrackerLightSyncPolicy > * _light_synchronizer
#define ROS_INFO(...)
virtual void PublishPredictedAndLastFeaturesImg()
Publish an image with the last feature locations and the predicted feature locations.
virtual void PublishPredictionMaskImg()
Publish the mask of the predictions.
boost::shared_ptr< T > instantiate() const
CvImagePtr toCvCopy(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
message_filters::Synchronizer< FTrackerSyncPolicy > * _synchronizer
virtual void AdvanceBagCallbackFromShapeTracker(const boost::shared_ptr< omip_msgs::ShapeTrackerStates const > &st_states)
ROSCPP_DECL bool ok()
void sendTransform(const StampedTransform &transform)
uint64_t toNSec() const
message_filters::sync_policies::ApproximateTime< sensor_msgs::Image, sensor_msgs::Image > FTrackerLightSyncPolicy
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
virtual void PublishDetectingMaskImg()
Publish the mask used to detect new features. Combines edges, max depth and mask of current features ...
#define ROS_WARN_STREAM(args)
#define ROS_DEBUG_STREAM(args)
ros::Subscriber _occlusion_mask_img_sub
FeatureTrackerNode class Connects to the ROS communication system to get messages from the sensors an...
image_transport::Publisher _predicted_and_past_feats_img_pub
virtual void OcclusionMaskImgCallback(const sensor_msgs::ImageConstPtr &occlusion_mask_img)
Callback for the mask of the self occlusion of the robot. Only for the WAM.
image_transport::Publisher _rgb_img_pub
virtual void PublishTrackingMaskImg()
Publish the mask used to track features. Combines edges, predictions mask and max depth...
void subscribe(ros::NodeHandle &nh, const std::string &topic, uint32_t queue_size, const ros::TransportHints &transport_hints=ros::TransportHints(), ros::CallbackQueueInterface *callback_queue=0)
static void transformMsgToTF(const geometry_msgs::Transform &msg, Transform &bt)
ros::Publisher _pred_feat_locs_repub
std::string const & getTopic() const
PointCloudPCL::ConstPtr _full_rgbd_pc
void toROSMsg(const sensor_msgs::PointCloud2 &cloud, sensor_msgs::Image &image)
#define ROS_ERROR_NAMED(name,...)
static Time now()
pcl::PointCloud< FeaturePCLwc > FeatureCloudPCLwc
image_transport::Publisher _tracked_feats_img_pub
image_transport::ImageTransport _image_transport
virtual void PublishFullRGBDPC()
Publish the full RGB-D point cloud used in the last iteration (used to synchronize the PC to the othe...
virtual void measurementCallback(const sensor_msgs::PointCloud2ConstPtr &pc_msg, const sensor_msgs::ImageConstPtr &depth_image_msg, const sensor_msgs::ImageConstPtr &rgb_image_msg)
Combined callback for the measurements of this RE level: point cloud, depth image and rgb image...
boost::shared_ptr< M const > waitForMessage(const std::string &topic, NodeHandle &nh, ros::Duration timeout)
image_transport::Publisher _tracking_mask_img_pub
BagSubscriber< sensor_msgs::PointCloud2 > _bag_full_rgbd_pc_sub
#define ROS_ERROR(...)
cv_bridge::CvImagePtr _cv_ptr_occlusion_msk
message_filters::Subscriber< sensor_msgs::Image > _depth_img_sub
virtual void statePredictionCallback(const boost::shared_ptr< ft_state_ros_t const > &predicted_next_state)
Callback for the predictions about the state of this RE level coming from the higher level of the hie...
TFSIMD_FORCE_INLINE void setOrigin(const Vector3 &origin)
static void transformTFToMsg(const Transform &bt, geometry_msgs::Transform &msg)
cv_bridge::CvImagePtr _cv_ptr_rgb
int main(int argc, char **argv)
virtual void ReadRosBag()
Read messages from a rosbag instead of receiving them from a sensor Internally it "publishes" the mes...


feature_tracker
Author(s): Roberto Martín-Martín
autogenerated on Mon Jun 10 2019 14:06:08