00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #define _FN1_ "/home/josh/tmp/1305031229.729077.png.img.pcd"
00012 #define _FN2_ "/home/josh/tmp/1305031229.764869.png.img.pcd"
00013
00014 #include <ros/ros.h>
00015 #include <pcl/point_types.h>
00016 #include <pcl/point_cloud.h>
00017 #include <pcl/ros/conversions.h>
00018
00019 #include <sensor_msgs/PointCloud2.h>
00020 #include <pcl/ModelCoefficients.h>
00021 #include <pcl/io/pcd_io.h>
00022 #include <pcl/point_types.h>
00023 #include <pcl/sample_consensus/method_types.h>
00024 #include <pcl/sample_consensus/model_types.h>
00025 #include <pcl/segmentation/sac_segmentation.h>
00026
00027 #include <pcl/segmentation/extract_clusters.h>
00028 #include <pcl/filters/extract_indices.h>
00029 #include <pcl/kdtree/kdtree.h>
00030
00031 #include <pcl/io/pcd_io.h>
00032 #include <pcl/filters/voxel_grid.h>
00033 #include <pcl/segmentation/extract_clusters.h>
00034 #include <pcl/kdtree/kdtree.h>
00035 #include <pcl/features/normal_3d_omp.h>
00036 #include <pcl/ModelCoefficients.h>
00037 #include <pcl/sample_consensus/method_types.h>
00038 #include <pcl/sample_consensus/model_types.h>
00039 #include <pcl/segmentation/sac_segmentation.h>
00040 #include <pcl/filters/extract_indices.h>
00041 #include <pcl/filters/project_inliers.h>
00042 #include <pcl/surface/concave_hull.h>
00043 #include <pcl/filters/voxel_grid.h>
00044 #include <pcl/common/pca.h>
00045 #include <pcl/registration/registration.h>
00046 #include <boost/timer.hpp>
00047 #include <pcl/filters/statistical_outlier_removal.h>
00048 #include <pcl/common/distances.h>
00049 #include <pcl/registration/icp.h>
00050
00051 #include "pcl/registration/registration.h"
00052 #include "pcl/sample_consensus/ransac.h"
00053 #include "pcl/sample_consensus/sac_model_registration.h"
00054
00055 #include <visualization_msgs/Marker.h>
00056 #include "std_msgs/String.h"
00057
00058 #include <pcl/common/transformation_from_correspondences.h>
00059 #include <tf/transform_broadcaster.h>
00060
00061
00062 #define USE_TF 1
00063
00064 #define DEBUG_SWITCH_ 0
00065
00066 #ifdef USE_LM
00067 #include <pcl/registration/transformation_estimation_lm.h>
00068 #endif
00069
00070
00071 #define MAP_
00072 #define RGB_
00073 #define WHOLE_DEPTH_
00074 #define DIS_TREE_
00075 #define OPT_SIZE_ 2
00076
00077 #define USE_SMART_GRID_ 0
00078 #define TESTING_ 0
00079
00080 bool g_step = false;
00081
00082
00083
00084 class PrecisionStopWatch {
00085 struct timeval precisionClock;
00086
00087 public:
00088 PrecisionStopWatch() {
00089 gettimeofday(&precisionClock, NULL);
00090 };
00091
00092 void precisionStart() {
00093 gettimeofday(&precisionClock, NULL);
00094 };
00095
00096 double precisionStop() {
00097 struct timeval precisionClockEnd;
00098 gettimeofday(&precisionClockEnd, NULL);
00099 double d= ((double)precisionClockEnd.tv_sec + 1.0e-6 * (double)precisionClockEnd.tv_usec) - ((double)precisionClock.tv_sec + 1.0e-6 * (double)precisionClock.tv_usec);
00100 precisionStart();
00101 return d;
00102 };
00103 };
00104
00105
00106 std_msgs::Header header_;
00107 ros::Publisher marker_pub_;
00108 ros::Publisher point_cloud_pub_,map_pub_;
00109
00110 inline bool makes_sense(const float f) {return f>0.2f && f<6.f;}
00111
00112 #define MY_POINT pcl::PointXYZRGB
00113
00114 struct SORT_S {
00115 float dis;
00116 int ind;
00117
00118 bool operator() (const SORT_S &i, const SORT_S &j) const { return (i.dis<j.dis);}
00119 };
00120
00121 struct SORT_S2 {
00122 float dis;
00123 int ind;
00124
00125 bool operator() (const SORT_S2 &i, const SORT_S2 &j) const { return (i.dis<j.dis);}
00126 };
00127
00128 struct COR_S {
00129 int ind_o, ind_n;
00130 float dis;
00131 };
00132
00133 inline Eigen::Vector3f Null3f() {
00134 Eigen::Vector3f r;
00135 r(0)=r(1)=r(2)=0;
00136 return r;
00137 }
00138
00139 inline void getDis(const Eigen::Vector3f &C, const Eigen::Vector3f &S, float &dT, float &dA) {
00140 dT = std::abs(C.norm()-S.norm());
00141 dA = acosf(C.dot(S)/(C.norm()*S.norm()));
00142 }
00143
00144 template <typename Point>
00145 Eigen::Vector3f getMidO(const pcl::PointCloud<Point> &pc, const std::vector<int> &weight, const std::vector<COR_S> &cors, const bool sm=true, const float max_dis=10000000) {
00146 Eigen::Vector3f m = Null3f();
00147 float n=0;
00148
00149 for(int i=0; i<cors.size(); i++) {
00150 Eigen::Vector3f v;
00151
00152
00153
00154
00155 float w=1/(float)(weight[cors[i].ind_o]);
00156 v=pc[cors[i].ind_o].getVector3fMap();
00157
00158 if(sm && v.squaredNorm()<max_dis) {
00159 m+=v*w;
00160 n+=w;
00161 }
00162 else if(!sm && v.squaredNorm()>=max_dis) {
00163 m+=v*w;
00164 n+=w;
00165 }
00166 }
00167
00168 ROS_WARN("w %f",n);
00169 if(n) m/=n;
00170 return m;
00171 }
00172
00173 template <typename Point>
00174 Eigen::Vector3f getMidN(const pcl::PointCloud<Point> &pc, const std::vector<int> &weight, const bool sm, const float max_dis, const pcl::PointCloud<Point> &old, const std::vector<COR_S> &cors) {
00175 Eigen::Vector3f m = Null3f();
00176 float n=0;
00177
00178 for(int i=0; i<cors.size(); i++) {
00179 Eigen::Vector3f v;
00180
00181
00182
00183
00184 float w=1/(float)(weight[cors[i].ind_o]);
00185 v=pc[cors[i].ind_n].getVector3fMap()*w;
00186
00187 if(sm && old[cors[i].ind_o].getVector3fMap().squaredNorm()<max_dis) {
00188 m+=v;
00189 n+=w;
00190 }
00191 else if(!sm && old[cors[i].ind_o].getVector3fMap().squaredNorm()>=max_dis) {
00192 m+=v;
00193 n+=w;
00194 }
00195 }
00196
00197 ROS_WARN("w %f",n);
00198 if(n) m/=n;
00199 return m;
00200 }
00201
00202 #include <pcl/visualization/cloud_viewer.h>
00203 #include <pcl/registration/correspondence_estimation.h>
00204 void visualize(const pcl::PointCloud<pcl::PointXYZ> &pc_old, const pcl::PointCloud<pcl::PointXYZ> &pc_new, const std::vector<COR_S> &cors, Eigen::Vector3f mo=Null3f(),Eigen::Vector3f mn=Null3f(),Eigen::Vector3f mot=Null3f())
00205 {
00206 std::cout<<"show cloud? y/n";
00207 if(getchar()!='y')
00208 return;
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 pcl::visualization::CloudViewer viewer("Cloud Viewer");
00236
00237 pcl::PointCloud<pcl::PointXYZRGB>::Ptr p1,p2,p3,p4,p5,p6;
00238 p1.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00239 p2.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00240 p3.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00241 p4.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00242 p5.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00243 p6.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00244 for(int i=0; i<pc_old.size(); i++) {
00245 pcl::PointXYZRGB p;
00246 p.x=pc_old[i].x;
00247 p.y=pc_old[i].y;
00248 p.z=pc_old[i].z;
00249 p.r=255;
00250 p.g=p.b=0;
00251 p1->push_back(p);
00252 }
00253 p1->width=p1->size();
00254 p1->height=1;
00255 for(int i=0; i<pc_new.size(); i++) {
00256 pcl::PointXYZRGB p;
00257 p.x=pc_new[i].x;
00258 p.y=pc_new[i].y;
00259 p.z=pc_new[i].z;
00260 p.g=255;
00261 p.b=p.b=0;
00262 p2->push_back(p);
00263 }
00264 p2->width=p2->size();
00265 p2->height=1;
00266
00267 Eigen::Vector3f X,v;
00268 X(0)=1;
00269 X(1)=X(2)=0;
00270
00271 for(int i=0; i<cors.size(); i++) {
00272 float dx=pc_old[cors[i].ind_o].x-pc_new[cors[i].ind_n].x;
00273 float dy=pc_old[cors[i].ind_o].y-pc_new[cors[i].ind_n].y;
00274 float dz=pc_old[cors[i].ind_o].z-pc_new[cors[i].ind_n].z;
00275 v=pc_new[cors[i].ind_n].getVector3fMap()-pc_old[cors[i].ind_o].getVector3fMap();
00276 for(int j=1; j<10; j++) {
00277 pcl::PointXYZRGB p;
00278 p.x=pc_new[cors[i].ind_n].x+dx*j/10.;
00279 p.y=pc_new[cors[i].ind_n].y+dy*j/10.;
00280 p.z=pc_new[cors[i].ind_n].z+dz*j/10.;
00281
00282 p.b=255;
00283 p.r=p.g=0;
00284 if(v.dot(X)>0) {
00285 }
00286 else {
00287 p.r=255;
00288 }
00289 p3->push_back(p);
00290 }
00291 }
00292 p3->width=p3->size();
00293 p3->height=1;
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 viewer.showCloud(p1,"p1");
00330 viewer.showCloud(p2,"p2");
00331 if(p3->size()>0) viewer.showCloud(p3,"p3");
00332
00333
00334
00335
00336 while (!viewer.wasStopped ())
00337 {
00338 usleep(1000);
00339 }
00340
00341 }
00342 void visualize(const pcl::PointCloud<pcl::PointXYZ> &pc_old, const pcl::PointCloud<pcl::PointXYZ> &pc_new, const std::vector<COR_S> &cors,
00343 const std::vector<int> &weight_o, const std::vector<int> &weight_n)
00344 {
00345 std::cout<<"show cloud? y/n/w";
00346 char c=getchar();
00347 if(c!='y'&&c!='w')
00348 return;
00349
00350 pcl::visualization::CloudViewer viewer("Cloud Viewer");
00351
00352 pcl::PointCloud<pcl::PointXYZRGB>::Ptr p1,p2,p3,p4,p5,p6;
00353 p1.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00354 p2.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00355 p3.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00356 for(int i=0; i<pc_old.size(); i++) {
00357 pcl::PointXYZRGB p;
00358 p.x=pc_old[i].x;
00359 p.y=pc_old[i].y;
00360 p.z=pc_old[i].z;
00361 p.r=255;
00362 p.g=p.b=weight_o[i]*5;
00363 p1->push_back(p);
00364 }
00365 p1->width=p1->size();
00366 p1->height=1;
00367 for(int i=0; i<pc_new.size(); i++) {
00368 pcl::PointXYZRGB p;
00369 p.x=pc_new[i].x;
00370 p.y=pc_new[i].y;
00371 p.z=pc_new[i].z;
00372 p.g=255;
00373 p.b=p.b=weight_n[i]*5;
00374 p2->push_back(p);
00375 }
00376 p2->width=p2->size();
00377 p2->height=1;
00378
00379 Eigen::Vector3f X,v;
00380 X(0)=1;
00381 X(1)=X(2)=0;
00382
00383 for(int i=0; i<cors.size(); i++) {
00384 float dx=pc_old[cors[i].ind_o].x-pc_new[cors[i].ind_n].x;
00385 float dy=pc_old[cors[i].ind_o].y-pc_new[cors[i].ind_n].y;
00386 float dz=pc_old[cors[i].ind_o].z-pc_new[cors[i].ind_n].z;
00387 v=pc_new[cors[i].ind_n].getVector3fMap()-pc_old[cors[i].ind_o].getVector3fMap();
00388 for(int j=1; j<10; j++) {
00389 pcl::PointXYZRGB p;
00390 p.x=pc_new[cors[i].ind_n].x+dx*j/10.;
00391 p.y=pc_new[cors[i].ind_n].y+dy*j/10.;
00392 p.z=pc_new[cors[i].ind_n].z+dz*j/10.;
00393
00394 p.b=255;
00395 p.r=p.g=0;
00396 if(v.dot(X)>0) {
00397 }
00398 else {
00399 p.r=255;
00400 }
00401 p3->push_back(p);
00402 }
00403 }
00404 p3->width=p3->size();
00405 p3->height=1;
00406
00407 viewer.showCloud(p1,"p1");
00408 viewer.showCloud(p2,"p2");
00409 if(p3->size()>0&&c!='w') viewer.showCloud(p3,"p3");
00410
00411 while (!viewer.wasStopped ())
00412 {
00413 usleep(1000);
00414 }
00415
00416 }
00417 void visualize(const pcl::PointCloud<pcl::PointXYZRGB> &pc_old)
00418 {
00419 std::cout<<"show cloud? y/n";
00420 if(getchar()!='y')
00421 return;
00422 pcl::visualization::CloudViewer viewer("Cloud Viewer");
00423
00424 pcl::PointCloud<pcl::PointXYZRGB>::Ptr p1,p2,p3,p4,p5,p6;
00425 p1.reset(new pcl::PointCloud<pcl::PointXYZRGB>);
00426 for(int i=0; i<pc_old.size(); i++) {
00427 p1->push_back(pc_old[i]);
00428 }
00429 p1->width=p1->size();
00430 p1->height=1;
00431
00432 viewer.showCloud(p1,"p1");
00433
00434 while (!viewer.wasStopped ())
00435 {
00436 usleep(1000);
00437 }
00438
00439 }
00440
00441 template <typename Point>
00442 Eigen::Vector3f getAxis(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new, const std::vector<COR_S> &cors, const bool sm, const float max_dis, const Eigen::Vector3f &rel_old, const Eigen::Vector3f &rel_new) {
00443 Eigen::Vector3f m = Null3f();
00444
00445 for(int i=0; i<cors.size(); i++) {
00446 Eigen::Vector3f v,vp;
00447
00448 v =pc_old[cors[i].ind_o].getVector3fMap();
00449 vp=pc_new[cors[i].ind_n].getVector3fMap();
00450
00451 if((sm && v.squaredNorm()<max_dis)||(!sm && v.squaredNorm()>=max_dis)) {
00452 v -=rel_old;
00453 vp-=rel_new;
00454 v.normalize();
00455 vp.normalize();
00456 v=vp-v;
00457 v.normalize();
00458 m+=v;
00459 }
00460 }
00461
00462 m.normalize();
00463 return m;
00464 }
00465
00466
00467 template <typename Point>
00468 Eigen::Vector3f getAxis3(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
00469 const std::vector<COR_S> &cors, const float max_dis,
00470 const Eigen::Vector3f &rel_old, const Eigen::Vector3f &rel_new
00471 , std::vector<int> &weight_o,std::vector<int> &weight_n, const Eigen::Vector3f &X2) {
00472 Eigen::Vector3f m[4];
00473 int g[4]={};
00474
00475 m[0] = Null3f();
00476 m[1] = Null3f();
00477 m[2] = Null3f();
00478 m[3] = Null3f();
00479
00480 Eigen::Vector3f X,Y;
00481
00482 X(0)=1;
00483 X(1)=X(2)=0;
00484 Y(1)=1;
00485 Y(2)=Y(0)=0;
00486
00487 X=rel_old.cross(X);
00488 Y=rel_old.cross(Y);
00489
00490 for(int i=0; i<cors.size(); i++) {
00491 Eigen::Vector3f v,vp;
00492
00493 v =pc_old[cors[i].ind_o].getVector3fMap();
00494 vp=pc_new[cors[i].ind_n].getVector3fMap();
00495
00496 v -=rel_old;
00497 vp-=rel_new;
00498
00499 int q=0;
00500
00501
00502
00503
00504
00505
00506 q+=v.dot(X)>0?1:0;
00507 q+=v.dot(Y)<0?2:0;
00508
00509
00510
00511 v=vp-v;
00512 v.normalize();
00513
00514
00515 if(pc_old[cors[i].ind_o].getVector3fMap().squaredNorm()<rel_old.squaredNorm()) v=-v;
00516
00517 if(v.dot(X2)<0) {
00518
00519 continue;
00520 }
00521
00522
00523 m[q]+=v;
00524
00525 g[q]++;
00526 }
00527
00528 m[0]/=g[0];
00529 m[1]/=g[1];
00530 m[2]/=g[2];
00531 m[3]/=g[3];
00532
00533 std::cout<<"m[0]\n"<<m[0]<<"\n";
00534 std::cout<<"m[1]\n"<<m[1]<<"\n";
00535 std::cout<<"m[2]\n"<<m[2]<<"\n";
00536 std::cout<<"m[3]\n"<<m[3]<<"\n";
00537 std::cout<<"m[0] "<<m[0].norm()<<"\n";
00538 std::cout<<"m[1] "<<m[1].norm()<<"\n";
00539 std::cout<<"m[2] "<<m[2].norm()<<"\n";
00540 std::cout<<"m[3] "<<m[3].norm()<<"\n";
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 std::cout<<"a x\n"<<(m[0]+m[1]).cross(m[2]+m[3])<<"\n";
00553 std::cout<<"a y\n"<<(m[0]+m[2]).cross(m[1]+m[3])<<"\n";
00554 std::cout<<"a z\n"<<(m[0]-m[3]).cross(m[1]-m[3])<<"\n";
00555
00556 Eigen::Vector3f axis, axis2;
00557
00558 Eigen::Matrix3f aX, aY, aZ;
00559
00560 aY=aZ=aX=aX.Identity();
00561
00562 aX(0,0)=0;
00563 aY(1,1)=0;
00564 aZ(2,2)=0;
00565
00566 Eigen::Vector3f ax,ay,az;
00567 ax=(m[0]+m[1]).cross(m[2]+m[3]);
00568 ay=(m[0]+m[2]).cross(m[1]+m[3]);
00569 az=(m[0]-m[3]).cross(m[1]-m[3]);
00570
00571 ax.normalize();
00572 ay.normalize();
00573 az.normalize();
00574
00575 axis(0) = (aX*(m[0]+m[1])).cross(aX*(m[2]+m[3])).norm() / std::abs((m[0]+m[1])(0)+(m[2]+m[3])(0));
00576 axis(1) = (aY*(m[0]+m[2])).cross(aY*(m[1]+m[3])).norm() / std::abs((m[0]+m[2])(1)+(m[1]+m[3])(1));
00577 axis(2) = (aZ*(m[0]-m[3])).cross(aZ*(m[1]-m[2])).norm() / std::abs((m[0]-m[3])(2)+(m[1]-m[2])(2));
00578
00579 axis(0) = (aX*(m[0]+m[1])).cross(aX*(m[2]+m[3])).norm() * (std::abs(ax(0))+std::abs(ay(0))+std::abs(az(0)));
00580 axis(1) = (aY*(m[0]+m[2])).cross(aY*(m[1]+m[3])).norm() * (std::abs(ax(1))+std::abs(ay(1))+std::abs(az(1)));
00581 axis(2) = (aZ*(m[0]-m[3])).cross(aZ*(m[1]-m[2])).norm() * (std::abs(ax(2))+std::abs(ay(2))+std::abs(az(2)));
00582
00583 axis(0) = (std::abs(ax(0))+std::abs(ay(0))+std::abs(az(0))) ;
00584 axis(1) = (std::abs(ax(1))+std::abs(ay(1))+std::abs(az(1))) ;
00585 axis(2) = (std::abs(ax(2))+std::abs(ay(2))+std::abs(az(2))) ;
00586
00587 axis(0) = std::abs( ((m[0]+m[1])).cross((m[2]+m[3]))(0) );
00588 axis(1) = std::abs( ((m[0]+m[2])).cross((m[1]+m[3]))(1) );
00589 axis(2) = std::abs( ((m[0]-m[3])).cross((m[1]-m[2]))(2) );
00590
00591 axis(0) = std::abs( ax(0) );
00592 axis(1) = std::abs( ay(1) );
00593 axis(2) = std::abs( az(2) );
00594
00595 axis.normalize();
00596
00597 if( m[0](1)+m[1](1)+m[2](1)+m[3](1) > 0)
00598 axis(0) = -axis(0);
00599 if( m[0](0)+m[1](0)+m[2](0)+m[3](0) < 0)
00600 axis(1) = -axis(1);
00601 if( m[0](0)*m[0](1)+m[3](0)*m[3](1) - m[1](0)*m[1](1)-m[2](0)*m[2](1)
00602 < 0)
00603 axis(2) = -axis(2);
00604
00605 axis2=axis;
00606 std::cout<<"axis\n"<<axis<<"\n";
00607
00608 aX(0,0)=0;
00609 aY(1,1)=0;
00610 aZ(2,2)=0;
00611
00612 axis(0) = -(aX*(m[0]+m[1])).cross(aX*(m[2]+m[3]))(0);
00613 axis(1) = -(aY*(m[0]+m[2])).cross(aY*(m[1]+m[3]))(1);
00614 axis(2) = -(aZ*(m[0]-m[3])).cross(aZ*(m[1]-m[3]))(2);
00615 axis.normalize();
00616
00617 std::cout<<"axis\n"<<axis<<"\n";
00618
00619 return axis2;
00620 }
00621 template <typename Point>
00622 Eigen::Vector3f getAxis2(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
00623 std::vector<COR_S> &cors, const float max_dis,
00624 const Eigen::Vector3f &rel_old, const Eigen::Vector3f &rel_new
00625 , std::vector<int> &weight_o,std::vector<int> &weight_n) {
00626 Eigen::Vector3f m[4];
00627 int g[4]={};
00628
00629 m[0] = Null3f();
00630 m[1] = Null3f();
00631 m[2] = Null3f();
00632 m[3] = Null3f();
00633
00634 Eigen::Vector3f X,Y;
00635
00636 X(0)=1;
00637 X(1)=X(2)=0;
00638 Y(1)=1;
00639 Y(2)=Y(0)=0;
00640
00641 Eigen::Vector3f X2=X;
00642
00643 X=rel_old.cross(X);
00644 Y=rel_old.cross(Y);
00645
00646 float bin[100]={};
00647 float bing[100]={};
00648
00649 static float border=2;
00650
00651
00652 pcl::PointCloud<pcl::PointXYZ> pc[4];
00653 pcl::PointCloud<pcl::PointXYZRGB> pc2[4];
00654 for(int i=0; i<cors.size(); i++) {
00655 Eigen::Vector3f v,vp;
00656
00657 v =pc_old[cors[i].ind_o].getVector3fMap();
00658 vp=pc_new[cors[i].ind_n].getVector3fMap();
00659
00660 v -=rel_old;
00661 vp-=rel_new;
00662
00663 int q=0;
00664
00665
00666
00667
00668
00669
00670 q+=v.dot(X)>0?1:0;
00671 q+=v.dot(Y)<0?2:0;
00672
00673
00674
00675 v=vp-v;
00676 v.normalize();
00677
00678
00679 if(pc_old[cors[i].ind_o].getVector3fMap().squaredNorm()<rel_old.squaredNorm()) v=-v;
00680
00681
00682
00683
00684
00685
00686 pcl::PointXYZ p;
00687 p.x=v(0);
00688 p.y=v(1);
00689 p.z=v(2);
00690 pc[q].points.push_back(p);
00691 pcl::PointXYZRGB p2;
00692 p2.x=v(0);
00693 p2.y=v(1);
00694 p2.z=10*(pc_new[cors[i].ind_n].getVector3fMap()-rel_new-(pc_old[cors[i].ind_o].getVector3fMap()-rel_old)).norm()/(pc_old[cors[i].ind_o].getVector3fMap()-rel_old).norm();
00695
00696 p2.x = (pc_new[cors[i].ind_n].getVector3fMap()-rel_new).norm()/(pc_old[cors[i].ind_o].getVector3fMap()-rel_old).norm();
00697 p2.z = 0;(pc_new[cors[i].ind_n].getVector3fMap()-rel_new-(pc_old[cors[i].ind_o].getVector3fMap()-rel_old)).norm()/(pc_old[cors[i].ind_o].getVector3fMap()-rel_old).norm();
00698 p2.y = 0;(rel_new-rel_old).norm()/(pc_new[cors[i].ind_n].getVector3fMap()-pc_old[cors[i].ind_o].getVector3fMap()).norm();
00699
00700 if(p2.x<1)
00701 p2.x=1/p2.x;
00702
00703
00704 p2.z = p2.z/sqrtf(p2.x*p2.x+p2.y*p2.y)+1;
00705
00706
00707
00708 p2.r=p2.b=p2.g=108;
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721 bin[(int)((p2.z-1)*60)]++;
00722 if(cors[i].ind_o==cors[i].ind_n) {
00723 p2.r=255;
00724 bing[(int)((p2.z-1)*60)]++;
00725 }
00726
00727 p2.x=p2.y=0;
00728
00729 p2.x = (pc_new[cors[i].ind_n].getVector3fMap()-rel_new).norm()/(pc_old[cors[i].ind_o].getVector3fMap()-rel_old).norm();
00730 p2.z = 0;
00731 p2.y = 0;(rel_new-rel_old).norm()/(pc_new[cors[i].ind_n].getVector3fMap()-pc_old[cors[i].ind_o].getVector3fMap()).norm();
00732
00733
00734 if(p2.x<1)
00735 p2.x=1/p2.x;
00736
00737
00738
00739 p2.x -= 1;
00740
00741
00742 pc2[0].points.push_back(p2);
00743
00744
00745 m[q]+=v;
00746
00747 g[q]++;
00748 }
00749
00750 int s=0;
00751 for(int i=0; i<20; i++) {
00752 s+=bin[i];
00753 std::cout<<s<<"\t";
00754 }
00755 std::cout<<"\n";
00756 for(int i=0; i<20; i++) {
00757 std::cout<<bin[i]*100/s<<"\t";
00758 }
00759 std::cout<<"\n";
00760 s=0;
00761 for(int i=0; i<20; i++) {
00762 s+=bing[i];
00763 std::cout<<s<<"\t";
00764 }
00765 std::cout<<"\n";
00766 for(int i=0; i<20; i++) {
00767 std::cout<<bing[i]*100/s<<"\t";
00768 }
00769 std::cout<<"\n";
00770
00771 for(int i=0; i<1; i++) {
00772 pcl::PCA<pcl::PointXYZ> pca;
00773 pca.compute(pc[i]);
00774
00775 std::cout<<pca.getEigenValues()<<"\n";
00776 std::cout<<pca.getEigenVectors()<<"\n";
00777
00778 visualize(pc2[i]);
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 }
00808
00809 m[0]/=g[0];
00810 m[1]/=g[1];
00811 m[2]/=g[2];
00812 m[3]/=g[3];
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 std::cout<<"m[0]\n"<<m[0]<<"\n";
00825 std::cout<<"m[1]\n"<<m[1]<<"\n";
00826 std::cout<<"m[2]\n"<<m[2]<<"\n";
00827 std::cout<<"m[3]\n"<<m[3]<<"\n";
00828 std::cout<<"m[0] "<<m[0].norm()<<"\n";
00829 std::cout<<"m[1] "<<m[1].norm()<<"\n";
00830 std::cout<<"m[2] "<<m[2].norm()<<"\n";
00831 std::cout<<"m[3] "<<m[3].norm()<<"\n";
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843 std::cout<<"a x\n"<<(m[0]+m[1]).cross(m[2]+m[3])<<"\n";
00844 std::cout<<"a y\n"<<(m[0]+m[2]).cross(m[1]+m[3])<<"\n";
00845 std::cout<<"a z\n"<<(m[0]-m[3]).cross(m[1]-m[3])<<"\n";
00846
00847 Eigen::Vector3f axis, axis2;
00848
00849 Eigen::Matrix3f aX, aY, aZ;
00850
00851 aY=aZ=aX=aX.Identity();
00852
00853 {
00854 axis(0) = ((m[0]-m[1])).cross((m[2]-m[3]))(0);
00855 axis(1) = ((m[0]-m[2])).cross((m[1]-m[3]))(1);
00856 axis(2) = ((m[0]-m[3])).cross((m[1]-m[2]))(2);
00857
00858 axis.normalize();
00859
00860 std::cout<<"axis\n"<<axis<<"\n";
00861 }
00862 aX(0,0)=0;
00863 aY(1,1)=0;
00864 aZ(2,2)=0;
00865
00866 Eigen::Vector3f ax,ay,az;
00867 ax=(m[0]+m[1]).cross(m[2]+m[3]);
00868 ay=(m[0]+m[2]).cross(m[1]+m[3]);
00869 az=(m[0]-m[3]).cross(m[1]-m[3]);
00870
00871 ax.normalize();
00872 ay.normalize();
00873 az.normalize();
00874
00875 axis(0) = (aX*(m[0]+m[1])).cross(aX*(m[2]+m[3])).norm() / std::abs((m[0]+m[1])(0)+(m[2]+m[3])(0));
00876 axis(1) = (aY*(m[0]+m[2])).cross(aY*(m[1]+m[3])).norm() / std::abs((m[0]+m[2])(1)+(m[1]+m[3])(1));
00877 axis(2) = (aZ*(m[0]-m[3])).cross(aZ*(m[1]-m[2])).norm() / std::abs((m[0]-m[3])(2)+(m[1]-m[2])(2));
00878
00879 axis(0) = (aX*(m[0]+m[1])).cross(aX*(m[2]+m[3])).norm() * (std::abs(ax(0))+std::abs(ay(0))+std::abs(az(0)));
00880 axis(1) = (aY*(m[0]+m[2])).cross(aY*(m[1]+m[3])).norm() * (std::abs(ax(1))+std::abs(ay(1))+std::abs(az(1)));
00881 axis(2) = (aZ*(m[0]-m[3])).cross(aZ*(m[1]-m[2])).norm() * (std::abs(ax(2))+std::abs(ay(2))+std::abs(az(2)));
00882
00883 axis(0) = (std::abs(ax(0))+std::abs(ay(0))+std::abs(az(0))) ;
00884 axis(1) = (std::abs(ax(1))+std::abs(ay(1))+std::abs(az(1))) ;
00885 axis(2) = (std::abs(ax(2))+std::abs(ay(2))+std::abs(az(2))) ;
00886
00887 axis(0) = std::abs( ((m[0]+m[1])).cross((m[2]+m[3]))(0) );
00888 axis(1) = std::abs( ((m[0]+m[2])).cross((m[1]+m[3]))(1) );
00889 axis(2) = std::abs( ((m[0]-m[3])).cross((m[1]-m[2]))(2) );
00890
00891 axis(0) = std::abs( ax(0) );
00892 axis(1) = std::abs( ay(1) );
00893 axis(2) = std::abs( az(2) );
00894
00895 axis.normalize();
00896
00897 if( m[0](1)+m[1](1)+m[2](1)+m[3](1) > 0)
00898 axis(0) = -axis(0);
00899 if( m[0](0)+m[1](0)+m[2](0)+m[3](0) < 0)
00900 axis(1) = -axis(1);
00901 if( m[0](0)*m[0](1)+m[3](0)*m[3](1) - m[1](0)*m[1](1)-m[2](0)*m[2](1)
00902 < 0)
00903 axis(2) = -axis(2);
00904
00905 axis2=axis;
00906 std::cout<<"axis\n"<<axis<<"\n";
00907
00908 aX(0,0)=0;
00909 aY(1,1)=0;
00910 aZ(2,2)=0;
00911
00912 axis(0) = -(aX*(m[0]+m[1])).cross(aX*(m[2]+m[3]))(0);
00913 axis(1) = -(aY*(m[0]+m[2])).cross(aY*(m[1]+m[3]))(1);
00914 axis(2) = -(aZ*(m[0]-m[3])).cross(aZ*(m[1]-m[3]))(2);
00915 axis.normalize();
00916
00917 std::cout<<"axis\n"<<axis<<"\n";
00918
00919 return getAxis3(pc_old, pc_new,
00920 cors, max_dis,
00921 rel_old, rel_new
00922 , weight_o,weight_n, axis2);
00923 return axis2;
00924 }
00925
00926 template <typename Point>
00927 int remByAxis(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new, std::vector<COR_S> &cors, const Eigen::Vector3f &rel_old, const Eigen::Vector3f &rel_new, const Eigen::Vector3f &axis, const float add
00928 , std::vector<int> &weight_o,std::vector<int> &weight_n) {
00929 int rem=0,mis=0;
00930
00931 for(int i=0; i<cors.size(); i++) {
00932 Eigen::Vector3f v,vp, d;
00933
00934 v =pc_old[cors[i].ind_o].getVector3fMap();
00935 vp=pc_new[cors[i].ind_n].getVector3fMap();
00936
00937 v -=rel_old;
00938 vp-=rel_new;
00939
00940 d=v.cross(axis);
00941 v+=d/d.norm()*add;
00942
00943 v=vp-v;
00944
00945 float a=v.dot(d);
00946 if(pc_old[cors[i].ind_o].getVector3fMap().squaredNorm()<rel_old.squaredNorm()) a=-a;
00947
00948
00949 if(a>0) {
00950 rem++;
00951
00952 if(cors[i].ind_o==cors[i].ind_n) {
00953 ROS_ERROR("%d",i);
00954 std::cout<<pc_old[cors[i].ind_o].getVector3fMap()<<"\n";
00955 std::cout<<pc_new[cors[i].ind_n].getVector3fMap()<<"\n";
00956 std::cout<<v<<"\n";
00957 std::cout<<v.cross(axis)<<"\n";
00958
00959
00960
00961
00962
00963
00964
00965
00966 mis++;
00967 }
00968 }
00969
00970 }
00971
00972 ROS_INFO("would remove %d of %d (%d)", rem, cors.size(), mis);
00973
00974 return rem;
00975 }
00976
00977 inline pcl::PointXYZ vec3TOxyz(const Eigen::Vector3f &v) {
00978 pcl::PointXYZ p;
00979 p.x=v(0);
00980 p.y=v(1);
00981 p.z=v(2);
00982 return p;
00983 }
00984
00985 Eigen::Matrix4f getTF3(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p3, const Eigen::Vector3f &p1n, const Eigen::Vector3f &p2n, const Eigen::Vector3f &p3n) {
00986
00987 pcl::PointCloud<pcl::PointXYZ> t,s;
00988
00989 t.push_back(vec3TOxyz(p1n));
00990 t.push_back(vec3TOxyz(p2n));
00991 t.push_back(vec3TOxyz(p3n));
00992
00993 s.push_back(vec3TOxyz(p1));
00994 s.push_back(vec3TOxyz(p2));
00995 s.push_back(vec3TOxyz(p3));
00996
00997 Eigen::Matrix4f transf = Eigen::Matrix4f::Identity();
00998 pcl::estimateRigidTransformationSVD(t,s, transf);
00999
01000 return transf;
01001 }
01002
01003 Eigen::Matrix4f getTF(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p1n, const Eigen::Vector3f &p2n) {
01004 Eigen::Quaternionf q;
01005
01006 Eigen::Vector3f Z, axis, a,b;
01007 Z(0)=0;
01008 Z(1)=0;
01009 Z(2)=1;
01010
01011 a=p1-p2;
01012 b=p1n-p2n;
01013
01014 axis=(b-a).cross(Z);
01015
01016 axis.normalize();
01017
01018 a = a.cross(axis);
01019 b = b.cross(axis);
01020
01021 a.normalize();
01022 b.normalize();
01023
01024 float dir = a.dot(b-a);
01025
01026 if(dir<0)
01027 axis*=-1;
01028
01029 float angle = acos(a.dot(b));
01030 std::cout<<"angle "<<angle<<"\n";
01031 std::cout<<"a "<<a<<"\n";
01032 std::cout<<"b"<<b<<"\n";
01033
01034 std::cout<<"dir"<<dir<<"\n";
01035
01036 Eigen::AngleAxisf rot(angle, axis);
01037
01038 std::cout<<"C1\n"<<axis<<"\n";
01039 std::cout<<"rot\n"<<rot.toRotationMatrix()<<"\n";
01040
01041 Eigen::Matrix3f R=rot.toRotationMatrix();
01042
01043 Eigen::Vector3f t=((p1n+p2n)-R*(p1+p2))*0.5f;
01044
01045 std::cout<<"t\n"<<((p2n)-R*(p2))<<"\n";
01046 std::cout<<"t\n"<<((p1n)-R*(p1))<<"\n";
01047
01048 Eigen::Matrix4f transf = Eigen::Matrix4f::Identity();
01049 for(int x=0; x<3; x++)
01050 for(int y=0; y<3; y++)
01051 transf(x,y) = R(x,y);
01052 transf.col(3).head<3>() = t;
01053
01054 return transf;
01055 }
01056
01057
01058 float getTF2dis(const Eigen::Vector3f &axis, const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p1n, const Eigen::Vector3f &p2n) {
01059 Eigen::Quaternionf q;
01060
01061 Eigen::Vector3f r, a,b;
01062
01063 a=p1-p2;
01064 b=p1n-p2n;
01065
01066 r = a.cross(axis);
01067
01068 return acosf( r.dot(a-b)/(r.norm()*(b-a).norm()));
01069 }
01070
01071 float getTF2dis2(const Eigen::Vector3f &axis, const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p1n, const Eigen::Vector3f &p2n) {
01072 Eigen::Quaternionf q;
01073
01074 Eigen::Vector3f r, a,b;
01075
01076 a=p1-p2;
01077 b=p1n-p2n;
01078
01079 a = a.cross(axis);
01080 b = b.cross(axis);
01081
01082 return asinf((a-b).norm()/a.norm());
01083
01084 a.normalize();
01085 b.normalize();
01086
01087 return acosf( a.dot(b) );
01088 }
01089
01090 Eigen::Matrix4f getTF2(const Eigen::Vector3f &axis, const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p_s, const Eigen::Vector3f &p1n, const Eigen::Vector3f &p2n, const Eigen::Vector3f &pn_s) {
01091 Eigen::Quaternionf q;
01092
01093 Eigen::Vector3f Z, a,b;
01094 Z(0)=0;
01095 Z(1)=0;
01096 Z(2)=1;
01097
01098 a=p1-p2;
01099 b=p1n-p2n;
01100
01101 a = a.cross(axis);
01102 b = b.cross(axis);
01103
01104 a.normalize();
01105 b.normalize();
01106
01107
01108
01109
01110 float angle = acos(a.dot(b));
01111 std::cout<<"angle "<<angle<<"\n";
01112 std::cout<<"a "<<a<<"\n";
01113 std::cout<<"b"<<b<<"\n";
01114
01115 std::cout<<"axis\n"<<axis<<"\n";
01116
01117 Eigen::AngleAxisf rot(angle, axis);
01118
01119 std::cout<<"C1\n"<<axis<<"\n";
01120 std::cout<<"rot\n"<<rot.toRotationMatrix()<<"\n";
01121
01122 Eigen::Matrix3f R=rot.toRotationMatrix();
01123
01124 Eigen::Vector3f t=pn_s-R*p_s;
01125
01126 std::cout<<"pn_s\n"<<pn_s<<"\n";
01127 std::cout<<"R*p_s\n"<<(R*p_s)<<"\n";
01128 std::cout<<"t\n"<<((p2n)-R*(p2))<<"\n";
01129 std::cout<<"t\n"<<((p1n)-R*(p1))<<"\n";
01130 std::cout<<"t\n"<<(((p1n+p2n)-R*(p1+p2))*0.5f)<<"\n";
01131
01132 Eigen::Matrix4f transf = Eigen::Matrix4f::Identity();
01133 for(int x=0; x<3; x++)
01134 for(int y=0; y<3; y++)
01135 transf(x,y) = R(x,y);
01136 transf.col(3).head<3>() = t;
01137
01138 return transf;
01139 }
01140
01141 template <typename Point>
01142 Eigen::Matrix4f getTF2ex(const Eigen::Vector3f &axis,
01143 const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
01144 const std::vector<COR_S> &cors, const std::vector<int> &weight_o, const std::vector<int> &weight_n,
01145 const Eigen::Vector3f &mid_old, const Eigen::Vector3f &mid_new
01146 ) {
01147 float avg_angel=0;
01148 float n=0;
01149
01150 for(int i=0; i<cors.size(); i++) {
01151
01152 float w=1/(float)weight_o[cors[i].ind_o];
01153
01154 Eigen::Vector3f a,b;
01155
01156 a=pc_old[cors[i].ind_o].getVector3fMap()-mid_old;
01157 b=pc_new[cors[i].ind_n].getVector3fMap()-mid_new;
01158
01159 a = a.cross(axis);
01160 b = b.cross(axis);
01161
01162 a.normalize();
01163 b.normalize();
01164
01165 float angle = acos(a.dot(b));
01166 avg_angel+=w*angle;
01167 n+=w;
01168
01169 }
01170 avg_angel/=n;
01171
01172 Eigen::AngleAxisf rot(avg_angel, axis);
01173 Eigen::Matrix3f R=rot.toRotationMatrix();
01174
01175 std::cout<<"C1\n"<<axis<<"\n";
01176 std::cout<<"rot\n"<<rot.toRotationMatrix()<<"\n";
01177 std::cout<<"angle "<<avg_angel<<"\n";
01178
01179 Eigen::Vector3f t;
01180 t(0)=t(1)=t(2)=0;
01181 n=0;
01182
01183 for(int i=0; i<cors.size(); i++) {
01184
01185 float w=1/(float)weight_o[cors[i].ind_o];
01186
01187 t+=w* (pc_new[cors[i].ind_n].getVector3fMap()-R*pc_old[cors[i].ind_o].getVector3fMap()-mid_old) ;
01188 n+=w;
01189
01190 }
01191 t/=n;
01192
01193 std::cout<<"t\n"<<t<<"\n";
01194
01195 Eigen::Matrix4f transf = Eigen::Matrix4f::Identity();
01196 for(int x=0; x<3; x++)
01197 for(int y=0; y<3; y++)
01198 transf(x,y) = R(x,y);
01199 transf.col(3).head<3>() = t;
01200
01201 return transf;
01202 }
01203
01204 template <typename Point>
01205 float avgError(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new, const std::vector<COR_S> &cors, const Eigen::Matrix4f &tf=Eigen::Matrix4f::Identity()) {
01206 float er=0.f;
01207 for(int i=0; i<cors.size(); i++) {
01208 er+=(tf*pc_old[cors[i].ind_o].getVector4fMap()-pc_new[cors[i].ind_n].getVector4fMap()).norm()/pc_old[cors[i].ind_o].getVector3fMap().norm();
01209 }
01210 return er/cors.size();
01211 }
01212
01213 inline float vorz(float v) {
01214 return v;
01215 }
01216
01217 template <typename Point>
01218 int remError(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
01219 std::vector<COR_S> &cors, const Eigen::Matrix4f &tf, const float border_a, const float border_t, std::vector<int> &weight_o,std::vector<int> &weight_n,
01220 const Eigen::Vector3f &mid_old, const Eigen::Vector3f &mid_new) {
01221
01222 std::vector<std::vector<int> > cs;
01223
01224 for(int i=0; i<pc_new.size(); i++)
01225 weight_n[i]=0;
01226 for(int i=0; i<pc_old.size(); i++) {
01227 weight_o[i]=0;
01228 std::vector<int> s;
01229 for(int j=0; j<cors.size(); j++) {
01230 if(cors[j].ind_o==i)
01231 s.push_back(cors[j].ind_n);
01232 }
01233 cs.push_back(s);
01234 }
01235
01236 pcl::PointCloud<Point> tpc,spc;
01237 cors.clear();
01238 for(int i=0; i<pc_old.size(); i++) {
01239
01240
01241
01242
01243 std::vector<float> f1,f2,f3,f4;
01244
01245 if(cs[i].size()<1) continue;
01246
01247 int mi=0;
01248 float vmi=10000000000;
01249
01250 for(int j=0; j<cs[i].size(); j++) {
01251
01252 float t=0;
01253 float t2=0;
01254 Eigen::Vector3f v=(pc_old[i].getVector3fMap()-mid_old).cross(pc_new[cs[i][j]].getVector3fMap()-pc_old[i].getVector3fMap());
01255 Eigen::Vector3f v2=(pc_old[i].getVector3fMap()-mid_old).cross(v);
01256 v.normalize();
01257 v2.normalize();
01258 for(int k=0; k<pc_old.size(); k++) {
01259 t+=vorz((pc_old[k].getVector3fMap()-pc_old[i].getVector3fMap()).dot(v));
01260 t2+=vorz((pc_old[k].getVector3fMap()-pc_old[i].getVector3fMap()).dot(v2));
01261 }
01262 f1.push_back(t);
01263 f3.push_back(t2);
01264
01265 v=(pc_new[cs[i][j]].getVector3fMap()-mid_new).cross(pc_new[cs[i][j]].getVector3fMap()-pc_old[i].getVector3fMap());
01266 v2=(pc_new[cs[i][j]].getVector3fMap()-mid_new).cross(v);
01267 t=0;
01268 t2=0;
01269 for(int k=0; k<pc_new.size(); k++) {
01270 t+=vorz((pc_new[k].getVector3fMap()-pc_new[cs[i][j]].getVector3fMap()).dot(v));
01271 t2+=vorz((pc_new[k].getVector3fMap()-pc_new[cs[i][j]].getVector3fMap()).dot(v2));
01272 }
01273 f2.push_back(t);
01274 f4.push_back(t2);
01275
01276
01277
01278 t=std::abs(f1.back()-f2.back())+std::abs(f3.back()-f4.back());
01279
01280 if(t<vmi) {
01281 mi=j;
01282 vmi=t;
01283 }
01284 }
01285
01286 if(cs[i][mi]!=i) {
01287 ROS_ERROR("%f %f", f1[mi], f2[mi]);
01288 for(int j=0; j<cs[i].size(); j++)
01289 std::cout<<i<<" "<<cs[i][j]<<": "<<f1[j]<<", "<<f2[j]<<" - "<<f3[j]<<", "<<f4[j]<<" = "<<
01290 std::abs( (f1[j]-f2[j])*(f3[j]-f4[j]) )
01291 <<"\n";
01292 }
01293
01294 COR_S c;
01295 c.ind_o=i;
01296 c.ind_n=cs[i][mi];
01297
01298 if(weight_n[c.ind_n]) continue;
01299
01300 cors.push_back(c);
01301
01302 weight_o[i]++;
01303 weight_n[c.ind_n]++;
01304
01305 tpc.points.push_back(pc_old[i]);
01306 spc.points.push_back(pc_new[c.ind_n]);
01307 }
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319 return 10;
01320 int n=0;
01321 int sz=cors.size();
01322 float dA,dT;
01323
01324 Eigen::Vector4f dir;
01325 dir(0)=dir(1)=dir(2)=dir(3)=0;
01326
01327 float avg=0;
01328 for(int i=0; i<cors.size(); i++) {
01329 Eigen::Vector4f v=(tf*pc_old[cors[i].ind_o].getVector4fMap());
01330
01331 float d=(v-pc_new[cors[i].ind_n].getVector4fMap()).squaredNorm();
01332 avg+=sqrtf(d);
01333
01334 v-=pc_new[cors[i].ind_n].getVector4fMap();
01335 v.normalize();
01336 dir += v;
01337 }
01338 avg/=sz;
01339 ROS_INFO("AVG %f TMAX %f",avg, border_t);
01340
01341 dir.normalize();
01342 std::cout<<"translation dir:\n"<<dir<<"\n";
01343
01344 for(int i=0; i<cors.size(); i++) {
01345
01346 Eigen::Vector4f v=(tf*pc_old[cors[i].ind_o].getVector4fMap());
01347 Eigen::Vector4f v2=pc_new[cors[i].ind_n].getVector4fMap();
01348
01349 float dT = std::abs(v.norm()-v2.norm());
01350 float dA = acosf(v.dot(v2)/(v.norm()*v2.norm()));
01351
01352 if( dA>border_a || dT>border_t || (v-v2).squaredNorm()>(pc_old[cors[i].ind_o].getVector4fMap()-v2).squaredNorm()+border_t )
01353
01354
01355
01356
01357
01358 {
01359
01360
01361 if(cors[i].ind_o==cors[i].ind_n) {
01362 ROS_ERROR("%f %f",dT,dA);
01363 }
01364
01365 weight_o[cors[i].ind_o]--;
01366 weight_n[cors[i].ind_n]--;
01367
01368 std::swap(cors[i],cors.back());
01369 cors.resize(cors.size()-1);
01370 --i;
01371 ++n;
01372 }
01373 }
01374
01375 ROS_INFO("AVG %f TMAX %f",avg, border_t);
01376 ROS_INFO("REMOVED %d",n);
01377 return n;
01378 }
01379
01380 #define GET_MIDS() \
01381 \
01382 mid_old = getMidO(pc_old,weight_o,cors);\
01383 mid_new = getMidO(pc_new,weight_o,cors);\
01384 \
01385 mid_ob = getMidO(pc_old,weight_o,cors, true, mid_old.squaredNorm());\
01386 mid_nb = getMidN(pc_new,weight_o, true, mid_old.squaredNorm(), pc_old,cors);\
01387 \
01388 mid_oa = getMidO(pc_old,weight_o,cors, false, mid_old.squaredNorm());\
01389 mid_na = getMidN(pc_new,weight_o, false, mid_old.squaredNorm(), pc_old,cors);\
01390 \
01391 mid_old = 0.5f*(mid_ob+mid_oa);\
01392 mid_new = 0.5f*(mid_nb+mid_na);
01393
01394 template <typename Point>
01395 Eigen::Matrix4f _findTF(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new, std::vector<COR_S> &cors, float border_a, float border_t, float border_a2,
01396 std::vector<int> &weight_o, std::vector<int> &weight_n, const Eigen::Vector3f &prev_trans=Null3f()) {
01397
01398 ROS_ERROR("tmax %f", border_t);
01399 ROS_ERROR("rmax %f", border_a);
01400
01401 Eigen::Vector3f mid_old, mid_new, mid_ob, mid_nb, mid_oa, mid_na, axis;
01402 int rem = 0;
01403
01404 GET_MIDS();
01405
01406 std::cout<<"mid_old\n"<<mid_old<<"\n";
01407 std::cout<<"mid_new\n"<<mid_new<<"\n";
01408 std::cout<<"mid_ob\n"<<mid_ob<<"\n";
01409 std::cout<<"mid_oa\n"<<mid_oa<<"\n";
01410 std::cout<<"mid_nb\n"<<mid_nb<<"\n";
01411 std::cout<<"mid_na\n"<<mid_na<<"\n";
01412 visualize(pc_old,pc_new, cors, mid_old,mid_new);
01413
01414 axis=getAxis2(pc_old, pc_new, cors, mid_old.squaredNorm(), mid_old, mid_new, weight_o, weight_n);
01415
01416
01417
01418
01419
01420 if(0) {
01421 int remR=0, remF=0;
01422 float a_avg=0;
01423 for(int i=0; i<cors.size(); i++) {
01424
01425
01426
01427
01428 float a=getTF2dis(axis, Null3f(),pc_old[cors[i].ind_o].getVector3fMap(), prev_trans,pc_new[cors[i].ind_n].getVector3fMap());
01429 a_avg+=a;
01430 }
01431 a_avg/=cors.size();
01432 ROS_INFO("avg %f",a_avg);
01433
01434
01435 int num_a=0, num_b=0;
01436 int num_ar=0, num_br=0;
01437 for(int i=0; i<cors.size(); i++) {
01438 float a=getTF2dis(axis, Null3f(),pc_old[cors[i].ind_o].getVector3fMap(), prev_trans,pc_new[cors[i].ind_n].getVector3fMap());
01439
01440 if(a>a_avg)
01441 num_a++;
01442 else
01443 num_b++;
01444
01445 if(cors[i].ind_o==cors[i].ind_n) {
01446 if(a>a_avg)
01447 num_ar++;
01448 else
01449 num_br++;
01450 }
01451
01452 if( (a>a_avg+border_a) && cors[i].ind_o==cors[i].ind_n) {
01453 ROS_ERROR("wrong remove %f",a);
01454 remF++;
01455 }
01456
01457 if( a>a_avg+border_a ) {
01458 remR++;
01459 weight_o[cors[i].ind_o]--;
01460 weight_n[cors[i].ind_n]--;
01461
01462 std::swap(cors[i],cors.back());
01463 cors.resize(cors.size()-1);
01464 --i;
01465
01466 ++rem;
01467 }
01468
01469 }
01470 ROS_INFO("suppose %d/%d (%d/%d)",num_b,num_a,num_br, num_ar);
01471 ROS_INFO("would rem %d/%d",remR,remF);
01472 visualize(pc_old,pc_new, cors, mid_old,mid_new);
01473
01474 GET_MIDS();
01475
01476 axis=getAxis2(pc_old, pc_new, cors, mid_old.squaredNorm(), mid_old, mid_new, weight_o, weight_n);
01477
01478 #if TESTING_
01479 getchar();
01480 #endif
01481 }
01482 if(0){
01483 int remR=0, remF=0;
01484 float a_avg=0;
01485 for(int i=0; i<cors.size(); i++) {
01486 float a=getTF2dis2(axis, Null3f(),pc_old[cors[i].ind_o].getVector3fMap(), prev_trans,pc_new[cors[i].ind_n].getVector3fMap());
01487 a_avg+=a;
01488 }
01489 a_avg/=cors.size();
01490 ROS_INFO("avg %f",a_avg);
01491
01492
01493 int num_a=0, num_b=0;
01494 int num_ar=0, num_br=0;
01495
01496 {
01497 for(int i=0; i<cors.size(); i++) {
01498 float a=getTF2dis2(axis, Null3f(),pc_old[cors[i].ind_o].getVector3fMap(), prev_trans,pc_new[cors[i].ind_n].getVector3fMap());
01499
01500 if(a>a_avg)
01501 num_a++;
01502 else
01503 num_b++;
01504
01505 if(cors[i].ind_o==cors[i].ind_n) {
01506 if(a>a_avg)
01507 num_ar++;
01508 else
01509 num_br++;
01510 }
01511
01512 bool b= a<a_avg-border_a || a>border_a*2+a_avg;
01513
01514 if( b && cors[i].ind_o==cors[i].ind_n) {
01515 ROS_ERROR("wrong remove %f",a);
01516 remF++;
01517 }
01518
01519 if( b ) {
01520 remR++;
01521 weight_o[cors[i].ind_o]--;
01522 weight_n[cors[i].ind_n]--;
01523
01524 std::swap(cors[i],cors.back());
01525 cors.resize(cors.size()-1);
01526 --i;
01527
01528 ++rem;
01529 }
01530
01531 }
01532
01533 }
01534 ROS_INFO("suppose %d/%d (%d/%d)",num_b,num_a,num_br, num_ar);
01535 ROS_INFO("would rem %d/%d",remR,remF);
01536
01537 GET_MIDS();
01538
01539 visualize(pc_old,pc_new, cors, mid_old,mid_new);
01540
01541 }
01542
01543 visualize(pc_old,pc_new, cors, mid_old,mid_new);
01544
01545
01546 Eigen::Matrix4f tf=getTF2(axis, mid_oa,mid_ob,mid_old, mid_na,mid_nb,mid_new);
01547 std::cout<<tf<<"\n";
01548
01549 if( (tf.col(3).head<3>()).squaredNorm() > 0.04) {
01550 tf.col(3).head<3>()=tf.col(3).head<3>()*0.2/tf.col(3).head<3>().norm();
01551 }
01552
01553 float border;
01554
01555 std::cout<<"mid_old\n"<<mid_old<<"\n";
01556 std::cout<<"mid_new\n"<<mid_new<<"\n";
01557 std::cout<<"mid_ob\n"<<mid_ob<<"\n";
01558 std::cout<<"mid_oa\n"<<mid_oa<<"\n";
01559 std::cout<<"mid_nb\n"<<mid_nb<<"\n";
01560 std::cout<<"mid_na\n"<<mid_na<<"\n";
01561
01562 ROS_ERROR("above/below");
01563 visualize(pc_old,pc_new, cors, mid_ob,mid_nb);
01564 visualize(pc_old,pc_new, cors, mid_oa,mid_na);
01565
01566 std::cout<<tf<<"\n";
01567
01568 #if TESTING_
01569 getchar();
01570 #endif
01571
01572 std::cout<<"error before "<<avgError(pc_old, pc_new, cors)<<"\n";
01573 std::cout<<"error after "<<(border=avgError(pc_old, pc_new, cors, tf))<<"\n";
01574
01575
01576 rem += remError(pc_old, pc_new, cors, tf, border_a, border_t, weight_o,weight_n, mid_old,mid_new);
01577 {
01578 Eigen::Vector4f mido;
01579 mido(0)=mid_old(0);mido(1)=mid_old(1);mido(2)=mid_old(2);
01580 mido(3)=0;
01581 visualize(pc_old,pc_new, cors, mid_old,mid_new, (tf*mido).head<3>());
01582 }
01583
01584
01585 border_a*=0.5f;
01586 border_t*=0.5f;
01587 border_a2*=0.5f;
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610 GET_MIDS();
01611 axis=getAxis2(pc_old, pc_new, cors, mid_old.squaredNorm(), mid_old, mid_new, weight_o, weight_n);
01612 tf=getTF2(axis, mid_oa,mid_ob,mid_old, mid_na,mid_nb,mid_new);
01613
01614 std::cout<<"FINAL TF\n"<<tf<<"\n";
01615
01616 std::cout<<"removed "<<rem<<" ("<<cors.size()<<")\n";
01617 std::cout<<"error after2 "<<avgError(pc_old, pc_new, cors, tf)<<"\n";
01618
01619 ROS_INFO("num %d",weight_o.size());
01620 ROS_INFO("num %d",weight_n.size());
01621 for(int i=0; i<weight_o.size(); i++)
01622 std::cout<<weight_o[i]<<" ";
01623 for(int i=0; i<weight_n.size(); i++)
01624 std::cout<<weight_n[i]<<" ";
01625
01626 int cor=0;
01627 for(int i=0; i<cors.size(); i++)
01628 cor+=cors[i].ind_n==cors[i].ind_o?1:0;
01629 ROS_ERROR("correct %d/%d", cor, cors.size());
01630
01631 #if TESTING_
01632 getchar();
01633 #endif
01634
01635 if(rem>2&&border>0.01&&cors.size()>pc_old.size())
01636 return _findTF(pc_old,pc_new,cors, border_a, border_t, border_a2, weight_o, weight_n, tf.col(3).head<3>() );
01637
01638 return tf;
01639 }
01640
01641 int search_sorted_vector(const std::vector<SORT_S2> &tv, const float val) {
01642 int i=tv.size()-1;
01643 int step=tv.size()/2-1;
01644 while(i&&step&&i<tv.size()) {
01645 if(tv[i].dis>=val) {
01646 i-=step;
01647 }
01648 else if(tv[i].dis<val)
01649 i+=step;
01650 else
01651 break;
01652 step/=2;
01653 }
01654 return i;
01655 }
01656
01657
01658 template <typename Point>
01659 Eigen::Matrix4f findTF_fast(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
01660 const float rmax=0.1, const float tmax=0.1, Eigen::Matrix4f tf=Eigen::Matrix4f::Identity())
01661 {
01662 std::vector<SORT_S2> tv;
01663 std::vector<COR_S> cors;
01664
01665 for(int i=0; i<pc_new.size(); i++) {
01666 SORT_S2 s;
01667 s.dis=pc_new.points[i].getVector3fMap().norm();
01668 s.ind=i;
01669 tv.push_back(s);
01670 }
01671
01672 SORT_S2 _s_;
01673 std::sort(tv.begin(),tv.end(), _s_);
01674
01675 std::vector<int> weight_o, weight_n;
01676
01677 weight_o.resize(pc_old.size(), 0);
01678 weight_n.resize(pc_new.size(), 0);
01679
01680 float rmax_ = sinf(rmax);
01681 rmax_*=rmax_;
01682
01683 weight_o.resize(pc_old.size(), 0);
01684 weight_n.resize(pc_new.size(), 0);
01685
01686 COR_S c;
01687 for(int i=0; i<pc_old.size(); i++) {
01688 float t = pc_old.points[i].getVector3fMap().norm();
01689 Eigen::Vector3f vo = pc_old.points[i].getVector3fMap();
01690
01691 int num=0;
01692 for(int j=search_sorted_vector(tv,t-tmax); j<tv.size(); j++) {
01693
01694 float dT = std::abs(tv[j].dis-t);
01695 if( dT < tmax) {
01696 Eigen::Vector3f vn = pc_new.points[tv[j].ind].getVector3fMap();
01697
01698 float dA = (((vn-vo).squaredNorm()/vo.squaredNorm()));
01699
01700 if(dA>=rmax_) continue;
01701
01702 if(num>0 &&
01703 (vn-vo)
01704 .dot
01705 (pc_new[cors.back().ind_n].getVector3fMap()-vo)<0. )
01706 {
01707 cors.resize(cors.size()-num);
01708 break;
01709 }
01710
01711 ++num;
01712
01713 c.ind_o = i;
01714 c.ind_n = tv[j].ind;
01715 cors.push_back(c);
01716
01717 weight_o[i]++;
01718 weight_n[c.ind_n]++;
01719 }
01720 else if(tv[j].dis-t > tmax)
01721 break;
01722 }
01723
01724 }
01725
01726 pcl::TransformationFromCorrespondences transFromCorr;
01727 for(int i=0; i<cors.size(); i++) {
01728 transFromCorr.add(pc_old[cors[i].ind_o].getVector3fMap(), pc_new[cors[i].ind_n].getVector3fMap(), 1./std::min(weight_o[cors[i].ind_o],weight_n[cors[i].ind_n]));
01729 }
01730 Eigen::Matrix4f tf2 = transFromCorr.getTransformation().matrix();
01731
01732 pcl::PointCloud<Point> tpc;
01733 pcl::transformPointCloud(pc_old,tpc,tf2);
01734
01735 if(tmax<0.01)
01736 return tf*tf2;
01737 return findTF_fast(tpc,pc_new, rmax*0.5, tmax*0.5, tf*tf2);
01738 }
01739
01740 template <typename Point>
01741 Eigen::Matrix4f findTF(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
01742 const float rmax=0.1, const float tmax=0.1, Eigen::Matrix4f tf=Eigen::Matrix4f::Identity())
01743 {
01744 int dbg_rem1=0,dbg_rem2=0;
01745
01746 std::vector<SORT_S2> tv;
01747 std::vector<COR_S> cors;
01748
01749 for(int i=0; i<pc_new.size(); i++) {
01750 SORT_S2 s;
01751 s.dis=pc_new.points[i].getVector3fMap().norm();
01752 s.ind=i;
01753 tv.push_back(s);
01754 }
01755
01756 SORT_S2 _s_;
01757 std::sort(tv.begin(),tv.end(), _s_);
01758
01759 float avgT=0.f;
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782 std::vector<int> weight_o, weight_n;
01783
01784 weight_o.resize(pc_old.size(), 0);
01785 weight_n.resize(pc_new.size(), 0);
01786
01787 for(int i=0; i<pc_old.size(); i++) {
01788 float t = pc_old.points[i].getVector3fMap().norm();
01789
01790 float bestd;
01791 int num=0;
01792 for(int j=search_sorted_vector(tv,t-tmax); j<tv.size(); j++) {
01793
01794
01795
01796 float dT=std::abs(tv[j].dis-t);
01797 if( dT < tmax) {
01798 float dA;
01799
01800 dA = (((pc_new.points[tv[j].ind].getVector3fMap()-pc_old.points[i].getVector3fMap()).norm()/pc_old.points[i].getVector3fMap().norm()));
01801
01802 if(dA>=rmax) continue;
01803
01804
01805
01806 Eigen::Vector3f X;
01807 X(0)=1;X(1)=0;X(2)=0;
01808
01809
01810
01811
01812
01813 ++num;
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826 COR_S c;
01827 c.ind_o = i;
01828 c.ind_n = tv[j].ind;
01829 if(num==1){
01830 cors.push_back(c);
01831 bestd=dA*dA+dT*dT;
01832 }
01833 else if(bestd>dA*dA+dT*dT) {
01834
01835 if(
01836 (pc_new[c.ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap())
01837 .dot
01838 (pc_new[cors.back().ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap())<0 )
01839 {
01840 cors.resize(cors.size()-1);
01841 break;
01842 }
01843
01844 bestd=dA*dA+dT*dT;
01845 cors.back()=c;
01846 }
01847
01848 weight_o[i]++;
01849 weight_n[c.ind_n]++;
01850 }
01851 else if(tv[j].dis-t > tmax)
01852 break;
01853 }
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892 }
01893
01894 pcl::PointCloud<Point> tpc;
01895
01896 pcl::TransformationFromCorrespondences transFromCorr;
01897 for(int i=0; i<cors.size(); i++) {
01898 transFromCorr.add(pc_old[cors[i].ind_o].getVector3fMap(), pc_new[cors[i].ind_n].getVector3fMap(), 1./(weight_o[cors[i].ind_o]*weight_n[cors[i].ind_n]));
01899 }
01900 Eigen::Matrix4f tf2 = transFromCorr.getTransformation().matrix();
01901 std::cout<<tf*tf2<<"\n";
01902
01903
01904
01905
01906
01907 PrecisionStopWatch psw;
01908
01909 float rmax_ = sinf(rmax);
01910 rmax_*=rmax_;
01911
01912 cors.clear();
01913 weight_o.resize(pc_old.size(), 0);
01914 weight_n.resize(pc_new.size(), 0);
01915 for(int i=0; i<pc_old.size(); i++) {
01916 float t = pc_old.points[i].getVector3fMap().norm();
01917 Eigen::Vector3f vo = pc_old.points[i].getVector3fMap();
01918
01919 int num=0;
01920 float bestd;
01921 for(int j=search_sorted_vector(tv,t-tmax); j<tv.size(); j++) {
01922
01923 float dT = std::abs(tv[j].dis-t);
01924 if( dT < tmax) {
01925 Eigen::Vector3f vn = pc_new.points[tv[j].ind].getVector3fMap();
01926
01927 float dA;
01928
01929 dA = (((vn-vo).squaredNorm()
01930 /vo.squaredNorm()));
01931
01932 if(dA>=rmax_) continue;
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944 if(num>0 &&
01945 (vn-vo)
01946 .dot
01947 (pc_new[cors.back().ind_n].getVector3fMap()-vo)<0. )
01948 {
01949 cors.resize(cors.size()-num);
01950 dbg_rem2+=num;
01951 break;
01952 }
01953 ++num;
01954
01955 COR_S c;
01956 c.ind_o = i;
01957 c.ind_n = tv[j].ind;
01958
01959 bestd=dA*dA+dT*dT;
01960 cors.push_back(c);
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977 weight_o[i]++;
01978 weight_n[c.ind_n]++;
01979 }
01980 else if(tv[j].dis-t > tmax)
01981 break;
01982 }
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007 }
02008 ROS_ERROR("took %f", psw.precisionStop());
02009
02010 transFromCorr.reset();
02011 for(int i=0; i<cors.size(); i++) {
02012 transFromCorr.add(pc_old[cors[i].ind_o].getVector3fMap(), pc_new[cors[i].ind_n].getVector3fMap(), 1./std::min(weight_o[cors[i].ind_o],weight_n[cors[i].ind_n]));
02013 }
02014 tf2 = transFromCorr.getTransformation().matrix();
02015 ROS_ERROR("took %f", psw.precisionStop());
02016
02017 std::cout<<tf*tf2<<"\n";
02018
02019 pcl::transformPointCloud(pc_old,tpc,tf2);
02020
02021 std::cout<<"num "<<cors.size()<<"\n";
02022 std::cout<<"dbg_rem1 "<<dbg_rem1<<"\n";
02023 std::cout<<"dbg_rem2 "<<dbg_rem2<<"\n";
02024 visualize(tpc,pc_new, cors,weight_o,weight_n);
02025
02026
02027 {
02028 pcl::PointCloud<pcl::PointXYZRGB> pc1_,pc2_;
02029 pcl::io::loadPCDFile(_FN1_,pc1_);
02030 pcl::io::loadPCDFile(_FN2_,pc2_);
02031
02032 pcl::transformPointCloud(pc1_,pc1_,tf*tf2);
02033
02034 pcl::io::savePCDFileBinary("out/a.pcd",pc1_);
02035 pcl::io::savePCDFileBinary("out/b.pcd",pc2_);
02036 }
02037
02038 if(tmax<0.01)
02039 return tf*tf2;
02040 return findTF(tpc,pc_new, rmax*0.5, tmax*0.5, tf*tf2);
02041
02042 for(int i=0; i<weight_o.size(); i++) std::cout<<weight_o[i]<<" ";
02043
02044 ROS_INFO("num %d",cors.size());
02045
02046 tf=_findTF(pc_old, pc_new, cors, rmax,tmax,M_PI*0.5, weight_o,weight_n);
02047 ROS_ERROR("FINISHED!");
02048 visualize(pc_old,pc_new, cors);
02049
02050 pcl::transformPointCloud(pc_old,tpc,tf);
02051 visualize(tpc,pc_new, cors);
02052
02053 return tf;
02054 }
02055
02056 template <typename Point>
02057 class calcTF
02058 {
02059 std::vector<SORT_S2> tv;
02060 const pcl::PointCloud<Point> &pc_old_;
02061 const pcl::PointCloud<Point> &pc_new_;
02062 const float rmax;
02063 const float tmax;
02064 const float mininfo;
02065 std::vector<float> dis_old, dis_new;
02066 public:
02067 calcTF(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new):
02068 pc_old_(pc_old), pc_new_(pc_new),
02069 rmax(0.1), tmax(0.1), mininfo(5)
02070 {
02071 for(int i=0; i<pc_old.size(); i++) {
02072 float t = pc_old.points[i].getVector3fMap().norm();
02073 dis_old.push_back(t);
02074 }
02075 for(int i=0; i<pc_new.size(); i++) {
02076 float t = pc_new.points[i].getVector3fMap().norm();
02077 dis_new.push_back(t);
02078 }
02079
02080 for(int i=0; i<pc_new.size(); i++) {
02081 SORT_S2 s;
02082 s.dis=dis_new[i];
02083 s.ind=i;
02084 tv.push_back(s);
02085 }
02086
02087 SORT_S2 _s_;
02088 std::sort(tv.begin(),tv.end(), _s_);
02089 }
02090
02091 void getWeights(const std::vector<int> &inds, std::vector<int> &weight_o, std::vector<int> &weight_n) {
02092 float __rmax = std::abs(cosf(rmax));
02093 weight_o.resize(pc_old_.size(), 0);
02094 weight_n.resize(pc_new_.size(), 0);
02095 for(int k=0; k<inds.size(); k++) {
02096 int i = inds[k];
02097 float t = dis_old[i];
02098
02099 for(int j=search_sorted_vector(tv,t-tmax); j<tv.size(); j++) {
02100
02101 if( std::abs(tv[j].dis-t) < tmax) {
02102 float dA;
02103 float t2 = dis_new[tv[j].ind];
02104 dA = std::abs(pc_old_.points[i].getVector3fMap().dot(pc_new_.points[tv[j].ind].getVector3fMap())/(t*t2));
02105
02106 if(dA<__rmax) continue;
02107 if((pc_old_.points[i].getVector3fMap()-pc_new_.points[tv[j].ind].getVector3fMap()).squaredNorm()==0)
02108 continue;
02109
02110 weight_o[i]++;
02111 weight_n[tv[j].ind]++;
02112 }
02113 else if(tv[j].dis-t > tmax)
02114 break;
02115 }
02116 }
02117 }
02118
02119 Eigen::Matrix4f findCloud() {
02120 PrecisionStopWatch psw;
02121
02122 pcl::PointCloud<Point> pc_o, pc_n;
02123
02124 std::vector<int> weight_o, weight_n;
02125 std::vector<int> *pinds = new std::vector<int>();
02126 std::vector<int> &inds = *pinds;
02127 for(int i=0; i<pc_old_.size(); i++) inds.push_back(i);
02128
02129 getWeights(inds,weight_o, weight_n);
02130 ROS_ERROR("took %f", psw.precisionStop());
02131
02132 for(int i=0; i<inds.size(); i++) {
02133 if(weight_o[inds[i]]<mininfo) {
02134 std::swap(inds[i],inds[inds.size()-1]);
02135 inds.resize(inds.size()-1);
02136 pc_o.push_back(pc_old_[i]);
02137 i--;
02138 }
02139 }
02140
02141 ROS_ERROR("took %f", psw.precisionStop());
02142 ROS_INFO("to check %d",inds.size());
02143
02144 if(inds.size()>0) {
02145 boost::shared_ptr<pcl::KdTree<Point> > tree (new pcl::KdTreeFLANN<Point>);
02146 tree->setInputCloud (pc_old_.makeShared(),pcl::IndicesConstPtr(pinds));
02147
02148 std::vector<bool> done;
02149 done.resize(inds.size(),false);
02150 std::vector<int> found;
02151 std::vector<float> k_sqr_distances;
02152
02153 float __rmax = std::abs(cosf(rmax));
02154
02155 for(int k=0; k<inds.size(); k++) {
02156 if(done[k]) continue;
02157 tree->radiusSearch(pc_old_[inds[k]],tmax*0.2f,found,k_sqr_distances);
02158
02159 Point po;
02160 po.x=po.y=po.z=0;
02161
02162 float s=0;
02163 float t=dis_old[inds[k]];
02164 for(size_t j=0; j<found.size(); j++) {
02165 int i=inds[found[j]];
02166
02167 float dA;
02168 float t2 = dis_old[i];
02169 dA = std::abs(pc_old_.points[inds[k]].getVector3fMap().dot(pc_old_.points[i].getVector3fMap())/(t*t2));
02170
02171 if(dA<__rmax || std::abs(t-t2)>tmax) continue;
02172
02173 float w=1/(float)weight_o[i];
02174 s+=w;
02175 po.x+=pc_old_[i].x*w;
02176 po.y+=pc_old_[i].y*w;
02177 po.z+=pc_old_[i].z*w;
02178
02179
02180 done[found[j]]=true;
02181
02182 }
02183
02184 po.x/=s;
02185 po.y/=s;
02186 po.z/=s;
02187
02188
02189 pc_o.push_back(po);
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237 }
02238 }
02239
02240 ROS_ERROR("took %f", psw.precisionStop());
02241
02242 ROS_INFO("%d -> %d",pc_old_.size(), pc_o.size());
02243
02244
02245
02246 return ::findTF(pc_old_,pc_new_);
02247 }
02248
02249
02250 Eigen::Matrix4f findTF(const pcl::PointCloud<Point> &pco, const pcl::PointCloud<Point> &pcn)
02251 {
02252 std::vector<COR_S> cors;
02253 PrecisionStopWatch psw;
02254
02255 dis_old.clear();
02256 for(int i=0; i<pco.size(); i++) {
02257 float t = pco.points[i].getVector3fMap().norm();
02258 dis_old.push_back(t);
02259 }
02260
02261 std::vector<int> weight_o, weight_n;
02262 weight_o.resize(pco.size(),0);
02263 weight_n.resize(pcn.size(),0);
02264
02265 float __rmax = std::abs(cosf(rmax));
02266 for(int i=0; i<pco.size(); i++) {
02267 float t = dis_old[i];
02268
02269 for(int j=search_sorted_vector(tv,t-tmax); j<tv.size(); j++) {
02270
02271 if( std::abs(tv[j].dis-t) < tmax) {
02272 float dA;
02273 float t2 = dis_new[tv[j].ind];
02274 dA = std::abs(pco.points[i].getVector3fMap().dot(pcn.points[tv[j].ind].getVector3fMap())/(t*t2));
02275
02276 if(dA<__rmax) continue;
02277 if((pco.points[i].getVector3fMap()-pcn.points[tv[j].ind].getVector3fMap()).squaredNorm()==0)
02278 continue;
02279
02280 COR_S c;
02281 c.ind_o = i;
02282 c.ind_n = tv[j].ind;
02283
02284 cors.push_back(c);
02285
02286 weight_o[i]++;
02287 weight_n[tv[j].ind]++;
02288 }
02289 else if(tv[j].dis-t > tmax)
02290 break;
02291 }
02292
02293 }
02294 ROS_ERROR("took %f", psw.precisionStop());
02295
02296 Eigen::Matrix4f tf=_findTF(pco, pcn, cors, rmax,tmax,M_PI*0.5, weight_o,weight_n);
02297 ROS_ERROR("took %f", psw.precisionStop());
02298
02299 std::cout<<tf<<"\n";
02300 ROS_ERROR("FINISHED!");
02301 visualize(pco,pcn, cors);
02302
02303 pcl::PointCloud<Point> tpc;
02304 pcl::transformPointCloud(pco,tpc,tf);
02305 cors.clear();
02306 visualize(tpc,pcn, cors);
02307 return tf;
02308 }
02309
02310 private:
02311 Eigen::Matrix4f _findTF(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new, std::vector<COR_S> &cors, float border_a, float border_t, float border_a2,
02312 std::vector<int> &weight_o, std::vector<int> &weight_n, const Eigen::Vector3f &prev_trans=Null3f()) {
02313
02314 Eigen::Vector3f mid_old, mid_new, mid_ob, mid_nb, mid_oa, mid_na, axis;
02315 int rem = 0;
02316
02317 GET_MIDS();
02318
02319 std::cout<<"mid_old\n"<<mid_old<<"\n";
02320 std::cout<<"mid_new\n"<<mid_new<<"\n";
02321 std::cout<<"mid_ob\n"<<mid_ob<<"\n";
02322 std::cout<<"mid_oa\n"<<mid_oa<<"\n";
02323 std::cout<<"mid_nb\n"<<mid_nb<<"\n";
02324 std::cout<<"mid_na\n"<<mid_na<<"\n";
02325
02326 axis=getAxis2(pc_old, pc_new, cors, mid_old.squaredNorm(), mid_old, mid_new, weight_o, weight_n);
02327 std::cout<<"axis\n"<<axis<<"\n";
02328 Eigen::Matrix4f tf=getTF2(axis, mid_oa,mid_ob,mid_old, mid_na,mid_nb,mid_new);
02329
02330
02331
02332 if( (tf.col(3).head<3>()).squaredNorm() > 0.04) {
02333 tf.col(3).head<3>()=tf.col(3).head<3>()*0.2/tf.col(3).head<3>().norm();
02334 }
02335
02336 bool bGoOn=false;
02337 do {
02338 std::cout<<"tmax: "<<border_t<<"\n";
02339 rem += remError(pc_old, pc_new, cors, tf, border_a, border_t, weight_o,weight_n);
02340
02341 border_a*=0.5f;
02342 border_t*=0.5f;
02343 border_a2*=0.5f;
02344
02345 bGoOn = border_t>0.01&&cors.size()>std::min(pc_new.size(),pc_old.size());
02346 } while(rem<1&&bGoOn);
02347
02348 if(bGoOn)
02349 return _findTF(pc_old,pc_new,cors, border_a, border_t, border_a2, weight_o, weight_n, tf.col(3).head<3>() );
02350
02351 GET_MIDS();
02352 axis=getAxis2(pc_old, pc_new, cors, mid_old.squaredNorm(), mid_old, mid_new, weight_o, weight_n);
02353 tf=getTF2(axis, mid_oa,mid_ob,mid_old, mid_na,mid_nb,mid_new);
02354
02355 return tf;
02356 }
02357
02358 int remError(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
02359 std::vector<COR_S> &cors, const Eigen::Matrix4f &tf, const float border_a, const float border_t, std::vector<int> &weight_o,std::vector<int> &weight_n) {
02360 int n=0;
02361 for(int i=0; i<cors.size(); i++) {
02362 Eigen::Vector4f v=(tf*pc_old[cors[i].ind_o].getVector4fMap());
02363 Eigen::Vector4f v2=pc_new[cors[i].ind_n].getVector4fMap();
02364
02365 float dT = std::abs(v.norm()-v2.norm());
02366 float dA = acosf(v.dot(v2)/(v.norm()*v2.norm()));
02367
02368 if( dA>border_a || dT>border_t ) {
02369 weight_o[cors[i].ind_o]--;
02370 weight_n[cors[i].ind_n]--;
02371
02372 std::swap(cors[i],cors.back());
02373 cors.resize(cors.size()-1);
02374 --i;
02375 ++n;
02376 }
02377 }
02378
02379 return n;
02380 }
02381
02382 Eigen::Matrix4f getTF2(const Eigen::Vector3f &axis, const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &p_s, const Eigen::Vector3f &p1n, const Eigen::Vector3f &p2n, const Eigen::Vector3f &pn_s) {
02383 Eigen::Quaternionf q;
02384
02385 Eigen::Vector3f Z, a,b;
02386 Z(0)=0;
02387 Z(1)=0;
02388 Z(2)=1;
02389
02390 a=p1-p2;
02391 b=p1n-p2n;
02392
02393 a = a.cross(axis);
02394 b = b.cross(axis);
02395
02396 a.normalize();
02397 b.normalize();
02398
02399 float angle = acos(a.dot(b));
02400
02401 Eigen::AngleAxisf rot(angle, axis);
02402
02403 Eigen::Matrix3f R=rot.toRotationMatrix();
02404
02405 Eigen::Vector3f t=pn_s-R*p_s;
02406
02407 Eigen::Matrix4f transf = Eigen::Matrix4f::Identity();
02408 for(int x=0; x<3; x++)
02409 for(int y=0; y<3; y++)
02410 transf(x,y) = R(x,y);
02411 transf.col(3).head<3>() = t;
02412
02413 return transf;
02414 }
02415
02416 Eigen::Vector3f getAxis2(const pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new,
02417 const std::vector<COR_S> &cors, const float max_dis,
02418 const Eigen::Vector3f &rel_old, const Eigen::Vector3f &rel_new
02419 , std::vector<int> &weight_o,std::vector<int> &weight_n) {
02420 Eigen::Vector3f m[4];
02421 int g[4]={};
02422
02423 m[0] = Null3f();
02424 m[1] = Null3f();
02425 m[2] = Null3f();
02426 m[3] = Null3f();
02427
02428 Eigen::Vector3f X,Y;
02429
02430 X(0)=1;
02431 X(1)=X(2)=0;
02432 Y(1)=1;
02433 Y(2)=Y(0)=0;
02434
02435 X=rel_old.cross(X);
02436 Y=rel_old.cross(Y);
02437
02438 for(int i=0; i<cors.size(); i++) {
02439 Eigen::Vector3f v,vp;
02440
02441 v =pc_old[cors[i].ind_o].getVector3fMap();
02442 vp=pc_new[cors[i].ind_n].getVector3fMap();
02443
02444 v -=rel_old;
02445 vp-=rel_new;
02446
02447 int q=0;
02448
02449 q+=v.dot(X)>0?1:0;
02450 q+=v.dot(Y)<0?2:0;
02451
02452 v=vp-v;
02453
02454
02455 if(pc_old[cors[i].ind_o].getVector3fMap().squaredNorm()<rel_old.squaredNorm()) v=-v;
02456
02457
02458 m[q]+=v;
02459 g[q]++;
02460
02461 }
02462
02463 m[0]/=g[0];
02464 m[1]/=g[1];
02465 m[2]/=g[2];
02466 m[3]/=g[3];
02467
02468 std::cout<<"m[0]\n"<<m[0]<<"\n";
02469 std::cout<<"m[1]\n"<<m[1]<<"\n";
02470 std::cout<<"m[2]\n"<<m[2]<<"\n";
02471 std::cout<<"m[3]\n"<<m[3]<<"\n";
02472
02473 Eigen::Vector3f axis, axis2;
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496 Eigen::Vector3f ax,ay,az;
02497 ax=(m[0]+m[1]).cross(m[2]+m[3]);
02498 ay=(m[0]+m[2]).cross(m[1]+m[3]);
02499 az=(m[0]-m[3]).cross(m[1]-m[3]);
02500
02501 ax.normalize();
02502 ay.normalize();
02503 az.normalize();
02504
02505 axis(0) = std::abs( ax(0) );
02506 axis(1) = std::abs( ay(1) );
02507 axis(2) = std::abs( az(2) );
02508
02509 axis.normalize();
02510
02511 if( m[0](1)+m[1](1)+m[2](1)+m[3](1) > 0)
02512 axis(0) = -axis(0);
02513 if( m[0](0)+m[1](0)+m[2](0)+m[3](0) < 0)
02514 axis(1) = -axis(1);
02515 if( m[0](0)*m[0](1)+m[3](0)*m[3](1) - m[1](0)*m[1](1)-m[2](0)*m[2](1)
02516 < 0)
02517 axis(2) = -axis(2);
02518
02519 return axis;
02520 }
02521 };
02522
02523 Eigen::Matrix4f findCorr3_tf(const pcl::PointCloud<MY_POINT> &pc_old, const pcl::PointCloud<MY_POINT> &pc_new, std::vector<int> inds_old, std::vector<int> inds, const int i_sz_old, const int i_sz) {
02524 if(!i_sz_old||!i_sz)
02525 return Eigen::Matrix4f::Identity();
02526
02527 Eigen::Vector3f mid_s1=pc_old.points[inds_old[0]].getVector3fMap();
02528 Eigen::Vector3f mid_t1=pc_new.points[inds[0]].getVector3fMap();
02529 float mi_s=10000,mi_t=100000, ma_s=0, ma_t=0;
02530 for(int i=1; i<i_sz_old; i++) {
02531
02532 if(!pcl_isfinite(pc_old.points[inds_old[i]].z))
02533 ROS_ERROR("fuck");
02534
02535 mid_s1+=pc_old.points[inds_old[i]].getVector3fMap();
02536 mi_s=std::min(mi_s,pc_old.points[inds_old[i]].z);
02537 ma_s=std::max(ma_s,pc_old.points[inds_old[i]].z);
02538 }
02539 for(int i=1; i<i_sz; i++) {
02540
02541 if(!pcl_isfinite(pc_new.points[inds[i]].z))
02542 ROS_ERROR("fuck");
02543
02544 mid_t1+=pc_new.points[inds[i]].getVector3fMap();
02545 mi_t=std::min(mi_t,pc_new.points[inds[i]].z);
02546 ma_t=std::max(ma_t,pc_new.points[inds[i]].z);
02547 }
02548
02549 ROS_INFO("num %d %d", i_sz_old,i_sz);
02550
02551 mid_s1/=i_sz_old;
02552 mid_t1/=i_sz;
02553
02554 std::cout<<"mt1\n"<<mid_t1<<"\n";
02555 std::cout<<"ms1\n"<<mid_s1<<"\n";
02556
02557 Eigen::Vector3f mid_s, mid_t, mid_s2, mid_t2;
02558
02559 mid_s(0)=mid_s(1)=mid_s(2)=0;
02560
02561 mid_t=mid_t2=mid_s2=mid_s;
02562
02563 int n1=0,n2=0;
02564 for(int i=0; i<i_sz_old; i++) {
02565 if(inds_old[i]>=pc_old.size())
02566 ROS_INFO("oh man");
02567
02568
02569 if(mid_s1.squaredNorm()<pc_old.points[inds_old[i]].getVector3fMap().squaredNorm()) {
02570 mid_s+=pc_old.points[inds_old[i]].getVector3fMap();
02571 n1++;
02572 }
02573 else {
02574 mid_s2+=pc_old.points[inds_old[i]].getVector3fMap();
02575 n2++;
02576 }
02577 }
02578 mid_s/=n1;
02579 mid_s2/=n2;
02580
02581 std::cout<<"n1\n"<<n1<<"\n";
02582 std::cout<<"n2\n"<<n2<<"\n";
02583 std::cout<<"ms\n"<<mid_s<<"\n";
02584 std::cout<<"ms2\n"<<mid_s2<<"\n";
02585
02586 if(!n1||!n2) return Eigen::Matrix4f::Identity();
02587
02588 n1=0,n2=0;
02589 for(int i=0; i<i_sz; i++) {
02590 if(inds[i]>=pc_new.size())
02591 ROS_INFO("oh man");
02592 if(mid_s1.squaredNorm()<pc_new.points[inds[i]].getVector3fMap().squaredNorm()) {
02593 mid_t+=pc_new.points[inds[i]].getVector3fMap();
02594 n1++;
02595 }
02596 else {
02597 mid_t2+=pc_new.points[inds[i]].getVector3fMap();
02598 n2++;
02599 }
02600 }
02601 mid_t/=n1;
02602 mid_t2/=n2;
02603
02604 Eigen::Matrix3f R;
02605
02606 std::cout<<"mt\n"<<mid_t<<"\n";
02607 std::cout<<"mt2\n"<<mid_t2<<"\n";
02608 std::cout<<"n1\n"<<n1<<"\n";
02609 std::cout<<"n2\n"<<n2<<"\n";
02610
02611 if(!n1||!n2) return Eigen::Matrix4f::Identity();
02612
02613 Eigen::Quaternionf q;
02614 q.setFromTwoVectors(mid_t-mid_t2,mid_s-mid_s2);
02615 Eigen::Vector3f v;
02616 v(0)=v(1)=0;
02617 v(2)=1;
02618 v=q.toRotationMatrix()*v;
02619 ROS_INFO("v %f %f %f",v(0),v(1),v(2));
02620
02621 R=q.toRotationMatrix();
02622
02623 Eigen::Vector3f t;
02624
02625
02626
02627
02628
02629 t=mid_t1-R*mid_s1;
02630
02631 Eigen::Matrix4f transf = Eigen::Matrix4f::Identity();
02632 for(int x=0; x<3; x++)
02633 for(int y=0; y<3; y++)
02634 transf(x,y) = R(x,y);
02635 transf.col(3).head<3>() = t;
02636
02637 std::cout<<(mid_s1-R*mid_t1)<<"\n";
02638 std::cout<<(mid_t1-R*mid_s1)<<"\n";
02639 std::cout<<transf<<"\n";
02640
02641 boost::shared_ptr<pcl::KdTree<MY_POINT> > tree (new pcl::KdTreeFLANN<MY_POINT>);
02642 tree->setInputCloud (pc_new.makeShared());
02643 boost::shared_ptr<pcl::KdTree<MY_POINT> > tree2 (new pcl::KdTreeFLANN<MY_POINT>);
02644 tree2->setInputCloud (pc_old.makeShared());
02645
02646 float dis=0;
02647 int nn=0;
02648 for(int j=0; j<inds_old.size(); j++) {
02649 int i=inds_old[j];
02650
02651 std::vector< int > k_indices;
02652 std::vector< float > k_distances;
02653 MY_POINT p=pc_old[i];
02654 Eigen::Vector4f v=transf.inverse()*pc_old[i].getVector4fMap();
02655 p.x=v(0);
02656 p.y=v(1);
02657 p.z=v(2);
02658 if(!tree->nearestKSearch(p,1,k_indices,k_distances))
02659 {
02660
02661 continue;
02662 }
02663
02664 dis+= sqrtf(k_distances[0]);
02665 nn++;
02666 }
02667 dis/=nn;
02668 dis*=1.5;
02669 dis=std::max(dis,0.05f);
02670
02671 for(int j=0; j<inds_old.size(); j++) {
02672 int i=inds_old[j];
02673
02674 std::vector< int > k_indices;
02675 std::vector< float > k_distances;
02676 MY_POINT p=pc_old[i];
02677 Eigen::Vector4f v=pc_old[i].getVector4fMap();
02678 p.x=v(0);
02679 p.y=v(1);
02680 p.z=v(2);
02681 if(!tree->nearestKSearch(p,1,k_indices,k_distances))
02682 {
02683
02684 continue;
02685 }
02686
02687
02688 if(sqrtf(k_distances[0])>10) {
02689 std::cout<<"\n"<<pc_old[i].getVector3fMap()<<"("<<k_distances.size()<<")\n";
02690 std::cout<<"\n"<<pc_new[k_indices[0]].getVector3fMap()<<"\n";
02691 }
02692
02693
02694 k_distances[0] = (transf.inverse()*pc_old[i].getVector4fMap()-pc_new[k_indices[0]].getVector4fMap()).squaredNorm();
02695 if(sqrtf(k_distances[0])>dis) {
02696 inds_old.erase(inds_old.begin()+j);
02697 --j;
02698 }
02699 }
02700
02701 for(int j=0; j<inds.size(); j++) {
02702 int i=inds[j];
02703
02704 std::vector< int > k_indices;
02705 std::vector< float > k_distances;
02706 MY_POINT p=pc_new[i];
02707 Eigen::Vector4f v=pc_new[i].getVector4fMap();
02708 p.x=v(0);
02709 p.y=v(1);
02710 p.z=v(2);
02711 if(!tree2->nearestKSearch(p,1,k_indices,k_distances))
02712 {
02713
02714 continue;
02715 }
02716
02717 k_distances[0] = (transf*pc_new[i].getVector4fMap()-pc_old[k_indices[0]].getVector4fMap()).squaredNorm();
02718 if(sqrtf(k_distances[0])>dis) {
02719 inds.erase(inds.begin()+j);
02720 --j;
02721 }
02722 }
02723
02724 ROS_INFO("--> %d %d %f", inds_old.size(), i_sz_old, dis);
02725
02726 getchar();
02727
02728
02729
02730 if( inds_old.size() != i_sz_old && dis>0.06)
02731 return findCorr3_tf(pc_new,pc_old, inds,inds_old, inds.size(),inds_old.size()).inverse();
02732
02733 return transf;
02734 }
02735
02736 class TestNode
02737 {
02738 #ifdef RGB_
02739 typedef pcl::PointXYZRGB Point;
02740 #else
02741 typedef pcl::PointXYZ Point;
02742 #endif
02743
02744 static void eigen2point(Point &p, const Eigen::Vector3f &e) {
02745 p.x = e(0);
02746 p.y = e(1);
02747 p.z = e(2);
02748 }
02749
02750 static void point2eigen(Eigen::Vector3f &e, const Point &p) {
02751 e(0) = p.x;
02752 e(1) = p.y;
02753 e(2) = p.z;
02754 }
02755
02756 static void point2eigen(Eigen::VectorXf &e, const Point &p) {
02757 e(0) = p.x;
02758 e(1) = p.y;
02759 e(2) = p.z;
02760 }
02761
02762 static void point2eigen(Eigen::Vector4f &e, const Point &p) {
02763 e(0) = p.x;
02764 e(1) = p.y;
02765 e(2) = 0;
02766 e(3) = 0;
02767 }
02768
02769
02770 struct Polyline {
02771 std::vector<Eigen::Vector4f> pl;
02772 float area_;
02773
02774 void findPolyline(pcl::PointCloud<Point> pc) {
02775
02776 pcl::VoxelGrid<Point> voxel;
02777 voxel.setInputCloud(pc.makeShared());
02778 voxel.setLeafSize(0.01,0.01,0.01);
02779 voxel.filter(pc);
02780
02781
02782 pcl::StatisticalOutlierRemoval<Point> sor;
02783 sor.setInputCloud (pc.makeShared());
02784 sor.setMeanK (10);
02785 sor.setStddevMulThresh (0.025);
02786 sor.filter (pc);
02787
02788 if(pc.points.size()<3)
02789 return;
02790
02791 if(g_step) {
02792 sensor_msgs::PointCloud2 pc_out;
02793 pcl::toROSMsg(pc,pc_out);
02794 pc_out.header = header_;
02795 point_cloud_pub_.publish(pc_out);
02796 }
02797
02798 Eigen::Vector4f mip, map, centroid;
02799
02800 pcl::getMinMax3D(pc, mip, map);
02801 pcl::compute3DCentroid(pc, centroid);
02802
02803 pl.insert(pl.end(), mip);
02804 pl.insert(pl.end(), map);
02805
02806 std::vector<bool> blacklist;
02807 blacklist.push_back(false);
02808 blacklist.push_back(false);
02809
02810
02811
02812
02813
02814 float max_dis, last_dis=10000;
02815 int iteration=0;
02816
02817 do {
02818
02819
02820
02821 std::cout<<"pl: round "<<iteration<<"\n";
02822 for(int i=0; i<pl.size(); i++) {
02823
02824 std::cout<<"pl: \t"<<pl[i](0)<<", "<<pl[i](1)<<", "<<pl[i](2)<<"\n";
02825 }
02826
02827 max_dis=-1;
02828
02829 float max_f=-1, avg = 0;
02830 int max_j, max_i=-1;
02831
02832 std::vector<int> support(pl.size(),0);
02833 std::vector<int> not_support(pl.size(),0);
02834 std::vector<int> seg_i(pl.size(),-1);
02835 std::vector<float> seg_f(pl.size(),0.f);
02836 for(int i=0; i<pc.points.size(); i++) {
02837 Eigen::Vector4f v;
02838 point2eigen(v, pc.points[i]);
02839
02840 float f=1000;
02841 int jm = -1;
02842 int found=0;
02843 for(int j=0; j<pl.size(); j++) {
02844
02845 Eigen::Vector4f m,
02846 p = v-centroid,
02847 a=pl[j]-centroid,
02848 b=(pl[ (j+1)%pl.size() ])-centroid;
02849
02850
02851
02852 p.normalize();
02853 b.normalize();
02854 a.normalize();
02855 m=(a+b)/2;
02856 m.normalize();
02857 float c = (a-m).norm();
02858
02859 if( pl.size()>2 && ((m-p).norm()>c || p.dot(m)<0 ) ) continue;
02860 found++;
02861
02862
02863
02864 float t = pcl::sqrPointToLineDistance(v,pl[j],pl[ (j+1)%pl.size() ]-pl[j]);
02865 if(t<f||jm==-1)
02866 {
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882 f=t;
02883 jm = j;
02884 }
02885 }
02886
02887 avg+=f;
02888
02889 if(jm!=-1) {
02890 if(f>0.05*0.05)
02891 not_support[jm]++;
02892 else
02893 support[jm]++;
02894 if(seg_f[jm]<f) {
02895 seg_f[jm]=f;
02896 seg_i[jm]=i;
02897 }
02898 }
02899
02900 if(f>max_f && jm!=-1 && !blacklist[jm]) {
02901 max_dis = max_f;
02902 max_f=f;
02903 max_j=jm;
02904 max_i=i;
02905 }
02906
02907 }
02908
02909 avg/=pc.size();
02910
02911 float pl_min=1000;int pl_i=-1;
02912 for(int i=0; i<pl.size(); i++) {
02913 std::cout<<"pl: \t"<<support[i]<<" "<<not_support[i]<<" -> "<<support[i]*100./not_support[i]<<"%\n";
02914 if(support[i]-10>not_support[i] && iteration>2)
02915 blacklist[i]=true;
02916 else
02917 blacklist[i]=false;
02918
02919 Eigen::Vector4f
02920 a=pl[i],
02921 b=(pl[ (i+1)%pl.size() ]);
02922 float len = (a-b).norm();
02923
02924 ROS_INFO("pl: %f %f %d %d", pl_min, (1+support[i])/(float)(not_support[i]+100)/len, seg_i[i],(int)blacklist[i]);
02925 if( pl_min> (1+support[i])/(float)(not_support[i]+100)/len && seg_i[i]!=-1 && !blacklist[i] ) {
02926
02927 pl_min=(1+support[i])/(float)(not_support[i]+100)/len;
02928 pl_i=i;
02929 }
02930 }
02931
02932 if(pl_i!=-1 && iteration>2) {
02933 max_f = seg_f[pl_i];
02934 max_i = seg_i[pl_i];
02935 max_j = pl_i;
02936 }
02937
02938 ROS_INFO("pl: dis %f %f -- %d %d", max_f, avg, max_j, pl_i);
02939 if(max_i!=-1) {
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950 if( blacklist[max_j] ) continue;
02951
02952 addPoint(pc,max_i,(max_j+1)%(pl.size()));
02953 blacklist.push_back(false);
02954 last_dis = max_f;
02955 }
02956 else
02957 break;
02958
02959
02960
02961
02962
02963
02964
02965
02966 if(iteration==1) {
02967 for(int j=0; j<pl.size(); j++) {
02968 if(pl[j]==mip||pl[j]==map) {
02969 pl.erase(pl.begin()+j);
02970 --j;
02971 }
02972 }
02973 }
02974 ++iteration;
02975
02976
02977 publishLineMarker(pl,-343);
02978 if(g_step&&getchar()=='q')
02979 exit(0);
02980
02981
02982
02983 } while(last_dis>0.01*0.01&&pl.size()<16&&pc.size()>0);
02984
02985 if(g_step&&getchar()=='q')
02986 exit(0);
02987
02988 {
02989 float avg=0;
02990 for(int i=0; i<pl.size();i++) {
02991 Eigen::Vector4f
02992 a=pl[i],
02993 b=(pl[ (i+1)%pl.size() ]);
02994 float len = (a-b).norm();
02995 avg+=len;
02996 }
02997 avg/=pl.size();
02998
02999 for(int i=0; i<pl.size();i++) {
03000 Eigen::Vector4f
03001 a=pl[i],
03002 b=(pl[ (i+1)%pl.size() ]),
03003 c=(pl[ (i+2)%pl.size() ]);
03004
03005 float len1 = (a-b).norm();
03006 float len2 = (c-b).norm();
03007
03008 if(len1+len2<avg*2) {
03009 int r = (i+1)%pl.size();
03010 pl.erase(pl.begin()+r);
03011 }
03012
03013 }
03014
03015 float area=0;
03016 for(int i=0; i<pl.size();i++) {
03017 Eigen::Vector4f
03018 a=pl[i]-centroid,
03019 b=(pl[ (i+1)%pl.size() ])-centroid;
03020
03021 area+=_4to3_(a).cross(_4to3_(b)).norm();
03022 }
03023 area*=100*100;
03024 ROS_INFO("area: %f", area);
03025
03026 area_ = area;
03027
03028 }
03029
03030 }
03031
03032 void show() {
03033 float max_alpha=-1;
03034 int offset=0;
03035 std::string r="";
03036 for(int j=0; j<pl.size(); j++) {
03037 Eigen::Vector4f a = pl[j]-pl[ (j+1)%pl.size() ];
03038 Eigen::Vector4f b = pl[ (j+1)%pl.size() ]-pl[ (j+2)%pl.size() ];
03039 if(alpha(a,b)>max_alpha) {
03040 max_alpha = alpha(a,b);
03041 offset=j;
03042 }
03043 }
03044
03045 std::cout<<"pl-info: ";
03046 for(int i=0; i<pl.size(); i++) {
03047 int j = i+offset;
03048
03049 Eigen::Vector4f a = pl[j%pl.size()]-pl[ (j+1)%pl.size() ];
03050 Eigen::Vector4f b = pl[ (j+1)%pl.size() ]-pl[ (j+2)%pl.size() ];
03051
03052 std::cout<<alpha(a,b)<<" ";
03053
03054 float t = alpha(a,b);
03055 if(t>1.7)
03056 r+="+";
03057 else if(t<1.3)
03058 r+="-";
03059 else
03060 r+="~";
03061 }
03062 std::cout<<r<<"\n";
03063
03064 }
03065
03066 float alpha(const Eigen::Vector4f &a, const Eigen::Vector4f &b) {
03067 return acosf(a.dot(b)/(a.norm()*b.norm()));
03068 }
03069
03070 bool SameSide(const Eigen::Vector3f &p1, const Eigen::Vector3f &p2, const Eigen::Vector3f &a,const Eigen::Vector3f &b) {
03071 Eigen::Vector3f cp1 = (b-a).cross(p1-a);
03072 Eigen::Vector3f cp2 = (b-a).cross(p2-a);
03073 if(cp1.dot(cp2) >= 0)
03074 return true;
03075 return false;
03076 }
03077
03078 Eigen::Vector3f _4to3_(const Eigen::Vector4f &p) {
03079 Eigen::Vector3f r;
03080 r(0)=p(0);
03081 r(1)=p(1);
03082 r(2)=p(2);
03083 return r;
03084 }
03085 bool PointInTriangle(Eigen::Vector4f &pp, Eigen::Vector4f &aa,Eigen::Vector4f &bb,Eigen::Vector4f &cc) {
03086 Eigen::Vector3f p=_4to3_(pp);
03087 Eigen::Vector3f a=_4to3_(aa);
03088 Eigen::Vector3f b=_4to3_(bb);
03089 Eigen::Vector3f c=_4to3_(cc);
03090
03091 if (SameSide(p,a, b,c) && SameSide(p,b, a,c)
03092 && SameSide(p,c, a,b) )
03093 return true;
03094 return false;
03095 }
03096
03097
03098 void resort() {
03099 std::vector<Eigen::Vector4f> t;
03100 t.push_back(pl[0]);
03101 pl.erase(pl.begin());
03102
03103 while(pl.size()) {
03104 int w=0;
03105 for(int j=1; j<pl.size(); j++) {
03106 if( (pl[w]-t.back()).norm()>(pl[j]-t.back()).norm() )
03107 w=j;
03108 }
03109
03110 t.push_back(pl[w]);
03111 pl.erase(pl.begin()+w);
03112 }
03113
03114 pl = t;
03115 }
03116
03117 void addPoint(pcl::PointCloud<Point> &pc, const int i, const int j) {
03118 Eigen::Vector4f v;
03119 point2eigen(v, pc.points[i]);
03120 pl.insert(pl.begin()+j, v);
03121 pc.points.erase(pc.points.begin()+i);
03122 }
03123
03124 };
03125
03126 struct DualFloat {
03127 float val[2];
03128 };
03129
03130 Point movement_overall;
03131 Eigen::Vector3f movement_rotation, old_t_;
03132 Eigen::Matrix3f old_q_;
03133
03134 ros::Subscriber settings_sub;
03135 bool show_labels_, show_markers_;
03136 #ifdef RECONF_
03137 dynamic_reconfigure::Server<dynamic_tutorials::serverConfig> srv;
03138 #endif
03139
03140 float min_alpha_, max_alpha_;
03141 float min_thr_;
03142 int factor_;
03143 float min_thr_factor_, min_alpha_factor_, max_alpha_factor_;
03144
03145 public:
03146
03147 TestNode():show_labels_(true), show_markers_(true),
03148 min_alpha_(0.3), max_alpha_(0.5), min_thr_(-0.01),
03149 min_thr_factor_(0.005), min_alpha_factor_(0.03), max_alpha_factor_(0.03),
03150 factor_(2)
03151 {
03152 #ifndef RGB_
03153 point_cloud_sub_ = n_.subscribe("/camera/depth/points", 1, &TestNode::pointCloudSubCallback, this);
03154 #else
03155 point_cloud_sub_ = n_.subscribe("/camera/rgb/points", 1, &TestNode::pointCloudSubCallback, this);
03156 #endif
03157 point_cloud_pub_ = n_.advertise<sensor_msgs::PointCloud2 >("point_cloud2_resized",1);
03158 map_pub_ = n_.advertise<sensor_msgs::PointCloud2 >("point_cloud_map",1);
03159 marker_pub_ = n_.advertise<visualization_msgs::Marker>("markers", 1);
03160 settings_sub = n_.subscribe<std_msgs::String>("command", 1000, &TestNode::commandCallback, this);
03161
03162
03163 old_q_ = Eigen::Matrix3f::Identity();
03164 old_t_(0)=old_t_(1)=old_t_(2)=0;
03165
03166
03167 #if 0
03168 {
03169 Eigen::Vector3f p1a,p1b, p2a, p2b;
03170
03171 p1a(0) = 1;
03172 p1a(1) = 0;
03173 p1a(2) = 0;
03174
03175 p1b(0) = 2;
03176 p1b(1) = 0;
03177 p1b(2) = 0;
03178
03179 p2a(0) = 1;
03180 p2a(1) = 1;
03181 p2a(2) = 0;
03182
03183 p2b(0) = 2;
03184 p2b(1) = 1;
03185 p2b(2) = 0;
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203 Eigen::Vector3f u = p1b-p1a, v=p2b-p2a;
03204
03205 Eigen::Quaternionf q;
03206 q.setFromTwoVectors(u,v);
03207
03208 Eigen::Vector3f t = p1b-q.toRotationMatrix()*p1a;
03209
03210 std::cout<<u<<std::endl;
03211 std::cout<<v<<std::endl;
03212 std::cout<<q.toRotationMatrix()<<std::endl;
03213 std::cout<<t<<std::endl;
03214 }
03215 exit(0);
03216 #endif
03217 }
03218
03219 void commandCallback(const std_msgs::String::ConstPtr& msg)
03220 {
03221 ROS_INFO("I heard: [%s]", msg->data.c_str());
03222
03223 }
03224
03225
03226
03227 ~TestNode()
03228 {
03230 }
03231
03232
03233 #define getInd(x, y) ((x)+(y)*pc.width)
03234
03235
03236 void
03237 pointCloudSubCallback(const sensor_msgs::PointCloud2ConstPtr& pc_in)
03238 {
03239 boost::timer _timer;
03240
03241 header_ = pc_in->header;
03242
03243 pcl::PointCloud<Point> pc;
03244 pcl::fromROSMsg(*pc_in,pc);
03245
03246
03247 static pcl::PointCloud<Point> pc_old;
03248
03249 static int snn=0;
03250 snn++;
03251 if(g_step&&snn%30) return;
03252
03253 if(pc_old.size()==pc.size())
03254 {
03255
03256 static Eigen::Matrix4f Stransf = Eigen::Matrix4f::Identity();
03257 static unsigned char *depth_map=new unsigned char[pc.height*pc.width];
03258
03259
03260 float diff1=0.03;
03261 float diff2=0.02;
03262 float diff3=0.03;
03263
03264 diff3=diff2=diff1=0.01;
03265
03266 std::vector<int> indices_pos, indices_neg;
03267
03268 memset(depth_map, 0, pc.height*pc.width);
03269 pcl::PointCloud<Point> _p;
03270 for(int y=0; y<pc.height; y++) {
03271 for(int x=0; x<pc.width; x++) {
03272
03273 int ind = getInd(x,y);
03274 Point &pn=pc.points[ind];
03275 Point &po=pc_old.points[ind];
03276
03277
03278
03279
03280 float d = pn.z-po.z;
03281 float di= std::min(pn.z, po.z);
03282 di = di*di*diff3;
03283 if(d>di) {
03284 depth_map[ind]=1;
03285 indices_pos.push_back(ind);}
03286 else if(d<-di) {
03287 depth_map[ind]=1;
03288 indices_neg.push_back(ind);
03289 }
03290
03291 Point pp=po;
03292 pp.b=pp.g=std::min(255.f,256*std::abs(d));
03293 pp.r=std::min(255.f,256*std::abs(d/di));
03294 if(d>di||d<-di)
03295 _p.push_back(pp);
03296
03297 }
03298 }
03299 {
03300 static int it=0;
03301 ++it;
03302 char buffer[128];
03303 sprintf(buffer,"_p%d.pcd",it);
03304 pcl::io::savePCDFile(buffer,_p);
03305 }
03306
03307
03308 ROS_INFO("found %d %d", indices_pos.size(), indices_neg.size());
03309 ROS_INFO("took1 %f s", _timer.elapsed());
03310
03311 if(indices_pos.size()+indices_neg.size()<1000)
03312 return;
03313
03314 std::vector<int> indices_pos2, indices_neg2;
03315 std::cout<<"INFO A: ";
03316 for(int i=0; i<indices_pos.size(); i++) {
03317 int mi;
03318 int info=getI(indices_pos[i], depth_map, pc);
03319
03320 if( info<17 && info>1) {
03321 if(getMaxDiff(pc_old, indices_pos[i])>diff2)
03322 if(makes_sense(pc_old[indices_pos[i]].z)) indices_pos2.push_back(indices_pos[i]);
03323 if(getMaxDiff2(pc, indices_pos[i], pc_old, mi)>diff2)
03324 if(makes_sense(pc[mi].z)) indices_neg2.push_back(mi);
03325 }
03326 }
03327 std::cout<<"\nINFO A: ";
03328 for(int i=0; i<indices_neg.size(); i++) {
03329 int mi;
03330 int info=getI(indices_neg[i], depth_map, pc);
03331
03332 if( info<17 && info>1 ) {
03333 if(getMaxDiff(pc, indices_neg[i])>diff2)
03334 if(makes_sense(pc[indices_neg[i]].z)) indices_neg2.push_back(indices_neg[i]);
03335 if(getMaxDiff2(pc_old, indices_neg[i], pc, mi)>diff2)
03336 if(makes_sense(pc_old[mi].z)) indices_pos2.push_back(mi);
03337 }
03338 }
03339 std::cout<<"\n";
03340 ROS_INFO("found %d %d", indices_pos2.size(), indices_neg2.size());
03341 ROS_INFO("took1.5 %f s", _timer.elapsed());
03342
03343
03344 std::vector<int> _cor_inds;
03345 float _cor_inds_qual;
03346 {
03347 pcl::PointCloud<Point> tmp_pc_old, tmp_pc_new;
03348 for(int i=0; i<indices_pos2.size(); i++) {
03349 tmp_pc_old.points.push_back(pc_old.points[indices_pos2[i]]);
03350 Point pp=tmp_pc_old[i];
03351 #ifdef RGB_
03352 pp.g=0;pp.r=255;
03353 pp.b=0;
03354 #endif
03355 _p.push_back(pp);
03356 }
03357 for(int i=0; i<indices_neg2.size(); i++) {
03358 tmp_pc_new.points.push_back(pc.points[indices_neg2[i]]);
03359 Point pp=tmp_pc_new[i];
03360 #ifdef RGB_
03361 pp.g=pp.r=0;
03362 pp.b=255;
03363 #endif
03364 _p.push_back(pp);
03365 }
03366 {
03367 static int it=0;
03368 ++it;
03369 char buffer[128];
03370 sprintf(buffer,"Op%d.pcd",it);
03371 pcl::io::savePCDFile(buffer,tmp_pc_old);
03372 sprintf(buffer,"Np%d.pcd",it);
03373 pcl::io::savePCDFile(buffer,tmp_pc_new);
03374 }
03375 {
03376 sensor_msgs::PointCloud2 pc_out;
03377
03378 pcl::toROSMsg(_p,pc_out);
03379 pc_out.header = header_;
03380 point_cloud_pub_.publish(pc_out);
03381 }
03382 #if 0
03383 tmp_pc_old.clear();
03384 Point p;
03385 for(int i=0; i<2; i++)
03386 for(int j=0; j<2; j++)
03387 for(int k=0; k<2; k++) {
03388 p.x=i;
03389 p.y=j;
03390 p.z=k;
03391 tmp_pc_old.push_back(p);
03392 }
03393 if(0){
03394 Eigen::Vector3f va,vb;
03395 va(2)=1;va(1)=0;va(0)=0;
03396 vb(2)=1;vb(1)=0.1;vb(0)=0;
03397 Eigen::Quaternionf qq;
03398 qq.setFromTwoVectors(va,vb);
03399 Eigen::Matrix4f ttt=Eigen::Matrix4f::Identity();
03400 for(int x=0; x<3; x++)
03401 for(int y=0; y<3; y++)
03402 ttt(x,y) = qq.toRotationMatrix()(x,y);
03403 pcl::transformPointCloud(tmp_pc_old,tmp_pc_new,ttt);
03404 std::cout<<"CORRECT TRANS\n"<<ttt<<"\n";
03405 }
03406
03407
03408 std::vector<int> ind_t_old, ind_t_new;
03409 for(int i=0; i<tmp_pc_old.size(); i++)ind_t_old.push_back(i);
03410 for(int i=0; i<tmp_pc_new.size(); i++)ind_t_new.push_back(i);
03411 Eigen::Matrix4f ttt=findCorr3_tf(tmp_pc_old,tmp_pc_new, ind_t_old,ind_t_new, ind_t_old.size(),ind_t_new.size());
03412
03413 Stransf=ttt*Stransf;
03414
03415 if(1) {
03416 pcl::PointCloud<pcl::PointXYZRGB> pc2;
03417 pcl::fromROSMsg(*pc_in,pc2);
03418 static pcl::PointCloud<pcl::PointXYZRGB> map_;
03419
03420 pcl::transformPointCloud(pc2,pc2,Stransf);
03421 map_.header = pc2.header;
03422 map_+=pc2;
03423
03424 pcl::VoxelGrid<pcl::PointXYZRGB> voxel;
03425 voxel.setInputCloud(map_.makeShared());
03426 voxel.setLeafSize(0.03,0.03,0.03);
03427 voxel.filter(map_);
03428
03429 sensor_msgs::PointCloud2 pc_out;
03430 pcl::toROSMsg(map_,pc_out);
03431 map_pub_.publish(pc_out);
03432 }
03433 #endif
03434
03435 #if 0
03436 std::vector<SORT_S> tv;
03437 for(int i=0; i<tmp_pc_new.size(); i++) {
03438 SORT_S s;
03439 Eigen::Vector3f v=tmp_pc_new.points[i].getArray3fMap();
03440 s.dis=v.norm();
03441 s.ind=i;
03442 tv.push_back(s);
03443 }
03444
03445 int numsR[8]={},numsT[9]={};
03446
03447 float rmax=0.1;
03448 float tmax=0.2;
03449 float m=0;
03450 for(int i=0; i<tmp_pc_old.size(); i++) {
03451 Eigen::Vector3f v=tmp_pc_old.points[i].getArray3fMap();
03452 float t = v.norm();
03453 for(int j=0; j<tv.size(); j++) {
03454 if( std::abs(tv[j].dis-t) < tmax) {
03455 float dT, dA;
03456 float d_min;
03457 getDis(tmp_pc_old.points[i].getArray3fMap(), tmp_pc_new.points[tv[j].ind].getArray3fMap(), dT, dA);
03458
03459 if(dA>=rmax) continue;
03460
03461 dA=std::max(0.f,dA);
03462 numsT[ (int)((tv[j].dis-t+tmax)/(2*tmax)*9) ]++;
03463 numsR[ (int)(dA/rmax*8) ]++;
03464 m++;
03465 }
03466 }
03467 }
03468
03469 for(int i=0; i<9; i++)
03470 std::cout<<(i-4.5)*tmax/(4.5)<<" \t";
03471 std::cout<<"\nts:\n";
03472 for(int i=0; i<9; i++)
03473 std::cout<<(int)(numsT[i]/m*100)<<" \t";
03474 std::cout<<"\n";
03475 for(int i=0; i<8; i++)
03476 std::cout<<(i)*rmax/(8)<<" \t";
03477 std::cout<<"\nrs:\n";
03478 for(int i=0; i<8; i++)
03479 std::cout<<(int)(numsR[i]/m*100)<<" \t";
03480 std::cout<<"\n";
03481
03482 float ges=1;
03483 int best=7;
03484 for(;best>0; best--) {
03485 if(ges-numsR[best]/m<0.2)
03486 break;
03487 ges-=numsR[best]/m;
03488 }
03489 std::cout<<"best rot: "<<best<<"\n";
03490
03491 best=numsT[0]/m;
03492 best=0;
03493 for(int i=1; i<9; i++)
03494 {
03495 if(best<numsT[i]/m) {
03496 best=numsT[i]/m;
03497 best=i;
03498 }
03499 }
03500 std::cout<<"best trans: "<<best<<"\n";
03501
03502 float min_t=(best-4.5)*tmax/(4.5);
03503 float max_t=(best+1-4.5)*tmax/(4.5);
03504
03505 m=0;
03506 for(int i=0; i<8; i++)numsR[i]=0;
03507
03508 std::vector<int> inds_A, inds_B;
03509
03510 for(int i=0; i<tmp_pc_old.size(); i++) {
03511
03512 Eigen::Vector3f v=tmp_pc_old.points[i].getArray3fMap();
03513 float t = v.norm();
03514 for(int j=0; j<tv.size(); j++) {
03515 if( (int)((tv[j].dis-t+tmax)/(2*tmax)*9) == best) {
03516 float dT, dA;
03517 float d_min;
03518 getDis(tmp_pc_old.points[i].getArray3fMap(), tmp_pc_new.points[tv[j].ind].getArray3fMap(), dT, dA);
03519
03520 if(dA>=rmax) continue;
03521
03522 dA=std::max(0.f,dA);
03523 numsR[ (int)(dA/rmax*8) ]++;
03524 m++;
03525
03526 inds_A.push_back(i);
03527 inds_B.push_back(tv[j].ind);
03528
03529 }
03530 }
03531 }
03532
03533 ROS_INFO("num %d",m);
03534
03535 findCorr3_tf(tmp_pc_old,tmp_pc_new,inds_A, inds_B, inds_A.size(), inds_B.size());
03536
03537 for(int i=0; i<8; i++)
03538 std::cout<<(i)*rmax/(8)<<" \t";
03539 std::cout<<"\nrs:\n";
03540 for(int i=0; i<8; i++)
03541 std::cout<<(int)(numsR[i]/m*100)<<" \t";
03542 std::cout<<"\n";
03543
03544 ges=1;
03545 best=7;
03546 for(;best>0; best--) {
03547 if(ges-numsR[best]/m<0.2)
03548 break;
03549 ges-=numsR[best]/m;
03550 }
03551 std::cout<<"best rot: "<<best<<"\n";
03552 #endif
03553
03554 #if 0
03555
03556
03557 pcl::IterativeClosestPoint<Point,Point> icp;
03558
03559 icp.setInputCloud( tmp_pc_new.makeShared());
03560
03561 icp.setInputTarget(tmp_pc_old.makeShared());
03562 icp.setMaximumIterations(50);
03563 icp.setRANSACOutlierRejectionThreshold(0.02);
03564 icp.setMaxCorrespondenceDistance(0.1);
03565 icp.setTransformationEpsilon (0.00001);
03566
03567 pcl::PointCloud<Point> result;
03568 icp.align(result);
03569
03570 Eigen::Matrix4f transf = icp.getFinalTransformation();
03571
03572 Stransf=transf*Stransf;
03573
03574 if(rand()%3==0) {
03575 pcl::PointCloud<pcl::PointXYZRGB> pc2;
03576 pcl::fromROSMsg(*pc_in,pc2);
03577 static pcl::PointCloud<pcl::PointXYZRGB> map_;
03578
03579 pcl::transformPointCloud(pc2,pc2,Stransf);
03580 map_.header = pc2.header;
03581 map_+=pc2;
03582
03583 pcl::VoxelGrid<pcl::PointXYZRGB> voxel;
03584 voxel.setInputCloud(map_.makeShared());
03585 voxel.setLeafSize(0.03,0.03,0.03);
03586 voxel.filter(map_);
03587
03588 sensor_msgs::PointCloud2 pc_out;
03589 pcl::toROSMsg(map_,pc_out);
03590 map_pub_.publish(pc_out);
03591 }
03592 }
03593
03594 #else
03595
03596 pcl::PointCloud<Point> source, target;
03597
03598 #if USE_SMART_GRID_
03599 #elif 1
03600
03601 if(tmp_pc_new.size()<tmp_pc_old.size())
03602 ROS_INFO("new method %f", _cor_inds_qual=findCorr(tmp_pc_old, tmp_pc_new, _cor_inds));
03603 else
03604 ROS_INFO("new method %f", _cor_inds_qual=findCorr(tmp_pc_new, tmp_pc_old, _cor_inds));
03605 ROS_INFO("took1.6 %f s", _timer.elapsed());
03606
03607 if(_cor_inds_qual<0.45f)
03608 return;
03609
03610 if(tmp_pc_new.size()<tmp_pc_old.size()) {
03611 for(int i=0; i<_cor_inds.size(); i++)
03612 if( _cor_inds[i]!=-1 ) {
03613 source.points.push_back(tmp_pc_old.points[i]);
03614 target.points.push_back(tmp_pc_new.points[_cor_inds[i]]);
03615 }
03616 }
03617 else {
03618 for(int i=0; i<_cor_inds.size(); i++)
03619 if( _cor_inds[i]!=-1 ) {
03620 source.points.push_back(tmp_pc_old.points[_cor_inds[i]]);
03621 target.points.push_back(tmp_pc_new.points[i]);
03622 }
03623 }
03624 #else
03625 {
03626
03627
03628 typedef typename pcl::SampleConsensusModelRegistration<Point>::Ptr SampleConsensusModelRegistrationPtr;
03629 SampleConsensusModelRegistrationPtr model;
03630 model.reset (new pcl::SampleConsensusModelRegistration<Point> (tmp_pc_new.makeShared ()));
03631
03632 model->setInputTarget (tmp_pc_old.makeShared());
03633
03634 pcl::RandomSampleConsensus<Point> sac (model, 0.02);
03635 sac.setMaxIterations (1000);
03636
03637
03638 if (!sac.computeModel ())
03639 {
03640 return;
03641 }
03642 else
03643 {
03644 std::vector<int> inliers;
03645
03646 sac.getInliers (inliers);
03647
03648 for (size_t i = 0; i < inliers.size (); ++i) {
03649 source.points.push_back(tmp_pc_old.points[i]);
03650 target.points.push_back(tmp_pc_new.points[inliers[i]]);
03651 }
03652
03653 }
03654 }
03655 #endif
03656
03657 for(int i=0; i<source.size(); i++) {
03658 publishLineMarker(source.points[i].getVector3fMap(), target.points[i].getVector3fMap(), -i);
03659 }
03660 if(g_step) return;
03661
03662 ROS_INFO("final size %d", source.size());
03663
03664
03665
03666 ROS_INFO("error before %f", calc_error(source, target));
03667 Eigen::Matrix4f transf=Eigen::Matrix4f::Identity();
03668 #if USE_SMART_GRID_
03669
03670
03671 if(!pcl_isfinite(transf(0,0)))
03672 return;
03673
03674 #elif USE_LM
03675 pcl::registration::TransformationEstimationLM<Point, Point> estimate;
03676
03677 estimate.estimateRigidTransformation(target,source, transf);
03678 #elif USE_TF
03679 if(!source.size()) return;
03680
03681 Eigen::Vector3f mid_s1=source.points[0].getVector3fMap();
03682 Eigen::Vector3f mid_t1=target.points[0].getVector3fMap();
03683 for(int i=1; i<source.size(); i++) {
03684 mid_s1+=source.points[i].getVector3fMap();
03685 mid_t1+=target.points[i].getVector3fMap();
03686 }
03687 mid_s1/=source.size();
03688 mid_t1/=target.size();
03689
03690 Eigen::Vector3f mid_s=source.points[0].getVector3fMap();
03691 Eigen::Vector3f mid_t=target.points[0].getVector3fMap();
03692
03693 Eigen::Vector3f mid_s2=source.points[source.size()-1].getVector3fMap();
03694 Eigen::Vector3f mid_t2=target.points[source.size()-1].getVector3fMap();
03695
03696 int n1=0,n2=0;
03697 for(int i=0; i<source.size(); i++) {
03698 if(mid_s1.squaredNorm()<source.points[i].getVector3fMap().squaredNorm()) {
03699 mid_s+=source.points[i].getVector3fMap();
03700 mid_t+=target.points[i].getVector3fMap();
03701 n1++;
03702 }
03703 else {
03704 mid_s2+=source.points[i].getVector3fMap();
03705 mid_t2+=target.points[i].getVector3fMap();
03706 n2++;
03707 }
03708 }
03709 mid_s/=n1;
03710 mid_t/=n1;
03711 mid_s2/=n2;
03712 mid_t2/=n2;
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749 Eigen::Matrix3f R;
03750
03751
03752
03753
03754 {
03755 Eigen::Quaternionf q;
03756 q.setFromTwoVectors(mid_t-mid_t2,mid_s-mid_s2);
03757 Eigen::Vector3f v;
03758 v(0)=v(1)=0;
03759 v(2)=1;
03760 v=q.toRotationMatrix()*v;
03761
03762
03763 ROS_INFO("angular distance %f", q.angularDistance(Eigen::Quaternionf::Identity()));
03764
03765 R=q.toRotationMatrix();
03766 }
03767
03768 Eigen::Vector3f t;
03769 t(0)=t(1)=t(2)=0.f;
03770
03771 for(int i=0; i<source.size(); i++) {
03772 t+=source.points[i].getVector3fMap()-R*target.points[i].getVector3fMap();
03773 }
03774 t/=source.size();
03775
03776 for(int x=0; x<3; x++)
03777 for(int y=0; y<3; y++)
03778 transf(x,y) = R(x,y);
03779 transf.col(3).head<3>() = t;
03780
03781 transf=getTF(mid_t,mid_t2,mid_s,mid_s2);
03782
03783 pcl::transformPointCloud(source,source,transf);
03784 #else
03785 int num_it=0;
03786 for(int i=0; i<150; i++) {
03787 pcl::PointCloud<Point> s, t;
03788 for(int j=0; j<10; j++) {
03789 int r=rand()%source.size();
03790 s.points.push_back( source.points[r] );
03791 t.points.push_back( target.points[r] );
03792 }
03793 float e1,e2;
03794 e1=calc_error(source, target);
03795
03796 Eigen::Matrix4f tr;
03797 pcl::estimateRigidTransformationSVD(t,s, tr);
03798
03799 t=target;
03800 pcl::transformPointCloud(t,t,tr);
03801 e2=calc_error(source, t);
03802 if(e2<e1) {
03803 transf=transf*tr;
03804 target=t;
03805 }
03806
03807 }
03808 #endif
03809 ROS_INFO("error after %f", calc_error(source, target));
03810
03811 std::cout<<transf<<"\n";
03812 Stransf=transf*Stransf;
03813
03814 if(rand()%4==0) {
03815 pcl::PointCloud<pcl::PointXYZRGB> pc2;
03816 pcl::fromROSMsg(*pc_in,pc2);
03817 static pcl::PointCloud<pcl::PointXYZRGB> map_;
03818
03819 pcl::transformPointCloud(pc2,pc2,Stransf);
03820 map_.header = pc2.header;
03821 map_+=pc2;
03822
03823 pcl::VoxelGrid<pcl::PointXYZRGB> voxel;
03824 voxel.setInputCloud(map_.makeShared());
03825 voxel.setLeafSize(0.03,0.03,0.03);
03826 voxel.filter(map_);
03827
03828 sensor_msgs::PointCloud2 pc_out;
03829 pcl::toROSMsg(map_,pc_out);
03830 map_pub_.publish(pc_out);
03831 }
03832 }
03833 #endif
03834 #if 0
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858 std::vector<int> try_pos, try_neg;
03859 std::vector<int> try_posC, try_negC;
03860 std::vector<int> tmp_try_posC, tmp_try_negC;
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883 ROS_INFO("edges %d %d", try_pos.size(), try_neg.size());
03884
03885
03886
03887
03888
03889
03890 if(indices_pos2.size()<indices_neg2.size()) {
03891 try_pos=indices_pos2;
03892
03893 pcl::PointCloud<Point> pc_new;
03894 for(int i=0; i<indices_neg2.size(); i++) {
03895 pc_new.points.push_back(pc.points[indices_neg2[i]]);
03896 }
03897
03898 pc_new.height=1;
03899 pc_new.width=pc_new.size();
03900 pcl::KdTree<Point>::Ptr tree (new pcl::KdTreeFLANN<Point>);
03901 tree->setInputCloud (pc_new.makeShared());
03902
03903 for(int i=0; i<indices_pos2.size(); i++) {
03904 std::vector< int > k_indices;
03905 std::vector< float > k_distances;
03906 tree->nearestKSearch(pc_old.points[indices_pos2[i]],1,k_indices,k_distances);
03907 if(k_distances[0]<0.2)
03908 try_posC.push_back(indices_neg2[k_indices[0]]);
03909 else
03910 try_posC.push_back(-1);
03911 }
03912 }
03913 else {
03914 try_neg=indices_neg2;
03915
03916 pcl::PointCloud<Point> pc_new;
03917 for(int i=0; i<indices_pos2.size(); i++) {
03918 pc_new.points.push_back(pc_old.points[indices_pos2[i]]);
03919 }
03920
03921 pc_new.height=1;
03922 pc_new.width=pc_new.size();
03923 pcl::KdTree<Point>::Ptr tree (new pcl::KdTreeFLANN<Point>);
03924 tree->setInputCloud (pc_new.makeShared());
03925
03926 for(int i=0; i<indices_neg2.size(); i++) {
03927 std::vector< int > k_indices;
03928 std::vector< float > k_distances;
03929 tree->nearestKSearch(pc.points[indices_neg2[i]],1,k_indices,k_distances);
03930 if(k_distances[0]<0.2)
03931 try_negC.push_back(indices_pos2[k_indices[0]]);
03932 else
03933 try_negC.push_back(-1);
03934 }
03935 }
03936
03937
03938 Eigen::Vector3f m_new, m_old;
03939 m_old(0)=m_old(1)=m_old(2)=0;
03940 m_new=m_old;
03941
03942
03943 int found_p=0;
03944 for(int i=0; i<try_posC.size(); i++)
03945 if( try_posC[i]!=-1 ) {
03946 m_old+=pc_old.points[try_pos[i]].getVector3fMap();
03947 m_new+=pc.points[try_posC[i]].getVector3fMap();
03948 found_p++;
03949 pc.points[try_posC[i]].r=255;
03950 pc.points[try_posC[i]].g=0;
03951 pc.points[try_posC[i]].b=0;
03952 pc_old.points[try_pos[i]].r=0;
03953 pc_old.points[try_pos[i]].g=0;
03954 pc_old.points[try_pos[i]].b=255;
03955 _p.points.push_back(pc_old.points[try_pos[i]]);
03956 _p.points.push_back(pc.points[try_posC[i]]);
03957 }
03958 int found_n=0;
03959 for(int i=0; i<try_negC.size(); i++)
03960 if( try_negC[i]!=-1 ) {
03961 m_old+=pc_old.points[try_negC[i]].getVector3fMap();
03962 m_new+=pc.points[try_neg[i]].getVector3fMap();
03963 found_n++;
03964 pc.points[try_neg[i]].r=255;
03965 pc.points[try_neg[i]].g=0;
03966 pc.points[try_neg[i]].b=0;
03967 pc_old.points[try_negC[i]].r=0;
03968 pc_old.points[try_negC[i]].g=0;
03969 pc_old.points[try_negC[i]].b=255;
03970 _p.points.push_back(pc.points[try_neg[i]]);
03971 _p.points.push_back(pc_old.points[try_negC[i]]);
03972 }
03973 ROS_INFO("edges match %d %d", found_p, found_n);
03974 ROS_INFO("took2 %f s", _timer.elapsed());
03975
03976 m_new/=found_n+found_p;
03977 m_old/=found_p+found_n;
03978
03979 std::cout<<m_new<<"\n";
03980 std::cout<<m_old<<"\n";
03981
03982 {
03983 sensor_msgs::PointCloud2 pc_out;
03984
03985 pcl::toROSMsg(_p,pc_out);
03986 pc_out.header = header_;
03987 point_cloud_pub_.publish(pc_out);
03988 }
03989 if(g_step&&0) {
03990 sensor_msgs::PointCloud2 pc_out;
03991 pcl::toROSMsg(pc_old,pc_out);
03992 map_pub_.publish(pc_out);
03993 return;
03994 }
03995
03996 tmp_try_posC=try_posC;
03997 tmp_try_negC=try_negC;
03998 for(int iteration=0; iteration<100; iteration++) {
03999 if(iteration==99)
04000 return;
04001
04002 try_posC=tmp_try_posC;
04003 try_negC=tmp_try_negC;
04004
04005 Eigen::Vector3f pos_new, pos_old;
04006
04007 if(try_posC.size()>0) {
04008 int i;
04009 while(try_posC.size()) {
04010 i=rand()%try_posC.size();
04011 if(try_posC[i]==-1) continue;
04012 m_old=pc_old.points[try_pos[i]].getVector3fMap();
04013 m_new=pc.points[try_posC[i]].getVector3fMap();
04014 break;
04015 }
04016 while(try_posC.size()) {
04017 i=rand()%try_posC.size();
04018 if(try_posC[i]==-1) continue;
04019 pos_old=pc_old.points[try_pos[i]].getVector3fMap();
04020 pos_new=pc.points[try_posC[i]].getVector3fMap();
04021 break;
04022 }
04023 }
04024 else if(try_negC.size()>0){
04025 int i;
04026 while(try_negC.size()) {
04027 i=rand()%try_negC.size();
04028 if(try_negC[i]==-1) continue;
04029 m_old=pc_old.points[try_negC[i]].getVector3fMap();
04030 m_new=pc.points[try_neg[i]].getVector3fMap();
04031 break;
04032 }
04033 while(try_negC.size()) {
04034 i=rand()%try_negC.size();
04035 if(try_negC[i]==-1) continue;
04036 pos_old=pc_old.points[try_negC[i]].getVector3fMap();
04037 pos_new=pc.points[try_neg[i]].getVector3fMap();
04038 break;
04039 }
04040 }
04041
04042 std::vector<float> dis_trans, dis_rot;
04043
04044 for(int i=0; i<try_posC.size(); i++)
04045 if( try_posC[i]!=-1 ) {
04046 Eigen::Vector3f C =pc_old.points[try_pos[i]].getVector3fMap();
04047 Eigen::Vector3f S =pc.points[try_posC[i]].getVector3fMap();
04048
04049
04050
04051
04052 if( std::abs((S-m_new).squaredNorm()-(C-m_old).squaredNorm())>0.015 ) {
04053 try_posC[i]=-1;
04054 continue;
04055 }
04056
04057 float delta_trans = std::abs(C.norm()-S.norm()),
04058 delta_rot = acosf(C.dot(S)/(C.norm()*S.norm()));
04059
04060 dis_trans.push_back(delta_trans);
04061 dis_rot.push_back(delta_rot);
04062 }
04063
04064 for(int i=0; i<try_negC.size(); i++)
04065 if( try_negC[i]!=-1 ) {
04066 Eigen::Vector3f C =pc_old.points[try_negC[i]].getVector3fMap();
04067 Eigen::Vector3f S =pc.points[try_neg[i]].getVector3fMap();
04068
04069
04070
04071
04072 if( std::abs((S-m_new).squaredNorm()-(C-m_old).squaredNorm())>0.015 ) {
04073 try_negC[i]=-1;
04074 continue;
04075 }
04076
04077 float delta_trans = std::abs(C.norm()-S.norm()),
04078 delta_rot = acosf(C.dot(S)/(C.norm()*S.norm()));
04079
04080 dis_trans.push_back(delta_trans);
04081 dis_rot.push_back(delta_rot);
04082 }
04083 ROS_INFO("final size %d %f", dis_trans.size(), dis_trans.size()/(float)(try_posC.size()+try_negC.size()));
04084
04085 if(dis_trans.size()<0.3*(try_posC.size()+try_negC.size()))
04086 continue;
04087
04088 std::sort(dis_trans.begin(),dis_trans.end());
04089 std::sort(dis_rot.begin(),dis_rot.end());
04090
04091
04092
04093
04094
04095 float bo_t=dis_trans[dis_trans.size()*5/6], bo_r=dis_rot[dis_rot.size()*5/6];
04096
04097
04098
04099
04100
04101
04102
04103
04104 if(dis_trans.size()>0)
04105 ROS_INFO("mean %f %f", bo_t, bo_r);
04106
04107 if(bo_t>0.2)
04108 return;
04109
04110 pcl::PointCloud<Point> source, target;
04111
04112 for(int i=0; i<try_posC.size(); i++)
04113 if( try_posC[i]!=-1 ) {
04114 Eigen::Vector3f C =pc_old.points[try_pos[i]].getVector3fMap();
04115 Eigen::Vector3f S =pc.points[try_posC[i]].getVector3fMap();
04116
04117 float delta_trans = std::abs(C.norm()-S.norm()),
04118 delta_rot = acosf(C.dot(S)/(C.norm()*S.norm()));
04119
04120 {
04121 source.points.push_back(pc_old.points[try_pos[i]]);
04122 target.points.push_back(pc.points[try_posC[i]]);
04123 }
04124 }
04125
04126 for(int i=0; i<try_negC.size(); i++)
04127 if( try_negC[i]!=-1 ) {
04128 Eigen::Vector3f C =pc_old.points[try_negC[i]].getVector3fMap();
04129 Eigen::Vector3f S =pc.points[try_neg[i]].getVector3fMap();
04130 float delta_trans = std::abs(C.norm()-S.norm()),
04131 delta_rot = acosf(C.dot(S)/(C.norm()*S.norm()));
04132
04133 {
04134 source.points.push_back(pc_old.points[try_negC[i]]);
04135 target.points.push_back(pc.points[try_neg[i]]);
04136 }
04137 }
04138
04139 for(int i=0; i<source.size(); i++) {
04140 publishLineMarker(source.points[i].getVector3fMap(), target.points[i].getVector3fMap(), -i);
04141 }
04142
04143 ROS_INFO("final size %d", source.size());
04144
04145 if(!source.size()) return;
04146
04147 ROS_INFO("error before %f", calc_error(source, target));
04148 Eigen::Matrix4f transf=Eigen::Matrix4f::Identity();
04149 for(int i=0; i<100; i++) {
04150 pcl::PointCloud<Point> s, t;
04151 for(int j=0; j<10; j++) {
04152 int r=rand()%source.size();
04153 s.points.push_back( source.points[r] );
04154 t.points.push_back( target.points[r] );
04155 }
04156 float e1,e2;
04157 e1=calc_error(source, target);
04158
04159 Eigen::Matrix4f tr;
04160 pcl::estimateRigidTransformationSVD(t,s, tr);
04161
04162 t=target;
04163 pcl::transformPointCloud(t,t,tr);
04164 e2=calc_error(source, t);
04165 if(e2<e1) {
04166 transf=transf*tr;
04167 target=t;
04168 }
04169
04170 }
04171 ROS_INFO("error after %f", calc_error(source, target));
04172
04173 std::cout<<transf<<"\n";
04174 Stransf=transf*Stransf;
04175
04176 if(rand()%3==0) {
04177 pcl::PointCloud<pcl::PointXYZRGB> pc2;
04178 pcl::fromROSMsg(*pc_in,pc2);
04179 static pcl::PointCloud<pcl::PointXYZRGB> map_;
04180
04181 pcl::transformPointCloud(pc2,pc2,Stransf);
04182 map_.header = pc2.header;
04183 map_+=pc2;
04184
04185 pcl::VoxelGrid<pcl::PointXYZRGB> voxel;
04186 voxel.setInputCloud(map_.makeShared());
04187 voxel.setLeafSize(0.03,0.03,0.03);
04188 voxel.filter(map_);
04189
04190 sensor_msgs::PointCloud2 pc_out;
04191 pcl::toROSMsg(map_,pc_out);
04192 map_pub_.publish(pc_out);
04193 }
04194
04195 break;
04196 }
04197
04198 #endif
04199 }
04200
04201 pc_old = pc;
04202
04203 ROS_INFO("took full %f s", _timer.elapsed());
04204 }
04205
04206 int getI(const int ind, unsigned char *depth_map, const pcl::PointCloud<Point> &pc) {
04207 int x=ind%pc.width;
04208 int y=ind/pc.width;
04209 if(x<2||y<2||x>=pc.width-2||y>=pc.height-2)
04210 return 25;
04211
04212 int r=0;
04213 for(int dx=-2; dx<=2; dx++) {
04214 for(int dy=-2; dy<=2; dy++) {
04215 if(dx==0 && dy==0)
04216 continue;
04217 r+=depth_map[getInd(x+dx,y+dy)];
04218 }
04219 }
04220
04221 return r;
04222 }
04223
04224 float calc_error(const pcl::PointCloud<Point> &s,const pcl::PointCloud<Point> &t) {
04225 float error=0.f;
04226 for(int i=0; i<s.points.size(); i++)
04227 error+=(s.points[i].getVector3fMap()-t.points[i].getVector3fMap()).norm();
04228 return error;
04229 }
04230
04231 #define _SEARCH_ 2
04232 float getMaxDiff(const pcl::PointCloud<Point> &pc,const int ind) {
04233 int x=ind%pc.width;
04234 int y=ind/pc.width;
04235 if(x<_SEARCH_||y<_SEARCH_||x>=pc.width-_SEARCH_||y>=pc.height-_SEARCH_)
04236 return 0.f;
04237
04238 float z=pc.points[ind].z;
04239
04240 float m=0.f;
04241 for(int dx=-_SEARCH_; dx<=_SEARCH_; dx++) {
04242 for(int dy=-_SEARCH_; dy<=_SEARCH_; dy++) {
04243 if(dx==0 && dy==0)
04244 continue;
04245 m=std::max(m,pc.points[getInd(x+dx,y+dy)].z-z);
04246 }
04247 }
04248
04249 return m;
04250 }
04251
04252 float getMaxDiff2(const pcl::PointCloud<Point> &pc,const int ind,const pcl::PointCloud<Point> &pc2, int &mi) {
04253 int x=ind%pc.width;
04254 int y=ind/pc.width;
04255 if(x<_SEARCH_||y<_SEARCH_||x>=pc.width-_SEARCH_||y>=pc.height-_SEARCH_)
04256 return 0.f;
04257
04258 float z=pc2.points[ind].z;
04259
04260 float m=0.f, _mi=z*z*0.01;
04261 for(int dx=-_SEARCH_; dx<=_SEARCH_; dx++) {
04262 for(int dy=-_SEARCH_; dy<=_SEARCH_; dy++) {
04263 if(dx==0 && dy==0)
04264 continue;
04265 float f=pc.points[getInd(x+dx,y+dy)].z-z;
04266 m=std::max(m,f);
04267 f=std::abs(f);
04268 if(f<_mi) {
04269 _mi=f;
04270 mi = getInd(x+dx,y+dy);
04271 }
04272 }
04273 }
04274
04275 return m;
04276 }
04277
04278 int getNearest(const pcl::PointCloud<Point> &pc, const pcl::PointCloud<Point> &pc2, const int ind, const float diff) {
04279 int x=ind%pc.width;
04280 int y=ind/pc.width;
04281 const int rad=40;
04282 if(x<rad||y<rad||x>=pc.width-rad||y>=pc.height-rad)
04283 return -1;
04284
04285 Eigen::Vector3f v = pc2.points[ind].getVector3fMap();
04286
04287 int mi=-1;
04288 float dis=100.f;
04289
04290 for(int dx=-rad; dx<=rad; dx++) {
04291 for(int dy=-rad; dy<=rad; dy++) {
04292 int in = getInd(x+dx,y+dy);
04293 if(in==ind) continue;
04294
04295 Eigen::Vector3f v2 = pc.points[in].getVector3fMap();
04296 float delta_trans = std::abs(v2.norm()-v.norm());
04297 if(delta_trans<0.05 && (v2-v).squaredNorm()<dis && getMaxDiff(pc, in)>diff) {
04298 dis=(v2-v).squaredNorm();
04299 mi= in;
04300 }
04301 }
04302 }
04303
04304
04305
04306
04307
04308
04309
04310
04311
04312
04313
04314
04315
04316 return mi;
04317 }
04318
04319 int getBest(const pcl::PointCloud<Point> &pc, const int ind, const float diff) {
04320 int x=ind%pc.width;
04321 int y=ind/pc.width;
04322 const int rad=20;
04323 if(x<rad||y<rad||x>=pc.width-rad||y>=pc.height-rad)
04324 return -1;
04325
04326 for(int dx=-rad; dx<=rad; dx++) {
04327 for(int dy=-rad; dy<=rad; dy++) {
04328 int in = getInd(x+dx,y+dy);
04329 if(getMaxDiff(pc, in)>diff) {
04330 return in;
04331 }
04332 }
04333 }
04334 return -1;
04335 }
04336
04337
04338
04339 float findCorr(pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new, std::vector<int> &cor_inds) {
04340
04341
04342 if(pc_old.size()<3 || pc_new.size()<3)
04343 return 0.f;
04344
04345 PrecisionStopWatch psw;
04346
04347 const int maxK_ = 20;
04348 const float matchingThreshold_ = 0.05*0.05;
04349
04350 boost::shared_ptr<pcl::KdTree<Point> > tree (new pcl::KdTreeFLANN<Point>);
04351 tree->setInputCloud (pc_new.makeShared());
04352 std::vector< int > k_indices;
04353 std::vector< float > k_distances;
04354
04355
04356
04357 std::vector<SORT_S> resort;
04358 for(int i=0; i<pc_old.size(); i++) {
04359
04360 if(!tree->nearestKSearch(pc_old[i],1,k_indices,k_distances))
04361 continue;
04362
04363 SORT_S s;
04364 s.ind = i;
04365 s.dis = k_distances[0];
04366 resort.push_back(s);
04367 }
04368
04369 SORT_S _s_;
04370 std::sort(resort.begin(), resort.end(), _s_);
04371 for(int i=0; i<resort.size(); i++) {
04372 if(resort[i].ind>i)
04373 std::swap(pc_old.points[i],pc_old.points[resort[i].ind]);
04374 }
04375
04376
04377 int usingA=resort.size()/8;
04378 Eigen::Vector4f best_pairs[4];
04379 float best_overall=0.f;
04380
04381 #if DEBUG_SWITCH_
04382 static double tt1=0;
04383 tt1+=psw.precisionStop();
04384 ROS_INFO("start %f", tt1);
04385 #endif
04386
04387 float per_sum=0.f, max_per=0.f;
04388 std::vector<int> inds;
04389 int inds_size;
04390 for(int k=0; k<15; k++) {
04391 #if DEBUG_SWITCH_
04392 ROS_INFO("-------------------------");
04393 #endif
04394
04395 if(k!=0 && pc_old.size()*0.7<inds_size) {
04396 ;
04397 }
04398 else {
04399 inds_size=pc_old.size();
04400 for(int i=0; i<inds_size; i++) inds.push_back(i);
04401 }
04402
04403 Eigen::Vector4f pairs[4];
04404
04405 per_sum=0.f;
04406 int tries=1;
04407 int matching_iteration_nr = 0;
04408 bool pairs_valid=false;
04409 do {
04410 ++matching_iteration_nr;
04411 if(matching_iteration_nr>20) {
04412 #if DEBUG_SWITCH_
04413 ROS_INFO("break because it");
04414 #endif
04415 break;
04416 }
04417
04418 if(inds_size<3) {
04419 #if DEBUG_SWITCH_
04420 ROS_INFO("break because inds");
04421 #endif
04422 break;
04423 }
04424
04425 int A,Ac, O,Oc;
04426 float desiredD;
04427 Eigen::Vector4f vO,vOc,vA,vAc;
04428
04429 int sample_selection_iteration_nr = 0;
04430 while(sample_selection_iteration_nr<12) {
04431 ++sample_selection_iteration_nr;
04432
04433 #if 0
04434
04435
04436 int Aind = rand()%inds_size;
04437 A = inds[Aind];
04438 std::swap(inds[Aind], inds[inds_size-1]);
04439 vA = pc_old.points[A].getVector4fMap();
04440
04441
04442 tree->nearestKSearch(pc_old.points[A],maxK_,k_indices,k_distances);
04443 Ac = k_indices[0];
04444 vAc = pc_new.points[Ac].getVector4fMap();
04445 float dT, dA;
04446 float d_min;
04447 getDis(vA, vAc, dT, dA);
04448 d_min = dT*dT+dA*dA;
04449
04450 #if PERHAPS_CHECK
04451 for(int i=1; i<k_indices.size(); i++) {
04452 getDis(vA, pc_new.points[k_indices[i]].getVector4fMap(), dT, dA);
04453 float f = dT*dT+dA*dA;
04454
04455 if(d_min>f) {
04456 d_min=f;
04457 Ac = k_indices[i];
04458 }
04459 }
04460 #endif
04461
04462
04463
04464
04465
04466 int inds_size2=inds_size-1;
04467 do {
04468 if(inds_size2<2) {
04469 ROS_INFO("error: not found");
04470 break;
04471 }
04472 int Oind = rand()%inds_size2;
04473 O=inds[Oind];
04474 if(O==A) continue;
04475
04476 vO = pc_old.points[O].getVector4fMap();
04477 desiredD = (vA-vO).squaredNorm();
04478
04479 --inds_size2;
04480 std::swap(inds[Oind], inds[inds_size2]);
04481
04482 if(desiredD<0.1) continue;
04483
04484 std::swap(inds[inds_size2], inds[inds_size-2]);
04485 break;
04486 } while(1);
04487
04488
04489 tree->nearestKSearch(pc_old.points[O],maxK_,k_indices,k_distances);
04490
04491
04492 Oc=k_indices[0];
04493 float tmp_min = std::abs(desiredD-(pc_new.points[Oc].getVector4fMap()-vAc).squaredNorm());
04494 for(int i=1; i<k_indices.size(); i++) {
04495 float f= std::abs(desiredD-(pc_new.points[k_indices[i]].getVector4fMap()-vAc).squaredNorm());
04496 if(f<tmp_min) {
04497 Oc=k_indices[i];
04498 tmp_min=f;
04499 }
04500 }
04501
04502 if(tmp_min>matchingThreshold_) {
04503
04504 continue;
04505 }
04506 vOc = pc_new.points[Oc].getVector4fMap();
04507
04508 #else
04509
04510
04511
04512 int Aind = (usingA++)%inds_size;
04513 A = inds[Aind];
04514 std::swap(inds[Aind], inds[inds_size-1]);
04515 vA = pc_old.points[A].getVector4fMap();
04516
04517
04518 tree->nearestKSearch(pc_old.points[A],maxK_,k_indices,k_distances);
04519
04520 #if DEBUG_SWITCH_
04521 static double tt21=0;
04522 tt21+=psw.precisionStop();
04523 ROS_INFO("A %f", tt21);
04524 #endif
04525
04526
04527
04528 int inds_size2=inds_size-1;
04529 do {
04530 if(inds_size2<2) {
04531 ROS_INFO("error: not found");
04532 break;
04533 }
04534 int Oind = rand()%inds_size2;
04535 O=inds[Oind];
04536 if(O==A) continue;
04537
04538 vO = pc_old.points[O].getVector4fMap();
04539 desiredD = (vA-vO).squaredNorm();
04540
04541 --inds_size2;
04542 std::swap(inds[Oind], inds[inds_size2]);
04543
04544 if(desiredD<0.1) continue;
04545
04546 std::swap(inds[inds_size2], inds[inds_size-2]);
04547 break;
04548 } while(1);
04549
04550 std::vector< int > k_indicesO;
04551 std::vector< float > k_distancesO;
04552
04553
04554 tree->nearestKSearch(pc_old.points[O],maxK_,k_indicesO,k_distancesO);
04555
04556 #if DEBUG_SWITCH_
04557 static double tt2=0;
04558 tt2+=psw.precisionStop();
04559 ROS_INFO("O+A %f", tt2);
04560 #endif
04561
04562
04563 float tmp_min = sqrtf(matchingThreshold_);
04564 int m_a=-1, m_o=-1;
04565 for(int a=0; a<k_indices.size(); a++) {
04566 for(int o=0; o<k_indicesO.size(); o++) {
04567 Eigen::Vector4f d;
04568 float dT1, dT2, dA1, dA2;
04569 getDis(vA.head<3>(), pc_new.points[k_indices[a]].getVector3fMap(), dT1, dA1);
04570 getDis(vO.head<3>(), pc_new.points[k_indicesO[o]].getVector3fMap(), dT2, dA2);
04571
04572
04573
04574
04575
04576
04577 float f = std::abs( sqrtf(desiredD)-(pc_new.points[k_indicesO[o]].getVector3fMap()-pc_new.points[k_indices[a]].getVector3fMap()).norm() );
04578
04579
04580 if(f<tmp_min) {
04581 m_a=k_indices[a];
04582 m_o=k_indicesO[o];
04583 tmp_min=f;
04584 }
04585 }
04586 }
04587
04588 #if DEBUG_SWITCH_
04589
04590 #endif
04591
04592 if(m_a==-1)
04593 continue;
04594
04595 Oc=m_o;
04596 Ac=m_a;
04597
04598 vOc = pc_new.points[Oc].getVector4fMap();
04599 vAc = pc_new.points[Ac].getVector4fMap();
04600 #endif
04601
04602 break;
04603 }
04604
04605 inds_size-=2;
04606
04607 if(sample_selection_iteration_nr==12) {
04608 #if DEBUG_SWITCH_
04609 ROS_INFO("nothing found");
04610 #endif
04611 continue;
04612 }
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636 const Eigen::Vector4f V=vO-vA, Vc=vOc-vAc;
04637 int supporters=0, max_supporters=inds_size;
04638
04639 if(pairs_valid) {
04640
04641 Eigen::Matrix4f tf=getTF(vA.head<3>(),vO.head<3>(),vAc.head<3>(),vOc.head<3>());
04642
04643
04644
04645 Eigen::Vector4f vPc = tf*pairs[0];
04646
04647 if( (pairs[2]-vPc).squaredNorm()>matchingThreshold_*9) {
04648 #if DEBUG_SWITCH_
04649 ROS_INFO("old couldn't be foundt 1");
04650 #endif
04651 continue;
04652 }
04653 #if DEBUG_SWITCH_
04654 else
04655 ROS_INFO("dis1 %f", (pairs[2]-vPc).norm());
04656 #endif
04657
04658
04659
04660
04661 vPc = tf*pairs[1];
04662
04663 if( (pairs[3]-vPc).squaredNorm()>matchingThreshold_*9) {
04664 #if DEBUG_SWITCH_
04665 ROS_INFO("old couldn't be foundt 2");
04666 #endif
04667 continue;
04668 }
04669 #if DEBUG_SWITCH_
04670 else
04671 ROS_INFO("dis2 %f", (pairs[3]-vPc).norm());
04672 #endif
04673 }
04674
04675 #if DEBUG_SWITCH_
04676 static double tt3=0;
04677 tt3+=psw.precisionStop();
04678 ROS_INFO("O*+A* %f", tt3);
04679 #endif
04680
04681 Eigen::Matrix4f tf=getTF(vA.head<3>(),vO.head<3>(),vAc.head<3>(),vOc.head<3>());
04682
04683
04684
04685
04686 for(int j=0; j<inds_size; j++) {
04687 if( (j>40 && supporters<4) || (j>100 && supporters<12))
04688 break;
04689
04690 int i=inds[j];
04691
04692 Eigen::Vector4f vP = pc_old[i].getVector4fMap();
04693 Eigen::Vector4f vPc = tf*vP;
04694
04695 Point p;
04696 p.x=vPc(0);
04697 p.y=vPc(1);
04698 p.z=vPc(2);
04699 if(!tree->nearestKSearch(p,1,k_indices,k_distances))
04700 continue;
04701
04702 if(k_distances[0]<matchingThreshold_) {
04703 supporters++;
04704
04705 --inds_size;
04706 std::swap(inds[j], inds[inds_size]);
04707 j--;
04708
04709 }
04710 }
04711
04712 #if DEBUG_SWITCH_
04713 static double tt4=0;
04714 tt4+=psw.precisionStop();
04715 ROS_INFO("cor %f", tt4);
04716 #endif
04717
04718 float per = supporters/(float)max_supporters;
04719 per_sum += supporters/(float)pc_old.size();
04720
04721 #if DEBUG_SWITCH_
04722 ROS_INFO("cor %d %d %d %d %f %f", supporters, max_supporters, inds_size, pc_old.size(), per, per_sum);
04723 #endif
04724
04725
04726 supporters=0;
04727 if(per>0.4) {
04728 pairs_valid=true;
04729 pairs[0] = vA;
04730 pairs[1] = vO;
04731 pairs[2] = vAc;
04732 pairs[3] = vOc;
04733
04734 #if 1
04735 Eigen::Matrix4f tf=getTF(vA.head<3>(),vO.head<3>(),vAc.head<3>(),vOc.head<3>());
04736
04737
04738
04739
04740 for(int i=0; i<pc_old.size(); i+=2) {
04741 Eigen::Vector4f vP = pc_old[i].getVector4fMap();
04742 Eigen::Vector4f vPc = tf*vP;
04743
04744 Point p;
04745 p.x=vPc(0);
04746 p.y=vPc(1);
04747 p.z=vPc(2);
04748
04749 if(!tree->nearestKSearch(p,1,k_indices,k_distances))
04750 continue;
04751
04752 if(k_distances[0]<matchingThreshold_)
04753 supporters++;
04754 }
04755 float overall=supporters/(float)(pc_old.size()/2);
04756 ROS_INFO("overall %f", overall);
04757 #else
04758 float overall = per_sum;
04759 #endif
04760
04761 if(overall+0.1<per_sum)
04762 ROS_INFO("ERROR: overall schould be around iterative percentage (hopefully)");
04763
04764 per = overall-per_sum;
04765 per_sum = overall;
04766
04767 if(overall>best_overall) {
04768 best_pairs[0] = pairs[0];
04769 best_pairs[1] = pairs[1];
04770 best_pairs[2] = pairs[2];
04771 best_pairs[3] = pairs[3];
04772 best_overall = overall;
04773 }
04774 }
04775
04776 #if DEBUG_SWITCH_
04777 static double tt5=0;
04778 tt5+=psw.precisionStop();
04779 ROS_INFO("o %f", tt5);
04780 #endif
04781
04782 if( (per<0.3f&&tries>1+matching_iteration_nr)||inds_size<10) {
04783 #if DEBUG_SWITCH_
04784 ROS_INFO("break because last");
04785 #endif
04786 break;
04787 }
04788 ++tries;
04789 if(per>0.3f)
04790 tries=0;
04791
04792 } while(per_sum<0.9f);
04793
04794 ROS_INFO("%f", per_sum);
04795
04796 max_per = std::max(max_per, per_sum);
04797
04798 if(best_overall>0.95)
04799 break;
04800 }
04801
04802 {
04803
04804
04805 std::vector< float > againstD;
04806 std::vector< int > k_indices, against;
04807 std::vector< float > k_distances;
04808 int supporters=0;
04809 int real_supporters=0;
04810 const Eigen::Vector4f V=best_pairs[1]-best_pairs[0], Vc=best_pairs[3]-best_pairs[2];
04811 const float desiredD = V.squaredNorm();
04812 for(int i=0; i<pc_new.size(); i++) {
04813 against.push_back(-1);
04814 againstD.push_back(-1);
04815 }
04816 Eigen::Matrix4f tf=getTF(best_pairs[0].head<3>(),best_pairs[1].head<3>(),
04817 best_pairs[2].head<3>(),best_pairs[3].head<3>());
04818 for(int i=0; i<pc_old.size(); i++) {
04819
04820
04821
04822
04823
04824 Eigen::Vector4f vPc = tf*pc_old[i].getVector4fMap();
04825
04826 Point p;
04827 p.x=vPc(0);
04828 p.y=vPc(1);
04829 p.z=vPc(2);
04830
04831 if(!tree->nearestKSearch(p,1,k_indices,k_distances)) {
04832 cor_inds.push_back(-1);
04833 continue;
04834 }
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844
04845
04846
04847
04848
04849 if(k_distances[0]<matchingThreshold_) {
04850
04851 supporters++;
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861
04862
04863 real_supporters++;
04864
04865 against[k_indices[0]] = i;
04866 againstD[k_indices[0]] = k_distances[0];
04867
04868
04869 cor_inds.push_back(k_indices[0]);
04870 }
04871 else
04872 cor_inds.push_back(-1);
04873 }
04874 per_sum=supporters/(float)pc_old.size();
04875 ROS_INFO("real %f", real_supporters/(float)pc_old.size());
04876 ROS_INFO("final matches %f", per_sum);
04877
04878 return per_sum;
04879 }
04880
04881 return max_per;
04882 }
04883
04884
04885 void publishMarkerPoint(const Point &p, int id, float r, float g, float b, float Size=0.02)
04886 {
04887 if(!show_markers_)
04888 return;
04889 visualization_msgs::Marker marker;
04890 marker.action = visualization_msgs::Marker::ADD;
04891 marker.type = visualization_msgs::Marker::CUBE;
04892 marker.lifetime = ros::Duration(0.5);
04893 marker.header = header_;
04894
04895
04896
04897
04898
04899 marker.pose.orientation.x = 0.0;
04900 marker.pose.orientation.y = 0.0;
04901 marker.pose.orientation.z = 0.0;
04902 marker.pose.orientation.w = 1.0;
04903
04904 marker.scale.x = Size;
04905 marker.scale.y = Size;
04906 marker.scale.z = Size;
04907 marker.color.r = r;
04908 marker.color.g = g;
04909 marker.color.b = b;
04910 marker.color.a = 1.0;
04911
04912 marker.id = id;
04913 marker.pose.position.x = p.x;
04914 marker.pose.position.y = p.y;
04915 marker.pose.position.z = p.z;
04916
04917 marker_pub_.publish(marker);
04918 }
04919
04920 static void publishTextMarker(const Eigen::Vector3f pos, const std::string &text, const int id=rand()%111111)
04921 {
04922 visualization_msgs::Marker marker;
04923 marker.action = visualization_msgs::Marker::ADD;
04924 marker.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
04925 marker.lifetime = ros::Duration(id<0?0:0.4);
04926 marker.header = header_;
04927
04928
04929
04930
04931
04932
04933
04934 marker.pose.orientation.x = 0.0;
04935 marker.pose.orientation.y = 0.0;
04936 marker.pose.orientation.z = 0.0;
04937 marker.pose.orientation.w = 1.0;
04938
04939 marker.pose.position.x = pos(0);
04940 marker.pose.position.y = pos(1);
04941 marker.pose.position.z = pos(2);
04942
04943 marker.scale.z = 10;
04944
04945 marker.scale.x = 0.02;
04946 marker.scale.y = 0.02;
04947 marker.scale.z = 0.3;
04948 marker.color.r = 1;
04949 marker.color.g = 1;
04950 marker.color.b = 1;
04951 marker.color.a = 1.0;
04952
04953 marker.id = id;
04954
04955 marker.text = text;
04956
04957 marker_pub_.publish(marker);
04958 }
04959
04960 static void publishLineMarker(const std::vector<Eigen::Vector4f> &pl, const int id=rand()%111111)
04961 {
04962 visualization_msgs::Marker marker;
04963 marker.action = visualization_msgs::Marker::ADD;
04964 marker.type = visualization_msgs::Marker::LINE_STRIP;
04965 marker.lifetime = ros::Duration(id<0?0:4);
04966 marker.header = header_;
04967
04968
04969
04970
04971
04972
04973
04974 marker.pose.orientation.x = 0.0;
04975 marker.pose.orientation.y = 0.0;
04976 marker.pose.orientation.z = 0.0;
04977 marker.pose.orientation.w = 1.0;
04978
04979 marker.scale.x = 0.02;
04980 marker.scale.y = 0.02;
04981 marker.scale.z = 0.02;
04982 marker.color.r = 0;
04983 marker.color.g = 0;
04984 marker.color.b = 1;
04985 marker.color.a = 1.0;
04986
04987 marker.id = id;
04988
04989 marker.points.resize(pl.size()+1);
04990
04991 for(int i=0; i<pl.size()+1; i++) {
04992 marker.points[i].x = pl[i%pl.size()](0);
04993 marker.points[i].y = pl[i%pl.size()](1);
04994 marker.points[i].z = pl[i%pl.size()](2);
04995 }
04996
04997 marker_pub_.publish(marker);
04998 }
04999
05000 static void publishLineMarker(Eigen::Vector3f a, Eigen::Vector3f b, const int id=rand()%111111)
05001 {
05002 visualization_msgs::Marker marker;
05003 marker.action = visualization_msgs::Marker::ADD;
05004 marker.type = visualization_msgs::Marker::LINE_STRIP;
05005 marker.lifetime = ros::Duration(id<0?0:4);
05006 marker.header = header_;
05007
05008
05009
05010
05011
05012
05013
05014 marker.pose.orientation.x = 0.0;
05015 marker.pose.orientation.y = 0.0;
05016 marker.pose.orientation.z = 0.0;
05017 marker.pose.orientation.w = 1.0;
05018
05019 marker.scale.x = 0.02;
05020 marker.scale.y = 0.02;
05021 marker.scale.z = 0.02;
05022 marker.color.r = 0;
05023 marker.color.g = 1;
05024 marker.color.b = 0;
05025 marker.color.a = 1.0;
05026
05027 marker.id = id;
05028
05029 marker.points.resize(2);
05030
05031 marker.points[0].x = a(0);
05032 marker.points[0].y = a(1);
05033 marker.points[0].z = a(2);
05034
05035 marker.points[1].x = b(0);
05036 marker.points[1].y = b(1);
05037 marker.points[1].z = b(2);
05038
05039 marker_pub_.publish(marker);
05040 }
05041
05042
05043 protected:
05044 ros::Subscriber point_cloud_sub_;
05045 ros::NodeHandle n_;
05046
05047 };
05048
05049 #include <pcl/surface/mls.h>
05050
05051 #include <registration/general_registration.h>
05052 #include <registration/registration_info.h>
05053 #include <boost/thread.hpp>
05054
05055 #define OCTOMAP_ 0
05056 class TestNode2
05057 {
05058 typedef pcl::PointXYZRGB Point;
05059
05060 Registration_Infobased<Point> reg;
05061 pcl::PointCloud<pcl::PointXYZRGB> pcreg;
05062
05063 Eigen::Matrix4f tf_;
05064 sensor_msgs::PointCloud2ConstPtr temporal_pcmsg_;
05065 boost::mutex mutex_, mutex2_;
05066 boost::thread *pthread_;
05067 protected:
05068 ros::Subscriber point_cloud_sub_;
05069 ros::NodeHandle n_;
05070
05071 bool first_, build_map_always_;
05072
05073
05074 int registered_fr_;
05075 public:
05076
05077 TestNode2():
05078 tf_(Eigen::Matrix4f::Identity()), first_(true), build_map_always_(false), registered_fr_(0)
05079 {
05080 point_cloud_sub_ = n_.subscribe("/camera/rgb/points", 1, &TestNode2::pointCloudSubCallback, this);
05081 point_cloud_pub_ = n_.advertise<sensor_msgs::PointCloud2 >("point_cloud2_resized",1);
05082 #if OCTOMAP_
05083 map_pub_ = n_.advertise<sensor_msgs::PointCloud2 >("cloud_in",1);
05084 #else
05085 map_pub_ = n_.advertise<sensor_msgs::PointCloud2 >("point_cloud_map",1);
05086 #endif
05087 marker_pub_ = n_.advertise<visualization_msgs::Marker>("reg_markers", 1);
05088
05089 build_map_always_=false;
05090
05091 reg.setThresholdDiff(0.06);
05092 reg.setThresholdStep(0.06);
05093 reg.setMinInfo(2);
05094 reg.setMaxInfo(16);
05095
05096
05097
05098 mutex2_.lock();
05099 pthread_ = new boost::thread(&TestNode2::createMap, this);
05100 }
05101
05102
05103
05104
05105 ~TestNode2()
05106 {
05107 pthread_->detach();
05108 delete pthread_;
05109 }
05110
05111 void
05112 dofile(const char *fn)
05113 {
05114
05115 std::cout<<"loading "<<fn<<"\n";
05116
05117 pcl::PointCloud<Point> pc;
05118 pcl::io::loadPCDFile(fn,pc);
05119
05120 PrecisionStopWatch psw2;
05121
05122 reg.setInputOginalCloud(pc.makeShared());
05123
05124 ++registered_fr_;
05125 PrecisionStopWatch psw;
05126 bool success = reg.compute();
05127 ROS_ERROR("took1 %f", psw.precisionStop());
05128 std::cout<<"Success: "<<success<<"\n";
05129 std::cout<<"No. frames: "<<registered_fr_<<"\n";
05130 std::cout<<reg.getTransformation()<<"\n";
05131
05132 pcl::PointCloud<Point> pcO, pcN;
05133 reg.getClouds(pcO,pcN);
05134
05135 sensor_msgs::PointCloud2 pc_out;
05136 pcl::toROSMsg(*reg.getMarkers2(),pc_out);
05137 pc_out.header.frame_id="openni_camera";
05138 point_cloud_pub_.publish(pc_out);
05139
05140 if(!success && pcreg.size()>0 && !first_) {
05141 ROS_ERROR("took2 %f", psw2.precisionStop());
05142 return;
05143 }
05144
05145 first_=false;
05146
05147 ROS_ERROR("took2 %f", psw2.precisionStop());
05148
05149 if(success) {
05150 pcl::PointCloud<pcl::PointXYZRGB> pc_rgb;
05151 pcl::io::loadPCDFile(fn,pc_rgb);
05152
05153 pcl::transformPointCloud(pc_rgb,pc_rgb,reg.getTransformation());
05154 pc_rgb.header.frame_id = pcreg.header.frame_id;
05155 pcreg += pc_rgb;
05156
05157 pcl::VoxelGrid<pcl::PointXYZRGB> voxel;
05158 voxel.setInputCloud(pcreg.makeShared());
05159 voxel.setLeafSize(0.01,0.01,0.01);
05160 voxel.filter(pcreg);
05161
05162 pcl::toROSMsg(pcreg,pc_out);
05163 pc_out.header.frame_id="openni_camera";
05164 map_pub_.publish(pc_out);
05165 }
05166 }
05167
05168 void
05169 pointCloudSubCallback(const sensor_msgs::PointCloud2ConstPtr& pc_in)
05170 {
05171 static int counter=0;
05172 if(++counter<5) return;
05173 PrecisionStopWatch psw2;
05174
05175 pcl::PointCloud<Point> pc;
05176 pcl::fromROSMsg(*pc_in,pc);
05177
05178 for(size_t i=0; i<pc.size(); i++) {
05179 if(pc[i].z>3.)
05180 pc[i].z=pc[i].y=pc[i].x=10.f;
05181 }
05182
05183 reg.setInputOginalCloud(pc.makeShared());
05184
05185 ++registered_fr_;
05186 PrecisionStopWatch psw;
05187 bool success = reg.compute();
05188 ROS_INFO("took1 %f", psw.precisionStop());
05189 std::cout<<"Success: "<<success<<"\n";
05190 std::cout<<"No. frames: "<<registered_fr_<<"\n";
05191
05192
05193 pcl::PointCloud<Point> pcO, pcN;
05194 reg.getClouds(pcO,pcN);
05195
05196 sensor_msgs::PointCloud2 pc_out;
05197 pcl::toROSMsg(*reg.getMarkers2(),pc_out);
05198 pc_out.header.frame_id="openni_camera";
05199 point_cloud_pub_.publish(pc_out);
05200
05201 if(!success && pcreg.size()>0 && !first_) {
05202 ROS_INFO("took2 %f", psw2.precisionStop());
05203
05204 if(reg.getBadCounter()>100) {
05205 pcreg.clear();
05206 reg.reset();
05207 if(mutex_.try_lock()) {
05208 tf_=tf_.Identity();
05209 temporal_pcmsg_=pc_in;
05210 mutex2_.unlock();
05211 mutex_.unlock();
05212 }
05213 }
05214 return;
05215 }
05216
05217 first_=false;
05218
05219
05220 if(mutex_.try_lock()) {
05221 tf_=reg.getTransformation();
05222 temporal_pcmsg_=pc_in;
05223 mutex2_.unlock();
05224 mutex_.unlock();
05225 }
05226
05227 ROS_INFO("took2 %f", psw2.precisionStop());
05228
05229 }
05230
05231 void createMap()
05232 {
05233
05234 Eigen::Matrix4f last=Eigen::Matrix4f::Identity();
05235
05236 while(ros::ok())
05237 {
05238 mutex2_.lock();
05239
05240 mutex_.lock();
05241 Eigen::Matrix4f tf=tf_;
05242 sensor_msgs::PointCloud2ConstPtr pc_in=temporal_pcmsg_;
05243 mutex_.unlock();
05244
05245 if(!pc_in)
05246 continue;
05247
05248 Eigen::Matrix4f T=last.inverse()*tf;
05249 if(build_map_always_ || pcreg.size()<1 || T.col(3).head<3>().squaredNorm()>0.01 || Eigen::Quaternionf(T.topLeftCorner<3, 3> ()).angularDistance(Eigen::Quaternionf::Identity())>0.1)
05250 {
05251 ROS_INFO("building map");
05252 #if OCTOMAP_
05253 map_pub_.publish(pc_in);
05254 static tf::TransformBroadcaster br;
05255 tf::Transform transform;
05256 Eigen::Vector4f t = tf.col(3);
05257 Eigen::Quaternionf R(T.topLeftCorner<3, 3> ());
05258 transform.setOrigin( tf::Vector3(t(0),t(1),t(2)) );
05259 transform.setRotation( tf::Quaternion(R.x(),R.y(),R.z(),R.w()) );
05260 br.sendTransform(tf::StampedTransform(transform, pc_in->header.stamp, "map", pc_in->header.frame_id));
05261 #else
05262
05263 pcl::PointCloud<pcl::PointXYZRGB> pc_rgb;
05264 pcl::fromROSMsg(*pc_in,pc_rgb);
05265
05266 for(int i=0; i<pc_rgb.size(); i++) {
05267 if(pc_rgb[i].z>4.)
05268 {
05269 pc_rgb[i].z=pc_rgb[i].y=pc_rgb[i].x=std::numeric_limits<float>::quiet_NaN();
05270 }
05271 }
05272 pc_rgb.width=pc_rgb.size();
05273 pc_rgb.height=1;
05274
05275 pcl::transformPointCloud(pc_rgb,pc_rgb,tf);
05276 pc_rgb.header.frame_id = pcreg.header.frame_id;
05277 pcreg += pc_rgb;
05278
05279 pcl::VoxelGrid<pcl::PointXYZRGB> voxel;
05280 voxel.setInputCloud(pcreg.makeShared());
05281 voxel.setLeafSize(0.01,0.01,0.01);
05282 voxel.filter(pcreg);
05283
05284 sensor_msgs::PointCloud2 pc_out;
05285 pcl::toROSMsg(pcreg,pc_out);
05286 pc_out.header.frame_id="openni_camera";
05287 map_pub_.publish(pc_out);
05288
05289 pcl::io::savePCDFileBinary("map.pcd",pcreg);
05290
05291 last=tf;
05292 #endif
05293 }
05294
05295 usleep(1000*250);
05296 }
05297
05298 }
05299 };
05300
05301 int main(int argc, char **argv) {
05302
05303
05304 if(1){
05305 ros::init(argc, argv, "dynamic_tutorials");
05306
05307 TestNode2 tn;
05308
05309 ROS_INFO("Spinning node");
05310 ros::spin();
05311
05312 return 0;
05313 }
05314 else {
05315 ros::init(argc, argv, "dynamic_tutorials");
05316
05317 TestNode2 tn;
05318 for(int i=1; i<argc; i++)
05319 tn.dofile(argv[i]);
05320 }
05321 g_step = argc>1;
05322
05323 #if TESTING_
05324
05325 #if 1
05326 std::vector<std::string> files;
05327 std::string fn="/home/josh/tmp/files.txt";
05328 if(argc>1)
05329 fn=argv[1];
05330 std::ifstream ifs(fn.c_str());
05331
05332 char buffer[256];
05333 while(!ifs.eof()) {
05334 ifs.getline(buffer,256);
05335 files.push_back(buffer);
05336 }
05337 std::cout<<"loading...\n";
05338
05339 ros::init(argc, argv, "dynamic_tutorials");
05340 ros::NodeHandle n_;
05341 point_cloud_pub_ = n_.advertise<sensor_msgs::PointCloud2 >("point_cloud2_resized",1);
05342 map_pub_ = n_.advertise<sensor_msgs::PointCloud2 >("point_cloud_map",1);
05343
05344 Registration_Infobased<pcl::PointXYZ> reg;
05345
05346 reg.setThresholdDiff(0.07);
05347 reg.setThresholdStep(0.07);
05348 reg.setMinInfo(1);
05349 reg.setMaxInfo(17);
05350
05351
05352 Eigen::Matrix4f all_tf = Eigen::Matrix4f::Identity();
05353 pcl::PointCloud<pcl::PointXYZRGB> pcreg;
05354 pcl::PointCloud<pcl::PointXYZ> pcold;
05355 for(int i=0; i<files.size(); i++) {
05356 pcl::PointCloud<pcl::PointXYZ> pc1_, pc1;
05357
05358 pcl::io::loadPCDFile(files[i],pc1_);
05359
05360 pc1=pc1_;
05361 for(int x=0; x<pc1.width; x++) {
05362 for(int y=0; y<pc1.height; y++) {
05363 int ic=((x)+(y)*pc1.width);
05364 int is=((y)+(x)*pc1.height);
05365 pc1[ic]=pc1_[is];
05366 }
05367 }
05368
05369 for(int i=0; i<pc1.size(); i++) {
05370 if(pc1[i].z==0||pc1[i].z>10)
05371 pc1[i].z=pc1[i].y=pc1[i].x=std::numeric_limits<float>::quiet_NaN();
05372 }
05373
05374 Eigen::Matrix4f tf = Eigen::Matrix4f::Identity();
05375
05376 #if 0
05377 sensor_msgs::PointCloud2 pc_out;
05378
05379 if(i>0)
05380 {
05381 Registration_Infobased<pcl::PointXYZ> reg;
05382
05383 reg.setThresholdDiff(0.1);
05384 reg.setThresholdStep(0.1);
05385 reg.setMinInfo(1);
05386 reg.setMaxInfo(17);
05387
05388 reg.setInputOginalCloud(pcold.makeShared());
05389 reg.compute_features();
05390
05391 reg.setInputOginalCloud(pc1.makeShared());
05392
05393 PrecisionStopWatch psw;
05394 reg.compute_features();
05395 ROS_ERROR("took1 %f", psw.precisionStop());
05396
05397 pcl::PointCloud<pcl::PointXYZ> pcO, pcN;
05398 reg.getClouds(pcO,pcN);
05399
05400 sensor_msgs::PointCloud2 pc_out;
05401 pcl::toROSMsg(*reg.getMarkers2(),pc_out);
05402 pc_out.header.frame_id="openni_camera";
05403 map_pub_.publish(pc_out);
05404
05405 {
05406 PrecisionStopWatch psw;
05407
05408 tf=findTF_fast(pcO,pcN).inverse();
05409
05410 ROS_ERROR("took2 %f", psw.precisionStop());
05411 }
05412
05413 std::cout<<tf<<"\n";
05414 }
05415 #else
05416 reg.setInputOginalCloud(pc1.makeShared());
05417
05418 PrecisionStopWatch psw;
05419 reg.compute();
05420 ROS_ERROR("took1 %f", psw.precisionStop());
05421
05422 all_tf = reg.getTransformation();
05423
05424 pcl::PointCloud<pcl::PointXYZ> pcO, pcN;
05425 reg.getClouds(pcO,pcN);
05426
05427 sensor_msgs::PointCloud2 pc_out;
05428 pcl::toROSMsg(*reg.getMarkers2(),pc_out);
05429 pc_out.header.frame_id="openni_camera";
05430 map_pub_.publish(pc_out);
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440 std::cout<<all_tf<<"\n";
05441 #endif
05442
05443 pcold=pc1;
05444
05445 all_tf=tf*all_tf;
05446
05447 pcl::PointCloud<pcl::PointXYZRGB> tmp;
05448 pcl::io::loadPCDFile(files[i],tmp);
05449 pcl::transformPointCloud(tmp,tmp,all_tf);
05450 pcreg += tmp;
05451
05452 pcl::VoxelGrid<pcl::PointXYZRGB> voxel;
05453 voxel.setInputCloud(pcreg.makeShared());
05454 voxel.setLeafSize(0.01,0.01,0.01);
05455 voxel.filter(pcreg);
05456
05457 pcl::io::savePCDFileBinary("out/a.pcd",pcreg);
05458
05459 pcl::toROSMsg(pcreg,pc_out);
05460 pc_out.header.frame_id="openni_camera";
05461 point_cloud_pub_.publish(pc_out);
05462
05463 std::cout<<"DONE with "<<i<<"\n";
05464 if(getchar()=='q')
05465 return 0;
05466 }
05467 #elif 1
05468 pcl::PointCloud<pcl::PointXYZ> pc1, pc2;
05469 pcl::PointCloud<pcl::PointXYZ> pc1_, pc2_;
05470 pcl::PointCloud<pcl::PointXYZ> pcO, pcN;
05471
05472
05473 pcl::io::loadPCDFile(_FN1_,pc1_);
05474 pcl::io::loadPCDFile(_FN2_,pc2_);
05475
05476 pc1=pc1_;
05477 pc2=pc2_;
05478
05479 for(int x=0; x<pc1.width; x++) {
05480 for(int y=0; y<pc1.height; y++) {
05481 int ic=((x)+(y)*pc1.width);
05482 int is=((y)+(x)*pc1.height);
05483 pc1[ic]=pc1_[is];
05484 pc2[ic]=pc2_[is];
05485 }
05486 }
05487
05488 for(int i=0; i<pc1.size(); i++) {
05489 if(pc1[i].z==0||pc1[i].z>10)
05490 pc1[i].z=pc1[i].y=pc1[i].x=std::numeric_limits<float>::quiet_NaN();
05491 }
05492
05493 for(int i=0; i<pc2.size(); i++) {
05494 if(pc2[i].z==0||pc2[i].z>10)
05495 pc2[i].z=pc2[i].y=pc2[i].x=std::numeric_limits<float>::quiet_NaN();
05496 }
05497
05498 while(1) {
05499 Registration_Infobased<pcl::PointXYZ> reg;
05500
05501 float f;
05502 int n;
05503
05504 reg.setThresholdDiff(0.1);
05505 reg.setThresholdStep(0.02);
05506 reg.setMinInfo(1);
05507 reg.setMaxInfo(17);
05508
05509
05510
05511
05512
05513
05514
05515
05516
05517
05518
05519
05520
05521
05522
05523
05524
05525 reg.setInputOginalCloud(pc1.makeShared());
05526 reg.compute_features();
05527
05528 reg.setInputOginalCloud(pc2.makeShared());
05529 reg.compute_features();
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539 reg.getClouds(pcO,pcN);
05540
05541 pcl::VoxelGrid<pcl::PointXYZ> voxel;
05542 voxel.setInputCloud(pcO.makeShared());
05543 voxel.setLeafSize(0.1,0.1,0.1);
05544 voxel.setLeafSize(0.01,0.01,0.01);
05545 voxel.setLeafSize(0.03,0.03,0.03);
05546
05547
05548 voxel.setInputCloud(pcN.makeShared());
05549 voxel.setLeafSize(0.1,0.1,0.1);
05550 voxel.setLeafSize(0.01,0.01,0.01);
05551 voxel.setLeafSize(0.03,0.03,0.03);
05552
05553
05554 {
05555 PrecisionStopWatch psw;
05556 pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
05557 icp.setInputCloud(pcO.makeShared());
05558 icp.setInputTarget(pcN.makeShared());
05559 pcl::PointCloud<pcl::PointXYZ> Final;
05560 icp.align(Final);
05561 ROS_ERROR("took %f", psw.precisionStop());
05562 std::cout << "has converged:" << icp.hasConverged() << " score: " <<
05563 icp.getFitnessScore() << std::endl;
05564 std::cout << icp.getFinalTransformation() << std::endl;
05565
05566 std::vector<COR_S> cors;
05567 pcl::PointCloud<pcl::PointXYZ> tpc;
05568 pcl::transformPointCloud(pc1,tpc,icp.getFinalTransformation());
05569 visualize(tpc,pc2, cors);
05570
05571 pcl::PointCloud<pcl::PointXYZRGB> pc1_,pc2_;
05572 pcl::io::loadPCDFile("/home/josh/tmp/1305031229.564442.png.img.pcd",pc1_);
05573 pcl::io::loadPCDFile("/home/josh/tmp/1305031229.596617.png.img.pcd",pc2_);
05574
05575 pcl::transformPointCloud(pc1_,pc1_,icp.getFinalTransformation());
05576
05577 pcl::io::savePCDFileBinary("out/a.pcd",pc1_);
05578 pcl::io::savePCDFileBinary("out/b.pcd",pc2_);
05579 }
05580
05581
05582 calcTF<pcl::PointXYZ> ctf(pcO,pcN);
05583
05584 std::cout<<ctf.findCloud()<<"\n";
05585
05586 }
05587
05588 #elif 1
05589 pcl::PointCloud<pcl::PointXYZ> pc1, pc2;
05590
05591
05592 pcl::io::loadPCDFile("/home/josh/tmp/Op6.pcd",pc1);
05593 pcl::io::loadPCDFile("/home/josh/tmp/Np6.pcd",pc2);
05594
05595
05596
05597 for(int i=0; i<pc1.size(); i++)
05598 if(!pcl_isfinite(pc1[i].x)) {pc1.points.erase(pc1.points.begin()+i);--i;}
05599 for(int i=0; i<pc2.size(); i++)
05600 if(!pcl_isfinite(pc2[i].x)) {pc2.points.erase(pc2.points.begin()+i);--i;}
05601
05602
05603
05604 pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
05605 sor.setMeanK (5);
05606 sor.setStddevMulThresh (0.05);
05607 sor.setNegative(true);
05608
05609
05610
05611
05612
05613
05614
05615 pcl::VoxelGrid<pcl::PointXYZ> voxel;
05616 voxel.setInputCloud(pc1.makeShared());
05617 voxel.setLeafSize(0.03,0.03,0.03);
05618 voxel.setLeafSize(0.1,0.1,0.1);
05619 voxel.setLeafSize(0.01,0.01,0.01);
05620 voxel.filter(pc1);
05621
05622 voxel.setInputCloud(pc2.makeShared());
05623 voxel.setLeafSize(0.03,0.03,0.03);
05624 voxel.setLeafSize(0.1,0.1,0.1);
05625 voxel.setLeafSize(0.01,0.01,0.01);
05626 voxel.filter(pc2);
05627
05628 calcTF<pcl::PointXYZ> ctf(pc1,pc2);
05629
05630 std::cout<<ctf.findCloud()<<"\n";
05631
05632
05633 {
05634 PrecisionStopWatch psw;
05635 pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
05636 icp.setInputCloud(pc1.makeShared());
05637 icp.setInputTarget(pc2.makeShared());
05638 pcl::PointCloud<pcl::PointXYZ> Final;
05639 icp.align(Final);
05640 ROS_ERROR("took %f", psw.precisionStop());
05641 std::cout << "has converged:" << icp.hasConverged() << " score: " <<
05642 icp.getFitnessScore() << std::endl;
05643 std::cout << icp.getFinalTransformation() << std::endl;
05644
05645 std::vector<COR_S> cors;
05646 pcl::PointCloud<pcl::PointXYZ> tpc;
05647 pcl::transformPointCloud(pc1,tpc,icp.getFinalTransformation());
05648 visualize(tpc,pc2, cors);
05649 }
05650
05651
05652 #else
05653 for(int j=0; j<3; j++) {
05654 srand(clock());
05655 pcl::PointCloud<pcl::PointXYZ> pc1, pc2;
05656 for(int i=0; i<500; i++) {
05657 pcl::PointXYZ p;
05658 for(int j=0; j<2; j++) {
05659 p.x = (rand()%500-250)/250.;
05660 p.y = (rand()%500-250)/250.;
05661 p.z = 1+(rand()%200)/45.;
05662
05663 pc1.points.push_back(p);}
05664
05665 p.x = i/100. + (rand()%100)/5000.;
05666 p.y = 1 + (rand()%100)/5000.;
05667 p.z = 2+i/100. + (rand()%100)/5000.;
05668 pc1.points.push_back(p);
05669 p.y = i/100. + (rand()%100)/5000.;
05670 p.x = 1 + (rand()%100)/5000.;
05671 p.z = 2 + (rand()%100)/5000.;
05672 pc1.points.push_back(p);
05673 }
05674
05675
05676
05677
05678
05679
05680
05681
05682
05683 Eigen::Vector3f va,vb;
05684
05685 va(2)=0;va(1)=1;va(0)=0;
05686 vb(2)=1;vb(1)=0;vb(0)=0.1;
05687
05688 std::swap(va(j),va(2));
05689 std::swap(vb(j),vb(2));
05690
05691 Eigen::Quaternionf qq;
05692 Eigen::Matrix3f R;
05693 qq.setFromTwoVectors(va,vb);
05694 R=qq.toRotationMatrix();
05695
05696 va.normalize();
05697 std::cout<<"correct axis\n"<<va<<"\n";
05698 Eigen::AngleAxisf aa(-0.05, va);
05699 R=aa.toRotationMatrix();
05700 Eigen::Matrix4f ttt=Eigen::Matrix4f::Identity();
05701
05702 for(int x=0; x<3; x++)
05703 for(int y=0; y<3; y++)
05704 ttt(x,y) = R(x,y);
05705 ttt(1,3)=0.05;
05706 pcl::transformPointCloud(pc1,pc2,ttt);
05707
05708 std::cout<< ttt*pc1[0].getVector4fMap()<<"\n";
05709 std::cout<< pc2[0].getVector4fMap()<<"\n";
05710
05711 for(int i=0; i<100; i++)
05712 pc2.points.erase(pc2.points.begin()+(rand()%pc2.size()));
05713 for(int i=0; i<pc2.size(); i++) {
05714 pc2[i].x+=(rand()%101-50)*0.0001;
05715 pc2[i].y+=(rand()%101-50)*0.0001;
05716 pc2[i].z+=(rand()%101-50)*0.0001;
05717 }
05718 for(int i=0; i<100; i++) {
05719 pcl::PointXYZ p;
05720 p.x = (rand()%500-250)/50.;
05721 p.y = (rand()%500-250)/50.;
05722 p.z = 1+(rand()%20)/5.;
05723
05724 pc2.points.push_back(p);
05725 }
05726
05727
05728
05729 calcTF<pcl::PointXYZ> ctf(pc1,pc2);
05730
05731 ctf.findCloud();
05732
05733 {
05734 PrecisionStopWatch psw;
05735 pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
05736 icp.setInputCloud(pc1.makeShared());
05737 icp.setInputTarget(pc2.makeShared());
05738 pcl::PointCloud<pcl::PointXYZ> Final;
05739 icp.align(Final);
05740 ROS_ERROR("took %f", psw.precisionStop());
05741 std::cout << "has converged:" << icp.hasConverged() << " score: " <<
05742 icp.getFitnessScore() << std::endl;
05743 std::cout << icp.getFinalTransformation() << std::endl;
05744 }
05745
05746
05747 std::cout<<"CORRECT TRANS\n"<<ttt<<"\n";
05748
05749 getchar();
05750
05751
05752 std::cout<<"CORRECT TRANS\n"<<ttt<<"\n";
05753 }
05754 #endif
05755 return 0;
05756 #endif
05757
05758 ros::init(argc, argv, "dynamic_tutorials");
05759
05760 TestNode tn;
05761
05762 ROS_INFO("Spinning node");
05763 ros::spin();
05764
05765 return 0;
05766 }