00001
00057
00058
00059
00060
00061
00062
00063
00064 #include <ros/ros.h>
00065 #include <pluginlib/class_list_macros.h>
00066 #include <nodelet/nodelet.h>
00067 #include <tf_conversions/tf_eigen.h>
00068 #include <tf/transform_broadcaster.h>
00069 #include <actionlib/server/simple_action_server.h>
00070 #include <pcl/point_types.h>
00071 #define PCL_MINOR (PCL_VERSION[2] - '0')
00072
00073 #include <pcl/filters/passthrough.h>
00074 #include <pcl_ros/transforms.h>
00075 #include <pcl_ros/point_cloud.h>
00076 #include <tf/transform_listener.h>
00077 #include <tf_conversions/tf_kdl.h>
00078 #include <pcl/io/pcd_io.h>
00079 #include <registration/general_registration.h>
00080 #include <registration/registration_info.h>
00081
00082 #include <registration/measurements/measure.h>
00083 #include <boost/progress.hpp>
00084
00085 #include <gtest/gtest.h>
00086
00087 #define CYCLES 100
00088 #define BLOCKSIZE 40
00089
00090 void generateRandomOrderedPC_Kinect(const int w, const int h, pcl::PointCloud<pcl::PointXYZ> &pc) {
00091 int x0 = w/2;
00092 int y0 = h/2;
00093 float f = 500.f;
00094
00095 pc.clear();
00096 pc.width=w;
00097 pc.height=h;
00098 pc.resize(w*h);
00099
00100 ROS_ASSERT(w%BLOCKSIZE==0);
00101 ROS_ASSERT(h%BLOCKSIZE==0);
00102
00103 for(int xx=0; xx<w; xx+=BLOCKSIZE) {
00104 for(int yy=0; yy<h; yy+=BLOCKSIZE) {
00105 pcl::PointXYZ p;
00106 p.z = (rand()%1000)/300.f;
00107 for(int _x=0; _x<BLOCKSIZE; _x++)
00108 for(int _y=0; _y<BLOCKSIZE; _y++)
00109 {
00110 p.x = p.z*(xx+_x-x0)/f;
00111 p.y = p.z*(yy+_y-y0)/f;
00112 pc(xx+_x,yy+_y)=p;
00113 }
00114 }
00115 }
00116 }
00117
00118 #define getInd(x, y) ((x)+(y)*pc.width)
00119 void reproject(const pcl::PointCloud<pcl::PointXYZ> &pc, pcl::PointCloud<pcl::PointXYZ> &pc_out, const Eigen::Matrix4f T)
00120 {
00121 int x0 = pc.width/2;
00122 int y0 = pc.height/2;
00123 float f = 500.f;
00124
00125 pc_out = pc;
00126
00127 for(int xx=0; xx<pc.width; xx++)
00128 for(int yy=0; yy<pc.height; yy++)
00129 pc_out[getInd(xx,yy)].x = pc_out[getInd(xx,yy)].y = pc_out[getInd(xx,yy)].z = std::numeric_limits<float>::quiet_NaN();
00130
00131
00132 for(int xx=0; xx<pc.width; xx++) {
00133 for(int yy=0; yy<pc.height; yy++) {
00134 int ind = getInd(xx,yy);
00135 if(pcl_isfinite(pc[ind].z)) {
00136 Eigen::Vector4f v=T*pc[ind].getVector4fMap();
00137
00138 int x=round(f*v(0)/v(2)+x0);
00139 int y=round(f*v(1)/v(2)+y0);
00140
00141 if(x<0||x>=pc.width || y<0||y>=pc.height)
00142 continue;
00143
00144 pc_out[getInd(x,y)].x = v(0);
00145 pc_out[getInd(x,y)].y = v(1);
00146 pc_out[getInd(x,y)].z = v(2);
00147 }
00148 }
00149 }
00150
00151 }
00152
00153
00154 void generateNaNOrderedPC_Kinect(const int w, const int h, pcl::PointCloud<pcl::PointXYZ> &pc) {
00155 pc.clear();
00156 pc.width=w;
00157 pc.height=h;
00158
00159 pcl::PointXYZ p;
00160 p.x=p.y=p.z=std::numeric_limits<float>::quiet_NaN();
00161 for(int xx=0; xx<w; xx++) {
00162 for(int yy=0; yy<h; yy++) {
00163 pc.push_back(p);
00164 }
00165 }
00166 }
00167
00168 void test_null_ptrs() {
00169 time_t ti = time(NULL);
00170 ROS_INFO("init test_null_ptrs with %d",ti);
00171 srand(ti);
00172
00173 Registration_Infobased<pcl::PointXYZ> frir;
00174 frir.compute();
00175 }
00176
00177 void test_nans() {
00178 ROS_INFO("test_nans");
00179 pcl::PointCloud<pcl::PointXYZ> pc1;
00180 generateNaNOrderedPC_Kinect(640,480, pc1);
00181
00182
00183 Registration_Infobased<pcl::PointXYZ> frir;
00184 frir.setKinectParameters(500,320,240);
00185 frir.setInputOginalCloud(pc1.makeShared());
00186 frir.compute();
00187 frir.setInputOginalCloud(pc1.makeShared());
00188 frir.compute();
00189 }
00190
00191 void test_many_random_pcs() {
00192 time_t ti = time(NULL);
00193 ROS_INFO("init test_many_random_pcs with %d",ti);
00194 srand(ti);
00195
00196 boost::progress_display show_progress(CYCLES);
00197 int success=0, num=0;
00198 double dur=0.;
00199 for(int i=0; i<CYCLES; i++)
00200 {
00201 pcl::PointCloud<pcl::PointXYZ> pc1, pc2;
00202 generateRandomOrderedPC_Kinect(640,480, pc1);
00203 generateRandomOrderedPC_Kinect(640,480, pc2);
00204
00205
00206 Registration_Infobased<pcl::PointXYZ> frir;
00207 frir.setKinectParameters(500,320,240);
00208 frir.setInputOginalCloud(pc1.makeShared());
00209 frir.compute();
00210 frir.setInputOginalCloud(pc2.makeShared());
00211 measurement_tools::PrecisionStopWatchAll psw;
00212 if(frir.compute())
00213 ++success;
00214 dur+=psw.precisionStop();
00215 ++num;
00216
00217 ++show_progress;
00218 }
00219
00220 ROS_INFO("took %f",dur/(float)num);
00221 ROS_INFO("success rate %f",success/(float)num);
00222 }
00223
00224 void test_many_tfs() {
00225 time_t ti = time(NULL);
00226 ROS_INFO("init test_many_tfs with %d",ti);
00227 srand(ti);
00228
00229 boost::progress_display show_progress(CYCLES);
00230 int success=0, num=0;
00231 float dis=0.f;
00232 float disS=0.f;
00233 double dur=0.;
00234 int sucs[10]={};
00235
00236 for(int i=0; i<CYCLES; i++)
00237 {
00238 pcl::PointCloud<pcl::PointXYZ> pc1, pc2;
00239 generateRandomOrderedPC_Kinect(640,480, pc1);
00240
00241 {
00242 Eigen::Matrix4f tf;
00243 tf=tf.Identity();
00244 tf.col(3)(2) = i/(float)(10*CYCLES);
00245 reproject(pc1,pc2,tf);
00246
00247
00248 Registration_Infobased<pcl::PointXYZ> frir;
00249 frir.setKinectParameters(500,320,240);
00250 frir.setInputOginalCloud(pc1.makeShared());
00251 frir.compute();
00252 frir.setInputOginalCloud(pc2.makeShared());
00253 measurement_tools::PrecisionStopWatchAll psw;
00254 if(frir.compute()) {
00255 ++success;
00256 disS+=(frir.getTransformation()-tf).norm();
00257 sucs[i*10/CYCLES]++;
00258 }
00259 dur+=psw.precisionStop();
00260 ++num;
00261
00262 dis+=(frir.getTransformation()-tf).norm();
00263 }
00264
00265 {
00266 Eigen::Vector3f v;
00267 v.fill(0.f);v(0)=1.f;
00268 Eigen::AngleAxisf aa(i/(float)(10*CYCLES),v);
00269 Eigen::Matrix4f tf;
00270 tf=tf.Identity();
00271 tf.topLeftCorner<3,3>() = aa.toRotationMatrix();
00272 reproject(pc1,pc2,tf);
00273
00274
00275
00276
00277
00278 Registration_Infobased<pcl::PointXYZ> frir;
00279 frir.setKinectParameters(500,320,240);
00280 frir.setInputOginalCloud(pc1.makeShared());
00281 frir.compute();
00282 frir.setInputOginalCloud(pc2.makeShared());
00283 measurement_tools::PrecisionStopWatchAll psw;
00284 if(frir.compute()) {
00285 ++success;
00286 disS+=(frir.getTransformation()-tf).norm();
00287 sucs[i*10/CYCLES]++;
00288 }
00289 dur+=psw.precisionStop();
00290 ++num;
00291
00292 dis+=(frir.getTransformation()-tf).norm();
00293 }
00294
00295 ++show_progress;
00296 }
00297
00298 ROS_INFO("took %f",dur/(float)num);
00299 ROS_INFO("success rate %f",success/(float)num);
00300 ROS_INFO("distance rate %f",dis/(float)num);
00301 ROS_INFO("distance rate %f (on success)",disS/(float)num);
00302
00303 for(int i=0; i<10; i++)
00304 std::cout<<sucs[i]<<"\t ";
00305 std::cout<<"\n";
00306 }
00307
00308 TEST(Registration_FRIF, null_ptrs){
00309 test_null_ptrs();
00310 }
00311
00312 TEST(Registration_FRIF, nans){
00313 test_nans();
00314 }
00315
00316 TEST(Registration_FRIF, many_random_pcs){
00317 test_many_random_pcs();
00318 }
00319
00320 TEST(Registration_FRIF, many_tfs){
00321 test_many_tfs();
00322 }
00323
00324 int main(int argc, char **argv) {
00325 ROS_INFO("EVALUATION_MODE_ is %d", EVALUATION_MODE_);
00326 ROS_INFO("DEBUG_SWITCH_ is %d", DEBUG_SWITCH_);
00327 ROS_INFO("USED_ODO_ is %d", USED_ODO_);
00328
00329 testing::InitGoogleTest(&argc, argv);
00330 return RUN_ALL_TESTS();
00331 }