UncertainTransformListener.cpp
Go to the documentation of this file.
00001 #include "uncertain_tf/UncertainTransformListener.h"
00002 
00003 
00004 using namespace Eigen;
00005 using namespace tf;
00006 using namespace uncertain_tf;
00007 using namespace std;
00008 
00009 namespace uncertain_tf
00010 {
00011 
00012 
00013 UncertainTransformListener::UncertainTransformListener(ros::Duration max_cache_time, bool spin_thread)
00014 {
00015     message_subscriber_utf_ = node_.subscribe<uncertain_tf::utfMessage>("/tf_uncertainty", 100, boost::bind(&UncertainTransformListener::subscription_callback, this, _1));
00016     ROS_INFO("SUBSCRIBER SET UP");
00017     VectorXd m(6);
00018     MatrixXd c(6,6);
00019     emn_ = new EigenMultivariateNormal<double, 6>(m,c);
00020     univ_ = new UnivariateNormal<double>(1,0);
00021 }
00022 
00023 
00024 VectorXd UncertainTransformListener::calculateSampleMean(const MatrixXd &x)
00025 {
00026     return x.colwise().sum() / x.rows();
00027 }
00028 
00029 bool UncertainTransformListener::isZero(const MatrixXd mat)
00030 {
00031     for (int i = 0; i < mat.cols(); ++i)
00032         for (int j = 0; j < mat.cols(); ++j)
00033             if (fabs(mat(i,j)) > 0) //.0000000000000001)
00034                 return false;
00035     return true;
00036 }
00037 
00038 MatrixXd UncertainTransformListener::sampleSetTFtoMatrixXd(std::vector<tf::StampedTransform> sampleset)
00039 {
00040     MatrixXd ret(sampleset.size(),6);
00041     for (size_t n=0; n < sampleset.size(); ++n)
00042     {
00043         ret.row(n) = transformTFToVectorXd(sampleset[n]);
00044     }
00045     return ret;
00046 }
00047 
00048 // sample n points from the given distribution
00049 MatrixXd UncertainTransformListener::sampleFromMeanCov(const VectorXd &mean_, const MatrixXd &cov_, size_t n)
00050 {
00051     //cout << "SAMPLING" << endl << endl << "Mean" << endl << mean_ << endl << "Cov" << endl << cov_ << endl;
00052 
00053     //EigenMultivariateNormal<double, 6> emn(mean_.transpose(),cov_);
00054     emn_->setMean(mean_.transpose());
00055     emn_->setCovar(cov_);
00056 
00057     Matrix<double,6,1>  nextSample;
00058     MatrixXd ret(mean_.rows(),n);
00059 
00060     for (size_t i = 0; i < n; ++i)
00061     {
00062         emn_->nextSample(nextSample);
00063         ret.col(i) = nextSample;
00064     }
00065 
00066     return ret;
00067 }
00068 
00069 void UncertainTransformListener::sampleFromMeanCov(const tf::Transform &mean, const MatrixXd &cov, std::vector<tf::Transform> &output, size_t n)
00070 {
00071     VectorXd mean_ = transformTFToVectorXd(mean);
00072     MatrixXd samples = sampleFromMeanCov(mean_, cov, n);
00073     for (int i = 0; i < samples.cols(); i++)
00074         output.push_back(transformVectorXdToTF(samples.col(i).transpose()));
00075 }
00076 
00077 tf::Transform UncertainTransformListener::sampleFromMeanCov(const tf::Transform &mean, const MatrixXd &cov)
00078 {
00079     std::vector<tf::Transform> samples;
00080     sampleFromMeanCov(mean, cov, samples);
00081     //std::cout << "Variances " << cov(0,0) << " " << cov(1,1) << " " << cov(2,2) << " " << cov(3,3) << " " << cov(4,4) << " " << cov(5,5) << endl;
00082     //printFrame("smpl", "mean", mean);
00083     //printFrame("smpl", "smpl", samples[0]);
00084     return samples[0];
00085 }
00086 
00087 VectorXd UncertainTransformListener::transformTFToVectorXd(const tf::Transform &transform)
00088 {
00089     VectorXd ret;
00090     ret.resize(6);
00091     ret(0) = transform.getOrigin().x();
00092     ret(1) = transform.getOrigin().y();
00093     ret(2) = transform.getOrigin().z();
00094     transform.getBasis().getEulerYPR(ret(3), ret(4), ret(5));
00095     return ret;
00096 }
00097 
00098 tf::Transform UncertainTransformListener::transformVectorXdToTF(const VectorXd &vec)
00099 {
00100     tf::Transform ret;
00101     ret.setOrigin(tf::Vector3(vec(0), vec(1), vec(2)));
00102     ret.getBasis().setEulerYPR(vec(3), vec(4), vec(5));
00103     return ret;
00104 
00105 }
00106 
00107 void UncertainTransformListener::subscription_callback(const uncertain_tf::utfMessageConstPtr& msg)
00108 {
00109     //std::cout << "got a message :" << endl;
00110     for (std::vector<uncertain_tf::CovarianceStamped>::const_iterator it = msg->covariances.begin(); it != msg->covariances.end(); ++it)
00111     {
00112         uncertain_tf::CovarianceStamped sc_msg = *it;
00113         //std::cout << sc_msg << endl;
00114         StampedCovariance sc;
00115         covarianceStampedMsgToTF(sc_msg, sc);
00116         setCovariance(sc);
00117     }
00118 }
00119 
00120 void UncertainTransformListener::printFrame(std::string last_frame, std::string current_frame, tf::Transform rel)
00121 {
00122     std::cout << last_frame << " to \t" << current_frame << ": \t\t(" << rel.getOrigin().x() << " , " << rel.getOrigin().y() << " , " << rel.getOrigin().z() << ") \t"
00123               << " (" << rel.getRotation().x() << " , " << rel.getRotation().y() << " , " << rel.getRotation().z() << " , " << rel.getRotation().w() << ")" << endl;
00124 }
00125 
00126 void UncertainTransformListener::sampleTransform(const std::string& target_frame, const std::string& source_frame,
00127         const ros::Time& time, std::vector<StampedTransform>& output, size_t n)
00128 {
00129     //ROS_INFO("START SAMPLING");
00130 
00131     ros::Time start = ros::Time::now();
00132 
00133     StampedTransform mean;
00134     try
00135     {
00136         ((const tf::TransformListener*)this)->lookupTransform(target_frame, source_frame, time, mean);
00137     }
00138     catch (tf::TransformException ex)
00139     {
00140         ROS_ERROR("UncertainTransformListener::sampleTransform caught exception: %s",ex.what());
00141         return;
00142     }
00143 
00144     std::list<std::string> source_parents;
00145     std::set<std::string> source_parents_set;
00146     std::list<std::string> target_parents;
00147     std::string parent = tf::resolve(((const tf::TransformListener*)this)->getTFPrefix(), source_frame);
00148     bool have_parent = true;
00149     while (have_parent)
00150     {
00151         //std::cout << "source_chain: \'" << parent << "\'" << endl;
00152         source_parents.push_back(parent);
00153         source_parents_set.insert(parent);
00154         //std::string next_parent;
00155         have_parent = ((const tf::TransformListener*)this)->getParent(parent,time,parent);
00156         //parent = next_parent;
00157     }
00158 
00159     parent = tf::resolve(((const tf::TransformListener*)this)->getTFPrefix(), target_frame);
00160     have_parent = true;
00161     //bool connected = false;
00162     while (have_parent)
00163     {
00164         //std::cout << "target_chain: \'" << parent << "\'" << endl;
00165         target_parents.push_back(parent);
00166 
00167         if (source_parents_set.find(parent) != source_parents_set.end())
00168         {
00169             have_parent = false;
00170             //connected = true;
00171         }
00172         else
00173             have_parent = ((const tf::TransformListener*)this)->getParent(parent,time,parent);
00174     }
00175 
00176     //todo: if not connected throw
00177     while ((source_parents.size() > 0) && (source_parents.back()) != target_parents.back())
00178     {
00179         //std::cout << "pop  " << source_parents.back() << " spf " << source_parents.back() << "  tpf " << target_parents.back() << endl;
00180         source_parents.pop_back();
00181     }
00182 
00183     // source -> common parent
00184 
00185     std::string last_frame_init = source_parents.front();
00186 
00187     source_parents.pop_front();
00188     target_parents.pop_back();
00189 
00190     std::vector<std::vector<tf::Transform> > chain_sampled_transforms;
00191 
00192     std::string last_frame = last_frame_init;
00193 
00194     //std::cout << "Sample" << k << last_frame << endl;
00195 
00196     //tf::Transform acc;
00197     //acc.setOrigin(tf::Vector3(0,0,0));
00198     //acc.setRotation(tf::Quaternion(0,0,0,1));
00199 
00200     tf::Transform zeroMean;
00201     zeroMean.setOrigin(tf::Vector3(0,0,0));
00202     zeroMean.setRotation(tf::Quaternion(0,0,0,1));
00203 
00204 
00205     for (std::list<std::string>::iterator it = source_parents.begin(); it!= source_parents.end(); ++it)
00206     {
00207         const std::string &current_frame = *it;
00208 
00209         StampedTransform rel;
00210         ((const tf::TransformListener*)this)->lookupTransform(current_frame, last_frame, time, rel);
00211 
00212         CovarianceStorage cs;
00213         getCovariance(lookupOrInsertFrameNumber(last_frame))->getData(time,cs);
00214 
00215         last_frame = current_frame;
00216 
00217         std::vector<tf::Transform> samples;
00218         chain_sampled_transforms.push_back(samples);
00219 
00220         if (isZero(cs.covariance_))
00221             chain_sampled_transforms.back().push_back(zeroMean);
00222         else
00223             sampleFromMeanCov(zeroMean,cs.covariance_,chain_sampled_transforms.back(),n);
00224 
00225         for (std::vector<tf::Transform>::iterator jt=chain_sampled_transforms.back().begin(); jt!= chain_sampled_transforms.back().end(); ++jt)
00226             *jt = rel * (*jt);
00227 
00228     }
00229 
00230     // common parent -> target
00231     for (std::list<std::string>::reverse_iterator it = target_parents.rbegin(); it!= target_parents.rend(); ++it)
00232     {
00233         const std::string &current_frame = *it;
00234         StampedTransform rel;
00235         ((const tf::TransformListener*)this)->lookupTransform(last_frame, current_frame, time, rel); // lookup inverse frame, where we can sample and then invert again
00236 
00237         CovarianceStorage cs;
00238         getCovariance(lookupOrInsertFrameNumber(current_frame))->getData(time,cs);
00239 
00240         last_frame = current_frame;
00241         std::vector<tf::Transform> samples;
00242         chain_sampled_transforms.push_back(samples);
00243 
00244 
00245         if (isZero(cs.covariance_))
00246             chain_sampled_transforms.back().push_back(zeroMean);
00247         else
00248             sampleFromMeanCov(zeroMean,cs.covariance_,chain_sampled_transforms.back(),n);
00249 
00250         for (std::vector<tf::Transform>::iterator jt=chain_sampled_transforms.back().begin(); jt!= chain_sampled_transforms.back().end(); ++jt)
00251             *jt = (rel * (*jt)).inverse(); // when walking down, we invert the transforms
00252 
00253         last_frame = current_frame;
00254     }
00255 
00256     for (unsigned int smp = 0; smp < n; ++smp)
00257     {
00258 
00259         tf::Transform acc;
00260         acc.setOrigin(tf::Vector3(0,0,0));
00261         acc.setRotation(tf::Quaternion(0,0,0,1));
00262 
00263         for (unsigned int chain = 0; chain < chain_sampled_transforms.size(); ++chain)
00264         {
00265             if (chain_sampled_transforms[chain].size() == 1)
00266                 acc = chain_sampled_transforms[chain][0] * acc;
00267             else
00268                 acc = chain_sampled_transforms[chain][smp] * acc;
00269         }
00270         mean.setData(acc);
00271         output.push_back(mean);
00272     }
00273 
00274     //ROS_INFO("DONE SAMPLING %f", (ros::Time::now() - start).toSec());
00275 
00276 }
00277 
00278 
00279 void UncertainTransformListener::sampleTransform(const std::string& target_frame, const ros::Time& target_time,
00280                           const std::string& source_frame, const ros::Time& source_time,
00281                           const std::string& fixed_frame,
00282                           std::vector<StampedTransform>& output, size_t n)
00283 {
00284     std::vector<StampedTransform> fixed_to_source;
00285     std::vector<StampedTransform> target_to_fixed;
00286 
00287     //std::cout << "looking for frame " << fixed_frame << " to " << source_frame << " at time " << source_time.toSec() << std::endl;
00288     sampleTransform(fixed_frame, source_frame, source_time, fixed_to_source, n);
00289 
00290     //std::cout << "looking for frame " << target_frame << " to " << fixed_frame << " at time " << target_time.toSec() << std::endl;
00291     sampleTransform(target_frame, fixed_frame, target_time, target_to_fixed, n);
00292 
00293     //std::cout << "sizes " << fixed_to_source.size() << " " << target_to_fixed.size() << std::endl;
00294 
00295     // we might have lost some transforms due to exeptions, such as when no data is know, so make sure we don't make up anything we don't know
00296     for (size_t k = 0 ; k < std::min(fixed_to_source.size(),target_to_fixed.size()); ++k)
00297     {
00298         tf::StampedTransform transform;
00299         transform.setData(target_to_fixed[k] * fixed_to_source[k]);
00300         transform.stamp_ = target_to_fixed[k].stamp_;
00301         transform.frame_id_ = target_frame;
00302         transform.child_frame_id_ = source_frame;
00303         // add transform to output
00304         output.push_back(transform);
00305     }
00306 
00307 }
00308 
00309 
00310 void UncertainTransformListener::sampleTransformGaussianTime(const std::string& target_frame, const std::string& source_frame,
00311         const ros::Time& time_mean, const ros::Duration& time_variance, std::vector<StampedTransform>& output, size_t n)
00312 {
00313     //UnivariateNormal<double> univ(time_mean.toSec(),time_variance.toSec());
00314     univ_->setMean(time_mean.toSec());
00315     univ_->setVar(time_variance.toSec());
00316     for (size_t k = 0; k < n; k++)
00317     {
00318         double act_time;
00319         univ_->nextSample(act_time);
00320         try
00321         {
00322             UncertainTransformListener::sampleTransform(target_frame, source_frame, ros::Time(act_time), output, 1);
00323         }
00324         catch (tf::TransformException ex)
00325         {
00326             //ROS_ERROR("s f %s",ex.what());
00327         }
00328 
00329     }
00330 }
00331 
00332 
00333 void UncertainTransformListener::sampleTransformUniformTime(const std::string& target_frame, const std::string& source_frame,
00334         const ros::Time& time_start, const ros::Time& time_end, std::vector<StampedTransform>& output, size_t n)
00335 {
00336     double time_step = (time_end - time_start).toSec() / n;
00337     double act_time = time_start.toSec();
00338     for (size_t k = 0; k < n; k++)
00339     {
00340         try
00341         {
00342             UncertainTransformListener::sampleTransform(target_frame, source_frame, ros::Time(act_time), output, 1);
00343         }
00344         catch (tf::TransformException ex)
00345         {
00346             //
00347         }
00348         act_time += time_step;
00349     }
00350 
00351 }
00352 
00353 } // namespace uncertain_tf


uncertain_tf
Author(s): Thomas Ruehr
autogenerated on Mon Oct 6 2014 08:20:49