buffer_core_test.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <gtest/gtest.h>
00031 #include <tf2/buffer_core.h>
00032 #include "tf2/exceptions.h"
00033 #include <sys/time.h>
00034 #include <ros/ros.h>
00035 #include "LinearMath/btVector3.h"
00036 #include "LinearMath/btTransform.h"
00037 #include "rostest/permuter.h"
00038 
00039 void setIdentity(geometry_msgs::Transform& trans)
00040 {
00041   trans.translation.x = 0;
00042   trans.translation.y = 0;
00043   trans.translation.z = 0;
00044   trans.rotation.x = 0;
00045   trans.rotation.y = 0;
00046   trans.rotation.z = 0;
00047   trans.rotation.w = 1;
00048 }
00049 
00050 
00051 void push_back_i(std::vector<std::string>& children, std::vector<std::string>& parents,
00052                  std::vector<double>& dx, std::vector<double>& dy)
00053 {
00054   /*
00055      "a"
00056      v   (1,0)
00057      "b"
00058      v   (1,0)
00059      "c"
00060   */
00061 
00062   children.push_back("b");
00063   parents.push_back("a");
00064   dx.push_back(1.0);
00065   dy.push_back(0.0);
00066   children.push_back("c");
00067   parents.push_back("b");
00068   dx.push_back(1.0);
00069   dy.push_back(0.0);
00070 }
00071 
00072 
00073 void push_back_y(std::vector<std::string>& children, std::vector<std::string>& parents,
00074                  std::vector<double>& dx, std::vector<double>& dy)
00075 {
00076     /*
00077       "a"
00078       v  (1,0)
00079       "b" ------(0,1)-----> "d"
00080       v  (1,0)              v  (0,1)
00081       "c"                   "e"
00082     */
00083     // a>b
00084     children.push_back("b");
00085     parents.push_back("a");
00086     dx.push_back(1.0);
00087     dy.push_back(0.0);
00088      // b>c
00089     children.push_back("c");
00090     parents.push_back("b");
00091     dx.push_back(1.0);
00092     dy.push_back(0.0);
00093      // b>d
00094     children.push_back("d");
00095     parents.push_back("b");
00096     dx.push_back(0.0);
00097     dy.push_back(1.0);
00098      // d>e
00099     children.push_back("e");
00100     parents.push_back("d");
00101     dx.push_back(0.0);
00102     dy.push_back(1.0);
00103 }
00104 
00105 void push_back_v(std::vector<std::string>& children, std::vector<std::string>& parents,
00106                  std::vector<double>& dx, std::vector<double>& dy)
00107 {
00108   /*
00109     "a" ------(0,1)-----> "f"
00110     v  (1,0)              v  (0,1)
00111     "b"                   "g"
00112     v  (1,0)
00113     "c"
00114   */
00115   // a>b
00116   children.push_back("b");
00117   parents.push_back("a");
00118   dx.push_back(1.0);
00119   dy.push_back(0.0);
00120   // b>c
00121   children.push_back("c");
00122   parents.push_back("b");
00123   dx.push_back(1.0);
00124   dy.push_back(0.0);
00125   // a>f
00126   children.push_back("f");
00127   parents.push_back("a");
00128   dx.push_back(0.0);
00129   dy.push_back(1.0);
00130   // f>g
00131   children.push_back("g");
00132   parents.push_back("f");
00133   dx.push_back(0.0);
00134   dy.push_back(1.0);
00135 
00136 }
00137 
00138 void push_back_1(std::vector<std::string>& children, std::vector<std::string>& parents,
00139                  std::vector<double>& dx, std::vector<double>& dy)
00140 {
00141   children.push_back("2");
00142   parents.push_back("1");
00143   dx.push_back(1.0);
00144   dy.push_back(0.0);
00145 }
00146 
00147 void setupTree(tf2::BufferCore& mBC, const std::string& mode, const ros::Time & time, const ros::Duration& interpolation_space = ros::Duration())
00148 {
00149   ROS_DEBUG("Clearing Buffer Core for new test setup");
00150   mBC.clear();
00151 
00152   ROS_DEBUG("Setting up test tree for formation %s", mode.c_str());
00153 
00154   std::vector<std::string> children;
00155   std::vector<std::string> parents;
00156   std::vector<double> dx, dy;
00157 
00158   if (mode == "i")
00159   {
00160     push_back_i(children, parents, dx, dy);
00161   }
00162   else if (mode == "y")
00163   {
00164     push_back_y(children, parents, dx, dy);
00165   }
00166 
00167   else if (mode == "v")
00168   {
00169     push_back_v(children, parents, dx, dy);
00170   }
00171 
00172   else if (mode == "ring_45")
00173   {
00174     /* Form a ring of transforms at every 45 degrees on the unit circle.  */
00175 
00176     std::vector<std::string> frames;
00177 
00178 
00179 
00180     frames.push_back("a");
00181     frames.push_back("b");
00182     frames.push_back("c");
00183     frames.push_back("d");
00184     frames.push_back("e");
00185     frames.push_back("f");
00186     frames.push_back("g");
00187     frames.push_back("h");
00188     frames.push_back("i");
00189 
00190     for (uint8_t iteration = 0; iteration < 2; ++iteration)
00191     {
00192       double direction = 1;
00193       std::string frame_prefix;
00194       if (iteration == 0)
00195       {
00196         frame_prefix = "inverse_";
00197         direction = -1;
00198       }
00199       else
00200         frame_prefix ="";
00201       for (uint64_t i = 1; i <  frames.size(); i++)
00202       {
00203         geometry_msgs::TransformStamped ts;
00204         setIdentity(ts.transform);
00205         ts.transform.translation.x = direction * ( sqrt(2)/2 - 1);
00206         ts.transform.translation.y = direction * sqrt(2)/2;
00207         ts.transform.rotation.x = 0;
00208         ts.transform.rotation.y = 0;
00209         ts.transform.rotation.z = sin(direction * M_PI/8);
00210         ts.transform.rotation.w = cos(direction * M_PI/8);
00211         if (time > ros::Time() + (interpolation_space * .5))
00212           ts.header.stamp = time - (interpolation_space * .5);
00213         else
00214           ts.header.stamp = ros::Time();
00215 
00216         ts.header.frame_id = frame_prefix + frames[i-1];
00217         if (i > 1)
00218           ts.child_frame_id = frame_prefix + frames[i];
00219         else
00220           ts.child_frame_id = frames[i]; // connect first frame
00221         EXPECT_TRUE(mBC.setTransform(ts, "authority"));
00222         if (interpolation_space > ros::Duration())
00223         {
00224           ts.header.stamp = time + interpolation_space * .5;
00225           EXPECT_TRUE(mBC.setTransform(ts, "authority"));
00226 
00227         }
00228       }
00229     }
00230     return; // nonstandard setup return before standard executinog
00231   }
00232   else if (mode == "1")
00233   {
00234     push_back_1(children, parents, dx, dy);
00235 
00236   }
00237   else if (mode =="1_v")
00238   {
00239     push_back_1(children, parents, dx, dy);
00240     push_back_v(children, parents, dx, dy);
00241   }
00242   else
00243     EXPECT_FALSE("Undefined mode for tree setup.  Test harness improperly setup.");
00244 
00245 
00247   for (uint64_t i = 0; i <  children.size(); i++)
00248   {
00249     geometry_msgs::TransformStamped ts;
00250     setIdentity(ts.transform);
00251     ts.transform.translation.x = dx[i];
00252     ts.transform.translation.y = dy[i];
00253     if (time > ros::Time() + (interpolation_space * .5))
00254       ts.header.stamp = time - (interpolation_space * .5);
00255     else
00256       ts.header.stamp = ros::Time();
00257 
00258     ts.header.frame_id = parents[i];
00259     ts.child_frame_id = children[i];
00260     EXPECT_TRUE(mBC.setTransform(ts, "authority"));
00261     if (interpolation_space > ros::Duration())
00262     {
00263       ts.header.stamp = time + interpolation_space * .5;
00264       EXPECT_TRUE(mBC.setTransform(ts, "authority"));
00265 
00266     }
00267   }
00268 }
00269 
00270 
00271 TEST(BufferCore_setTransform, NoInsertOnSelfTransform)
00272 {
00273   tf2::BufferCore mBC;
00274   geometry_msgs::TransformStamped tranStamped;
00275   setIdentity(tranStamped.transform);
00276   tranStamped.header.stamp = ros::Time().fromNSec(10.0);
00277   tranStamped.header.frame_id = "same_frame";
00278   tranStamped.child_frame_id = "same_frame";
00279   EXPECT_FALSE(mBC.setTransform(tranStamped, "authority"));
00280 }
00281 
00282 TEST(BufferCore_setTransform, NoInsertWithNan)
00283 {
00284   tf2::BufferCore mBC;
00285   geometry_msgs::TransformStamped tranStamped;
00286   setIdentity(tranStamped.transform);
00287   tranStamped.header.stamp = ros::Time().fromNSec(10.0);
00288   tranStamped.header.frame_id = "same_frame";
00289   tranStamped.child_frame_id = "other_frame";
00290   EXPECT_TRUE(mBC.setTransform(tranStamped, "authority"));
00291   tranStamped.transform.translation.x = 0.0/0.0;
00292   EXPECT_TRUE(std::isnan(tranStamped.transform.translation.x));
00293   EXPECT_FALSE(mBC.setTransform(tranStamped, "authority"));
00294 
00295 }
00296 
00297 TEST(BufferCore_setTransform, NoInsertWithNoFrameID)
00298 {
00299   tf2::BufferCore mBC;
00300   geometry_msgs::TransformStamped tranStamped;
00301   setIdentity(tranStamped.transform);
00302   tranStamped.header.stamp = ros::Time().fromNSec(10.0);
00303   tranStamped.header.frame_id = "same_frame";
00304   tranStamped.child_frame_id = "";
00305   EXPECT_FALSE(mBC.setTransform(tranStamped, "authority"));
00306   tranStamped.child_frame_id = "/";
00307   EXPECT_FALSE(mBC.setTransform(tranStamped, "authority"));
00308 
00309 }
00310 
00311 TEST(BufferCore_setTransform, NoInsertWithNoParentID)
00312 {
00313   tf2::BufferCore mBC;
00314   geometry_msgs::TransformStamped tranStamped;
00315   setIdentity(tranStamped.transform);
00316   tranStamped.header.stamp = ros::Time().fromNSec(10.0);
00317   tranStamped.header.frame_id = "";
00318   tranStamped.child_frame_id = "some_frame";
00319   EXPECT_FALSE(mBC.setTransform(tranStamped, "authority"));
00320 
00321   tranStamped.header.frame_id = "/";
00322   EXPECT_FALSE(mBC.setTransform(tranStamped, "authority"));
00323 }
00324 
00325 /*
00326 TEST(tf, ListOneInverse)
00327 {
00328   unsigned int runs = 4;
00329   double epsilon = 1e-6;
00330   seed_rand();
00331 
00332   tf::Transformer mTR(true);
00333   std::vector<double> xvalues(runs), yvalues(runs), zvalues(runs);
00334   for ( uint64_t i = 0; i < runs ; i++ )
00335   {
00336     xvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00337     yvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00338     zvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00339 
00340     StampedTransform tranStamped (btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10 + i),  "my_parent", "child");
00341     mTR.setTransform(tranStamped);
00342   }
00343 
00344   //  std::cout << mTR.allFramesAsString() << std::endl;
00345   //  std::cout << mTR.chainAsString("child", 0, "my_parent2", 0, "my_parent2") << std::endl;
00346 
00347   for ( uint64_t i = 0; i < runs ; i++ )
00348 
00349   {
00350     Stamped<Pose> inpose (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10 + i), "child");
00351 
00352     try{
00353     Stamped<Pose> outpose;
00354     outpose.setIdentity(); //to make sure things are getting mutated
00355     mTR.transformPose("my_parent",inpose, outpose);
00356     EXPECT_NEAR(outpose.getOrigin().x(), xvalues[i], epsilon);
00357     EXPECT_NEAR(outpose.getOrigin().y(), yvalues[i], epsilon);
00358     EXPECT_NEAR(outpose.getOrigin().z(), zvalues[i], epsilon);
00359     }
00360     catch (tf::TransformException & ex)
00361     {
00362       std::cout << "TransformExcepion got through!!!!! " << ex.what() << std::endl;
00363       bool exception_improperly_thrown = true;
00364       EXPECT_FALSE(exception_improperly_thrown);
00365     }
00366   }
00367 
00368 }
00369 
00370 TEST(tf, ListTwoInverse)
00371 {
00372   unsigned int runs = 4;
00373   double epsilon = 1e-6;
00374   seed_rand();
00375 
00376   tf::Transformer mTR(true);
00377   std::vector<double> xvalues(runs), yvalues(runs), zvalues(runs);
00378   for ( unsigned int i = 0; i < runs ; i++ )
00379   {
00380     xvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00381     yvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00382     zvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00383 
00384     StampedTransform tranStamped(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10 + i),  "my_parent", "child");
00385     mTR.setTransform(tranStamped);
00386     StampedTransform tranStamped2(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10 + i),  "child", "grandchild");
00387     mTR.setTransform(tranStamped2);
00388   }
00389 
00390   //  std::cout << mTR.allFramesAsString() << std::endl;
00391   //  std::cout << mTR.chainAsString("child", 0, "my_parent2", 0, "my_parent2") << std::endl;
00392 
00393   for ( unsigned int i = 0; i < runs ; i++ )
00394 
00395   {
00396     Stamped<Pose> inpose (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10 + i), "grandchild");
00397 
00398     try{
00399     Stamped<Pose> outpose;
00400     outpose.setIdentity(); //to make sure things are getting mutated
00401     mTR.transformPose("my_parent",inpose, outpose);
00402     EXPECT_NEAR(outpose.getOrigin().x(), 2*xvalues[i], epsilon);
00403     EXPECT_NEAR(outpose.getOrigin().y(), 2*yvalues[i], epsilon);
00404     EXPECT_NEAR(outpose.getOrigin().z(), 2*zvalues[i], epsilon);
00405     }
00406     catch (tf::TransformException & ex)
00407     {
00408       std::cout << "TransformExcepion got through!!!!! " << ex.what() << std::endl;
00409       bool exception_improperly_thrown = true;
00410       EXPECT_FALSE(exception_improperly_thrown);
00411     }
00412   }
00413 
00414 }
00415 
00416 
00417 TEST(tf, ListOneForward)
00418 {
00419   unsigned int runs = 4;
00420   double epsilon = 1e-6;
00421   seed_rand();
00422 
00423   tf::Transformer mTR(true);
00424   std::vector<double> xvalues(runs), yvalues(runs), zvalues(runs);
00425   for ( uint64_t i = 0; i < runs ; i++ )
00426   {
00427     xvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00428     yvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00429     zvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00430 
00431     StampedTransform tranStamped(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10 + i),  "my_parent", "child");
00432     mTR.setTransform(tranStamped);
00433   }
00434 
00435   //  std::cout << mTR.allFramesAsString() << std::endl;
00436   //  std::cout << mTR.chainAsString("child", 0, "my_parent2", 0, "my_parent2") << std::endl;
00437 
00438   for ( uint64_t i = 0; i < runs ; i++ )
00439 
00440   {
00441     Stamped<Pose> inpose (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10 + i), "my_parent");
00442 
00443     try{
00444     Stamped<Pose> outpose;
00445     outpose.setIdentity(); //to make sure things are getting mutated
00446     mTR.transformPose("child",inpose, outpose);
00447     EXPECT_NEAR(outpose.getOrigin().x(), -xvalues[i], epsilon);
00448     EXPECT_NEAR(outpose.getOrigin().y(), -yvalues[i], epsilon);
00449     EXPECT_NEAR(outpose.getOrigin().z(), -zvalues[i], epsilon);
00450     }
00451     catch (tf::TransformException & ex)
00452     {
00453       std::cout << "TransformExcepion got through!!!!! " << ex.what() << std::endl;
00454       bool exception_improperly_thrown = true;
00455       EXPECT_FALSE(exception_improperly_thrown);
00456     }
00457   }
00458 
00459 }
00460 
00461 TEST(tf, ListTwoForward)
00462 {
00463   unsigned int runs = 4;
00464   double epsilon = 1e-6;
00465   seed_rand();
00466 
00467   tf::Transformer mTR(true);
00468   std::vector<double> xvalues(runs), yvalues(runs), zvalues(runs);
00469   for ( unsigned int i = 0; i < runs ; i++ )
00470   {
00471     xvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00472     yvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00473     zvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00474 
00475     StampedTransform tranStamped(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10 + i),  "my_parent", "child");
00476     mTR.setTransform(tranStamped);
00477     StampedTransform tranStamped2(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10 + i),  "child", "grandchild");
00478     mTR.setTransform(tranStamped2);
00479   }
00480 
00481   //  std::cout << mTR.allFramesAsString() << std::endl;
00482   //  std::cout << mTR.chainAsString("child", 0, "my_parent2", 0, "my_parent2") << std::endl;
00483 
00484   for ( unsigned int i = 0; i < runs ; i++ )
00485 
00486   {
00487     Stamped<Pose> inpose (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10 + i), "my_parent");
00488 
00489     try{
00490     Stamped<Pose> outpose;
00491     outpose.setIdentity(); //to make sure things are getting mutated
00492     mTR.transformPose("grandchild",inpose, outpose);
00493     EXPECT_NEAR(outpose.getOrigin().x(), -2*xvalues[i], epsilon);
00494     EXPECT_NEAR(outpose.getOrigin().y(), -2*yvalues[i], epsilon);
00495     EXPECT_NEAR(outpose.getOrigin().z(), -2*zvalues[i], epsilon);
00496     }
00497     catch (tf::TransformException & ex)
00498     {
00499       std::cout << "TransformExcepion got through!!!!! " << ex.what() << std::endl;
00500       bool exception_improperly_thrown = true;
00501       EXPECT_FALSE(exception_improperly_thrown);
00502     }
00503   }
00504 
00505 }
00506 
00507 TEST(tf, TransformThrougRoot)
00508 {
00509   unsigned int runs = 4;
00510   double epsilon = 1e-6;
00511   seed_rand();
00512 
00513   tf::Transformer mTR(true);
00514   std::vector<double> xvalues(runs), yvalues(runs), zvalues(runs);
00515   for ( unsigned int i = 0; i < runs ; i++ )
00516   {
00517     xvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00518     yvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00519     zvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00520 
00521     StampedTransform tranStamped(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(1000 + i*100),  "my_parent", "childA");
00522     mTR.setTransform(tranStamped);
00523     StampedTransform tranStamped2(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(1000 + i*100),  "my_parent", "childB");
00524     mTR.setTransform(tranStamped2);
00525   }
00526 
00527   //  std::cout << mTR.allFramesAsString() << std::endl;
00528   //  std::cout << mTR.chainAsString("child", 0, "my_parent2", 0, "my_parent2") << std::endl;
00529 
00530   for ( unsigned int i = 0; i < runs ; i++ )
00531 
00532   {
00533     Stamped<Pose> inpose (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000 + i*100), "childA");
00534 
00535     try{
00536     Stamped<Pose> outpose;
00537     outpose.setIdentity(); //to make sure things are getting mutated
00538     mTR.transformPose("childB",inpose, outpose);
00539     EXPECT_NEAR(outpose.getOrigin().x(), 0*xvalues[i], epsilon);
00540     EXPECT_NEAR(outpose.getOrigin().y(), 0*yvalues[i], epsilon);
00541     EXPECT_NEAR(outpose.getOrigin().z(), 0*zvalues[i], epsilon);
00542     }
00543     catch (tf::TransformException & ex)
00544     {
00545       std::cout << "TransformExcepion got through!!!!! " << ex.what() << std::endl;
00546       bool exception_improperly_thrown = true;
00547       EXPECT_FALSE(exception_improperly_thrown);
00548     }
00549   }
00550 
00551 }
00552 
00553 TEST(tf, TransformThroughNO_PARENT)
00554 {
00555   unsigned int runs = 4;
00556   double epsilon = 1e-6;
00557   seed_rand();
00558 
00559   tf::Transformer mTR(true);
00560   std::vector<double> xvalues(runs), yvalues(runs), zvalues(runs);
00561   for ( unsigned int i = 0; i < runs ; i++ )
00562   {
00563     xvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00564     yvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00565     zvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00566 
00567     StampedTransform tranStamped(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10 + i),  "my_parentA", "childA");
00568     mTR.setTransform(tranStamped);
00569     StampedTransform tranStamped2(btTransform(btQuaternion(0,0,0,1), btVector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10 + i),  "my_parentB", "childB");
00570     mTR.setTransform(tranStamped2);
00571   }
00572 
00573   //  std::cout << mTR.allFramesAsString() << std::endl;
00574   //  std::cout << mTR.chainAsString("child", 0, "my_parent2", 0, "my_parent2") << std::endl;
00575 
00576   for ( unsigned int i = 0; i < runs ; i++ )
00577 
00578   {
00579     Stamped<btTransform> inpose (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10 + i), "childA");
00580     bool exception_thrown = false;
00581 
00582     try{
00583     Stamped<btTransform> outpose;
00584     outpose.setIdentity(); //to make sure things are getting mutated
00585     mTR.transformPose("childB",inpose, outpose);
00586     EXPECT_NEAR(outpose.getOrigin().x(), 0*xvalues[i], epsilon);
00587     EXPECT_NEAR(outpose.getOrigin().y(), 0*yvalues[i], epsilon);
00588     EXPECT_NEAR(outpose.getOrigin().z(), 0*zvalues[i], epsilon);
00589     }
00590     catch (tf::TransformException & ex)
00591     {
00592       exception_thrown = true;
00593     }
00594     EXPECT_TRUE(exception_thrown);
00595   }
00596 
00597 }
00598 
00599 */
00600 
00601 
00602 TEST(BufferCore_lookupTransform, i_configuration)
00603 {
00604   double epsilon = 1e-6;
00605 
00606 
00607 
00608   rostest::Permuter permuter;
00609 
00610   std::vector<ros::Time> times;
00611   times.push_back(ros::Time(1.0));
00612   times.push_back(ros::Time(10.0));
00613   times.push_back(ros::Time(0.0));
00614   ros::Time eval_time;
00615   permuter.addOptionSet(times, &eval_time);
00616 
00617   std::vector<ros::Duration> durations;
00618   durations.push_back(ros::Duration(1.0));
00619   durations.push_back(ros::Duration(0.001));
00620   durations.push_back(ros::Duration(0.1));
00621   ros::Duration interpolation_space;
00622   //  permuter.addOptionSet(durations, &interpolation_space);
00623 
00624   std::vector<std::string> frames;
00625   frames.push_back("a");
00626   frames.push_back("b");
00627   frames.push_back("c");
00628   std::string source_frame;
00629   permuter.addOptionSet(frames, &source_frame);
00630 
00631   std::string target_frame;
00632   permuter.addOptionSet(frames, &target_frame);
00633 
00634   while  (permuter.step())
00635   {
00636 
00637     tf2::BufferCore mBC;
00638     setupTree(mBC, "i", eval_time, interpolation_space);
00639 
00640     geometry_msgs::TransformStamped outpose = mBC.lookupTransform(source_frame, target_frame, eval_time);
00641     //printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
00642     EXPECT_EQ(outpose.header.stamp, eval_time);
00643     EXPECT_EQ(outpose.header.frame_id, source_frame);
00644     EXPECT_EQ(outpose.child_frame_id, target_frame);
00645     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00646     EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
00647     EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
00648     EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
00649     EXPECT_NEAR(outpose.transform.rotation.z, 0, epsilon);
00650     EXPECT_NEAR(outpose.transform.rotation.w, 1, epsilon);
00651 
00652     //Zero distance
00653     if (source_frame == target_frame)
00654     {
00655       EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00656     }
00657     else if ((source_frame == "a" && target_frame =="b") ||
00658              (source_frame == "b" && target_frame =="c"))
00659     {
00660       EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00661     }
00662     else if ((source_frame == "b" && target_frame =="a") ||
00663              (source_frame == "c" && target_frame =="b"))
00664     {
00665       EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00666     }
00667     else if (source_frame == "a" && target_frame =="c")
00668     {
00669       EXPECT_NEAR(outpose.transform.translation.x, 2, epsilon);
00670     }
00671     else if (source_frame == "c" && target_frame =="a")
00672     {
00673       EXPECT_NEAR(outpose.transform.translation.x, -2, epsilon);
00674     }
00675     else
00676     {
00677       EXPECT_FALSE("i configuration: Shouldn't get here");
00678       printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
00679     }
00680 
00681   }
00682 }
00683 
00684 /* Check 1 result return false if test parameters unmet */
00685 bool check_1_result(const geometry_msgs::TransformStamped& outpose, const std::string& source_frame, const std::string& target_frame, const ros::Time& eval_time, double epsilon)
00686 {
00687   //printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
00688   EXPECT_EQ(outpose.header.stamp, eval_time);
00689   EXPECT_EQ(outpose.header.frame_id, source_frame);
00690   EXPECT_EQ(outpose.child_frame_id, target_frame);
00691   EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00692   EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
00693   EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
00694   EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
00695   EXPECT_NEAR(outpose.transform.rotation.z, 0, epsilon);
00696   EXPECT_NEAR(outpose.transform.rotation.w, 1, epsilon);
00697 
00698   //Zero distance
00699   if (source_frame == target_frame)
00700   {
00701     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00702   }
00703   else if (source_frame == "1" && target_frame =="2")
00704   {
00705     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00706   }
00707   else if (source_frame == "2" && target_frame =="1")
00708   {
00709     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00710   }
00711   else
00712   {
00713     //printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
00714     return false;
00715   }
00716   return true;
00717 }
00718 
00719 /* Check v result return false if test parameters unmet */
00720 bool check_v_result(const geometry_msgs::TransformStamped& outpose, const std::string& source_frame, const std::string& target_frame, const ros::Time& eval_time, double epsilon)
00721 {
00722   //printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
00723   EXPECT_EQ(outpose.header.stamp, eval_time);
00724   EXPECT_EQ(outpose.header.frame_id, source_frame);
00725   EXPECT_EQ(outpose.child_frame_id, target_frame);
00726   EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
00727   EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
00728   EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
00729   EXPECT_NEAR(outpose.transform.rotation.z, 0, epsilon);
00730   EXPECT_NEAR(outpose.transform.rotation.w, 1, epsilon);
00731 
00732   //Zero distance
00733   if (source_frame == target_frame)
00734   {
00735     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00736   }
00737   else if ((source_frame == "a" && target_frame =="b") ||
00738            (source_frame == "b" && target_frame =="c"))
00739   {
00740     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00741     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00742   }
00743   else if ((source_frame == "b" && target_frame =="a") ||
00744            (source_frame == "c" && target_frame =="b"))
00745   {
00746     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00747     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00748   }
00749   else if ((source_frame == "a" && target_frame =="f") ||
00750            (source_frame == "f" && target_frame =="g"))
00751   {
00752     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00753     EXPECT_NEAR(outpose.transform.translation.y, 1, epsilon);
00754   }
00755   else if ((source_frame == "f" && target_frame =="a") ||
00756            (source_frame == "g" && target_frame =="f"))
00757   {
00758     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00759     EXPECT_NEAR(outpose.transform.translation.y, -1, epsilon);
00760   }
00761   else if (source_frame == "a" && target_frame =="g")
00762   {
00763     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00764     EXPECT_NEAR(outpose.transform.translation.y, 2, epsilon);
00765   }
00766   else if (source_frame == "g" && target_frame =="a")
00767   {
00768     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00769     EXPECT_NEAR(outpose.transform.translation.y, -2, epsilon);
00770   }
00771   else if (source_frame == "a" && target_frame =="c")
00772   {
00773     EXPECT_NEAR(outpose.transform.translation.x, 2, epsilon);
00774     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00775   }
00776   else if (source_frame == "c" && target_frame =="a")
00777   {
00778     EXPECT_NEAR(outpose.transform.translation.x, -2, epsilon);
00779     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00780   }
00781   else if (source_frame == "b" && target_frame =="f")
00782   {
00783     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00784     EXPECT_NEAR(outpose.transform.translation.y, 1, epsilon);
00785   }
00786   else if (source_frame == "f" && target_frame =="b")
00787   {
00788     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00789     EXPECT_NEAR(outpose.transform.translation.y, -1, epsilon);
00790   }
00791   else if (source_frame == "c" && target_frame =="f")
00792   {
00793     EXPECT_NEAR(outpose.transform.translation.x, -2, epsilon);
00794     EXPECT_NEAR(outpose.transform.translation.y, 1, epsilon);
00795   }
00796   else if (source_frame == "f" && target_frame =="c")
00797   {
00798     EXPECT_NEAR(outpose.transform.translation.x, 2, epsilon);
00799     EXPECT_NEAR(outpose.transform.translation.y, -1, epsilon);
00800   }
00801   else if (source_frame == "b" && target_frame =="g")
00802   {
00803     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00804     EXPECT_NEAR(outpose.transform.translation.y, 2, epsilon);
00805   }
00806   else if (source_frame == "g" && target_frame =="b")
00807   {
00808     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00809     EXPECT_NEAR(outpose.transform.translation.y, -2, epsilon);
00810   }
00811   else if (source_frame == "c" && target_frame =="g")
00812   {
00813     EXPECT_NEAR(outpose.transform.translation.x, -2, epsilon);
00814     EXPECT_NEAR(outpose.transform.translation.y, 2, epsilon);
00815   }
00816   else if (source_frame == "g" && target_frame =="c")
00817   {
00818     EXPECT_NEAR(outpose.transform.translation.x, 2, epsilon);
00819     EXPECT_NEAR(outpose.transform.translation.y, -2, epsilon);
00820   }
00821   else
00822   {
00823     //printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
00824     return false;
00825   }
00826   return true;
00827 }
00828 
00829 /* Check v result return false if test parameters unmet */
00830 bool check_y_result(const geometry_msgs::TransformStamped& outpose, const std::string& source_frame, const std::string& target_frame, const ros::Time& eval_time, double epsilon)
00831 {
00832   //printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
00833   EXPECT_EQ(outpose.header.stamp, eval_time);
00834   EXPECT_EQ(outpose.header.frame_id, source_frame);
00835   EXPECT_EQ(outpose.child_frame_id, target_frame);
00836   EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
00837   EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
00838   EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
00839   EXPECT_NEAR(outpose.transform.rotation.z, 0, epsilon);
00840   EXPECT_NEAR(outpose.transform.rotation.w, 1, epsilon);
00841 
00842   //Zero distance
00843   if (source_frame == target_frame)
00844   {
00845     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00846   }
00847   else if ((source_frame == "a" && target_frame =="b") ||
00848            (source_frame == "b" && target_frame =="c"))
00849   {
00850     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00851     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00852   }
00853   else if ((source_frame == "b" && target_frame =="a") ||
00854            (source_frame == "c" && target_frame =="b"))
00855   {
00856     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00857     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00858   }
00859   else if ((source_frame == "b" && target_frame =="d") ||
00860            (source_frame == "d" && target_frame =="e"))
00861   {
00862     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00863     EXPECT_NEAR(outpose.transform.translation.y, 1, epsilon);
00864   }
00865   else if ((source_frame == "d" && target_frame =="b") ||
00866            (source_frame == "e" && target_frame =="d"))
00867   {
00868     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00869     EXPECT_NEAR(outpose.transform.translation.y, -1, epsilon);
00870   }
00871   else if (source_frame == "b" && target_frame =="e")
00872   {
00873     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00874     EXPECT_NEAR(outpose.transform.translation.y, 2, epsilon);
00875   }
00876   else if (source_frame == "e" && target_frame =="b")
00877   {
00878     EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
00879     EXPECT_NEAR(outpose.transform.translation.y, -2, epsilon);
00880   }
00881   else if (source_frame == "a" && target_frame =="c")
00882   {
00883     EXPECT_NEAR(outpose.transform.translation.x, 2, epsilon);
00884     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00885   }
00886   else if (source_frame == "c" && target_frame =="a")
00887   {
00888     EXPECT_NEAR(outpose.transform.translation.x, -2, epsilon);
00889     EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
00890   }
00891   else if (source_frame == "a" && target_frame =="d")
00892   {
00893     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00894     EXPECT_NEAR(outpose.transform.translation.y, 1, epsilon);
00895   }
00896   else if (source_frame == "d" && target_frame =="a")
00897   {
00898     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00899     EXPECT_NEAR(outpose.transform.translation.y, -1, epsilon);
00900   }
00901   else if (source_frame == "c" && target_frame =="d")
00902   {
00903     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00904     EXPECT_NEAR(outpose.transform.translation.y, 1, epsilon);
00905   }
00906   else if (source_frame == "d" && target_frame =="c")
00907   {
00908     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00909     EXPECT_NEAR(outpose.transform.translation.y, -1, epsilon);
00910   }
00911   else if (source_frame == "a" && target_frame =="e")
00912   {
00913     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00914     EXPECT_NEAR(outpose.transform.translation.y, 2, epsilon);
00915   }
00916   else if (source_frame == "e" && target_frame =="a")
00917   {
00918     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00919     EXPECT_NEAR(outpose.transform.translation.y, -2, epsilon);
00920   }
00921   else if (source_frame == "c" && target_frame =="e")
00922   {
00923     EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
00924     EXPECT_NEAR(outpose.transform.translation.y, 2, epsilon);
00925   }
00926   else if (source_frame == "e" && target_frame =="c")
00927   {
00928     EXPECT_NEAR(outpose.transform.translation.x, 1, epsilon);
00929     EXPECT_NEAR(outpose.transform.translation.y, -2, epsilon);
00930   }
00931   else
00932   {
00933     //printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
00934     return false;
00935   }
00936   return true;
00937 }
00938 
00939 
00940 TEST(BufferCore_lookupTransform, one_link_configuration)
00941 {
00942   double epsilon = 1e-6;
00943 
00944 
00945 
00946   rostest::Permuter permuter;
00947 
00948   std::vector<ros::Time> times;
00949   times.push_back(ros::Time(1.0));
00950   times.push_back(ros::Time(10.0));
00951   times.push_back(ros::Time(0.0));
00952   ros::Time eval_time;
00953   permuter.addOptionSet(times, &eval_time);
00954 
00955   std::vector<ros::Duration> durations;
00956   durations.push_back(ros::Duration(1.0));
00957   durations.push_back(ros::Duration(0.001));
00958   durations.push_back(ros::Duration(0.1));
00959   ros::Duration interpolation_space;
00960   //  permuter.addOptionSet(durations, &interpolation_space);
00961 
00962   std::vector<std::string> frames;
00963   frames.push_back("1");
00964   frames.push_back("2");
00965   std::string source_frame;
00966   permuter.addOptionSet(frames, &source_frame);
00967 
00968   std::string target_frame;
00969   permuter.addOptionSet(frames, &target_frame);
00970 
00971   while  (permuter.step())
00972   {
00973 
00974     tf2::BufferCore mBC;
00975     setupTree(mBC, "1", eval_time, interpolation_space);
00976 
00977     geometry_msgs::TransformStamped outpose = mBC.lookupTransform(source_frame, target_frame, eval_time);
00978 
00979     EXPECT_TRUE(check_1_result(outpose, source_frame, target_frame, eval_time, epsilon));
00980   }
00981 }
00982 
00983 
00984 TEST(BufferCore_lookupTransform, v_configuration)
00985 {
00986   double epsilon = 1e-6;
00987 
00988 
00989 
00990   rostest::Permuter permuter;
00991 
00992   std::vector<ros::Time> times;
00993   times.push_back(ros::Time(1.0));
00994   times.push_back(ros::Time(10.0));
00995   times.push_back(ros::Time(0.0));
00996   ros::Time eval_time;
00997   permuter.addOptionSet(times, &eval_time);
00998 
00999   std::vector<ros::Duration> durations;
01000   durations.push_back(ros::Duration(1.0));
01001   durations.push_back(ros::Duration(0.001));
01002   durations.push_back(ros::Duration(0.1));
01003   ros::Duration interpolation_space;
01004   //  permuter.addOptionSet(durations, &interpolation_space);
01005 
01006   std::vector<std::string> frames;
01007   frames.push_back("a");
01008   frames.push_back("b");
01009   frames.push_back("c");
01010   frames.push_back("f");
01011   frames.push_back("g");
01012   std::string source_frame;
01013   permuter.addOptionSet(frames, &source_frame);
01014 
01015   std::string target_frame;
01016   permuter.addOptionSet(frames, &target_frame);
01017 
01018   while  (permuter.step())
01019   {
01020 
01021     tf2::BufferCore mBC;
01022     setupTree(mBC, "v", eval_time, interpolation_space);
01023 
01024     geometry_msgs::TransformStamped outpose = mBC.lookupTransform(source_frame, target_frame, eval_time);
01025 
01026     EXPECT_TRUE(check_v_result(outpose, source_frame, target_frame, eval_time, epsilon));
01027   }
01028 }
01029 
01030 
01031 TEST(BufferCore_lookupTransform, y_configuration)
01032 {
01033   double epsilon = 1e-6;
01034 
01035 
01036 
01037   rostest::Permuter permuter;
01038 
01039   std::vector<ros::Time> times;
01040   times.push_back(ros::Time(1.0));
01041   times.push_back(ros::Time(10.0));
01042   times.push_back(ros::Time(0.0));
01043   ros::Time eval_time;
01044   permuter.addOptionSet(times, &eval_time);
01045 
01046   std::vector<ros::Duration> durations;
01047   durations.push_back(ros::Duration(1.0));
01048   durations.push_back(ros::Duration(0.001));
01049   durations.push_back(ros::Duration(0.1));
01050   ros::Duration interpolation_space;
01051   //  permuter.addOptionSet(durations, &interpolation_space);
01052 
01053   std::vector<std::string> frames;
01054   frames.push_back("a");
01055   frames.push_back("b");
01056   frames.push_back("c");
01057   frames.push_back("d");
01058   frames.push_back("e");
01059   std::string source_frame;
01060   permuter.addOptionSet(frames, &source_frame);
01061 
01062   std::string target_frame;
01063   permuter.addOptionSet(frames, &target_frame);
01064 
01065   while  (permuter.step())
01066   {
01067 
01068     tf2::BufferCore mBC;
01069     setupTree(mBC, "y", eval_time, interpolation_space);
01070 
01071     geometry_msgs::TransformStamped outpose = mBC.lookupTransform(source_frame, target_frame, eval_time);
01072 
01073     EXPECT_TRUE(check_y_result(outpose, source_frame, target_frame, eval_time, epsilon));
01074   }
01075 }
01076 
01077 TEST(BufferCore_lookupTransform, multi_configuration)
01078 {
01079   double epsilon = 1e-6;
01080 
01081 
01082 
01083   rostest::Permuter permuter;
01084 
01085   std::vector<ros::Time> times;
01086   times.push_back(ros::Time(1.0));
01087   times.push_back(ros::Time(10.0));
01088   times.push_back(ros::Time(0.0));
01089   ros::Time eval_time;
01090   permuter.addOptionSet(times, &eval_time);
01091 
01092   std::vector<ros::Duration> durations;
01093   durations.push_back(ros::Duration(1.0));
01094   durations.push_back(ros::Duration(0.001));
01095   durations.push_back(ros::Duration(0.1));
01096   ros::Duration interpolation_space;
01097   //  permuter.addOptionSet(durations, &interpolation_space);
01098 
01099   std::vector<std::string> frames;
01100   frames.push_back("1");
01101   frames.push_back("2");
01102   frames.push_back("a");
01103   frames.push_back("b");
01104   frames.push_back("c");
01105   frames.push_back("f");
01106   frames.push_back("g");
01107   std::string source_frame;
01108   permuter.addOptionSet(frames, &source_frame);
01109 
01110   std::string target_frame;
01111   permuter.addOptionSet(frames, &target_frame);
01112 
01113   while  (permuter.step())
01114   {
01115 
01116     tf2::BufferCore mBC;
01117     setupTree(mBC, "1_v", eval_time, interpolation_space);
01118 
01119     if (mBC.canTransform(source_frame, target_frame, eval_time))
01120     {
01121       geometry_msgs::TransformStamped outpose = mBC.lookupTransform(source_frame, target_frame, eval_time);
01122 
01123       if ((source_frame == "1" || source_frame =="2") && (target_frame =="1" || target_frame == "2"))
01124         EXPECT_TRUE(check_1_result(outpose, source_frame, target_frame, eval_time, epsilon));
01125       else if ((source_frame == "a" || source_frame == "b" || source_frame == "c" || source_frame == "f" || source_frame == "g") &&
01126                (target_frame == "a" || target_frame == "b" || target_frame == "c" || target_frame == "f" || target_frame == "g"))
01127         EXPECT_TRUE(check_v_result(outpose, source_frame, target_frame, eval_time, epsilon));
01128       else
01129         EXPECT_FALSE("Frames unhandled");
01130     }
01131     else
01132       EXPECT_TRUE(((source_frame == "a" || source_frame =="b" || source_frame == "c" || source_frame == "f" || source_frame == "g") &&
01133                    (target_frame == "1" || target_frame == "2") )
01134                   ||
01135                   ((target_frame == "a" || target_frame =="b" || target_frame == "c" || target_frame == "f" || target_frame == "g") &&
01136                    (source_frame == "1" || source_frame == "2"))
01137                   );
01138 
01139   }
01140 }
01141 
01142 #define CHECK_QUATERNION_NEAR(_q1, _x, _y, _z, _w, _epsilon)                 \
01143            {                                                                                                             \
01144            btQuaternion q1(_q1.x, _q1.y, _q1.z, _q1.w);                          \
01145        btQuaternion q2(_x, _y, _z, _w);                                      \
01146        double angle = q1.angle(q2);                                          \
01147            EXPECT_TRUE(fabs(angle) < _epsilon || fabs(angle - M_PI) < _epsilon); \
01148            }
01149 
01150 #define CHECK_TRANSFORMS_NEAR(_out, _expected, _eps)                                                                                                                                                                                                                        \
01151         EXPECT_NEAR(_out.transform.translation.x, _expected.getOrigin().x(), epsilon);                                                                                                                                                          \
01152         EXPECT_NEAR(_out.transform.translation.y, _expected.getOrigin().y(), epsilon);                                                                                                                                                                  \
01153         EXPECT_NEAR(_out.transform.translation.z, _expected.getOrigin().z(), epsilon);                                                                                                                                                          \
01154         CHECK_QUATERNION_NEAR(_out.transform.rotation, _expected.getRotation().x(), _expected.getRotation().y(), _expected.getRotation().z(), _expected.getRotation().w(), _eps);
01155 
01156 
01157 // Simple test with compound transform
01158 TEST(BufferCore_lookupTransform, compound_xfm_configuration)
01159 {
01160         /*
01161          * Frames
01162          *
01163          * root->a
01164          *
01165          * root->b->c->d
01166          *
01167          */
01168 
01169         double epsilon = 2e-5; // Larger epsilon for interpolation values
01170 
01171     tf2::BufferCore mBC;
01172 
01173     geometry_msgs::TransformStamped tsa;
01174     tsa.header.frame_id = "root";
01175     tsa.child_frame_id  = "a";
01176     tsa.transform.translation.x = 1.0;
01177     tsa.transform.translation.y = 1.0;
01178     tsa.transform.translation.z = 1.0;
01179     btQuaternion q1;
01180     q1.setEuler(0.25, .5, .75);
01181     tsa.transform.rotation.x = q1.x();
01182     tsa.transform.rotation.y = q1.y();
01183     tsa.transform.rotation.z = q1.z();
01184     tsa.transform.rotation.w = q1.w();
01185     EXPECT_TRUE(mBC.setTransform(tsa, "authority"));
01186 
01187     geometry_msgs::TransformStamped tsb;
01188     tsb.header.frame_id = "root";
01189     tsb.child_frame_id  = "b";
01190     tsb.transform.translation.x = -1.0;
01191     tsb.transform.translation.y =  0.0;
01192     tsb.transform.translation.z = -1.0;
01193     btQuaternion q2;
01194     q2.setEuler(1.0, 0.25, 0.5);
01195     tsb.transform.rotation.x = q2.x();
01196     tsb.transform.rotation.y = q2.y();
01197     tsb.transform.rotation.z = q2.z();
01198     tsb.transform.rotation.w = q2.w();
01199     EXPECT_TRUE(mBC.setTransform(tsb, "authority"));
01200 
01201     geometry_msgs::TransformStamped tsc;
01202     tsc.header.frame_id = "b";
01203     tsc.child_frame_id  = "c";
01204     tsc.transform.translation.x =  0.0;
01205     tsc.transform.translation.y =  2.0;
01206     tsc.transform.translation.z =  0.5;
01207     btQuaternion q3;
01208     q3.setEuler(0.25, .75, 1.25);
01209     tsc.transform.rotation.x = q3.x();
01210     tsc.transform.rotation.y = q3.y();
01211     tsc.transform.rotation.z = q3.z();
01212     tsc.transform.rotation.w = q3.w();
01213     EXPECT_TRUE(mBC.setTransform(tsc, "authority"));
01214 
01215     geometry_msgs::TransformStamped tsd;
01216     tsd.header.frame_id = "c";
01217     tsd.child_frame_id  = "d";
01218     tsd.transform.translation.x =  0.5;
01219     tsd.transform.translation.y =  -1;
01220     tsd.transform.translation.z =  1.5;
01221     btQuaternion q4;
01222     q4.setEuler(-0.5, 1.0, -.75);
01223     tsd.transform.rotation.x = q4.x();
01224     tsd.transform.rotation.y = q4.y();
01225     tsd.transform.rotation.z = q4.z();
01226     tsd.transform.rotation.w = q4.w();
01227     EXPECT_TRUE(mBC.setTransform(tsd, "authority"));
01228 
01229     btTransform ta, tb, tc, td, expected_ab, expected_bc, expected_cb, expected_ac, expected_ba, expected_ca, expected_ad, expected_da, expected_bd, expected_db, expected_rootd, expected_rootc;
01230     ta.setOrigin(btVector3(1.0,  1.0,  1.0));
01231     ta.setRotation(q1);
01232     tb.setOrigin(btVector3(-1.0, 0.0, -1.0));
01233     tb.setRotation(q2);
01234     tc.setOrigin(btVector3(0.0, 2.0, 0.5));
01235     tc.setRotation(q3);
01236     td.setOrigin(btVector3(0.5, -1, 1.5));
01237     td.setRotation(q4);
01238 
01239 
01240     expected_ab = ta.inverse() * tb;
01241     expected_ac = ta.inverse() * tb * tc;
01242     expected_ad = ta.inverse() * tb * tc * td;
01243     expected_cb = tc.inverse();
01244     expected_bc = tc;
01245     expected_bd = tc * td;
01246     expected_db = expected_bd.inverse();
01247     expected_ba = tb.inverse() * ta;
01248     expected_ca = tc.inverse() * tb.inverse() * ta;
01249     expected_da = td.inverse() * tc.inverse() * tb.inverse() * ta;
01250     expected_rootd = tb * tc * td;
01251     expected_rootc = tb * tc;
01252 
01253     // root -> b -> c
01254     geometry_msgs::TransformStamped out_rootc = mBC.lookupTransform("root", "c", ros::Time());
01255     CHECK_TRANSFORMS_NEAR(out_rootc, expected_rootc, epsilon);
01256 
01257     // root -> b -> c -> d
01258     geometry_msgs::TransformStamped out_rootd = mBC.lookupTransform("root", "d", ros::Time());
01259     CHECK_TRANSFORMS_NEAR(out_rootd, expected_rootd, epsilon);
01260 
01261     // a <- root -> b
01262     geometry_msgs::TransformStamped out_ab = mBC.lookupTransform("a", "b", ros::Time());
01263     CHECK_TRANSFORMS_NEAR(out_ab, expected_ab, epsilon);
01264 
01265     geometry_msgs::TransformStamped out_ba = mBC.lookupTransform("b", "a", ros::Time());
01266     CHECK_TRANSFORMS_NEAR(out_ba, expected_ba, epsilon);
01267 
01268     // a <- root -> b -> c
01269     geometry_msgs::TransformStamped out_ac = mBC.lookupTransform("a", "c", ros::Time());
01270     CHECK_TRANSFORMS_NEAR(out_ac, expected_ac, epsilon);
01271 
01272     geometry_msgs::TransformStamped out_ca = mBC.lookupTransform("c", "a", ros::Time());
01273     CHECK_TRANSFORMS_NEAR(out_ca, expected_ca, epsilon);
01274 
01275     // a <- root -> b -> c -> d
01276     geometry_msgs::TransformStamped out_ad = mBC.lookupTransform("a", "d", ros::Time());
01277     CHECK_TRANSFORMS_NEAR(out_ad, expected_ad, epsilon);
01278 
01279     geometry_msgs::TransformStamped out_da = mBC.lookupTransform("d", "a", ros::Time());
01280     CHECK_TRANSFORMS_NEAR(out_da, expected_da, epsilon);
01281 
01282     // b -> c
01283     geometry_msgs::TransformStamped out_cb = mBC.lookupTransform("c", "b", ros::Time());
01284     CHECK_TRANSFORMS_NEAR(out_cb, expected_cb, epsilon);
01285 
01286     geometry_msgs::TransformStamped out_bc = mBC.lookupTransform("b", "c", ros::Time());
01287     CHECK_TRANSFORMS_NEAR(out_bc, expected_bc, epsilon);
01288 
01289     // b -> c -> d
01290     geometry_msgs::TransformStamped out_bd = mBC.lookupTransform("b", "d", ros::Time());
01291     CHECK_TRANSFORMS_NEAR(out_bd, expected_bd, epsilon);
01292 
01293     geometry_msgs::TransformStamped out_db = mBC.lookupTransform("d", "b", ros::Time());
01294     CHECK_TRANSFORMS_NEAR(out_db, expected_db, epsilon);
01295 }
01296 
01297 // Time varying transforms, testing interpolation
01298 TEST(BufferCore_lookupTransform, helix_configuration)
01299 {
01300         double epsilon = 2e-5; // Larger epsilon for interpolation values
01301 
01302     tf2::BufferCore mBC;
01303 
01304     ros::Time     t0        = ros::Time() + ros::Duration(10);
01305     ros::Duration step      = ros::Duration(0.05);
01306     ros::Duration half_step = ros::Duration(0.025);
01307     ros::Time     t1        = t0 + ros::Duration(5.0);
01308 
01309     /*
01310      * a->b->c
01311      *
01312      * b.z = vel * (t - t0)
01313      * c.x = cos(theta * (t - t0))
01314      * c.y = sin(theta * (t - t0))
01315      *
01316      * a->d
01317      *
01318      * d.z = 2 * cos(theta * (t - t0))
01319      * a->d transforms are at half-step between a->b->c transforms
01320      */
01321 
01322     double theta = 0.25;
01323     double vel   = 1.0;
01324 
01325     for (ros::Time t = t0; t <= t1; t += step)
01326     {
01327         ros::Time t2 = t + half_step;
01328         double dt  = (t - t0).toSec();
01329         double dt2 = (t2 - t0).toSec();
01330 
01331         geometry_msgs::TransformStamped ts;
01332         ts.header.frame_id = "a";
01333         ts.header.stamp    = t;
01334         ts.child_frame_id  = "b";
01335         ts.transform.translation.z = vel * dt;
01336         ts.transform.rotation.w = 1.0;
01337         EXPECT_TRUE(mBC.setTransform(ts, "authority"));
01338 
01339         geometry_msgs::TransformStamped ts2;
01340         ts2.header.frame_id = "b";
01341         ts2.header.stamp    = t;
01342         ts2.child_frame_id  = "c";
01343         ts2.transform.translation.x = cos(theta * dt);
01344         ts2.transform.translation.y = sin(theta * dt);
01345         btQuaternion q;
01346         q.setEuler(0,0,theta*dt);
01347         ts2.transform.rotation.z = q.z();
01348         ts2.transform.rotation.w = q.w();
01349         EXPECT_TRUE(mBC.setTransform(ts2, "authority"));
01350 
01351         geometry_msgs::TransformStamped ts3;
01352         ts3.header.frame_id = "a";
01353         ts3.header.stamp    = t2;
01354         ts3.child_frame_id  = "d";
01355         ts3.transform.translation.z = cos(theta * dt2);
01356         ts3.transform.rotation.w = 1.0;
01357         EXPECT_TRUE(mBC.setTransform(ts3, "authority"));
01358     }
01359 
01360 
01361     for (ros::Time t = t0 + half_step; t < t1; t += step)
01362     {
01363         ros::Time t2 = t + half_step;
01364         double dt  = (t - t0).toSec();
01365         double dt2 = (t2 - t0).toSec();
01366 
01367         geometry_msgs::TransformStamped out_ab = mBC.lookupTransform("a", "b", t);
01368         EXPECT_NEAR(out_ab.transform.translation.z, vel * dt, epsilon);
01369 
01370         geometry_msgs::TransformStamped out_ac = mBC.lookupTransform("a", "c", t);
01371         EXPECT_NEAR(out_ac.transform.translation.x, cos(theta * dt), epsilon);
01372         EXPECT_NEAR(out_ac.transform.translation.y, sin(theta * dt), epsilon);
01373         EXPECT_NEAR(out_ac.transform.translation.z, vel * dt,            epsilon);
01374         btQuaternion q;
01375         q.setEuler(0,0,theta*dt);
01376         CHECK_QUATERNION_NEAR(out_ac.transform.rotation, 0, 0, q.z(), q.w(), epsilon);
01377 
01378         geometry_msgs::TransformStamped out_ad = mBC.lookupTransform("a", "d", t);
01379         EXPECT_NEAR(out_ad.transform.translation.z, cos(theta * dt), epsilon);
01380 
01381         geometry_msgs::TransformStamped out_cd = mBC.lookupTransform("c", "d", t2);
01382         EXPECT_NEAR(out_cd.transform.translation.x, -1,                                       epsilon);
01383         EXPECT_NEAR(out_cd.transform.translation.y,  0,                                       epsilon);
01384         EXPECT_NEAR(out_cd.transform.translation.z, cos(theta * dt2) - vel * dt2, epsilon);
01385         btQuaternion mq;
01386         mq.setEuler(0,0,-theta*dt2);
01387         CHECK_QUATERNION_NEAR(out_cd.transform.rotation, 0, 0, mq.z(), mq.w(), epsilon);
01388     }
01389 
01390     // Advanced API
01391     for (ros::Time t = t0 + half_step; t < t1; t += (step + step))
01392     {
01393         ros::Time t2 = t + step;
01394         double dt  = (t - t0).toSec();
01395         double dt2 = (t2 - t0).toSec();
01396 
01397         geometry_msgs::TransformStamped out_cd2 = mBC.lookupTransform("c", t, "d", t2, "a");
01398         EXPECT_NEAR(out_cd2.transform.translation.x, -1,                                      epsilon);
01399         EXPECT_NEAR(out_cd2.transform.translation.y,  0,                                      epsilon);
01400         EXPECT_NEAR(out_cd2.transform.translation.z, cos(theta * dt2) - vel * dt, epsilon);
01401         btQuaternion mq2;
01402         mq2.setEuler(0,0,-theta*dt);
01403         CHECK_QUATERNION_NEAR(out_cd2.transform.rotation, 0, 0, mq2.z(), mq2.w(), epsilon);
01404     }
01405 }
01406 
01407 
01408 TEST(BufferCore_lookupTransform, ring_45_configuration)
01409 {
01410   double epsilon = 1e-6;
01411   rostest::Permuter permuter;
01412 
01413   std::vector<ros::Time> times;
01414   times.push_back(ros::Time(1.0));
01415   times.push_back(ros::Time(10.0));
01416   times.push_back(ros::Time(0.0));
01417   ros::Time eval_time;
01418   permuter.addOptionSet(times, &eval_time);
01419 
01420   std::vector<ros::Duration> durations;
01421   durations.push_back(ros::Duration(1.0));
01422   durations.push_back(ros::Duration(0.001));
01423   durations.push_back(ros::Duration(0.1));
01424   ros::Duration interpolation_space;
01425   //  permuter.addOptionSet(durations, &interpolation_space);
01426 
01427   std::vector<std::string> frames;
01428   frames.push_back("a");
01429   frames.push_back("b");
01430   frames.push_back("c");
01431   frames.push_back("d");
01432   frames.push_back("e");
01433   frames.push_back("f");
01434   frames.push_back("g");
01435   frames.push_back("h");
01436   frames.push_back("i");
01437   /*  frames.push_back("inverse_b");
01438   frames.push_back("inverse_c");
01439   frames.push_back("inverse_d");
01440   frames.push_back("inverse_e");
01441   frames.push_back("inverse_f");
01442   frames.push_back("inverse_g");
01443   frames.push_back("inverse_h");
01444   frames.push_back("inverse_i");*/
01445   std::string source_frame;
01446   permuter.addOptionSet(frames, &source_frame);
01447 
01448   std::string target_frame;
01449   permuter.addOptionSet(frames, &target_frame);
01450 
01451   while  (permuter.step())
01452   {
01453 
01454     tf2::BufferCore mBC;
01455     setupTree(mBC, "ring_45", eval_time, interpolation_space);
01456 
01457     geometry_msgs::TransformStamped outpose = mBC.lookupTransform(source_frame, target_frame, eval_time);
01458 
01459 
01460     //printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
01461     EXPECT_EQ(outpose.header.stamp, eval_time);
01462     EXPECT_EQ(outpose.header.frame_id, source_frame);
01463     EXPECT_EQ(outpose.child_frame_id, target_frame);
01464 
01465 
01466 
01467     //Zero distance or all the way
01468     if (source_frame == target_frame               ||
01469         (source_frame == "a" && target_frame == "i") ||
01470         (source_frame == "i" && target_frame == "a") ||
01471         (source_frame == "a" && target_frame == "inverse_i") ||
01472         (source_frame == "inverse_i" && target_frame == "a") )
01473     {
01474       //printf ("here %s %s\n", source_frame.c_str(), target_frame.c_str());
01475       EXPECT_NEAR(outpose.transform.translation.x, 0, epsilon);
01476       EXPECT_NEAR(outpose.transform.translation.y, 0, epsilon);
01477       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01478       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01479       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01480       EXPECT_NEAR(outpose.transform.rotation.z, 0, epsilon);
01481       EXPECT_NEAR(fabs(outpose.transform.rotation.w), 1, epsilon);
01482     }
01483     // Chaining 1
01484     else if ((source_frame == "a" && target_frame =="b") ||
01485              (source_frame == "b" && target_frame =="c") ||
01486              (source_frame == "c" && target_frame =="d") ||
01487              (source_frame == "d" && target_frame =="e") ||
01488              (source_frame == "e" && target_frame =="f") ||
01489              (source_frame == "f" && target_frame =="g") ||
01490              (source_frame == "g" && target_frame =="h") ||
01491              (source_frame == "h" && target_frame =="i")
01492              )
01493     {
01494       EXPECT_NEAR(outpose.transform.translation.x, sqrt(2)/2 - 1, epsilon);
01495       EXPECT_NEAR(outpose.transform.translation.y, sqrt(2)/2 , epsilon);
01496       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01497       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01498       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01499       EXPECT_NEAR(outpose.transform.rotation.z, sin(M_PI/8), epsilon);
01500       EXPECT_NEAR(outpose.transform.rotation.w, cos(M_PI/8), epsilon);
01501     }
01502     // Inverse Chaining 1
01503     else if ((source_frame == "b" && target_frame =="a") ||
01504              (source_frame == "c" && target_frame =="b") ||
01505              (source_frame == "d" && target_frame =="c") ||
01506              (source_frame == "e" && target_frame =="d") ||
01507              (source_frame == "f" && target_frame =="e") ||
01508              (source_frame == "g" && target_frame =="f") ||
01509              (source_frame == "h" && target_frame =="g") ||
01510              (source_frame == "i" && target_frame =="h")
01511              )
01512     {
01513       EXPECT_NEAR(outpose.transform.translation.x, sqrt(2)/2 - 1, epsilon);
01514       EXPECT_NEAR(outpose.transform.translation.y, -sqrt(2)/2 , epsilon);
01515       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01516       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01517       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01518       EXPECT_NEAR(outpose.transform.rotation.z, sin(-M_PI/8), epsilon);
01519       EXPECT_NEAR(outpose.transform.rotation.w, cos(-M_PI/8), epsilon);
01520     }
01521     // Chaining 2
01522     else if ((source_frame == "a" && target_frame =="c") ||
01523              (source_frame == "b" && target_frame =="d") ||
01524              (source_frame == "c" && target_frame =="e") ||
01525              (source_frame == "d" && target_frame =="f") ||
01526              (source_frame == "e" && target_frame =="g") ||
01527              (source_frame == "f" && target_frame =="h") ||
01528              (source_frame == "g" && target_frame =="i")
01529              )
01530     {
01531       EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
01532       EXPECT_NEAR(outpose.transform.translation.y, 1 , epsilon);
01533       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01534       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01535       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01536       EXPECT_NEAR(outpose.transform.rotation.z, sin(M_PI/4), epsilon);
01537       EXPECT_NEAR(outpose.transform.rotation.w, cos(M_PI/4), epsilon);
01538     }
01539     // Inverse Chaining 2
01540     else if ((source_frame == "c" && target_frame =="a") ||
01541              (source_frame == "d" && target_frame =="b") ||
01542              (source_frame == "e" && target_frame =="c") ||
01543              (source_frame == "f" && target_frame =="d") ||
01544              (source_frame == "g" && target_frame =="e") ||
01545              (source_frame == "h" && target_frame =="f") ||
01546              (source_frame == "i" && target_frame =="g")
01547              )
01548     {
01549       EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
01550       EXPECT_NEAR(outpose.transform.translation.y, -1 , epsilon);
01551       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01552       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01553       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01554       EXPECT_NEAR(outpose.transform.rotation.z, sin(-M_PI/4), epsilon);
01555       EXPECT_NEAR(outpose.transform.rotation.w, cos(-M_PI/4), epsilon);
01556     }
01557     // Chaining 3
01558     else if ((source_frame == "a" && target_frame =="d") ||
01559              (source_frame == "b" && target_frame =="e") ||
01560              (source_frame == "c" && target_frame =="f") ||
01561              (source_frame == "d" && target_frame =="g") ||
01562              (source_frame == "e" && target_frame =="h") ||
01563              (source_frame == "f" && target_frame =="i")
01564              )
01565     {
01566       EXPECT_NEAR(outpose.transform.translation.x, -1 - sqrt(2)/2, epsilon);
01567       EXPECT_NEAR(outpose.transform.translation.y, sqrt(2)/2 , epsilon);
01568       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01569       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01570       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01571       EXPECT_NEAR(outpose.transform.rotation.z, sin(M_PI*3/8), epsilon);
01572       EXPECT_NEAR(outpose.transform.rotation.w, cos(M_PI*3/8), epsilon);
01573     }
01574     // Inverse Chaining 3
01575     else if ((target_frame == "a" && source_frame =="d") ||
01576              (target_frame == "b" && source_frame =="e") ||
01577              (target_frame == "c" && source_frame =="f") ||
01578              (target_frame == "d" && source_frame =="g") ||
01579              (target_frame == "e" && source_frame =="h") ||
01580              (target_frame == "f" && source_frame =="i")
01581              )
01582     {
01583       EXPECT_NEAR(outpose.transform.translation.x, -1 - sqrt(2)/2, epsilon);
01584       EXPECT_NEAR(outpose.transform.translation.y, - sqrt(2)/2 , epsilon);
01585       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01586       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01587       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01588       EXPECT_NEAR(outpose.transform.rotation.z, sin(-M_PI*3/8), epsilon);
01589       EXPECT_NEAR(outpose.transform.rotation.w, cos(-M_PI*3/8), epsilon);
01590     }
01591     // Chaining 4
01592     else if ((source_frame == "a" && target_frame =="e") ||
01593              (source_frame == "b" && target_frame =="f") ||
01594              (source_frame == "c" && target_frame =="g") ||
01595              (source_frame == "d" && target_frame =="h") ||
01596              (source_frame == "e" && target_frame =="i")
01597              )
01598     {
01599       EXPECT_NEAR(outpose.transform.translation.x, -2, epsilon);
01600       EXPECT_NEAR(outpose.transform.translation.y, 0 , epsilon);
01601       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01602       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01603       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01604       EXPECT_NEAR(outpose.transform.rotation.z, sin(M_PI/2), epsilon);
01605       EXPECT_NEAR(outpose.transform.rotation.w, cos(M_PI/2), epsilon);
01606     }
01607     // Inverse Chaining 4
01608     else if ((target_frame == "a" && source_frame =="e") ||
01609              (target_frame == "b" && source_frame =="f") ||
01610              (target_frame == "c" && source_frame =="g") ||
01611              (target_frame == "d" && source_frame =="h") ||
01612              (target_frame == "e" && source_frame =="i")
01613              )
01614     {
01615       EXPECT_NEAR(outpose.transform.translation.x, -2, epsilon);
01616       EXPECT_NEAR(outpose.transform.translation.y, 0 , epsilon);
01617       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01618       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01619       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01620       EXPECT_NEAR(outpose.transform.rotation.z, sin(-M_PI/2), epsilon);
01621       EXPECT_NEAR(outpose.transform.rotation.w, cos(-M_PI/2), epsilon);
01622     }
01623     // Chaining 5
01624     else if ((source_frame == "a" && target_frame =="f") ||
01625              (source_frame == "b" && target_frame =="g") ||
01626              (source_frame == "c" && target_frame =="h") ||
01627              (source_frame == "d" && target_frame =="i")
01628              )
01629     {
01630       EXPECT_NEAR(outpose.transform.translation.x, -1 - sqrt(2) /2, epsilon);
01631       EXPECT_NEAR(outpose.transform.translation.y, - sqrt(2) /2 , epsilon);
01632       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01633       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01634       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01635       EXPECT_NEAR(outpose.transform.rotation.z, sin(M_PI*5/8), epsilon);
01636       EXPECT_NEAR(outpose.transform.rotation.w, cos(M_PI*5/8), epsilon);
01637     }
01638     // Inverse Chaining 5
01639     else if ((target_frame == "a" && source_frame =="f") ||
01640              (target_frame == "b" && source_frame =="g") ||
01641              (target_frame == "c" && source_frame =="h") ||
01642              (target_frame == "d" && source_frame =="i")
01643              )
01644     {
01645       EXPECT_NEAR(outpose.transform.translation.x, -1 - sqrt(2)/2, epsilon);
01646       EXPECT_NEAR(outpose.transform.translation.y, sqrt(2)/2 , epsilon);
01647       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01648       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01649       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01650       EXPECT_NEAR(outpose.transform.rotation.z, sin(-M_PI*5/8), epsilon);
01651       EXPECT_NEAR(outpose.transform.rotation.w, cos(-M_PI*5/8), epsilon);
01652     }
01653     // Chaining 6
01654     else if ((source_frame == "a" && target_frame =="g") ||
01655              (source_frame == "b" && target_frame =="h") ||
01656              (source_frame == "c" && target_frame =="i")
01657              )
01658     {
01659       EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
01660       EXPECT_NEAR(outpose.transform.translation.y, -1 , epsilon);
01661       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01662       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01663       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01664       EXPECT_NEAR(outpose.transform.rotation.z, sin(M_PI*6/8), epsilon);
01665       EXPECT_NEAR(outpose.transform.rotation.w, cos(M_PI*6/8), epsilon);
01666     }
01667     // Inverse Chaining 6
01668     else if ((target_frame == "a" && source_frame =="g") ||
01669              (target_frame == "b" && source_frame =="h") ||
01670              (target_frame == "c" && source_frame =="i")
01671              )
01672     {
01673       EXPECT_NEAR(outpose.transform.translation.x, -1, epsilon);
01674       EXPECT_NEAR(outpose.transform.translation.y, 1 , epsilon);
01675       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01676       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01677       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01678       EXPECT_NEAR(outpose.transform.rotation.z, sin(-M_PI*6/8), epsilon);
01679       EXPECT_NEAR(outpose.transform.rotation.w, cos(-M_PI*6/8), epsilon);
01680     }
01681     // Chaining 7
01682     else if ((source_frame == "a" && target_frame =="h") ||
01683              (source_frame == "b" && target_frame =="i")
01684              )
01685     {
01686       EXPECT_NEAR(outpose.transform.translation.x, sqrt(2)/2 - 1, epsilon);
01687       EXPECT_NEAR(outpose.transform.translation.y, -sqrt(2)/2 , epsilon);
01688       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01689       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01690       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01691       EXPECT_NEAR(outpose.transform.rotation.z, sin(M_PI*7/8), epsilon);
01692       EXPECT_NEAR(outpose.transform.rotation.w, cos(M_PI*7/8), epsilon);
01693     }
01694     // Inverse Chaining 7
01695     else if ((target_frame == "a" && source_frame =="h") ||
01696              (target_frame == "b" && source_frame =="i")
01697              )
01698     {
01699       EXPECT_NEAR(outpose.transform.translation.x, sqrt(2)/2 - 1, epsilon);
01700       EXPECT_NEAR(outpose.transform.translation.y, sqrt(2)/2 , epsilon);
01701       EXPECT_NEAR(outpose.transform.translation.z, 0, epsilon);
01702       EXPECT_NEAR(outpose.transform.rotation.x, 0, epsilon);
01703       EXPECT_NEAR(outpose.transform.rotation.y, 0, epsilon);
01704       EXPECT_NEAR(outpose.transform.rotation.z, sin(-M_PI*7/8), epsilon);
01705       EXPECT_NEAR(outpose.transform.rotation.w, cos(-M_PI*7/8), epsilon);
01706     }
01707     else
01708     {
01709       EXPECT_FALSE("Ring_45 testing Shouldn't get here");
01710       printf("source_frame %s target_frame %s time %f\n", source_frame.c_str(), target_frame.c_str(), eval_time.toSec());
01711     }
01712 
01713   }
01714 }
01715 
01716 TEST(BufferCore_lookupTransform, invalid_arguments)
01717 {
01718   tf2::BufferCore mBC;
01719 
01720   setupTree(mBC, "i", ros::Time(1.0));
01721 
01722   EXPECT_NO_THROW(mBC.lookupTransform("b", "a", ros::Time()));
01723 
01724   //Empty frame_id
01725   EXPECT_THROW(mBC.lookupTransform("", "a", ros::Time()), tf2::InvalidArgumentException);
01726   EXPECT_THROW(mBC.lookupTransform("b", "", ros::Time()), tf2::InvalidArgumentException);
01727 
01728   //frame_id with /
01729   EXPECT_THROW(mBC.lookupTransform("/b", "a", ros::Time()), tf2::InvalidArgumentException);
01730   EXPECT_THROW(mBC.lookupTransform("b", "/a", ros::Time()), tf2::InvalidArgumentException);
01731 
01732 };
01733 
01734 TEST(BufferCore_canTransform, invalid_arguments)
01735 {
01736   tf2::BufferCore mBC;
01737 
01738   setupTree(mBC, "i", ros::Time(1.0));
01739 
01740   EXPECT_TRUE(mBC.canTransform("b", "a", ros::Time()));
01741 
01742 
01743   //Empty frame_id
01744   EXPECT_FALSE(mBC.canTransform("", "a", ros::Time()));
01745   EXPECT_FALSE(mBC.canTransform("b", "", ros::Time()));
01746 
01747   //frame_id with /
01748   EXPECT_FALSE(mBC.canTransform("/b", "a", ros::Time()));
01749   EXPECT_FALSE(mBC.canTransform("b", "/a", ros::Time()));
01750 
01751 };
01752 
01753 struct TransformableHelper
01754 {
01755   TransformableHelper()
01756   : called(false)
01757   {}
01758 
01759   void callback(tf2::TransformableRequestHandle request_handle, const std::string& target_frame, const std::string& source_frame,
01760           ros::Time time, tf2::TransformableResult result)
01761   {
01762     called = true;
01763   }
01764 
01765   bool called;
01766 };
01767 
01768 TEST(BufferCore_transformableCallbacks, alreadyTransformable)
01769 {
01770   tf2::BufferCore b;
01771   TransformableHelper h;
01772 
01773   geometry_msgs::TransformStamped t;
01774   t.header.stamp = ros::Time(1);
01775   t.header.frame_id = "a";
01776   t.child_frame_id = "b";
01777   t.transform.rotation.w = 1.0;
01778   b.setTransform(t, "me");
01779 
01780   tf2::TransformableCallbackHandle cb_handle = b.addTransformableCallback(boost::bind(&TransformableHelper::callback, &h, _1, _2, _3, _4, _5));
01781   EXPECT_EQ(b.addTransformableRequest(cb_handle, "a", "b", ros::Time(1)), 0U);
01782 }
01783 
01784 TEST(BufferCore_transformableCallbacks, waitForNewTransform)
01785 {
01786   tf2::BufferCore b;
01787   TransformableHelper h;
01788   tf2::TransformableCallbackHandle cb_handle = b.addTransformableCallback(boost::bind(&TransformableHelper::callback, &h, _1, _2, _3, _4, _5));
01789   EXPECT_GT(b.addTransformableRequest(cb_handle, "a", "b", ros::Time(10)), 0U);
01790 
01791   geometry_msgs::TransformStamped t;
01792   for (uint32_t i = 1; i <= 10; ++i)
01793   {
01794     t.header.stamp = ros::Time(i);
01795     t.header.frame_id = "a";
01796     t.child_frame_id = "b";
01797     t.transform.rotation.w = 1.0;
01798     b.setTransform(t, "me");
01799 
01800     if (i < 10)
01801     {
01802       ASSERT_FALSE(h.called);
01803     }
01804     else
01805     {
01806       ASSERT_TRUE(h.called);
01807     }
01808   }
01809 }
01810 
01811 TEST(BufferCore_transformableCallbacks, waitForOldTransform)
01812 {
01813   tf2::BufferCore b;
01814   TransformableHelper h;
01815   tf2::TransformableCallbackHandle cb_handle = b.addTransformableCallback(boost::bind(&TransformableHelper::callback, &h, _1, _2, _3, _4, _5));
01816   EXPECT_GT(b.addTransformableRequest(cb_handle, "a", "b", ros::Time(1)), 0U);
01817 
01818   geometry_msgs::TransformStamped t;
01819   for (uint32_t i = 10; i > 0; --i)
01820   {
01821     t.header.stamp = ros::Time(i);
01822     t.header.frame_id = "a";
01823     t.child_frame_id = "b";
01824     t.transform.rotation.w = 1.0;
01825     b.setTransform(t, "me");
01826 
01827     if (i > 1)
01828     {
01829       ASSERT_FALSE(h.called);
01830     }
01831     else
01832     {
01833       ASSERT_TRUE(h.called);
01834     }
01835   }
01836 }
01837 
01838 /*
01839 TEST(tf, Exceptions)
01840 {
01841 
01842  tf::Transformer mTR(true);
01843 
01844 
01845  Stamped<btTransform> outpose;
01846 
01847  //connectivity when no data
01848  EXPECT_FALSE(mTR.canTransform("parent", "me", ros::Time().fromNSec(10000000)));
01849  try
01850  {
01851    mTR.transformPose("parent",Stamped<Pose>(btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10000000) , "me"), outpose);
01852    EXPECT_FALSE("ConnectivityException Not Thrown");
01853  }
01854  catch ( tf::LookupException &ex)
01855  {
01856    EXPECT_TRUE("Lookupgh Exception Caught");
01857  }
01858  catch (tf::TransformException& ex)
01859  {
01860    printf("%s\n",ex.what());
01861    EXPECT_FALSE("Other Exception Caught");
01862  }
01863 
01864  mTR.setTransform( StampedTransform(btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(100000), "parent", "me"));
01865 
01866  //Extrapolation not valid with one value
01867  EXPECT_FALSE(mTR.canTransform("parent", "me", ros::Time().fromNSec(200000)));
01868  try
01869  {
01870    mTR.transformPose("parent",Stamped<Pose>(btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(200000) , "me"), outpose);
01871    EXPECT_TRUE("ExtrapolationException Not Thrown");
01872  }
01873  catch ( tf::ExtrapolationException &ex)
01874  {
01875    EXPECT_TRUE("Extrapolation Exception Caught");
01876  }
01877  catch (tf::TransformException& ex)
01878  {
01879    printf("%s\n",ex.what());
01880    EXPECT_FALSE("Other Exception Caught");
01881  }
01882 
01883 
01884  mTR.setTransform( StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(300000), "parent", "me"));
01885 
01886  //NO Extration when Interpolating
01887  //inverse list
01888  EXPECT_TRUE(mTR.canTransform("parent", "me", ros::Time().fromNSec(200000)));
01889  try
01890  {
01891    mTR.transformPose("parent",Stamped<Pose>(btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(200000) , "me"), outpose);
01892    EXPECT_TRUE("ExtrapolationException Not Thrown");
01893  }
01894  catch ( tf::ExtrapolationException &ex)
01895  {
01896    EXPECT_FALSE("Extrapolation Exception Caught");
01897  }
01898  catch (tf::TransformException& ex)
01899  {
01900    printf("%s\n",ex.what());
01901    EXPECT_FALSE("Other Exception Caught");
01902  }
01903 
01904 
01905 
01906  //forward list
01907  EXPECT_TRUE(mTR.canTransform("me", "parent", ros::Time().fromNSec(200000)));
01908  try
01909  {
01910    mTR.transformPose("me",Stamped<Pose>(btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(200000) , "parent"), outpose);
01911    EXPECT_TRUE("ExtrapolationException Not Thrown");
01912  }
01913  catch ( tf::ExtrapolationException &ex)
01914  {
01915    EXPECT_FALSE("Extrapolation Exception Caught");
01916  }
01917  catch (tf::TransformException& ex)
01918  {
01919    printf("%s\n",ex.what());
01920    EXPECT_FALSE("Other Exception Caught");
01921  }
01922 
01923 
01924  //Extrapolating backwards
01925  //inverse list
01926  EXPECT_FALSE(mTR.canTransform("parent", "me", ros::Time().fromNSec(1000)));
01927  try
01928  {
01929    mTR.transformPose("parent",Stamped<Pose> (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000) , "me"), outpose);
01930    EXPECT_FALSE("ExtrapolationException Not Thrown");
01931  }
01932  catch ( tf::ExtrapolationException &ex)
01933  {
01934    EXPECT_TRUE("Extrapolation Exception Caught");
01935  }
01936  catch (tf::TransformException& ex)
01937  {
01938    printf("%s\n",ex.what());
01939    EXPECT_FALSE("Other Exception Caught");
01940  }
01941  //forwards list
01942  EXPECT_FALSE(mTR.canTransform("me", "parent", ros::Time().fromNSec(1000)));
01943  try
01944  {
01945    mTR.transformPose("me",Stamped<Pose> (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000) , "parent"), outpose);
01946    EXPECT_FALSE("ExtrapolationException Not Thrown");
01947  }
01948  catch ( tf::ExtrapolationException &ex)
01949  {
01950    EXPECT_TRUE("Extrapolation Exception Caught");
01951  }
01952  catch (tf::TransformException& ex)
01953  {
01954    printf("%s\n",ex.what());
01955    EXPECT_FALSE("Other Exception Caught");
01956  }
01957 
01958 
01959 
01960  // Test extrapolation inverse and forward linkages FORWARD
01961 
01962  //inverse list
01963  EXPECT_FALSE(mTR.canTransform("parent", "me", ros::Time().fromNSec(350000)));
01964  try
01965  {
01966    mTR.transformPose("parent", Stamped<Pose> (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(350000) , "me"), outpose);
01967    EXPECT_FALSE("ExtrapolationException Not Thrown");
01968  }
01969  catch ( tf::ExtrapolationException &ex)
01970  {
01971    EXPECT_TRUE("Extrapolation Exception Caught");
01972  }
01973  catch (tf::TransformException& ex)
01974  {
01975    printf("%s\n",ex.what());
01976    EXPECT_FALSE("Other Exception Caught");
01977  }
01978 
01979  //forward list
01980  EXPECT_FALSE(mTR.canTransform("parent", "me", ros::Time().fromNSec(350000)));
01981  try
01982  {
01983    mTR.transformPose("me", Stamped<Pose> (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(350000) , "parent"), outpose);
01984    EXPECT_FALSE("ExtrapolationException Not Thrown");
01985  }
01986  catch ( tf::ExtrapolationException &ex)
01987  {
01988    EXPECT_TRUE("Extrapolation Exception Caught");
01989  }
01990  catch (tf::TransformException& ex)
01991  {
01992    printf("%s\n",ex.what());
01993    EXPECT_FALSE("Other Exception Caught");
01994  }
01995 
01996 
01997 
01998 
01999 }
02000 
02001 
02002 
02003 TEST(tf, NoExtrapolationExceptionFromParent)
02004 {
02005   tf::Transformer mTR(true, ros::Duration().fromNSec(1000000));
02006 
02007 
02008 
02009   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000), "parent", "a"));
02010   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10000),  "parent", "a"));
02011 
02012 
02013   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000),  "parent", "b"));
02014   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10000),  "parent", "b"));
02015 
02016   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000),  "parent's parent", "parent"));
02017   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000),  "parent's parent's parent", "parent's parent"));
02018 
02019   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10000),  "parent's parent", "parent"));
02020   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(10000),  "parent's parent's parent", "parent's parent"));
02021 
02022   Stamped<Point> output;
02023 
02024   try
02025   {
02026     mTR.transformPoint( "b", Stamped<Point>(Point(1,1,1), ros::Time().fromNSec(2000), "a"), output);
02027   }
02028   catch (ExtrapolationException &ex)
02029   {
02030     EXPECT_FALSE("Shouldn't have gotten this exception");
02031   }
02032 
02033 
02034 
02035 };
02036 
02037 
02038 
02039 TEST(tf, ExtrapolationFromOneValue)
02040 {
02041   tf::Transformer mTR(true, ros::Duration().fromNSec(1000000));
02042 
02043 
02044 
02045   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000),  "parent", "a"));
02046 
02047   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000),  "parent's parent", "parent"));
02048 
02049 
02050   Stamped<Point> output;
02051 
02052   bool excepted = false;
02053   //Past time
02054   try
02055   {
02056     mTR.transformPoint( "parent", Stamped<Point>(Point(1,1,1), ros::Time().fromNSec(10), "a"), output);
02057   }
02058   catch (ExtrapolationException &ex)
02059   {
02060     excepted = true;
02061   }
02062 
02063   EXPECT_TRUE(excepted);
02064 
02065   excepted = false;
02066   //Future one element
02067   try
02068   {
02069     mTR.transformPoint( "parent", Stamped<Point>(Point(1,1,1), ros::Time().fromNSec(100000), "a"), output);
02070   }
02071   catch (ExtrapolationException &ex)
02072   {
02073     excepted = true;
02074   }
02075 
02076   EXPECT_TRUE(excepted);
02077 
02078   //Past multi link
02079   excepted = false;
02080   try
02081   {
02082     mTR.transformPoint( "parent's parent", Stamped<Point>(Point(1,1,1), ros::Time().fromNSec(1), "a"), output);
02083   }
02084   catch (ExtrapolationException &ex)
02085   {
02086     excepted = true;
02087   }
02088 
02089   EXPECT_TRUE(excepted);
02090 
02091   //Future case multi link
02092   excepted = false;
02093   try
02094   {
02095     mTR.transformPoint( "parent's parent", Stamped<Point>(Point(1,1,1), ros::Time().fromNSec(10000), "a"), output);
02096   }
02097   catch (ExtrapolationException &ex)
02098   {
02099     excepted = true;
02100   }
02101 
02102   EXPECT_TRUE(excepted);
02103 
02104   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(20000),  "parent", "a"));
02105 
02106   excepted = false;
02107   try
02108   {
02109     mTR.transformPoint( "parent", Stamped<Point>(Point(1,1,1), ros::Time().fromNSec(10000), "a"), output);
02110   }
02111   catch (ExtrapolationException &ex)
02112   {
02113     excepted = true;
02114   }
02115 
02116   EXPECT_FALSE(excepted);
02117 
02118 };
02119 
02120 
02121 
02122 TEST(tf, getLatestCommonTime)
02123 {
02124   tf::Transformer mTR(true);
02125   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(1000),  "parent", "a"));
02126   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(2000),  "parent's parent", "parent"));
02127 
02128   //simple case
02129   ros::Time t;
02130   mTR.getLatestCommonTime("a", "parent's parent", t, NULL);
02131   EXPECT_EQ(t, ros::Time().fromNSec(1000));
02132 
02133   //no connection
02134   EXPECT_EQ(tf::LOOKUP_ERROR, mTR.getLatestCommonTime("a", "not valid", t, NULL));
02135   EXPECT_EQ(t, ros::Time());
02136 
02137   //testing with update
02138   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(3000),  "parent", "a"));
02139   mTR.getLatestCommonTime("a", "parent's parent",t, NULL);
02140   EXPECT_EQ(t, ros::Time().fromNSec(2000));
02141 
02142   //longer chain
02143   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(4000),  "parent", "b"));
02144   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(3000),  "b", "c"));
02145   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(9000),  "c", "d"));
02146   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(5000),  "f", "e"));
02147 
02148   //shared parent
02149   mTR.getLatestCommonTime("a", "b",t, NULL);
02150   EXPECT_EQ(t, ros::Time().fromNSec(3000));
02151 
02152   //two degrees
02153   mTR.getLatestCommonTime("a", "c", t, NULL);
02154   EXPECT_EQ(t, ros::Time().fromNSec(3000));
02155   //reversed
02156   mTR.getLatestCommonTime("c", "a", t, NULL);
02157   EXPECT_EQ(t, ros::Time().fromNSec(3000));
02158 
02159   //three degrees
02160   mTR.getLatestCommonTime("a", "d", t, NULL);
02161   EXPECT_EQ(t, ros::Time().fromNSec(3000));
02162   //reversed
02163   mTR.getLatestCommonTime("d", "a", t, NULL);
02164   EXPECT_EQ(t, ros::Time().fromNSec(3000));
02165 
02166   //disconnected tree
02167   mTR.getLatestCommonTime("e", "f", t, NULL);
02168   EXPECT_EQ(t, ros::Time().fromNSec(5000));
02169   //reversed order
02170   mTR.getLatestCommonTime("f", "e", t, NULL);
02171   EXPECT_EQ(t, ros::Time().fromNSec(5000));
02172 
02173 
02174   mTR.setExtrapolationLimit(ros::Duration().fromNSec(20000));
02175 
02176   //check timestamps resulting
02177   tf::Stamped<tf::Point> output, output2;
02178   try
02179   {
02180     mTR.transformPoint( "parent", Stamped<Point>(Point(1,1,1), ros::Time(), "b"), output);
02181     mTR.transformPoint( "a", ros::Time(),Stamped<Point>(Point(1,1,1), ros::Time(), "b"), "c",  output2);
02182   }
02183   catch (tf::TransformException &ex)
02184   {
02185     printf("%s\n", ex.what());
02186     EXPECT_FALSE("Shouldn't get this Exception");
02187   }
02188 
02189   EXPECT_EQ(output.stamp_, ros::Time().fromNSec(4000));
02190   EXPECT_EQ(output2.stamp_, ros::Time().fromNSec(3000));
02191 
02192 
02193   //zero length lookup zero time
02194   ros::Time now1 = ros::Time::now();
02195   ros::Time time_output;
02196   mTR.getLatestCommonTime("a", "a", time_output, NULL);
02197   EXPECT_LE(now1.toSec(), time_output.toSec());
02198   EXPECT_LE(time_output.toSec(), ros::Time::now().toSec());
02199 
02200 
02201 }
02202 
02203 TEST(tf, RepeatedTimes)
02204 {
02205   Transformer mTR;
02206   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(1,0,0), btVector3(0,0,0)), ros::Time().fromNSec(4000),  "parent", "b"));
02207   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(1,1,0), btVector3(0,0,0)), ros::Time().fromNSec(4000),  "parent", "b"));
02208 
02209   tf::StampedTransform  output;
02210   try{
02211     mTR.lookupTransform("parent", "b" , ros::Time().fromNSec(4000), output);
02212     EXPECT_TRUE(!std::isnan(output.getOrigin().x()));
02213     EXPECT_TRUE(!std::isnan(output.getOrigin().y()));
02214     EXPECT_TRUE(!std::isnan(output.getOrigin().z()));
02215     EXPECT_TRUE(!std::isnan(output.getRotation().x()));
02216     EXPECT_TRUE(!std::isnan(output.getRotation().y()));
02217     EXPECT_TRUE(!std::isnan(output.getRotation().z()));
02218     EXPECT_TRUE(!std::isnan(output.getRotation().w()));
02219   }
02220   catch (...)
02221   {
02222     EXPECT_FALSE("Excetion improperly thrown");
02223   }
02224 
02225 
02226 }
02227 
02228 TEST(tf, frameExists)
02229 {
02230   Transformer mTR;
02231 
02232   // test with fully qualified name
02233   EXPECT_FALSE(mTR.frameExists("/b"));;
02234   EXPECT_FALSE(mTR.frameExists("/parent"));
02235   EXPECT_FALSE(mTR.frameExists("/other"));
02236   EXPECT_FALSE(mTR.frameExists("/frame"));
02237 
02238   //test with resolveping
02239   EXPECT_FALSE(mTR.frameExists("b"));;
02240   EXPECT_FALSE(mTR.frameExists("parent"));
02241   EXPECT_FALSE(mTR.frameExists("other"));
02242   EXPECT_FALSE(mTR.frameExists("frame"));
02243 
02244   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(1,0,0), btVector3(0,0,0)), ros::Time().fromNSec(4000),  "/parent", "/b"));
02245 
02246   // test with fully qualified name
02247   EXPECT_TRUE(mTR.frameExists("/b"));
02248   EXPECT_TRUE(mTR.frameExists("/parent"));
02249   EXPECT_FALSE(mTR.frameExists("/other"));
02250   EXPECT_FALSE(mTR.frameExists("/frame"));
02251 
02252   //Test with resolveping
02253   EXPECT_TRUE(mTR.frameExists("b"));
02254   EXPECT_TRUE(mTR.frameExists("parent"));
02255   EXPECT_FALSE(mTR.frameExists("other"));
02256   EXPECT_FALSE(mTR.frameExists("frame"));
02257 
02258   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(1,1,0), btVector3(0,0,0)), ros::Time().fromNSec(4000),  "/frame", "/other"));
02259 
02260   // test with fully qualified name
02261   EXPECT_TRUE(mTR.frameExists("/b"));
02262   EXPECT_TRUE(mTR.frameExists("/parent"));
02263   EXPECT_TRUE(mTR.frameExists("/other"));
02264   EXPECT_TRUE(mTR.frameExists("/frame"));
02265 
02266   //Test with resolveping
02267   EXPECT_TRUE(mTR.frameExists("b"));
02268   EXPECT_TRUE(mTR.frameExists("parent"));
02269   EXPECT_TRUE(mTR.frameExists("other"));
02270   EXPECT_TRUE(mTR.frameExists("frame"));
02271 
02272 }
02273 
02274 TEST(tf, resolve)
02275 {
02276   //no prefix
02277   EXPECT_STREQ("/id", tf::resolve("","id").c_str());
02278   //prefix w/o /
02279   EXPECT_STREQ("/asdf/id", tf::resolve("asdf","id").c_str());
02280   //prefix w /
02281   EXPECT_STREQ("/asdf/id", tf::resolve("/asdf","id").c_str());
02282   // frame_id w / -> no prefix
02283   EXPECT_STREQ("/id", tf::resolve("asdf","/id").c_str());
02284   // frame_id w / -> no prefix
02285   EXPECT_STREQ("/id", tf::resolve("/asdf","/id").c_str());
02286 
02287 }
02288 
02289 TEST(tf, canTransform)
02290 {
02291   Transformer mTR;
02292 
02293   //confirm zero length list disconnected will return true
02294   EXPECT_TRUE(mTR.canTransform("some_frame","some_frame", ros::Time()));
02295   EXPECT_TRUE(mTR.canTransform("some_frame","some_frame", ros::Time::now()));
02296 
02297   //Create a two link tree between times 10 and 20
02298   for (int i = 10; i < 20; i++)
02299   {
02300     mTR.setTransform(  StampedTransform (btTransform(btQuaternion(1,0,0), btVector3(0,0,0)), ros::Time().fromSec(i),  "parent", "child"));
02301     mTR.setTransform(  StampedTransform (btTransform(btQuaternion(1,0,0), btVector3(0,0,0)), ros::Time().fromSec(i),  "parent", "other_child"));
02302   }
02303 
02304   // four different timestamps related to tf state
02305   ros::Time zero_time = ros::Time().fromSec(0);
02306   ros::Time old_time = ros::Time().fromSec(5);
02307   ros::Time valid_time = ros::Time().fromSec(15);
02308   ros::Time future_time = ros::Time().fromSec(25);
02309 
02310 
02311   //confirm zero length list disconnected will return true
02312   EXPECT_TRUE(mTR.canTransform("some_frame","some_frame", zero_time));
02313   EXPECT_TRUE(mTR.canTransform("some_frame","some_frame", old_time));
02314   EXPECT_TRUE(mTR.canTransform("some_frame","some_frame", valid_time));
02315   EXPECT_TRUE(mTR.canTransform("some_frame","some_frame", future_time));
02316 
02317   // Basic API Tests
02318 
02319   //Valid data should pass
02320   EXPECT_TRUE(mTR.canTransform("child", "parent", valid_time));
02321   EXPECT_TRUE(mTR.canTransform("child", "other_child", valid_time));
02322 
02323   //zero data should pass
02324   EXPECT_TRUE(mTR.canTransform("child", "parent", zero_time));
02325   EXPECT_TRUE(mTR.canTransform("child", "other_child", zero_time));
02326 
02327   //Old data should fail
02328   EXPECT_FALSE(mTR.canTransform("child", "parent", old_time));
02329   EXPECT_FALSE(mTR.canTransform("child", "other_child", old_time));
02330 
02331   //Future data should fail
02332   EXPECT_FALSE(mTR.canTransform("child", "parent", future_time));
02333   EXPECT_FALSE(mTR.canTransform("child", "other_child", future_time));
02334 
02335   //Same Frame should pass for all times
02336   EXPECT_TRUE(mTR.canTransform("child", "child", zero_time));
02337   EXPECT_TRUE(mTR.canTransform("child", "child", old_time));
02338   EXPECT_TRUE(mTR.canTransform("child", "child", valid_time));
02339   EXPECT_TRUE(mTR.canTransform("child", "child", future_time));
02340 
02341   // Advanced API Tests
02342 
02343   // Source = Fixed
02344   //zero data in fixed frame should pass
02345   EXPECT_TRUE(mTR.canTransform("child", zero_time, "parent", valid_time, "child"));
02346   EXPECT_TRUE(mTR.canTransform("child", zero_time, "other_child", valid_time, "child"));
02347   //Old data in fixed frame should pass
02348   EXPECT_TRUE(mTR.canTransform("child", old_time, "parent", valid_time, "child"));
02349   EXPECT_TRUE(mTR.canTransform("child", old_time, "other_child", valid_time, "child"));
02350   //valid data in fixed frame should pass
02351   EXPECT_TRUE(mTR.canTransform("child", valid_time, "parent", valid_time, "child"));
02352   EXPECT_TRUE(mTR.canTransform("child", valid_time, "other_child", valid_time, "child"));
02353   //future data in fixed frame should pass
02354   EXPECT_TRUE(mTR.canTransform("child", future_time, "parent", valid_time, "child"));
02355   EXPECT_TRUE(mTR.canTransform("child", future_time, "other_child", valid_time, "child"));
02356 
02357   //transforming through fixed into the past
02358   EXPECT_FALSE(mTR.canTransform("child", valid_time, "parent", old_time, "child"));
02359   EXPECT_FALSE(mTR.canTransform("child", valid_time, "other_child", old_time, "child"));
02360   //transforming through fixed into the future
02361   EXPECT_FALSE(mTR.canTransform("child", valid_time, "parent", future_time, "child"));
02362   EXPECT_FALSE(mTR.canTransform("child", valid_time, "other_child", future_time, "child"));
02363 
02364   // Target = Fixed
02365   //zero data in fixed frame should pass
02366   EXPECT_TRUE(mTR.canTransform("child", zero_time, "parent", valid_time, "parent"));
02367   //Old data in fixed frame should pass
02368   EXPECT_FALSE(mTR.canTransform("child", old_time, "parent", valid_time, "parent"));
02369   //valid data in fixed frame should pass
02370   EXPECT_TRUE(mTR.canTransform("child", valid_time, "parent", valid_time, "parent"));
02371   //future data in fixed frame should pass
02372   EXPECT_FALSE(mTR.canTransform("child", future_time, "parent", valid_time, "parent"));
02373 
02374   //transforming through fixed into the zero
02375   EXPECT_TRUE(mTR.canTransform("child", valid_time, "parent", zero_time, "parent"));
02376   //transforming through fixed into the past
02377   EXPECT_TRUE(mTR.canTransform("child", valid_time, "parent", old_time, "parent"));
02378   //transforming through fixed into the valid
02379   EXPECT_TRUE(mTR.canTransform("child", valid_time, "parent", valid_time, "parent"));
02380   //transforming through fixed into the future
02381   EXPECT_TRUE(mTR.canTransform("child", valid_time, "parent", future_time, "parent"));
02382 
02383 }
02384 
02385 TEST(tf, lookupTransform)
02386 {
02387   Transformer mTR;
02388   //Create a two link tree between times 10 and 20
02389   for (int i = 10; i < 20; i++)
02390   {
02391     mTR.setTransform(  StampedTransform (btTransform(btQuaternion(1,0,0), btVector3(0,0,0)), ros::Time().fromSec(i),  "parent", "child"));
02392     mTR.setTransform(  StampedTransform (btTransform(btQuaternion(1,0,0), btVector3(0,0,0)), ros::Time().fromSec(i),  "parent", "other_child"));
02393   }
02394 
02395   // four different timestamps related to tf state
02396   ros::Time zero_time = ros::Time().fromSec(0);
02397   ros::Time old_time = ros::Time().fromSec(5);
02398   ros::Time valid_time = ros::Time().fromSec(15);
02399   ros::Time future_time = ros::Time().fromSec(25);
02400 
02401   //output
02402   tf::StampedTransform output;
02403 
02404   // Basic API Tests
02405 
02406   try
02407   {
02408     //confirm zero length list disconnected will return true
02409     mTR.lookupTransform("some_frame","some_frame", zero_time, output);
02410     mTR.lookupTransform("some_frame","some_frame", old_time, output);
02411     mTR.lookupTransform("some_frame","some_frame", valid_time, output);
02412     mTR.lookupTransform("some_frame","some_frame", future_time, output);
02413     mTR.lookupTransform("child","child", future_time, output);
02414     mTR.lookupTransform("other_child","other_child", future_time, output);
02415 
02416     //Valid data should pass
02417     mTR.lookupTransform("child", "parent", valid_time, output);
02418     mTR.lookupTransform("child", "other_child", valid_time, output);
02419 
02420     //zero data should pass
02421     mTR.lookupTransform("child", "parent", zero_time, output);
02422     mTR.lookupTransform("child", "other_child", zero_time, output);
02423   }
02424   catch (tf::TransformException &ex)
02425   {
02426     printf("Exception improperly thrown: %s", ex.what());
02427     EXPECT_FALSE("Exception thrown");
02428   }
02429   try
02430   {
02431     //Old data should fail
02432     mTR.lookupTransform("child", "parent", old_time, output);
02433     EXPECT_FALSE("Exception should have been thrown");
02434   }
02435   catch (tf::TransformException)
02436   {
02437     EXPECT_TRUE("Exception Thrown Correctly");
02438   }
02439   try {
02440     //Future data should fail
02441     mTR.lookupTransform("child", "parent", future_time, output);
02442     EXPECT_FALSE("Exception should have been thrown");
02443   }
02444   catch (tf::TransformException)
02445   {
02446     EXPECT_TRUE("Exception Thrown Correctly");
02447   }
02448 
02449   try {
02450     //Same Frame should pass for all times
02451     mTR.lookupTransform("child", "child", zero_time, output);
02452     mTR.lookupTransform("child", "child", old_time, output);
02453     mTR.lookupTransform("child", "child", valid_time, output);
02454     mTR.lookupTransform("child", "child", future_time, output);
02455 
02456     // Advanced API Tests
02457 
02458     // Source = Fixed
02459     //zero data in fixed frame should pass
02460     mTR.lookupTransform("child", zero_time, "parent", valid_time, "child", output);
02461     mTR.lookupTransform("child", zero_time, "other_child", valid_time, "child", output);
02462     //Old data in fixed frame should pass
02463     mTR.lookupTransform("child", old_time, "parent", valid_time, "child", output);
02464     mTR.lookupTransform("child", old_time, "other_child", valid_time, "child", output);
02465     //valid data in fixed frame should pass
02466     mTR.lookupTransform("child", valid_time, "parent", valid_time, "child", output);
02467     mTR.lookupTransform("child", valid_time, "other_child", valid_time, "child", output);
02468     //future data in fixed frame should pass
02469     mTR.lookupTransform("child", future_time, "parent", valid_time, "child", output);
02470     mTR.lookupTransform("child", future_time, "other_child", valid_time, "child", output);
02471   }
02472   catch (tf::TransformException &ex)
02473   {
02474     printf("Exception improperly thrown: %s", ex.what());
02475     EXPECT_FALSE("Exception incorrectly thrown");
02476   }
02477 
02478   try {
02479     //transforming through fixed into the past
02480     mTR.lookupTransform("child", valid_time, "parent", old_time, "child", output);
02481     EXPECT_FALSE("Exception should have been thrown");
02482   }
02483   catch (tf::TransformException)
02484   {
02485     EXPECT_TRUE("Exception Thrown Correctly");
02486   }
02487 
02488   try {
02489     //transforming through fixed into the future
02490     mTR.lookupTransform("child", valid_time, "parent", future_time, "child", output);
02491     EXPECT_FALSE("Exception should have been thrown");
02492   }
02493   catch (tf::TransformException)
02494   {
02495     EXPECT_TRUE("Exception Thrown Correctly");
02496   }
02497 
02498   try {
02499     // Target = Fixed
02500     //zero data in fixed frame should pass
02501     mTR.lookupTransform("child", zero_time, "parent", valid_time, "parent", output);
02502     //valid data in fixed frame should pass
02503     mTR.lookupTransform("child", valid_time, "parent", valid_time, "parent", output);
02504   }
02505   catch (tf::TransformException &ex)
02506   {
02507     printf("Exception improperly thrown: %s", ex.what());
02508     EXPECT_FALSE("Exception incorrectly thrown");
02509   }
02510 
02511   try {
02512   //Old data in fixed frame should pass
02513   mTR.lookupTransform("child", old_time, "parent", valid_time, "parent", output);
02514       EXPECT_FALSE("Exception should have been thrown");
02515   }
02516   catch (tf::TransformException)
02517   {
02518     EXPECT_TRUE("Exception Thrown Correctly");
02519   }
02520   try {
02521     //future data in fixed frame should pass
02522     mTR.lookupTransform("child", future_time, "parent", valid_time, "parent", output);
02523     EXPECT_FALSE("Exception should have been thrown");
02524   }
02525   catch (tf::TransformException)
02526   {
02527     EXPECT_TRUE("Exception Thrown Correctly");
02528   }
02529 
02530   try {
02531     //transforming through fixed into the zero
02532     mTR.lookupTransform("child", valid_time, "parent", zero_time, "parent", output);
02533     //transforming through fixed into the past
02534     mTR.lookupTransform("child", valid_time, "parent", old_time, "parent", output);
02535     //transforming through fixed into the valid
02536     mTR.lookupTransform("child", valid_time, "parent", valid_time, "parent", output);
02537     //transforming through fixed into the future
02538     mTR.lookupTransform("child", valid_time, "parent", future_time, "parent", output);
02539   }
02540   catch (tf::TransformException &ex)
02541   {
02542     printf("Exception improperly thrown: %s", ex.what());
02543     EXPECT_FALSE("Exception improperly thrown");
02544   }
02545 
02546 
02547   //make sure zero goes to now for zero length
02548   try
02549   {
02550     ros::Time now1 = ros::Time::now();
02551 
02552     mTR.lookupTransform("a", "a", ros::Time(),output);
02553     EXPECT_LE(now1.toSec(), output.stamp_.toSec());
02554     EXPECT_LE(output.stamp_.toSec(), ros::Time::now().toSec());
02555   }
02556   catch (tf::TransformException &ex)
02557   {
02558     printf("Exception improperly thrown: %s", ex.what());
02559     EXPECT_FALSE("Exception improperly thrown");
02560   }
02561 
02562 }
02563 
02564 
02565 TEST(tf, getFrameStrings)
02566 {
02567   Transformer mTR;
02568 
02569 
02570   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(4000),  "/parent", "/b"));
02571   std::vector <std::string> frames_string;
02572   mTR.getFrameStrings(frames_string);
02573   ASSERT_EQ(frames_string.size(), (unsigned)2);
02574   EXPECT_STREQ(frames_string[0].c_str(), std::string("/b").c_str());
02575   EXPECT_STREQ(frames_string[1].c_str(), std::string("/parent").c_str());
02576 
02577 
02578   mTR.setTransform(  StampedTransform (btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)), ros::Time().fromNSec(4000),  "/frame", "/other"));
02579 
02580   mTR.getFrameStrings(frames_string);
02581   ASSERT_EQ(frames_string.size(), (unsigned)4);
02582   EXPECT_STREQ(frames_string[0].c_str(), std::string("/b").c_str());
02583   EXPECT_STREQ(frames_string[1].c_str(), std::string("/parent").c_str());
02584   EXPECT_STREQ(frames_string[2].c_str(), std::string("/other").c_str());
02585   EXPECT_STREQ(frames_string[3].c_str(), std::string("/frame").c_str());
02586 
02587 }
02588 
02589 bool expectInvalidQuaternion(tf::Quaternion q)
02590 {
02591   try
02592   {
02593     tf::assertQuaternionValid(q);
02594     printf("this should have thrown\n");
02595     return false;
02596   }
02597   catch (tf::InvalidArgument &ex)
02598   {
02599     return true;
02600   }
02601   catch  (...)
02602   {
02603     printf("A different type of exception was expected\n");
02604     return false;
02605   }
02606   return false;
02607 }
02608 
02609 bool expectValidQuaternion(tf::Quaternion q)
02610 {
02611   try
02612   {
02613     tf::assertQuaternionValid(q);
02614   }
02615   catch (tf::TransformException &ex)
02616   {
02617     return false;
02618   }
02619   return true;
02620 }
02621 
02622 bool expectInvalidQuaternion(geometry_msgs::Quaternion q)
02623 {
02624   try
02625   {
02626     tf::assertQuaternionValid(q);
02627     printf("this should have thrown\n");
02628     return false;
02629   }
02630   catch (tf::InvalidArgument &ex)
02631   {
02632     return true;
02633   }
02634   catch  (...)
02635   {
02636     printf("A different type of exception was expected\n");
02637     return false;
02638   }
02639   return false;
02640 }
02641 
02642 bool expectValidQuaternion(geometry_msgs::Quaternion q)
02643 {
02644   try
02645   {
02646     tf::assertQuaternionValid(q);
02647   }
02648   catch (tf::TransformException &ex)
02649   {
02650     return false;
02651   }
02652   return true;
02653 }
02654 
02655 
02656 TEST(tf, assertQuaternionValid)
02657 {
02658   tf::Quaternion q(1,0,0,0);
02659   EXPECT_TRUE(expectValidQuaternion(q));
02660   q.setX(0);
02661   EXPECT_TRUE(expectInvalidQuaternion(q));
02662   q.setY(1);
02663   EXPECT_TRUE(expectValidQuaternion(q));
02664   q.setZ(1);
02665   EXPECT_TRUE(expectInvalidQuaternion(q));
02666   q.setY(0);
02667   EXPECT_TRUE(expectValidQuaternion(q));
02668   q.setW(1);
02669   EXPECT_TRUE(expectInvalidQuaternion(q));
02670   q.setZ(0);
02671   EXPECT_TRUE(expectValidQuaternion(q));
02672   q.setZ(sqrt(2.0)/2.0);
02673   EXPECT_TRUE(expectInvalidQuaternion(q));
02674   q.setW(sqrt(2.0)/2.0);
02675   EXPECT_TRUE(expectValidQuaternion(q));
02676 
02677   q.setZ(sqrt(2.0)/2.0 + 0.01);
02678   EXPECT_TRUE(expectInvalidQuaternion(q));
02679 
02680   q.setZ(sqrt(2.0)/2.0 - 0.01);
02681   EXPECT_TRUE(expectInvalidQuaternion(q));
02682 
02683   EXPECT_THROW(tf::assertQuaternionValid(q), tf::InvalidArgument);
02684   //    Waiting for gtest 1.1 or later
02685   //  EXPECT_NO_THROW(tf::assertQuaternionValid(q));
02686   //q.setX(0);
02687   //EXPECT_THROW(tf::assertQuaternionValid(q), tf::InvalidArgument);
02688   //q.setY(1);
02689   //EXPECT_NO_THROW(tf::assertQuaternionValid(q));
02690 
02691 }
02692 TEST(tf, assertQuaternionMsgValid)
02693 {
02694   geometry_msgs::Quaternion q;
02695   q.x = 1;//others zeroed to start
02696 
02697   EXPECT_TRUE(expectValidQuaternion(q));
02698   q.x = 0;
02699   EXPECT_TRUE(expectInvalidQuaternion(q));
02700   q.y = 1;
02701   EXPECT_TRUE(expectValidQuaternion(q));
02702   q.z = 1;
02703   EXPECT_TRUE(expectInvalidQuaternion(q));
02704   q.y = 0;
02705   EXPECT_TRUE(expectValidQuaternion(q));
02706   q.w = 1;
02707   EXPECT_TRUE(expectInvalidQuaternion(q));
02708   q.z = 0;
02709   EXPECT_TRUE(expectValidQuaternion(q));
02710   q.z = sqrt(2.0)/2.0;
02711   EXPECT_TRUE(expectInvalidQuaternion(q));
02712   q.w = sqrt(2.0)/2.0;
02713   EXPECT_TRUE(expectValidQuaternion(q));
02714 
02715   q.z = sqrt(2.0)/2.0 + 0.01;
02716   EXPECT_TRUE(expectInvalidQuaternion(q));
02717 
02718   q.z = sqrt(2.0)/2.0 - 0.01;
02719   EXPECT_TRUE(expectInvalidQuaternion(q));
02720 
02721 
02722   //    Waiting for gtest 1.1 or later
02723   //  EXPECT_NO_THROW(tf::assertQuaternionValid(q));
02724   //q.x = 0);
02725   //EXPECT_THROW(tf::assertQuaternionValid(q), tf::InvalidArgument);
02726   //q.y = 1);
02727   //EXPECT_NO_THROW(tf::assertQuaternionValid(q));
02728 
02729 }
02730 
02731 
02732 TEST(tf2_stamped, OperatorEqualEqual)
02733 {
02734   btTransform transform0, transform1, transform0a;
02735   transform0.setIdentity();
02736   transform0a.setIdentity();
02737   transform1.setIdentity();
02738   transform1.setOrigin(btVector3(1, 0, 0));
02739   tf2::StampedTransform stamped_transform_reference(transform0a, ros::Time(), "frame_id", "child_frame_id");
02740   tf2::StampedTransform stamped_transform0A(transform0, ros::Time(), "frame_id", "child_frame_id");
02741   EXPECT_TRUE(stamped_transform0A == stamped_transform_reference); // Equal
02742   tf2::StampedTransform stamped_transform0B(transform0, ros::Time(), "frame_id_not_equal", "child_frame_id");
02743   EXPECT_FALSE(stamped_transform0B == stamped_transform_reference); // Different Frame id
02744   tf2::StampedTransform stamped_transform0C(transform0, ros::Time(1.0), "frame_id", "child_frame_id");
02745   EXPECT_FALSE(stamped_transform0C == stamped_transform_reference); // Different Time
02746   tf2::StampedTransform stamped_transform0D(transform0, ros::Time(1.0), "frame_id_not_equal", "child_frame_id");
02747   EXPECT_FALSE(stamped_transform0D == stamped_transform_reference); // Different frame id and time
02748   tf2::StampedTransform stamped_transform0E(transform1, ros::Time(), "frame_id_not_equal", "child_frame_id");
02749   EXPECT_FALSE(stamped_transform0E == stamped_transform_reference); // Different transform, frame id
02750   tf2::StampedTransform stamped_transform0F(transform1, ros::Time(1.0), "frame_id", "child_frame_id");
02751   EXPECT_FALSE(stamped_transform0F == stamped_transform_reference); // Different transform, time
02752   tf2::StampedTransform stamped_transform0G(transform1, ros::Time(1.0), "frame_id_not_equal", "child_frame_id");
02753   EXPECT_FALSE(stamped_transform0G == stamped_transform_reference); // Different transform, frame id and time
02754   tf2::StampedTransform stamped_transform0H(transform1, ros::Time(), "frame_id", "child_frame_id");
02755   EXPECT_FALSE(stamped_transform0H == stamped_transform_reference); // Different transform
02756 
02757 
02758   //Different child_frame_id
02759   tf2::StampedTransform stamped_transform1A(transform0, ros::Time(), "frame_id", "child_frame_id2");
02760   EXPECT_FALSE(stamped_transform1A == stamped_transform_reference); // Equal
02761   tf2::StampedTransform stamped_transform1B(transform0, ros::Time(), "frame_id_not_equal", "child_frame_id2");
02762   EXPECT_FALSE(stamped_transform1B == stamped_transform_reference); // Different Frame id
02763   tf2::StampedTransform stamped_transform1C(transform0, ros::Time(1.0), "frame_id", "child_frame_id2");
02764   EXPECT_FALSE(stamped_transform1C == stamped_transform_reference); // Different Time
02765   tf2::StampedTransform stamped_transform1D(transform0, ros::Time(1.0), "frame_id_not_equal", "child_frame_id2");
02766   EXPECT_FALSE(stamped_transform1D == stamped_transform_reference); // Different frame id and time
02767   tf2::StampedTransform stamped_transform1E(transform1, ros::Time(), "frame_id_not_equal", "child_frame_id2");
02768   EXPECT_FALSE(stamped_transform1E == stamped_transform_reference); // Different transform, frame id
02769   tf2::StampedTransform stamped_transform1F(transform1, ros::Time(1.0), "frame_id", "child_frame_id2");
02770   EXPECT_FALSE(stamped_transform1F == stamped_transform_reference); // Different transform, time
02771   tf2::StampedTransform stamped_transform1G(transform1, ros::Time(1.0), "frame_id_not_equal", "child_frame_id2");
02772   EXPECT_FALSE(stamped_transform1G == stamped_transform_reference); // Different transform, frame id and time
02773   tf2::StampedTransform stamped_transform1H(transform1, ros::Time(), "frame_id", "child_frame_id2");
02774   EXPECT_FALSE(stamped_transform1H == stamped_transform_reference); // Different transform
02775 
02776 }
02777 
02778 TEST(tf2_stamped, OperatorEqual)
02779 {
02780   btTransform pose0, pose1, pose0a;
02781   pose0.setIdentity();
02782   pose1.setIdentity();
02783   pose1.setOrigin(btVector3(1, 0, 0));
02784   tf2::Stamped<btTransform> stamped_pose0(pose0, ros::Time(), "frame_id");
02785   tf2::Stamped<btTransform> stamped_pose1(pose1, ros::Time(1.0), "frame_id_not_equal");
02786   EXPECT_FALSE(stamped_pose1 == stamped_pose0);
02787   stamped_pose1 = stamped_pose0;
02788   EXPECT_TRUE(stamped_pose1 == stamped_pose0);
02789 
02790 }
02791   */
02792 int main(int argc, char **argv){
02793   testing::InitGoogleTest(&argc, argv);
02794   ros::Time::init(); //needed for ros::TIme::now()
02795   ros::init(argc, argv, "tf_unittest");
02796   return RUN_ALL_TESTS();
02797 }


test_tf2
Author(s): Tully Foote, Eitan Marder-Eppstein
autogenerated on Thu Jun 6 2019 20:23:14