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 }