00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <gtest/gtest.h>
00031 #include <tf/tf.h>
00032 #include <sys/time.h>
00033
00034 #include "tf/LinearMath/Vector3.h"
00035
00036 void seed_rand()
00037 {
00038
00039 timeval temp_time_struct;
00040 gettimeofday(&temp_time_struct,NULL);
00041 srand(temp_time_struct.tv_usec);
00042 };
00043
00044 void generate_rand_vectors(double scale, uint64_t runs, std::vector<double>& xvalues, std::vector<double>& yvalues, std::vector<double>&zvalues)
00045 {
00046 seed_rand();
00047 for ( uint64_t i = 0; i < runs ; i++ )
00048 {
00049 xvalues[i] = 1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00050 yvalues[i] = 1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00051 zvalues[i] = 1.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00052 }
00053 }
00054
00055
00056 using namespace tf;
00057
00058
00059 TEST(tf_benchmark, canTransformCacheLength0)
00060 {
00061 tf::Transformer mTR(true);
00062
00063 uint64_t runs = 100000;
00064 ros::WallTime start_time = ros::WallTime::now();
00065
00066
00067 start_time = ros::WallTime::now();
00068 for (uint64_t i = 0 ; i < runs; i++)
00069 {
00070 EXPECT_FALSE(mTR.canTransform("target","source_frame", ros::Time::now()));
00071 }
00072 ros::WallDuration run_duration = ros::WallTime::now() - start_time;
00073 double frequency = (double)runs / run_duration.toSec() ;
00074 printf("can frequency %.2f KHz\n", frequency / 1000.0);
00075 EXPECT_GT( frequency, 10000.0);
00076 }
00077
00078
00079 TEST(tf_benchmark, canTransformCacheLength10000)
00080 {
00081 tf::Transformer mTR(true);
00082
00083 unsigned int cache_length = 10000;
00084 for (unsigned int i = 0; i < cache_length; i++)
00085 {
00086 StampedTransform tranStamped(tf::Transform(tf::Quaternion(0,0,0,1), tf::Vector3(0,0,0)), ros::Time().fromNSec(10.0+i), "my_parent", "child");
00087 mTR.setTransform(tranStamped);
00088 }
00089
00090 uint64_t runs = 100000;
00091 ros::WallTime start_time = ros::WallTime::now();
00092
00093
00094
00095 start_time = ros::WallTime::now();
00096 for (uint64_t i = 0 ; i < runs; i++)
00097 {
00098 EXPECT_TRUE(mTR.canTransform("child","my_parent", ros::Time().fromNSec(10)));
00099 }
00100 ros::WallDuration run_duration = ros::WallTime::now() - start_time;
00101 double frequency = (double)runs / run_duration.toSec() ;
00102 printf("Worst Case Frequency %.2f KHz\n", frequency / 1000.0);
00103 EXPECT_GT( frequency, 10000.0);
00104
00105
00106 start_time = ros::WallTime::now();
00107 for (uint64_t i = 0 ; i < runs; i++)
00108 {
00109 EXPECT_TRUE(mTR.canTransform("child","my_parent", ros::Time().fromNSec(10+cache_length/2)));
00110 }
00111 run_duration = ros::WallTime::now() - start_time;
00112 frequency = (double)runs / run_duration.toSec() ;
00113 printf("Intermediate Case Frequency %.2f KHz\n", frequency / 1000.0);
00114 EXPECT_GT( frequency, 10000.0);
00115
00116
00117 start_time = ros::WallTime::now();
00118 for (uint64_t i = 0 ; i < runs; i++)
00119 {
00120 EXPECT_TRUE(mTR.canTransform("child","my_parent", ros::Time().fromNSec(10+cache_length -1)));
00121 }
00122 run_duration = ros::WallTime::now() - start_time;
00123 frequency = (double)runs / run_duration.toSec() ;
00124 printf("Best Case Frequency %.2f KHz\n", frequency / 1000.0);
00125 EXPECT_GT( frequency, 10000.0);
00126 }
00127
00128 TEST(tf_benchmark, lookupTransformCacheLength10000)
00129 {
00130 tf::Transformer mTR(true);
00131
00132 unsigned int cache_length = 10000;
00133 for (unsigned int i = 0; i < cache_length; i++)
00134 {
00135 StampedTransform tranStamped(tf::Transform(tf::Quaternion(0,0,0,1), tf::Vector3(0,0,0)), ros::Time().fromNSec(10.0+i), "my_parent", "child");
00136 mTR.setTransform(tranStamped);
00137 }
00138
00139 uint64_t runs = 100000;
00140 ros::WallTime start_time = ros::WallTime::now();
00141
00142 StampedTransform rv;
00143
00144 start_time = ros::WallTime::now();
00145 for (uint64_t i = 0 ; i < runs; i++)
00146 {
00147 mTR.lookupTransform("child","my_parent", ros::Time().fromNSec(10), rv);
00148 }
00149 ros::WallDuration run_duration = ros::WallTime::now() - start_time;
00150 double frequency = (double)runs / run_duration.toSec() ;
00151 printf("Worst Case Lookup Frequency %.2f KHz\n", frequency / 1000.0);
00152 EXPECT_GT( frequency, 10000.0);
00153
00154
00155 start_time = ros::WallTime::now();
00156 for (uint64_t i = 0 ; i < runs; i++)
00157 {
00158 mTR.lookupTransform("child","my_parent", ros::Time().fromNSec(10+cache_length/2), rv);
00159 }
00160 run_duration = ros::WallTime::now() - start_time;
00161 frequency = (double)runs / run_duration.toSec() ;
00162 printf("Intermediate Case Lookup Frequency %.2f KHz\n", frequency / 1000.0);
00163 EXPECT_GT( frequency, 10000.0);
00164
00165
00166 start_time = ros::WallTime::now();
00167 for (uint64_t i = 0 ; i < runs; i++)
00168 {
00169 mTR.lookupTransform("child","my_parent", ros::Time().fromNSec(10+cache_length -1), rv);
00170 }
00171 run_duration = ros::WallTime::now() - start_time;
00172 frequency = (double)runs / run_duration.toSec() ;
00173 printf("Best Case Lookup Frequency %.2f KHz\n", frequency / 1000.0);
00174 EXPECT_GT( frequency, 10000.0);
00175 }
00176
00177 TEST(tf_benchmark, benchmarkExhaustiveSearch)
00178 {
00179 uint64_t runs = 40000;
00180 double epsilon = 1e-6;
00181 seed_rand();
00182
00183 tf::Transformer mTR(true);
00184 std::vector<double> xvalues(runs), yvalues(runs), zvalues(runs);
00185 for ( uint64_t i = 0; i < runs ; i++ )
00186 {
00187 xvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00188 yvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00189 zvalues[i] = 10.0 * ((double) rand() - (double)RAND_MAX /2.0) /(double)RAND_MAX;
00190
00191 StampedTransform tranStamped(tf::Transform(tf::Quaternion(0,0,0,1), tf::Vector3(xvalues[i],yvalues[i],zvalues[i])), ros::Time().fromNSec(10.0 + i), "my_parent", "child");
00192 mTR.setTransform(tranStamped);
00193 }
00194
00195 ros::WallTime start_time = ros::WallTime::now();
00196 for ( uint64_t i = 0; i < runs ; i++ )
00197
00198 {
00199 Stamped<tf::Transform> inpose (tf::Transform(tf::Quaternion(0,0,0,1), tf::Vector3(0,0,0)), ros::Time().fromNSec(10.0 + i), "child");
00200
00201 try{
00202 Stamped<Pose> outpose;
00203 outpose.setIdentity();
00204 mTR.transformPose("my_parent",inpose, outpose);
00205 EXPECT_NEAR(outpose.getOrigin().x(), xvalues[i], epsilon);
00206 EXPECT_NEAR(outpose.getOrigin().y(), yvalues[i], epsilon);
00207 EXPECT_NEAR(outpose.getOrigin().z(), zvalues[i], epsilon);
00208 }
00209 catch (tf::TransformException & ex)
00210 {
00211 std::cout << "TransformExcepion got through!!!!! " << ex.what() << std::endl;
00212 bool exception_improperly_thrown = true;
00213 EXPECT_FALSE(exception_improperly_thrown);
00214 }
00215 }
00216
00217 Stamped<Pose> inpose (tf::Transform(tf::Quaternion(0,0,0,1), tf::Vector3(0,0,0)), ros::Time().fromNSec(runs), "child");
00218 Stamped<Pose> outpose;
00219 outpose.setIdentity();
00220 mTR.transformPose("child",inpose, outpose);
00221 EXPECT_NEAR(outpose.getOrigin().x(), 0, epsilon);
00222 EXPECT_NEAR(outpose.getOrigin().y(), 0, epsilon);
00223 EXPECT_NEAR(outpose.getOrigin().z(), 0, epsilon);
00224
00225 ros::WallDuration run_duration = ros::WallTime::now() - start_time;
00226 double frequency = (double)runs / run_duration.toSec() ;
00227 printf("exhaustive search frequency %.2f KHz\n", frequency / 1000.0);
00228 EXPECT_GT( frequency, 500.0);
00229
00230 }
00231
00232 int main(int argc, char **argv){
00233 ros::Time::init();
00234 testing::InitGoogleTest(&argc, argv);
00235 return RUN_ALL_TESTS();
00236 }