MultiRBTrackerNode.cpp
Go to the documentation of this file.
00001 #include <vector>
00002 #include <stdio.h>
00003 #include "geometry_msgs/PoseArray.h"
00004 #include <geometry_msgs/PoseWithCovarianceStamped.h>
00005 #include <rosbag/message_instance.h>
00006 #include <rosbag/query.h>
00007 #include <rosbag/view.h>
00008 #include <sensor_msgs/Range.h>
00009 
00010 #include "rb_tracker/MultiRBTrackerNode.h"
00011 #include "rb_tracker/RBFilter.h"
00012 
00013 #include "omip_common/OMIPUtils.h"
00014 
00015 #include <pcl_conversions/pcl_conversions.h>
00016 
00017 #if ROS_VERSION_MINIMUM(1, 11, 1) // if current ros version is >= 1.11.1 (indigo)
00018 #else
00019 #include "rb_tracker/pcl_conversions_indigo.h"
00020 #endif
00021 
00022 #define LINES_OF_TERMINAL_RBT 20
00023 
00024 using namespace omip;
00025 
00026 #define MAX_DELAY_BETWEEN_FT_AND_ST 0.02
00027 
00028 MultiRBTrackerNode::MultiRBTrackerNode() :
00029     RecursiveEstimatorNodeInterface(1),
00030     _loop_period_ns(0.),
00031     _ransac_iterations(-1),
00032     _estimation_error_threshold(-1.),
00033     _static_motion_threshold(-1.),
00034     _new_rbm_error_threshold(-1.),
00035     _max_error_to_reassign_feats(-1.),
00036     _sensor_fps(0.0),
00037     _processing_factor(0),
00038     _supporting_features_threshold(-1),
00039     _min_num_feats_for_new_rb(-1),
00040     _min_num_frames_for_new_rb(-1),
00041     _publishing_rbposes_with_cov(false),
00042     _publishing_clustered_pc(true),
00043     _publishing_tf(true),
00044     _printing_rb_poses(true),
00045     _shape_tracker_received(false)
00046 {
00047     this->_namespace = std::string("rb_tracker");
00048 
00049     this->ReadParameters();
00050 
00051     this->_previous_measurement_time.fromSec(0.);
00052 
00053     // Setup the callback for the dynamic reconfigure
00054     this->_dr_callback = boost::bind(&MultiRBTrackerNode::DynamicReconfigureCallback, this, _1, _2);
00055     this->_dr_srv.setCallback(this->_dr_callback);
00056 
00057     // Setup the subscriber for the measurements from the lower RE level
00058     this->_measurement_subscriber= this->_measurements_node_handle.subscribe("/feature_tracker/state", 100, &MultiRBTrackerNode::measurementCallback, this);
00059     // Setup the subscriber for state predictions from the higher RE level
00060     this->_state_prediction_subscriber = this->_state_prediction_node_handles[0].subscribe(this->_namespace + "/predicted_measurement", 10,
00061                                                                                               &MultiRBTrackerNode::statePredictionCallback, this);
00062 
00063     this->_meas_from_st_subscriber = this->_state_prediction_node_handles[0].subscribe("/shape_tracker/state", 10,
00064                                                                                           &MultiRBTrackerNode::MeasurementFromShapeTrackerCallback, this);
00065 
00066     // Setup the publisher for the predicted measurements. They are used as state predictions by the lower RE level
00067     this->_measurement_prediction_publisher = this->_measurements_node_handle.advertise<ft_state_ros_t>("/feature_tracker/predicted_measurement", 1);
00068     this->_state_publisher = this->_measurements_node_handle.advertise<omip_msgs::RigidBodyPosesAndVelsMsg>(this->_namespace + "/state", 1);
00069 
00070 
00071     this->_state_publisher2 = this->_measurements_node_handle.advertise<omip_msgs::RigidBodyPosesAndVelsMsg>(this->_namespace + "/state_after_feat_correction", 1);
00072 
00073     // Additional published topics
00074     this->_clustered_pc_publisher = this->_measurements_node_handle.advertise<sensor_msgs::PointCloud2>(this->_namespace + "/clustered_tracked_feats", 100);
00075     this->_freefeats_pc_publisher = this->_measurements_node_handle.advertise<sensor_msgs::PointCloud2>(this->_namespace + "/free_feats", 100);
00076 
00077     this->_predictedfeats_pc_publisher = this->_measurements_node_handle.advertise<sensor_msgs::PointCloud2>(this->_namespace + "/predicted_feats", 100);
00078     this->_atbirthfeats_pc_publisher = this->_measurements_node_handle.advertise<sensor_msgs::PointCloud2>(this->_namespace + "/atbirth_feats", 100);
00079 
00080 
00081     // Initial constraint in the motion of the camera (initially constrained to no motion)
00082     int max_num_rb = -1;
00083     this->getROSParameter<int>(this->_namespace + std::string("/max_num_rb"), max_num_rb, max_num_rb);
00084 
00085     // Initial constraint in the motion of the camera (initially constrained to no motion)
00086     int initial_cam_motion_constraint = 6;
00087     this->getROSParameter<int>(this->_namespace + std::string("/cam_motion_constraint"), initial_cam_motion_constraint, initial_cam_motion_constraint);
00088 
00089     // Type of filter for the static environment (EKF based or ICP based)
00090     int static_environment_tracker_type_int;
00091     this->getROSParameter<int>(this->_namespace + std::string("/static_environment_type"), static_environment_tracker_type_int);
00092     this->_static_environment_tracker_type = (static_environment_tracker_t)static_environment_tracker_type_int;
00093 
00094     double meas_depth_factor;
00095     this->getROSParameter<double>(this->_namespace + std::string("/cov_meas_depth_factor"), meas_depth_factor);
00096     double min_cov_meas_x;
00097     this->getROSParameter<double>(this->_namespace + std::string("/min_cov_meas_x"), min_cov_meas_x);
00098     double min_cov_meas_y;
00099     this->getROSParameter<double>(this->_namespace + std::string("/min_cov_meas_y"), min_cov_meas_y);
00100     double min_cov_meas_z;
00101     this->getROSParameter<double>(this->_namespace + std::string("/min_cov_meas_z"), min_cov_meas_z);
00102     double prior_cov_pose;
00103     this->getROSParameter<double>(this->_namespace + std::string("/prior_cov_pose"), prior_cov_pose);
00104     double prior_cov_vel;
00105     this->getROSParameter<double>(this->_namespace + std::string("/prior_cov_vel"), prior_cov_vel);
00106     double cov_sys_acc_tx;
00107     this->getROSParameter<double>(this->_namespace + std::string("/cov_sys_acc_tx"), cov_sys_acc_tx);
00108     double cov_sys_acc_ty;
00109     this->getROSParameter<double>(this->_namespace + std::string("/cov_sys_acc_ty"), cov_sys_acc_ty);
00110     double cov_sys_acc_tz;
00111     this->getROSParameter<double>(this->_namespace + std::string("/cov_sys_acc_tz"), cov_sys_acc_tz);
00112     double cov_sys_acc_rx;
00113     this->getROSParameter<double>(this->_namespace + std::string("/cov_sys_acc_rx"), cov_sys_acc_rx);
00114     double cov_sys_acc_ry;
00115     this->getROSParameter<double>(this->_namespace + std::string("/cov_sys_acc_ry"), cov_sys_acc_ry);
00116     double cov_sys_acc_rz;
00117     this->getROSParameter<double>(this->_namespace + std::string("/cov_sys_acc_rz"), cov_sys_acc_rz);
00118 
00119     int min_num_points_in_segment;
00120     this->getROSParameter<int>(this->_namespace + std::string("/min_num_points_in_segment"), min_num_points_in_segment);
00121     double min_probabilistic_value;
00122     this->getROSParameter<double>(this->_namespace + std::string("/min_probabilistic_value"), min_probabilistic_value);
00123     double max_fitness_score;
00124     this->getROSParameter<double>(this->_namespace + std::string("/max_fitness_score"), max_fitness_score);
00125 
00126     double min_amount_translation_for_new_rb;
00127     this->getROSParameter<double>(this->_namespace + std::string("/min_amount_translation_for_new_rb"), min_amount_translation_for_new_rb);
00128     double min_amount_rotation_for_new_rb;
00129     this->getROSParameter<double>(this->_namespace + std::string("/min_amount_rotation_for_new_rb"), min_amount_rotation_for_new_rb);
00130 
00131     int min_num_supporting_feats_to_correct;
00132     this->getROSParameter<int>(this->_namespace + std::string("/min_num_supporting_feats_to_correct"), min_num_supporting_feats_to_correct);
00133 
00134     ROS_INFO_STREAM_NAMED( "MultiRBTrackerNode.ReadParameters",
00135                            "MultiRBTrackerNode Parameters: " <<
00136                            "\n\tmax_num_rb: " << max_num_rb <<
00137                            "\n\tmeas_depth_factor: " << meas_depth_factor <<
00138                            "\n\tmin_cov_meas_x: " << min_cov_meas_x <<
00139                            "\n\tmin_cov_meas_y: " << min_cov_meas_y <<
00140                            "\n\tmin_cov_meas_z: " << min_cov_meas_z <<
00141                            "\n\tprior_cov_pose: " << prior_cov_pose <<
00142                            "\n\tprior_cov_vel: " << prior_cov_vel <<
00143                            "\n\tcov_sys_acc_tx: " << cov_sys_acc_tx <<
00144                            "\n\tcov_sys_acc_ty: " << cov_sys_acc_ty <<
00145                            "\n\tcov_sys_acc_tz: " << cov_sys_acc_tz <<
00146                            "\n\tcov_sys_acc_rx: " << cov_sys_acc_rx <<
00147                            "\n\tcov_sys_acc_ry: " << cov_sys_acc_ry <<
00148                            "\n\tcov_sys_acc_rz: " << cov_sys_acc_rz <<
00149                            "\n\tmin_num_points_in_segment: " << min_num_points_in_segment <<
00150                            "\n\tmin_probabilistic_value: " << min_probabilistic_value <<
00151                            "\n\tmax_fitness_score: " << max_fitness_score <<
00152                            "\n\tmin_amount_translation_for_new_rb: " << min_amount_translation_for_new_rb <<
00153                            "\n\tmin_amount_rotation_for_new_rb: " << min_amount_rotation_for_new_rb <<
00154                            "\n\tmin_num_supporting_feats_to_correct: " << min_num_supporting_feats_to_correct <<
00155                            "\n\tcam_motion_constraint: " << initial_cam_motion_constraint);
00156 
00157     // Create the RE filter
00158     this->_re_filter = new MultiRBTracker(max_num_rb, this->_loop_period_ns,
00159                                           this->_ransac_iterations,
00160                                           this->_estimation_error_threshold,
00161                                           this->_static_motion_threshold,
00162                                           this->_new_rbm_error_threshold,
00163                                           this->_max_error_to_reassign_feats,
00164                                           this->_supporting_features_threshold,
00165                                           this->_min_num_feats_for_new_rb,
00166                                           this->_min_num_frames_for_new_rb,
00167                                           initial_cam_motion_constraint,
00168                                           this->_static_environment_tracker_type
00169                                           );
00170 
00171     this->_re_filter->setMeasurementDepthFactor(meas_depth_factor);
00172     this->_re_filter->setMinCovarianceMeasurementX(min_cov_meas_x);
00173     this->_re_filter->setMinCovarianceMeasurementY(min_cov_meas_y);
00174     this->_re_filter->setMinCovarianceMeasurementZ(min_cov_meas_z);
00175     this->_re_filter->setPriorCovariancePose(prior_cov_pose);
00176     this->_re_filter->setPriorCovarianceVelocity(prior_cov_vel);
00177     this->_re_filter->setCovarianceSystemAccelerationTx(cov_sys_acc_tx);
00178     this->_re_filter->setCovarianceSystemAccelerationTy(cov_sys_acc_ty);
00179     this->_re_filter->setCovarianceSystemAccelerationTz(cov_sys_acc_tz);
00180     this->_re_filter->setCovarianceSystemAccelerationRx(cov_sys_acc_rx);
00181     this->_re_filter->setCovarianceSystemAccelerationRy(cov_sys_acc_ry);
00182     this->_re_filter->setCovarianceSystemAccelerationRz(cov_sys_acc_rz);
00183     this->_re_filter->setNumberOfTrackedFeatures(this->_num_tracked_feats);
00184     this->_re_filter->setMinNumPointsInSegment(min_num_points_in_segment);
00185     this->_re_filter->setMinProbabilisticValue(min_probabilistic_value);
00186     this->_re_filter->setMaxFitnessScore(max_fitness_score);
00187     this->_re_filter->setMinAmountTranslationForNewRB(min_amount_translation_for_new_rb);
00188     this->_re_filter->setMinAmountRotationForNewRB(min_amount_rotation_for_new_rb);
00189     this->_re_filter->setMinNumberOfSupportingFeaturesToCorrectPredictedState(min_num_supporting_feats_to_correct);
00190 
00191     this->_re_filter->Init();
00192 }
00193 
00194 MultiRBTrackerNode::~MultiRBTrackerNode()
00195 {
00196 }
00197 
00198 void MultiRBTrackerNode::DynamicReconfigureCallback(rb_tracker::RBTrackerDynReconfConfig &config, uint32_t level)
00199 {
00200     // Set class variables to new values. They should match what is input at the dynamic reconfigure GUI.
00201     this->_publishing_rbposes_with_cov = config.pub_rb_poses_with_cov;
00202     this->_publishing_clustered_pc = config.pub_clustered_pc;
00203     this->_publishing_tf = config.pub_tf;
00204     this->_printing_rb_poses = config.print_rb_poses;
00205     if(this->_re_filter)
00206     {
00207         this->_re_filter->setDynamicReconfigureValues(config);
00208     }
00209 }
00210 
00211 void MultiRBTrackerNode::ReadParameters()
00212 {
00213     this->getROSParameter<int>(this->_namespace + std::string("/ransac_iterations"), this->_ransac_iterations);
00214     this->getROSParameter<double>(this->_namespace + std::string("/estimation_error_threshold"), this->_estimation_error_threshold);
00215     this->getROSParameter<double>(this->_namespace + std::string("/static_motion_threshold"), this->_static_motion_threshold);
00216     this->getROSParameter<double>(this->_namespace + std::string("/new_rbm_error_threshold"), this->_new_rbm_error_threshold);
00217     this->getROSParameter<double>(this->_namespace + std::string("/max_error_to_reassign_feats"), this->_max_error_to_reassign_feats);
00218     this->getROSParameter<int>(this->_namespace + std::string("/supporting_features_threshold"), this->_supporting_features_threshold);
00219     this->getROSParameter<int>(this->_namespace + std::string("/min_num_feats_for_new_rb"), this->_min_num_feats_for_new_rb);
00220     this->getROSParameter<int>(this->_namespace + std::string("/min_num_frames_for_new_rb"), this->_min_num_frames_for_new_rb);
00221 
00222     this->getROSParameter<bool>(this->_namespace + std::string("/pub_rb_poses_with_cov"), this->_publishing_rbposes_with_cov, false);
00223     this->getROSParameter<bool>(this->_namespace + std::string("/pub_clustered_pc"), this->_publishing_clustered_pc, true);
00224     this->getROSParameter<bool>(this->_namespace + std::string("/pub_tf"), this->_publishing_tf, true);
00225     this->getROSParameter<bool>(this->_namespace + std::string("/print_rb_poses"), this->_printing_rb_poses, true);
00226 
00227     this->getROSParameter<double>(std::string("/omip/sensor_fps"), this->_sensor_fps);
00228     this->getROSParameter<int>(std::string("/omip/processing_factor"), this->_processing_factor);
00229     this->_loop_period_ns = 1e9/(this->_sensor_fps/(double)this->_processing_factor);
00230 
00231     this->getROSParameter<int>(std::string("/feature_tracker/number_features"), this->_num_tracked_feats);
00232 
00233 
00234     ROS_INFO_STREAM_NAMED( "MultiRBTrackerNode.ReadParameters",
00235                            "MultiRBTrackerNode Parameters: " << std::endl //
00236                            << "\tRANSAC iterations: " << this->_ransac_iterations << std::endl //
00237                            << "\tEstimation error threshold: " << this->_estimation_error_threshold<< std::endl //
00238                            << "\tStatic motion threshold: " << this->_static_motion_threshold << std::endl //
00239                            << "\tNew RB motion threshold: " << this->_new_rbm_error_threshold<< std::endl //
00240                            << "\tMax error to reassign features: " << this->_max_error_to_reassign_feats<< std::endl //
00241                            << "\tNumber of tracked features: " << this->_num_tracked_feats<< std::endl //
00242                            << "\tSupporting features threshold: " << this->_supporting_features_threshold<< std::endl //
00243                            << "\tMin num of feats for motion estimation: " << this->_min_num_feats_for_new_rb << std::endl //
00244                            << "\tMin age for creation: " << this->_min_num_frames_for_new_rb << std::endl //
00245                            << "\tMax framerate (factor): " << this->_sensor_fps << "(" << this->_processing_factor << ")" );
00246 }
00247 
00248 void MultiRBTrackerNode::MeasurementFromShapeTrackerCallback(const boost::shared_ptr<omip_msgs::ShapeTrackerStates const> &shape_tracker_states)
00249 {
00250     this->_shape_tracker_meas = omip_msgs::ShapeTrackerStates(*shape_tracker_states);
00251     this->_re_filter->processMeasurementFromShapeTracker(this->_shape_tracker_meas);
00252 
00253 
00254 //    ROS_WARN_STREAM( "Current time minus refinement time: " << (this->_current_measurement_time - shape_tracker_states->header.stamp).toSec() );
00255 //    //Check if the result includes a valid refinement and updates
00256 //    if((this->_current_measurement_time - shape_tracker_states->header.stamp).toSec() < MAX_DELAY_BETWEEN_FT_AND_ST)
00257 //    {
00258 //        ROS_WARN_STREAM("Received measurement from shape tracker");
00259 //        this->_shape_tracker_meas = omip_msgs::ShapeTrackerStates(*shape_tracker_states);
00260 //        this->_shape_tracker_received = true;
00261 //    }else{
00262 //        ROS_ERROR_STREAM("Received measurement from shape tracker but too late. Time of the refinement: "
00263 //                         << shape_tracker_states->header.stamp <<  " Current time: " << this->_current_measurement_time);
00264 //    }
00265 }
00266 
00267 void MultiRBTrackerNode::measurementCallback(const boost::shared_ptr<rbt_measurement_ros_t const> &features_pc)
00268 {
00269     ros::Time tinit = ros::Time::now();
00270 
00271     // Get the time of the measurement as reference time
00272     this->_current_measurement_time = features_pc->header.stamp;
00273 
00274     // Convert point cloud of features to PCL pc
00275     rbt_measurement_t features_pc_pcl = rbt_measurement_t(new FeatureCloudPCLwc());
00276     pcl::fromROSMsg(*features_pc, *features_pc_pcl);
00277 
00278     this->_re_filter->setMeasurement(features_pc_pcl, (double)this->_current_measurement_time.toNSec());
00279 
00280     // Measure the time interval between the previous measurement and the current measurement
00281     ros::Duration time_between_meas = this->_current_measurement_time - this->_previous_measurement_time;
00282 
00283     // The time interval between frames is the inverse of the max_framerate
00284     double period_between_frames = 1.0/this->_sensor_fps;
00285 
00286     // The number of frames elapsed is the time elapsed divided by the period between frames
00287     int frames_between_meas = round((time_between_meas.toSec())/period_between_frames);
00288 
00289     // Processing fps: ignore (this->_processing_factor - 1) frames and process one. This gives effectively the desired processing fps: _sensor_fps/_processing_factor
00290     if( this->_previous_measurement_time.toSec() == 0.)
00291     {
00292         ROS_ERROR("First iteration. We predict after correct");
00293     }else{
00294         if( frames_between_meas != this->_processing_factor)
00295         {
00296             ROS_ERROR("Lost frames:%3d. Need to predict state and measurement again.", frames_between_meas - this->_processing_factor);
00297 
00298             // Predict next RE state
00299             this->_re_filter->predictState((double)time_between_meas.toNSec());
00300 
00301             // If the received prediction from the higher level is for this time step we use it
00302             if(abs((_last_predictions_kh.header.stamp - this->_current_measurement_time).toNSec()) < _loop_period_ns/2  )
00303             {
00304                 ROS_ERROR_STREAM_NAMED("MultiRBTrackerNode.measurementCallback", "The prediction from higher level can be used to predict next measurement before correction");
00305                 this->_re_filter->addPredictedState(_last_predictions_kh, (double)_last_predictions_kh.header.stamp.toNSec());
00306             }else{
00307                 ROS_ERROR_STREAM_NAMED("MultiRBTrackerNode.measurementCallback",
00308                                        "The prediction from higher level can NOT be used to predict next measurement before correction. Delay: "
00309                                        << (double)(this->_current_measurement_time - _last_predictions_kh.header.stamp).toNSec()/1e9);
00310             }
00311 
00312             // Predict next measurement based on the predicted state
00313             this->_re_filter->predictMeasurement();
00314         }else{
00315             ROS_INFO("Frames between measurements:%3d.", frames_between_meas);
00316         }
00317     }
00318 
00319     // In the first iteration we cannot correct the state because we have only one measurement
00320     if(this->_previous_measurement_time.toSec() != 0.)
00321     {
00322         // Use the predicted measurement and the received measurement to correct the state
00323         this->_re_filter->correctState();
00324     }
00325 
00326     this->_re_filter->ReflectState();
00327 
00328     // Publish the obtained new state
00329     this->_publishState();
00330 
00331     // Publish additional stuff
00332     this->_PrintResults();
00333     this->_PublishTF();
00334     this->_PublishClusteredFeatures();
00335     this->_PublishPosesWithCovariance();
00336 
00337     ros::Duration loop_duration(0.02);
00338     loop_duration.sleep();
00339 
00340     // Predict next RE state
00341     this->_re_filter->predictState(this->_loop_period_ns);
00342 
00343     // If the received prediction from the higher level is for the next time step we use it
00344     if(abs((_last_predictions_kh.header.stamp - (this->_current_measurement_time + ros::Duration(_loop_period_ns/1e9))).toNSec()) < _loop_period_ns/2 )
00345     {
00346         ROS_ERROR_STREAM_NAMED("MultiRBTrackerNode.measurementCallback", "The prediction from higher level can be used to predict next measurement after correction");
00347         this->_re_filter->addPredictedState(_last_predictions_kh, (double)_last_predictions_kh.header.stamp.toNSec());
00348     }else{
00349         ROS_ERROR_STREAM_NAMED("MultiRBTrackerNode.measurementCallback",
00350                                "The prediction from higher level can NOT be used to predict next measurment after correction. Delay: "
00351                                << (double)((this->_current_measurement_time + ros::Duration(_loop_period_ns/1e9)) - _last_predictions_kh.header.stamp).toNSec()/1e9);
00352     }
00353 
00354     // Predict next measurement based on the predicted state
00355     this->_re_filter->predictMeasurement();
00356 
00357     this->_publishPredictedMeasurement();
00358 
00359     this->_previous_measurement_time = this->_current_measurement_time;
00360 
00361     ros::Time tend = ros::Time::now();
00362     ROS_WARN_STREAM("Time between meas vision: " << time_between_meas.toSec()*1000 << " ms");
00363     ROS_WARN_STREAM("Total meas processing time vision: " << (tend-tinit).toSec()*1000 << " ms");
00364 }
00365 
00366 void MultiRBTrackerNode::statePredictionCallback(const boost::shared_ptr<rbt_state_t const> &predicted_rb_poses)
00367 {
00368     this->_last_predictions_kh = rbt_state_t(*predicted_rb_poses);
00369 }
00370 
00371 void MultiRBTrackerNode::_publishState() const
00372 {
00373     rbt_state_t poses_and_vels_msg = this->_re_filter->getState();
00374     poses_and_vels_msg.header.stamp = this->_current_measurement_time;
00375 
00376     poses_and_vels_msg.header.frame_id = "camera_rgb_optical_frame";
00377     this->_state_publisher2.publish(poses_and_vels_msg);
00378 
00379     rbt_state_t poses_and_vels_msg_corrected = this->_re_filter->getState();
00380     poses_and_vels_msg_corrected.header.stamp = this->_current_measurement_time;
00381 
00382     poses_and_vels_msg_corrected.header.frame_id = "camera_rgb_optical_frame";
00383 
00384     this->_state_publisher.publish(poses_and_vels_msg_corrected);
00385 
00386     this->_shape_tracker_received = false;
00387 }
00388 
00389 void MultiRBTrackerNode::_publishPredictedMeasurement() const
00390 {
00391     FeatureCloudPCLwc::Ptr predicted_locations = this->_re_filter->getPredictedMeasurement();
00392     predicted_locations->header.frame_id = "camera_rgb_optical_frame";
00393 
00394     sensor_msgs::PointCloud2 predicted_locations_ros;
00395     pcl::toROSMsg(*predicted_locations, predicted_locations_ros);
00396 
00397     this->_measurement_prediction_publisher.publish(predicted_locations_ros);
00398 }
00399 
00400 void MultiRBTrackerNode::_PrintResults() const
00401 {
00402     if(this->_printing_rb_poses)
00403     {
00404         // Get the poses (twists) of each RB
00405         std::vector<Eigen::Matrix4d> tracked_bodies_motion = this->_re_filter->getPoses();
00406 
00407         Eigen::Twistd pose_in_ec;
00408 
00409         RB_id_t RB_id;
00410         int num_supporting_feats = 0;
00411         for (size_t poses_idx = 0; poses_idx < tracked_bodies_motion.size(); poses_idx++)
00412         {
00413             RB_id = this->_re_filter->getRBId(poses_idx);
00414             num_supporting_feats = this->_re_filter->getNumberSupportingFeatures(poses_idx);
00415 
00416             TransformMatrix2Twist(tracked_bodies_motion[poses_idx], pose_in_ec);
00417             ROS_INFO_NAMED( "MultiRBTrackerNode::_PublishRBPoses", "RB%2d: Supporting feats: %d, Pose (vx,vy,vz,rx,ry,rz): % 2.2f,% 2.2f,% 2.2f,% 2.2f,% 2.2f,% 2.2f",
00418                             (int)RB_id,
00419                             num_supporting_feats,
00420                             pose_in_ec.vx(),
00421                             pose_in_ec.vy(),
00422                             pose_in_ec.vz(),
00423                             pose_in_ec.rx(),
00424                             pose_in_ec.ry(),
00425                             pose_in_ec.rz());
00426         }
00427     }
00428 }
00429 
00430 void MultiRBTrackerNode::_PublishPosesWithCovariance()
00431 {
00432     if(this->_publishing_rbposes_with_cov)
00433     {
00434         // Get the poses and covariances on the poses (pose with cov) of each RB
00435         std::vector<geometry_msgs::PoseWithCovariancePtr> tracked_poses_with_cov = this->_re_filter->getPosesWithCovariance();
00436 
00437         RB_id_t RB_id;
00438         for (size_t poses_idx = 0; poses_idx < tracked_poses_with_cov.size(); poses_idx++)
00439         {
00440             RB_id = this->_re_filter->getRBId(poses_idx);
00441             std::ostringstream oss;
00442             oss << "ip/rb" << RB_id;
00443 
00444             // Publish the pose with covariance of each RB with a different publisher and on a different topic name
00445             if (this->_est_body_publishers.find(RB_id) == this->_est_body_publishers.end())
00446             {
00447                 ros::Publisher* new_estimated_pose_publisher = new ros::Publisher(
00448                             this->_measurements_node_handle.advertise<geometry_msgs::PoseWithCovarianceStamped>(oss.str(), 100));
00449                 this->_est_body_publishers[RB_id] = new_estimated_pose_publisher;
00450             }
00451             geometry_msgs::PoseWithCovarianceStamped pose_with_cov_stamped;
00452             pose_with_cov_stamped.header.stamp = this->_current_measurement_time;
00453             pose_with_cov_stamped.header.frame_id = "camera_rgb_optical_frame";
00454             pose_with_cov_stamped.pose = *(tracked_poses_with_cov[poses_idx]);
00455             this->_est_body_publishers[this->_re_filter->getRBId(poses_idx)]->publish(pose_with_cov_stamped);
00456         }
00457     }
00458 }
00459 
00460 void MultiRBTrackerNode::_PublishTF()
00461 {
00462     static tf::TransformBroadcaster tf_br;
00463 
00464     if(this->_publishing_tf)
00465     {
00466         // Get the poses and covariances on the poses (pose with cov) of each RB
00467         std::vector<geometry_msgs::PoseWithCovariancePtr> tracked_poses_with_cov = this->_re_filter->getPosesWithCovariance();
00468         RB_id_t RB_id;
00469         for (size_t poses_idx = 0; poses_idx < tracked_poses_with_cov.size(); poses_idx++)
00470         {
00471             RB_id = this->_re_filter->getRBId(poses_idx);
00472             std::ostringstream oss;
00473             oss << "ip/rb" << RB_id;
00474 
00475             // Publish the pose of the RBs on the TF tree
00476             tf::Transform transform_auxiliar;
00477             transform_auxiliar.setOrigin(tf::Vector3(tracked_poses_with_cov[poses_idx]->pose.position.x, tracked_poses_with_cov[poses_idx]->pose.position.y,
00478                                                      tracked_poses_with_cov[poses_idx]->pose.position.z));
00479             transform_auxiliar.setRotation(tf::Quaternion(tracked_poses_with_cov.at(poses_idx)->pose.orientation.x,tracked_poses_with_cov.at(poses_idx)->pose.orientation.y,
00480                                                           tracked_poses_with_cov.at(poses_idx)->pose.orientation.z, tracked_poses_with_cov.at(poses_idx)->pose.orientation.w));
00481 
00482             tf_br.sendTransform(tf::StampedTransform(transform_auxiliar, this->_current_measurement_time, "camera_rgb_optical_frame",
00483                                                      RB_id == 0 ? "static_environment" : oss.str().c_str()));
00484         }
00485     }
00486 }
00487 
00488 void MultiRBTrackerNode::_PublishClusteredFeatures()
00489 {
00490     if(this->_publishing_clustered_pc)
00491     {
00492         FeatureCloudPCL clustered_pc = this->_re_filter->getLabelledSupportingFeatures();
00493         clustered_pc.header.frame_id = "camera_rgb_optical_frame";
00494         clustered_pc.header.stamp = pcl_conversions::toPCL(this->_current_measurement_time);
00495 
00496         sensor_msgs::PointCloud2 feature_set_ros;
00497         pcl::toROSMsg(clustered_pc, feature_set_ros);
00498         feature_set_ros.header.stamp = this->_current_measurement_time;
00499         this->_clustered_pc_publisher.publish(feature_set_ros);
00500 
00501         FeatureCloudPCL freefeats_pc = this->_re_filter->getFreeFeatures();
00502         freefeats_pc.header.frame_id = "camera_rgb_optical_frame";
00503         freefeats_pc.header.stamp = pcl_conversions::toPCL(this->_current_measurement_time);
00504 
00505         sensor_msgs::PointCloud2 freefeats_pc_ros;
00506         pcl::toROSMsg(freefeats_pc, freefeats_pc_ros);
00507         this->_freefeats_pc_publisher.publish(freefeats_pc_ros);
00508 
00509         FeatureCloudPCL predictedfeats_pc = this->_re_filter->getPredictedFeatures();
00510         predictedfeats_pc.header.frame_id = "camera_rgb_optical_frame";
00511         predictedfeats_pc.header.stamp = pcl_conversions::toPCL(this->_current_measurement_time);
00512 
00513         sensor_msgs::PointCloud2 predictedfeats_pc_ros;
00514         pcl::toROSMsg(predictedfeats_pc, predictedfeats_pc_ros);
00515         this->_predictedfeats_pc_publisher.publish(predictedfeats_pc_ros);
00516 
00517         FeatureCloudPCL atbirthfeats_pc = this->_re_filter->getAtBirthFeatures();
00518         atbirthfeats_pc.header.frame_id = "camera_rgb_optical_frame";
00519         atbirthfeats_pc.header.stamp = pcl_conversions::toPCL(this->_current_measurement_time);
00520 
00521         sensor_msgs::PointCloud2 atbirthfeats_pc_ros;
00522         pcl::toROSMsg(atbirthfeats_pc, atbirthfeats_pc_ros);
00523         this->_atbirthfeats_pc_publisher.publish(atbirthfeats_pc_ros);
00524     }
00525 }
00526 
00527 int main(int argc, char** argv)
00528 {
00529     ros::init(argc, argv, "rb_tracker");
00530     MultiRBTrackerNode rbtvn;
00531     rbtvn.run();
00532 
00533     return (0);
00534 }


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