00001 #include <boost/foreach.hpp>
00002
00003 #include "rb_tracker/MultiRBTracker.h"
00004
00005 #include "omip_common/OMIPUtils.h"
00006
00007 #include <cmath>
00008
00009 #include <pcl/correspondence.h>
00010 #include <pcl/registration/correspondence_rejection_sample_consensus.h>
00011
00012 #include <pcl_conversions/pcl_conversions.h>
00013
00014 #if ROS_VERSION_MINIMUM(1, 11, 1) // if current ros version is >= 1.11.1 (indigo)
00015 #else
00016 #include "rb_tracker/pcl_conversions_indigo.h"
00017 #endif
00018
00019 #include <pcl/console/print.h>
00020
00021 using namespace omip;
00022
00023 inline void estimateRigidTransformation(
00024 const FeaturesDataBase::MapOfFeatureLocationPairs& last2locations,
00025 Eigen::Matrix4d &transformation_matrix)
00026 {
00027
00028 const int npts = static_cast<int>(last2locations.size());
00029
00030 Eigen::Matrix<double, 3, Eigen::Dynamic> cloud_src(3, npts);
00031 Eigen::Matrix<double, 3, Eigen::Dynamic> cloud_tgt(3, npts);
00032
00033 FeaturesDataBase::MapOfFeatureLocationPairs::const_iterator locations_it =
00034 last2locations.begin();
00035 FeaturesDataBase::MapOfFeatureLocationPairs::const_iterator locations_it_end =
00036 last2locations.end();
00037 for (int i = 0; locations_it != locations_it_end; locations_it++, i++)
00038 {
00039 cloud_src(0, i) = locations_it->second.second.get<0>();
00040 cloud_src(1, i) = locations_it->second.second.get<1>();
00041 cloud_src(2, i) = locations_it->second.second.get<2>();
00042
00043 cloud_tgt(0, i) = locations_it->second.first.get<0>();
00044 cloud_tgt(1, i) = locations_it->second.first.get<1>();
00045 cloud_tgt(2, i) = locations_it->second.first.get<2>();
00046 }
00047
00048
00049 transformation_matrix = Eigen::umeyama(cloud_src, cloud_tgt, false);
00050 }
00051
00052 MultiRBTracker::MultiRBTracker(int max_num_rb,
00053 double loop_period_ns,
00054 int ransac_iterations,
00055 double estimation_error_threshold,
00056 double static_motion_threshold,
00057 double new_rbm_error_threshold,
00058 double max_error_to_reassign_feats,
00059 int supporting_features_threshold,
00060 int min_num_feats_for_new_rb,
00061 int min_num_frames_for_new_rb,
00062 int initial_cam_motion_constraint,
00063 static_environment_tracker_t static_environment_tracker_type) :
00064 RecursiveEstimatorFilterInterface(loop_period_ns),
00065 _max_num_rb(max_num_rb),
00066 _ransac_iterations(ransac_iterations),
00067 _estimation_error_threshold(estimation_error_threshold),
00068 _static_motion_threshold(static_motion_threshold),
00069 _new_rbm_error_threshold(new_rbm_error_threshold),
00070 _max_error_to_reassign_feats(max_error_to_reassign_feats),
00071 _supporting_features_threshold(supporting_features_threshold),
00072 _min_num_feats_for_new_rb(min_num_feats_for_new_rb),
00073 _min_num_frames_for_new_rb(min_num_frames_for_new_rb),
00074 _min_num_points_in_segment(0),
00075 _min_probabilistic_value(0.0),
00076 _max_fitness_score(0.0),
00077 _min_num_supporting_feats_to_correct(7),
00078 _max_distance_ee(-1),
00079 _max_distance_irb(-1)
00080 {
00081
00082
00083 this->_filter_name = "RBMFilter";
00084
00085 if (this->_features_db)
00086 this->_features_db.reset();
00087
00088 this->_features_db = FeaturesDataBase::Ptr(new FeaturesDataBase());
00089
00090 this->_predicted_measurement = rbt_measurement_t(new FeatureCloudPCLwc());
00091
00092
00093
00094 _static_environment_filter = StaticEnvironmentFilter::Ptr(new StaticEnvironmentFilter(this->_loop_period_ns,
00095 this->_features_db,
00096 this->_static_motion_threshold));
00097 _static_environment_filter->setComputationType(static_environment_tracker_type);
00098 _static_environment_filter->setFeaturesDatabase(this->_features_db);
00099 _static_environment_filter->setMotionConstraint(initial_cam_motion_constraint);
00100
00101 this->_kalman_filters.push_back(_static_environment_filter);
00102 }
00103
00104 void MultiRBTracker::Init()
00105 {
00106 _static_environment_filter->setMeasurementDepthFactor(this->_meas_depth_factor);
00107 _static_environment_filter->setMinCovarianceMeasurementX(this->_min_cov_meas_x);
00108 _static_environment_filter->setMinCovarianceMeasurementY(this->_min_cov_meas_y);
00109 _static_environment_filter->setMinCovarianceMeasurementZ(this->_min_cov_meas_z);
00110 _static_environment_filter->setPriorCovariancePose(this->_prior_cov_pose);
00111 _static_environment_filter->setPriorCovarianceVelocity(this->_prior_cov_vel);
00112 _static_environment_filter->setCovarianceSystemAccelerationTx(this->_cov_sys_acc_tx);
00113 _static_environment_filter->setCovarianceSystemAccelerationTy(this->_cov_sys_acc_ty);
00114 _static_environment_filter->setCovarianceSystemAccelerationTz(this->_cov_sys_acc_tz);
00115 _static_environment_filter->setCovarianceSystemAccelerationRx(this->_cov_sys_acc_rx);
00116 _static_environment_filter->setCovarianceSystemAccelerationRy(this->_cov_sys_acc_ry);
00117 _static_environment_filter->setCovarianceSystemAccelerationRz(this->_cov_sys_acc_rz);
00118 _static_environment_filter->setNumberOfTrackedFeatures(this->_num_tracked_feats);
00119 _static_environment_filter->setMinNumberOfSupportingFeaturesToCorrectPredictedState(this->_min_num_supporting_feats_to_correct);
00120 _static_environment_filter->Init();
00121 }
00122
00123 MultiRBTracker::~MultiRBTracker()
00124 {
00125
00126 }
00127
00128 void MultiRBTracker::setMeasurement(rbt_measurement_t acquired_measurement, const double& measurement_timestamp)
00129 {
00130 this->_previous_measurement_timestamp_ns = this->_measurement_timestamp_ns;
00131
00132 {
00133 boost::mutex::scoped_lock(this->_measurement_timestamp_ns_mutex);
00134 this->_measurement_timestamp_ns = measurement_timestamp;
00135 }
00136
00137 this->_features_db->clearListOfAliveFeatureIds();
00138 this->_measurement = acquired_measurement;
00139
00140 int num_tracked_features = acquired_measurement->points.size();
00141
00142 int tracked_features_index = 0;
00143 uint32_t feature_id;
00144 for (; tracked_features_index < num_tracked_features; tracked_features_index++)
00145 {
00146 feature_id = acquired_measurement->points[tracked_features_index].label;
00147 if(feature_id != 0)
00148 {
00149 Feature::Location feature_location = Feature::Location(acquired_measurement->points[tracked_features_index].x, acquired_measurement->points[tracked_features_index].y,
00150 acquired_measurement->points[tracked_features_index].z);
00151 this->addFeatureLocation(feature_id, feature_location);
00152 }
00153 }
00154 this->_features_db->step();
00155 }
00156
00157 void MultiRBTracker::predictState(double time_interval_ns)
00158 {
00159
00160 for (std::vector<RBFilter::Ptr>::iterator filter_it = this->_kalman_filters.begin(); filter_it != this->_kalman_filters.end(); filter_it++)
00161 {
00162 (*filter_it)->predictState(time_interval_ns);
00163 (*filter_it)->doNotUsePredictionFromHigherLevel();
00164 }
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 void MultiRBTracker::predictMeasurement()
00177 {
00178 std::vector<RBFilter::Ptr>::iterator filter_it = this->_kalman_filters.begin();
00179 for (; filter_it != this->_kalman_filters.end(); filter_it++)
00180 {
00181 (*filter_it)->predictMeasurement();
00182 }
00183
00184 this->_predicted_measurement->points.clear();
00185
00186 std::vector<Feature::Id> feature_ids;
00187 FeatureCloudPCLwc one_filter_predicted_measurement;
00188 filter_it = this->_kalman_filters.begin();
00189 filter_it++;
00190 for (; filter_it != this->_kalman_filters.end(); filter_it++)
00191 {
00192 one_filter_predicted_measurement = (*filter_it)->getPredictedMeasurement();
00193 for (size_t feat_idx = 0; feat_idx < one_filter_predicted_measurement.points.size(); feat_idx++)
00194 {
00195 this->_predicted_measurement->points.push_back(one_filter_predicted_measurement.points.at(feat_idx));
00196 feature_ids.push_back(one_filter_predicted_measurement.points.at(feat_idx).label);
00197 }
00198 }
00199
00200
00201 std::vector<Feature::Id> free_features_ids = this->EstimateFreeFeatures(feature_ids);
00202 FeaturePCLwc free_feat;
00203 for (size_t feat_idx = 0; feat_idx < free_features_ids.size(); feat_idx++)
00204 {
00205 free_feat.x = this->_features_db->getFeatureLastX(free_features_ids.at(feat_idx));
00206 free_feat.y = this->_features_db->getFeatureLastY(free_features_ids.at(feat_idx));
00207 free_feat.z = this->_features_db->getFeatureLastZ(free_features_ids.at(feat_idx));
00208 free_feat.label = free_features_ids.at(feat_idx);
00209 free_feat.covariance[0] = 20;
00210 this->_predicted_measurement->points.push_back(free_feat);
00211 }
00212 }
00213
00214 rbt_measurement_t MultiRBTracker::getPredictedMeasurement() const
00215 {
00216 this->_predicted_measurement->header.stamp = pcl_conversions::toPCL(ros::Time(this->_measurement_timestamp_ns/1e9+this->_loop_period_ns/1e9));
00217 return this->_predicted_measurement;
00218 }
00219
00220 std::vector<Feature::Id> MultiRBTracker::estimateBestPredictionsAndSupportingFeatures()
00221 {
00222 std::vector<Feature::Id> all_filters_supporting_features;
00223 for (std::vector<RBFilter::Ptr>::iterator filter_it = this->_kalman_filters.begin(); filter_it != this->_kalman_filters.end();)
00224 {
00225 (*filter_it)->estimateBestPredictionAndSupportingFeatures();
00226 std::vector<Feature::Id> this_filter_supporting_features = (*filter_it)->getSupportingFeatures();
00227
00228
00229
00230 if (this_filter_supporting_features.size() < (size_t)this->_supporting_features_threshold
00231 && *filter_it != this->_static_environment_filter )
00232 {
00233 Eigen::Twistd last_pose_ec;
00234 TransformMatrix2Twist((*filter_it)->getPose(), last_pose_ec);
00235 ROS_ERROR_NAMED( "MultiRBTracker.estimateBestPredictionsAndSupportingFeatures",
00236 "RBFilter %2d: Supporting feats:%3d (<%3d), Pose (vx,vy,vz,rx,ry,rz): % 2.2f,% 2.2f,% 2.2f,% 2.2f,% 2.2f,% 2.2f. REMOVED",
00237 (int)(*filter_it)->getId(),
00238 (int)this_filter_supporting_features.size() ,
00239 (int)(this->_supporting_features_threshold),
00240 last_pose_ec.vx(),
00241 last_pose_ec.vy(),
00242 last_pose_ec.vz(),
00243 last_pose_ec.rx(),
00244 last_pose_ec.ry(),
00245 last_pose_ec.rz());
00246 filter_it = this->_kalman_filters.erase(filter_it);
00247 }
00248 else
00249 {
00250 all_filters_supporting_features.insert(all_filters_supporting_features.end(),
00251 this_filter_supporting_features.begin(),
00252 this_filter_supporting_features.end());
00253 filter_it++;
00254 }
00255 }
00256 return all_filters_supporting_features;
00257 }
00258
00259 void MultiRBTracker::correctState()
00260 {
00261
00262 std::vector<Feature::Id> all_filters_supporting_features = this->estimateBestPredictionsAndSupportingFeatures();
00263
00264
00265 std::vector<Feature::Id> free_feat_ids = this->EstimateFreeFeatures(all_filters_supporting_features);
00266
00267
00268 std::vector<Feature::Id> really_free_feat_ids = this->ReassignFreeFeatures(free_feat_ids);
00269
00270 ROS_INFO_NAMED("MultiRBTracker::correctState","Moving bodies: %3d, free features: %3d", (int)this->_kalman_filters.size(), (int)really_free_feat_ids.size());
00271
00272
00273 for (std::vector<RBFilter::Ptr>::iterator filter_it = this->_kalman_filters.begin(); filter_it != this->_kalman_filters.end(); filter_it++)
00274 {
00275 (*filter_it)->correctState();
00276 }
00277
00278
00279
00280 if(this->_kalman_filters.size() < this->_max_num_rb)
00281 {
00282 this->TryToCreateNewFilter(really_free_feat_ids);
00283 }
00284 }
00285
00286 void MultiRBTracker::ReflectState()
00287 {
00288 this->_state.rb_poses_and_vels.clear();
00289
00290 std::vector<geometry_msgs::TwistWithCovariancePtr> tracked_poses_twist_with_cov = this->getPosesECWithCovariance();
00291 std::vector<geometry_msgs::TwistWithCovariancePtr> tracked_vels_twist_with_cov = this->getVelocitiesWithCovariance();
00292 std::vector<Eigen::Vector3d> centroids = this->getCentroids();
00293
00294 RB_id_t RB_id;
00295
00296 for (size_t poses_idx = 0; poses_idx < tracked_poses_twist_with_cov.size(); poses_idx++)
00297 {
00298 RB_id = this->getRBId(poses_idx);
00299
00300 geometry_msgs::Point centroid;
00301 centroid.x = centroids.at(poses_idx).x();
00302 centroid.y = centroids.at(poses_idx).y();
00303 centroid.z = centroids.at(poses_idx).z();
00304
00305 omip_msgs::RigidBodyPoseAndVelMsg rbpose_and_vel;
00306 rbpose_and_vel.rb_id = RB_id;
00307 rbpose_and_vel.pose_wc = *(tracked_poses_twist_with_cov.at(poses_idx));
00308 rbpose_and_vel.velocity_wc = *(tracked_vels_twist_with_cov.at(poses_idx));
00309 rbpose_and_vel.centroid = centroid;
00310 this->_state.rb_poses_and_vels.push_back(rbpose_and_vel);
00311 }
00312 }
00313
00314 rbt_state_t MultiRBTracker::getState() const
00315 {
00316 return this->_state;
00317 }
00318
00319 void MultiRBTracker::setDynamicReconfigureValues(rb_tracker::RBTrackerDynReconfConfig &config)
00320 {
00321 _static_environment_filter->setMotionConstraint(config.cam_motion_constraint);
00322 this->_min_num_feats_for_new_rb = config.min_feats_new_rb;
00323 this->_supporting_features_threshold = config.min_feats_survive_rb;
00324 }
00325
00326 void MultiRBTracker::processMeasurementFromShapeTracker(const omip_msgs::ShapeTrackerStates &meas_from_st)
00327 {
00328 for(int idx = 0; idx < meas_from_st.shape_tracker_states.size(); idx++)
00329 {
00330 BOOST_FOREACH(RBFilter::Ptr filter, this->_kalman_filters)
00331 {
00332 if (filter->getId() == meas_from_st.shape_tracker_states.at(idx).rb_id )
00333 {
00334
00335 if((meas_from_st.shape_tracker_states.at(idx).number_of_points_of_model > _min_num_points_in_segment) &&
00336 (meas_from_st.shape_tracker_states.at(idx).number_of_points_of_current_pc > _min_num_points_in_segment) &&
00337 (meas_from_st.shape_tracker_states.at(idx).probabilistic_value > _min_probabilistic_value) &&
00338 (meas_from_st.shape_tracker_states.at(idx).fitness_score < _max_fitness_score))
00339 {
00340 ROS_ERROR_STREAM("Integrating shape-based tracked pose RB " << meas_from_st.shape_tracker_states.at(idx).rb_id);
00341 filter->integrateShapeBasedPose(meas_from_st.shape_tracker_states.at(idx).pose_wc, this->_measurement_timestamp_ns - meas_from_st.header.stamp.toNSec() );
00342 }else{
00343 ROS_ERROR_STREAM("Ignoring shape-based tracked pose RB " << meas_from_st.shape_tracker_states.at(idx).rb_id);
00344 }
00345 }
00346 }
00347 }
00348 }
00349
00350 void MultiRBTracker::CreateNewFilter(const std::vector<Eigen::Matrix4d>& initial_trajectory,
00351 const Eigen::Twistd& initial_velocity,
00352 const std::vector<Feature::Id>& initial_supporting_feats)
00353 {
00354 RBFilter::Ptr new_kf = RBFilter::Ptr(new RBFilter(this->_loop_period_ns,
00355 initial_trajectory,
00356 initial_velocity,
00357 this->_features_db,
00358 this->_estimation_error_threshold));
00359
00360 new_kf->setMeasurementDepthFactor(this->_meas_depth_factor);
00361 new_kf->setMinCovarianceMeasurementX(this->_min_cov_meas_x);
00362 new_kf->setMinCovarianceMeasurementY(this->_min_cov_meas_y);
00363 new_kf->setMinCovarianceMeasurementZ(this->_min_cov_meas_z);
00364 new_kf->setPriorCovariancePose(this->_prior_cov_pose);
00365 new_kf->setPriorCovarianceVelocity(this->_prior_cov_vel);
00366 new_kf->setCovarianceSystemAccelerationTx(this->_cov_sys_acc_tx);
00367 new_kf->setCovarianceSystemAccelerationTy(this->_cov_sys_acc_ty);
00368 new_kf->setCovarianceSystemAccelerationTz(this->_cov_sys_acc_tz);
00369 new_kf->setCovarianceSystemAccelerationRx(this->_cov_sys_acc_rx);
00370 new_kf->setCovarianceSystemAccelerationRy(this->_cov_sys_acc_ry);
00371 new_kf->setCovarianceSystemAccelerationRz(this->_cov_sys_acc_rz);
00372 new_kf->setNumberOfTrackedFeatures(this->_num_tracked_feats);
00373 new_kf->setMinNumberOfSupportingFeaturesToCorrectPredictedState(this->_min_num_supporting_feats_to_correct);
00374
00375 new_kf->Init();
00376
00377 this->_kalman_filters.push_back(new_kf);
00378 BOOST_FOREACH(Feature::Id supporting_feat_id, initial_supporting_feats)
00379 {
00380 new_kf->addSupportingFeature(supporting_feat_id);
00381 }
00382 }
00383
00384 std::vector<Feature::Id> MultiRBTracker::EstimateFreeFeatures(const std::vector<Feature::Id>& supporting_features)
00385 {
00386
00387 std::vector<Feature::Id> alive_feat_ids = this->_features_db->getListOfAliveFeatureIds();
00388 std::vector<Feature::Id> free_feat_ids;
00389 BOOST_FOREACH(Feature::Id alive_feat_id, alive_feat_ids)
00390 {
00391
00392 if (std::find(supporting_features.begin(), supporting_features.end(),alive_feat_id) == supporting_features.end())
00393 {
00394 free_feat_ids.push_back(alive_feat_id);
00395 }
00396 }
00397 _free_feat_ids = free_feat_ids;
00398 return free_feat_ids;
00399 }
00400
00401
00402
00403
00404 std::vector<Feature::Id> MultiRBTracker::ReassignFreeFeatures(const std::vector<Feature::Id>& free_feat_ids)
00405 {
00406 std::vector<Feature::Id> really_free_feat_ids;
00407
00408 Feature::Ptr free_feat;
00409 Feature::Location free_feature_last_location;
00410 Feature::Location free_feature_pre_last_location;
00411 Feature::Location free_feature_predicted_location;
00412 double feat_error = 0.0;
00413 double prediction_error = 0.0;
00414 int best_ekf_idx = -1;
00415 Eigen::Matrix4d predicted_pose;
00416
00417
00418 BOOST_FOREACH(Feature::Id free_feat_id, free_feat_ids)
00419 {
00420 free_feature_last_location = this->_features_db->getFeatureLastLocation(free_feat_id);
00421 free_feature_pre_last_location = this->_features_db->getFeatureNextToLastLocation(free_feat_id);
00422 free_feat = this->_features_db->getFeature(free_feat_id);
00423 feat_error = (double)this->_max_error_to_reassign_feats;
00424 best_ekf_idx = -1;
00425 Feature::Location best_predicted_location;
00426
00427
00428
00429 for (size_t filter_idx = 0; filter_idx < this->_kalman_filters.size();filter_idx++)
00430 {
00431
00432
00433
00434
00435 predicted_pose = this->_kalman_filters.at(filter_idx)->getPose();
00436 this->_kalman_filters.at(filter_idx)->PredictFeatureLocation(free_feat, predicted_pose, false, free_feature_predicted_location,true);
00437 prediction_error = L2Distance(free_feature_last_location, free_feature_predicted_location);
00438
00439 if (prediction_error < feat_error)
00440 {
00441 feat_error = prediction_error;
00442 best_ekf_idx = filter_idx;
00443 best_predicted_location = free_feature_predicted_location;
00444 }
00445 }
00446
00447 if (best_ekf_idx != -1)
00448 {
00449 this->_kalman_filters.at(best_ekf_idx)->addSupportingFeature(free_feat_id);
00450 this->_kalman_filters.at(best_ekf_idx)->addPredictedFeatureLocation(best_predicted_location,free_feature_pre_last_location, free_feat_id);
00451 }
00452 else
00453 {
00454 really_free_feat_ids.push_back(free_feat_id);
00455 }
00456 }
00457 _really_free_feat_ids = really_free_feat_ids;
00458 return really_free_feat_ids;
00459 }
00460
00461 void MultiRBTracker::TryToCreateNewFilter(const std::vector<Feature::Id>& really_free_feat_ids)
00462 {
00463
00464 if(really_free_feat_ids.size() > this->_min_num_feats_for_new_rb)
00465 {
00466 pcl::PointCloud<pcl::PointXYZ>::Ptr source = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>());
00467 pcl::PointCloud<pcl::PointXYZ>::Ptr target = pcl::PointCloud<pcl::PointXYZ>::Ptr(new pcl::PointCloud<pcl::PointXYZ>());
00468 pcl::Correspondences initial_correspondeces, filtered_correspondences;
00469 int index = 0;
00470 std::map<int, int> index_to_feat_id;
00471 PointPCL point_pcl;
00472
00473
00474 BOOST_FOREACH(Feature::Id free_feat_id, really_free_feat_ids)
00475 {
00476
00477 if ((int)this->_features_db->getFeatureAge(free_feat_id) > this->_min_num_frames_for_new_rb)
00478 {
00479 Feature::Location first = this->_features_db->getFeatureNToLastLocation(free_feat_id, this->_min_num_frames_for_new_rb);
00480 Feature::Location second = this->_features_db->getFeatureLastLocation(free_feat_id);
00481 Location2PointPCL(first, point_pcl);
00482 source->push_back(point_pcl);
00483 Location2PointPCL(second, point_pcl);
00484 target->push_back(point_pcl);
00485 initial_correspondeces.push_back(pcl::Correspondence(index, index, 0.0));
00486 index_to_feat_id[index] = free_feat_id;
00487 index++;
00488 }
00489 }
00490
00491
00492 if(index > this->_min_num_feats_for_new_rb)
00493 {
00494
00495
00496 pcl::registration::CorrespondenceRejectorSampleConsensus<pcl::PointXYZ> rejector;
00497 rejector.setInputSource(source);
00498 rejector.setInputTarget(target);
00499 rejector.setInlierThreshold(this->_new_rbm_error_threshold);
00500 rejector.setMaximumIterations(this->_ransac_iterations);
00501 rejector.getRemainingCorrespondences(initial_correspondeces, filtered_correspondences);
00502
00503 Eigen::Matrix4f best_transformation = rejector.getBestTransformation();
00504
00505
00506
00507
00508
00509 Eigen::Transform<float, 3, Eigen::Affine> best_transformation2(best_transformation);
00510 double amount_translation = best_transformation2.translation().norm();
00511 Eigen::AngleAxisf best_axis_angle;
00512 double amount_rotation = best_axis_angle.fromRotationMatrix(best_transformation2.rotation()).angle();
00513
00514 if ((int)filtered_correspondences.size() > this->_min_num_feats_for_new_rb && (
00515 amount_translation > _min_amount_translation_for_new_rb ||
00516 amount_rotation > _min_amount_rotation_for_new_rb*(M_PI/180.0) ) )
00517 {
00518 std::vector<Eigen::Matrix4d> trajectory;
00519 Feature::Location centroid_in_cf;
00520
00521
00522
00523
00524
00525 std::vector<Feature::Id> ransac_best_trial_inliers;
00526 BOOST_FOREACH(pcl::Correspondence filter_correspondence, filtered_correspondences)
00527 {
00528 int feature_id = index_to_feat_id.at(filter_correspondence.index_match);
00529 ransac_best_trial_inliers.push_back(feature_id);
00530 Feature::Location feat_loc = this->_features_db->getFeatureNToLastLocation(feature_id, this->_min_num_frames_for_new_rb-1);
00531 boost::tuples::get<0>(centroid_in_cf) = boost::tuples::get<0>(centroid_in_cf) + boost::tuples::get<0>(feat_loc);
00532 boost::tuples::get<1>(centroid_in_cf) = boost::tuples::get<1>(centroid_in_cf) + boost::tuples::get<1>(feat_loc);
00533 boost::tuples::get<2>(centroid_in_cf) = boost::tuples::get<2>(centroid_in_cf) + boost::tuples::get<2>(feat_loc);
00534 }
00535
00536 boost::tuples::get<0>(centroid_in_cf) = boost::tuples::get<0>(centroid_in_cf)/(double)filtered_correspondences.size();
00537 boost::tuples::get<1>(centroid_in_cf) = boost::tuples::get<1>(centroid_in_cf)/(double)filtered_correspondences.size();
00538 boost::tuples::get<2>(centroid_in_cf) = boost::tuples::get<2>(centroid_in_cf)/(double)filtered_correspondences.size();
00539
00540 Eigen::Matrix4d pre_translation = Eigen::Matrix4d::Identity();
00541 pre_translation(0,3) = boost::tuples::get<0>(centroid_in_cf);
00542 pre_translation(1,3) = boost::tuples::get<1>(centroid_in_cf);
00543 pre_translation(2,3) = boost::tuples::get<2>(centroid_in_cf);
00544
00545 trajectory.push_back(pre_translation);
00546
00547
00548 for(int frame = this->_min_num_frames_for_new_rb-2; frame >= 0; frame--)
00549 {
00550 FeaturesDataBase::MapOfFeatureLocationPairs one_frame_best_subset;
00551 BOOST_FOREACH(Feature::Id matched_feat_id, ransac_best_trial_inliers)
00552 {
00553 one_frame_best_subset[matched_feat_id] = Feature::LocationPair(this->_features_db->getFeatureNToLastLocation(matched_feat_id, frame),
00554 this->_features_db->getFeatureNToLastLocation(matched_feat_id, this->_min_num_frames_for_new_rb-1)
00555 - centroid_in_cf);
00556 }
00557 Eigen::Matrix4d one_frame_best_transformation_matrix;
00558 estimateRigidTransformation(one_frame_best_subset,one_frame_best_transformation_matrix);
00559 trajectory.push_back(one_frame_best_transformation_matrix);
00560 }
00561
00562 Eigen::Matrix4d last_delta = trajectory.at(trajectory.size()-1)*(trajectory.at(trajectory.size()-2).inverse());
00563 Eigen::Twistd initial_velocity;
00564 TransformMatrix2Twist(last_delta, initial_velocity);
00565
00566 double measured_loop_period_ns= this->_measurement_timestamp_ns - this->_previous_measurement_timestamp_ns;
00567 initial_velocity /=(measured_loop_period_ns/1e9);
00568
00569 this->CreateNewFilter(trajectory, initial_velocity, ransac_best_trial_inliers);
00570 }else
00571 {
00572 ROS_INFO_STREAM_NAMED("RBMTracker._createNewFilters", "Not enough Consensus to create a new Filter with the free Features ("<<
00573 filtered_correspondences.size() <<" inliers are too few, or the the amount of translation " <<
00574 amount_translation << " < " << _min_amount_translation_for_new_rb << " and the amount of rotation " <<
00575 amount_rotation << " < " << _min_amount_rotation_for_new_rb*(M_PI/180.0));
00576 return;
00577 }
00578 }
00579 }
00580 }
00581
00582 std::vector<Eigen::Matrix4d> MultiRBTracker::getPoses() const
00583 {
00584 std::vector<Eigen::Matrix4d> return_filter_results;
00585
00586 BOOST_FOREACH(RBFilter::Ptr filter, this->_kalman_filters)
00587 {
00588 return_filter_results.push_back(filter->getPose());
00589 }
00590 return return_filter_results;
00591 }
00592
00593 std::vector<geometry_msgs::PoseWithCovariancePtr> MultiRBTracker::getPosesWithCovariance() const
00594 {
00595 std::vector<geometry_msgs::PoseWithCovariancePtr> return_filter_results;
00596 BOOST_FOREACH(RBFilter::Ptr filter, this->_kalman_filters)
00597 {
00598 return_filter_results.push_back(filter->getPoseWithCovariance());
00599 }
00600 return return_filter_results;
00601 }
00602
00603 std::vector<geometry_msgs::TwistWithCovariancePtr> MultiRBTracker::getPosesECWithCovariance() const
00604 {
00605 std::vector<geometry_msgs::TwistWithCovariancePtr> return_filter_results;
00606 BOOST_FOREACH(RBFilter::Ptr filter, this->_kalman_filters)
00607 {
00608 return_filter_results.push_back(filter->getPoseECWithCovariance());
00609 }
00610 return return_filter_results;
00611 }
00612
00613 std::vector<geometry_msgs::TwistWithCovariancePtr> MultiRBTracker::getVelocitiesWithCovariance() const
00614 {
00615 std::vector<geometry_msgs::TwistWithCovariancePtr> return_filter_results;
00616 BOOST_FOREACH(RBFilter::Ptr filter, this->_kalman_filters)
00617 {
00618 return_filter_results.push_back(filter->getVelocityWithCovariance());
00619 }
00620 return return_filter_results;
00621 }
00622
00623 void MultiRBTracker::addFeatureLocation(Feature::Id f_id, Feature::Location f_loc)
00624 {
00625 if (this->_features_db->addFeatureLocation(f_id, f_loc))
00626 {
00627
00628 _static_environment_filter->addSupportingFeature(f_id);
00629 }
00630 }
00631
00632 RB_id_t MultiRBTracker::getRBId(int n) const
00633 {
00634 return this->_kalman_filters.at(n)->getId();
00635 }
00636
00637 int MultiRBTracker::getNumberSupportingFeatures(int n) const
00638 {
00639 return this->_kalman_filters.at(n)->getNumberSupportingFeatures();
00640 }
00641
00642 FeatureCloudPCL MultiRBTracker::getLabelledSupportingFeatures()
00643 {
00644 FeatureCloudPCL colored_pc;
00645 std::vector<RBFilter::Ptr>::iterator filter_it =this->_kalman_filters.begin();
00646
00647
00648
00649 filter_it++;
00650 for (; filter_it != this->_kalman_filters.end(); filter_it++)
00651 {
00652 std::vector<Feature::Id> this_filter_supporting_features = (*filter_it)->getSupportingFeatures();
00653 for (size_t feat_idx = 0; feat_idx < this_filter_supporting_features.size();feat_idx++)
00654 {
00655 if (this->_features_db->isFeatureStored(this_filter_supporting_features.at(feat_idx)))
00656 {
00657 FeaturePCL temp_point;
00658 RB_id_t label = (*filter_it)->getId();
00659 temp_point.x = this->_features_db->getFeatureLastX(this_filter_supporting_features.at(feat_idx));
00660 temp_point.y = this->_features_db->getFeatureLastY(this_filter_supporting_features.at(feat_idx));
00661 temp_point.z = this->_features_db->getFeatureLastZ(this_filter_supporting_features.at(feat_idx));
00662
00663 temp_point.label = label;
00664 colored_pc.points.push_back(temp_point);
00665 }
00666 }
00667 }
00668 return colored_pc;
00669 }
00670
00671 FeatureCloudPCL MultiRBTracker::getFreeFeatures()
00672 {
00673 FeatureCloudPCL colored_pc;
00674 for (size_t feat_idx = 0; feat_idx < _really_free_feat_ids.size();feat_idx++)
00675 {
00676 if (this->_features_db->isFeatureStored(_really_free_feat_ids.at(feat_idx)))
00677 {
00678 FeaturePCL temp_point;
00679 temp_point.x = this->_features_db->getFeatureLastX(_really_free_feat_ids.at(feat_idx));
00680 temp_point.y = this->_features_db->getFeatureLastY(_really_free_feat_ids.at(feat_idx));
00681 temp_point.z = this->_features_db->getFeatureLastZ(_really_free_feat_ids.at(feat_idx));
00682
00683 temp_point.label = _really_free_feat_ids.at(feat_idx);
00684 colored_pc.points.push_back(temp_point);
00685 }
00686 }
00687 return colored_pc;
00688 }
00689
00690 FeatureCloudPCL MultiRBTracker::getPredictedFeatures()
00691 {
00692 FeatureCloudPCL colored_pc;
00693 std::vector<RBFilter::Ptr>::iterator filter_it =this->_kalman_filters.begin();
00694 filter_it++;
00695 for (; filter_it != this->_kalman_filters.end(); filter_it++)
00696 {
00697 FeatureCloudPCLwc::Ptr predicted_locations_pc = (*filter_it)->getFeaturesPredicted();
00698 for (size_t feat_idx = 0; feat_idx < predicted_locations_pc->points.size();feat_idx++)
00699 {
00700 FeaturePCL temp_point;
00701 temp_point.x = predicted_locations_pc->points[feat_idx].x;
00702 temp_point.y = predicted_locations_pc->points[feat_idx].y;
00703 temp_point.z = predicted_locations_pc->points[feat_idx].z;
00704 temp_point.label = predicted_locations_pc->points[feat_idx].label;
00705 colored_pc.points.push_back(temp_point);
00706 }
00707 (*filter_it)->resetFeaturesPredicted();
00708 }
00709 return colored_pc;
00710 }
00711
00712 FeatureCloudPCL MultiRBTracker::getAtBirthFeatures()
00713 {
00714 FeatureCloudPCL colored_pc;
00715 std::vector<RBFilter::Ptr>::iterator filter_it =this->_kalman_filters.begin();
00716 filter_it++;
00717 for (; filter_it != this->_kalman_filters.end(); filter_it++)
00718 {
00719 FeatureCloudPCLwc::Ptr at_birth_locations_pc = (*filter_it)->getFeaturesAtBirth();
00720 for (size_t feat_idx = 0; feat_idx < at_birth_locations_pc->points.size();feat_idx++)
00721 {
00722 FeaturePCL temp_point;
00723 temp_point.x = at_birth_locations_pc->points[feat_idx].x;
00724 temp_point.y = at_birth_locations_pc->points[feat_idx].y;
00725 temp_point.z = at_birth_locations_pc->points[feat_idx].z;
00726 temp_point.label = at_birth_locations_pc->points[feat_idx].label;
00727 colored_pc.points.push_back(temp_point);
00728 }
00729 (*filter_it)->resetFeaturesAtBirth();
00730 }
00731 return colored_pc;
00732 }
00733
00734 std::vector<Eigen::Vector3d> MultiRBTracker::getCentroids() const
00735 {
00736 std::vector<Eigen::Vector3d> centroids;
00737 centroids.push_back(Eigen::Vector3d(0., 0., 0.));
00738 std::vector<RBFilter::Ptr>::const_iterator filter_it = this->_kalman_filters.begin();
00739 filter_it++;
00740
00741 for (; filter_it != this->_kalman_filters.end(); filter_it++)
00742 {
00743
00744
00745 if((*filter_it)->getTrajectory().size() < this->_min_num_frames_for_new_rb)
00746 {
00747 Feature::Location initial_location = (*filter_it)->getIntialLocationOfCentroid();
00748 centroids.push_back(Eigen::Vector3d(boost::tuples::get<0>(initial_location),
00749 boost::tuples::get<1>(initial_location),
00750 boost::tuples::get<2>(initial_location)));
00751 }else{
00752 Eigen::Vector3d temp_centroid = Eigen::Vector3d(0., 0., 0.);
00753 int supporting_feats_ctr = 0;
00754 std::vector<Feature::Id> this_filter_supporting_features = (*filter_it)->getSupportingFeatures();
00755 for (size_t feat_idx = 0; feat_idx < this_filter_supporting_features.size();feat_idx++)
00756 {
00757 if (this->_features_db->isFeatureStored(this_filter_supporting_features.at(feat_idx)))
00758 {
00759 temp_centroid.x() += this->_features_db->getFeatureLastX(this_filter_supporting_features.at(feat_idx));
00760 temp_centroid.y() += this->_features_db->getFeatureLastY(this_filter_supporting_features.at(feat_idx));
00761 temp_centroid.z() += this->_features_db->getFeatureLastZ(this_filter_supporting_features.at(feat_idx));
00762 supporting_feats_ctr++;
00763 }
00764 }
00765 centroids.push_back(temp_centroid / (double)supporting_feats_ctr);
00766 }
00767 }
00768 return centroids;
00769 }
00770
00771 void MultiRBTracker::addPredictedState(const rbt_state_t& predicted_state, const double &predicted_state_timestamp_ns)
00772 {
00773 BOOST_FOREACH(omip_msgs::RigidBodyPoseAndVelMsg predicted_pose_and_vel, predicted_state.rb_poses_and_vels)
00774 {
00775 BOOST_FOREACH(RBFilter::Ptr filter, this->_kalman_filters)
00776 {
00777 if (filter->getId() == predicted_pose_and_vel.rb_id)
00778 {
00779
00780 filter->setPredictedState(predicted_pose_and_vel);
00781 }
00782 }
00783 }
00784 }
00785
00786 FeaturesDataBase::Ptr MultiRBTracker::getFeaturesDatabase()
00787 {
00788 return this->_features_db;
00789 }
00790