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)
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
00049 MatrixXd UncertainTransformListener::sampleFromMeanCov(const VectorXd &mean_, const MatrixXd &cov_, size_t n)
00050 {
00051
00052
00053
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
00082
00083
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
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
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
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
00152 source_parents.push_back(parent);
00153 source_parents_set.insert(parent);
00154
00155 have_parent = ((const tf::TransformListener*)this)->getParent(parent,time,parent);
00156
00157 }
00158
00159 parent = tf::resolve(((const tf::TransformListener*)this)->getTFPrefix(), target_frame);
00160 have_parent = true;
00161
00162 while (have_parent)
00163 {
00164
00165 target_parents.push_back(parent);
00166
00167 if (source_parents_set.find(parent) != source_parents_set.end())
00168 {
00169 have_parent = false;
00170
00171 }
00172 else
00173 have_parent = ((const tf::TransformListener*)this)->getParent(parent,time,parent);
00174 }
00175
00176
00177 while ((source_parents.size() > 0) && (source_parents.back()) != target_parents.back())
00178 {
00179
00180 source_parents.pop_back();
00181 }
00182
00183
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
00195
00196
00197
00198
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 ¤t_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
00231 for (std::list<std::string>::reverse_iterator it = target_parents.rbegin(); it!= target_parents.rend(); ++it)
00232 {
00233 const std::string ¤t_frame = *it;
00234 StampedTransform rel;
00235 ((const tf::TransformListener*)this)->lookupTransform(last_frame, current_frame, time, rel);
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();
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
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
00288 sampleTransform(fixed_frame, source_frame, source_time, fixed_to_source, n);
00289
00290
00291 sampleTransform(target_frame, fixed_frame, target_time, target_to_fixed, n);
00292
00293
00294
00295
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
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
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
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 }