frir_freehand.cpp
Go to the documentation of this file.
00001 /*
00002  * frir_freehand.cpp
00003  *
00004  *  Created on: 25.06.2012
00005  *      Author: josh
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 //#define USE_LM
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 //#define RECONF_
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_;              //publisher for map
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     //if(weight[i]<1)
00153     //  continue;
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     //if(weight[i]<1)
00182     //  continue;
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   /* pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
00211 
00212   //blocks until the cloud is actually rendered
00213   pcl::registration::Correspondences cc;
00214   char buffer[128];
00215   for(int i=0; i<cors.size(); i++) {
00216     pcl::registration::Correspondence corr;
00217     corr.indexQuery=cors[i].ind_o;
00218     corr.indexMatch=cors[i].ind_n;
00219     cc.push_back(corr);
00220 
00221     sprintf(buffer,"l%d",i);
00222     viewer.addLine(pc_old[corr.indexQuery], pc_new[corr.indexMatch], 0,0,255, buffer);
00223   }
00224   pcl::visualization::PointCloudColorHandlerCustom<Point> single_color1(pc_old.makeShared(), 0, 255, 0);
00225   pcl::visualization::PointCloudColorHandlerCustom<Point> single_color2(pc_new.makeShared(), 255, 0, 0);
00226   viewer.addPointCloud<Point>(pc_old.makeShared(),single_color1, "p1");
00227   viewer.addPointCloud<Point>(pc_new.makeShared(),single_color2, "p2");
00228 
00229   viewer.setBackgroundColor (10, 10, 10);
00230   viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "p1");
00231   viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "p2");
00232   viewer.addCoordinateSystem (1.0);
00233   viewer.initCameraParameters ();*/
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   /*for(int i=0; i<50; i++) {
00296     pcl::PointXYZRGB p;
00297     p.x=sinf(M_PI*2*i/50.)*0.1+mo(0);
00298     p.y=cosf(M_PI*2*i/50.)*0.1+mo(1);
00299     p.z=mo(2);
00300     p.r=128;p.b=p.g=255;
00301     p4->push_back(p);
00302   }
00303   p4->width=p2->size();
00304   p4->height=1;
00305   for(int i=0; i<50; i++) {
00306     pcl::PointXYZRGB p;
00307     p.x=sinf(M_PI*2*i/50.)*0.1+mn(0);
00308     p.y=cosf(M_PI*2*i/50.)*0.1+mn(1);
00309     p.z=mn(2);
00310     p.r=p.b=p.g=255;
00311     p5->push_back(p);
00312   }
00313   p5->width=p2->size();
00314   p5->height=1;
00315   for(int i=0; i<50; i++) {
00316     pcl::PointXYZRGB p;
00317     p.x=sinf(M_PI*2*i/50.)*0.1+mot(0);
00318     p.y=cosf(M_PI*2*i/50.)*0.1+mot(1);
00319     p.z=mot(2);
00320     p.r=p.b=128;p.g=255;
00321     p6->push_back(p);
00322   }
00323   p6->width=p2->size();
00324   p6->height=1;*/
00325 
00326   //viewer.runOnVisualizationThreadOnce (viewerOneOff);
00327 
00328   //blocks until the cloud is actually rendered
00329   viewer.showCloud(p1,"p1");
00330   viewer.showCloud(p2,"p2");
00331   if(p3->size()>0) viewer.showCloud(p3,"p3");
00332   /*viewer.showCloud(p4,"p4");
00333   viewer.showCloud(p5,"p5");
00334   viewer.showCloud(p6,"p6");*/
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   //blocks until the cloud is actually rendered
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     //q+=v(0)>0?1:0;
00501     //q+=v(1)<0?2:0;
00502 
00503     //q+=v(0)>rel_new(0)?1:0;
00504     //q+=v(1)<rel_new(1)?2:0;
00505 
00506     q+=v.dot(X)>0?1:0;
00507     q+=v.dot(Y)<0?2:0;
00508 
00509     //v.normalize();
00510     //vp.normalize();
00511     v=vp-v;
00512     v.normalize();
00513     //v/=v.squaredNorm();
00514 
00515     if(pc_old[cors[i].ind_o].getVector3fMap().squaredNorm()<rel_old.squaredNorm()) v=-v;
00516 
00517     if(v.dot(X2)<0) {
00518       //ROS_ERROR(".");
00519       continue;
00520     }
00521 
00522     //m[q]+=v / (float)(weight_o[cors[i].ind_o]*weight_n[cors[i].ind_n]); //weight by I
00523     m[q]+=v;// / (float)(weight_o[cors[i].ind_o]); //weight by I
00524 
00525     g[q]++;//=1.f / (float)(weight_o[cors[i].ind_o]); //weight by I
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   /*m[0].normalize();
00543   m[1].normalize();
00544   m[2].normalize();
00545   m[3].normalize();*/
00546 
00547   /*std::cout<<"m[0]\n"<<m[0]<<"\n";
00548   std::cout<<"m[1]\n"<<m[1]<<"\n";
00549   std::cout<<"m[2]\n"<<m[2]<<"\n";
00550   std::cout<<"m[3]\n"<<m[3]<<"\n";*/
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   //border/=2;
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     //q+=v(0)>0?1:0;
00665     //q+=v(1)<0?2:0;
00666 
00667     //q+=v(0)>rel_new(0)?1:0;
00668     //q+=v(1)<rel_new(1)?2:0;
00669 
00670     q+=v.dot(X)>0?1:0;
00671     q+=v.dot(Y)<0?2:0;
00672 
00673     //v.normalize();
00674     //vp.normalize();
00675     v=vp-v;
00676     v.normalize();
00677     //v/=v.squaredNorm();
00678 
00679     if(pc_old[cors[i].ind_o].getVector3fMap().squaredNorm()<rel_old.squaredNorm()) v=-v;
00680 
00681     /*if(v.dot(X2)<0) {
00682       //ROS_ERROR(".");
00683       continue;
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     //if(p2.y<1)
00703     //  p2.y=1/p2.y;
00704     p2.z = p2.z/sqrtf(p2.x*p2.x+p2.y*p2.y)+1;
00705 
00706 
00707     //std::cout<<p2<<"\n";
00708     p2.r=p2.b=p2.g=108;
00709 
00710     /*if(p2.x>border) {
00711 
00712       weight_o[cors[i].ind_o]--;
00713       weight_n[cors[i].ind_n]--;
00714 
00715       std::swap(cors[i],cors.back());
00716       cors.resize(cors.size()-1);
00717 
00718       --i;
00719       continue;
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;//(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();
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     //if(p2.y<1)
00737     //  p2.y=1/p2.y;
00738 
00739     p2.x -= 1;
00740 
00741     //if(std::abs(p2.y-1)<0.1&&std::abs(p2.x-1)<0.1)
00742     pc2[0].points.push_back(p2);
00743 
00744     //m[q]+=v / (float)(weight_o[cors[i].ind_o]*weight_n[cors[i].ind_n]); //weight by I
00745     m[q]+=v;// / (float)(weight_o[cors[i].ind_o]); //weight by I
00746 
00747     g[q]++;//=1.f / (float)(weight_o[cors[i].ind_o]); //weight by I
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   for(int i=0;i<weight_o.size(); i++)
00781     if(weight_o[i]>0) {
00782       pcl::PointXYZ p;
00783       p.x=pc_old[i].x;
00784       p.y=pc_old[i].y;
00785       p.z=pc_old[i].z;
00786       pc.push_back(p);
00787     }
00788   for(int i=0;i<weight_n.size(); i++)
00789     if(weight_n[i]>0) {
00790       pcl::PointXYZ p;
00791       p.x=pc_new[i].x;
00792       p.y=pc_new[i].y;
00793       p.z=pc_new[i].z;
00794       pc2.push_back(p);
00795     }
00796   pcl::PCA<pcl::PointXYZ> pca2;
00797   pca.compute(pc);
00798   pca2.compute(pc2);
00799 
00800   std::cout<<pca.getEigenValues()<<"\n";
00801   std::cout<<pca.getEigenVectors()<<"\n";
00802 
00803   std::cout<<pca2.getEigenValues()<<"\n";
00804   std::cout<<pca2.getEigenVectors()<<"\n";
00805 
00806   std::cout<<(pca.getEigenVectors().inverse()*pca2.getEigenVectors())<<"\n";*/
00807   }
00808 
00809   m[0]/=g[0];
00810   m[1]/=g[1];
00811   m[2]/=g[2];
00812   m[3]/=g[3];
00813 
00814   /*pca.getEigenValues().col(0)(0) = std::abs(pca.getEigenValues().col(0)(0));
00815   pca.getEigenValues().col(0)(1) = std::abs(pca.getEigenValues().col(0)(1));
00816   pca.getEigenValues().col(0)(2) = std::abs(pca.getEigenValues().col(0)(2));
00817 
00818   for(int i=0; i<4; i++) {
00819     m[i](0)*=pca.getEigenValues().col(0)(0);
00820     m[i](1)*=pca.getEigenValues().col(0)(1);
00821     m[i](2)*=pca.getEigenValues().col(0)(2);
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   /*m[0].normalize();
00834   m[1].normalize();
00835   m[2].normalize();
00836   m[3].normalize();*/
00837 
00838   /*std::cout<<"m[0]\n"<<m[0]<<"\n";
00839   std::cout<<"m[1]\n"<<m[1]<<"\n";
00840   std::cout<<"m[2]\n"<<m[2]<<"\n";
00841   std::cout<<"m[3]\n"<<m[3]<<"\n";*/
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         /*weight_o[cors[i].ind_o]--;
00960         weight_n[cors[i].ind_n]--;
00961 
00962         std::swap(cors[i],cors.back());
00963         cors.resize(cors.size()-1);
00964         --i;*/
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   /*if(dir<0)
01108     axis*=-1;*/
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     //if(i%100==0)
01241     //  std::cout<<".";
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       //std::cout<<i<<" "<<cs[i][j]<<": "<<f1.back()<<", "<<f2.back()<<"\n";
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   /* Eigen::Matrix4f transf = Eigen::Matrix4f::Identity();
01311   pcl::estimateRigidTransformationSVD(tpc,spc, transf);
01312 
01313   pcl::PointCloud<Point> tpc2;
01314   pcl::transformPointCloud(tpc,tpc2,tf);
01315   std::cout<<tf<<"\n";
01316   cors.clear();
01317   visualize(tpc2,pc_new, cors);*/
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();//testing;
01335     v.normalize();//testing;
01336     dir += v;//testing;
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       /*getDis( v.head<3>(),
01354             pc_new[cors[i].ind_n].getVector3fMap(),
01355             dT, dA);
01356     if(dT>border_t || dA>border_a)*/
01357       //if( (tf*pc_old[cors[i].ind_o].getVector4fMap()-pc_new[cors[i].ind_n].getVector4fMap()).norm()/pc_old[cors[i].ind_o].getVector3fMap().norm()>border )
01358     {
01359       //cors.erase(cors.begin()+i);
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   //remByAxis(pc_old, pc_new, cors, mid_old, mid_new, axis, 2*axis2*border_t);
01419   //remByAxis(pc_old, pc_new, cors, ::Null3f(), ::Null3f(), axis, axis*border_t);
01420   if(0) {
01421     int remR=0, remF=0;
01422     float a_avg=0;
01423     for(int i=0; i<cors.size(); i++) {
01424       //float a=getTF2dis(axis, mid_old,pc_old[cors[i].ind_o].getVector3fMap(), mid_new,pc_new[cors[i].ind_n].getVector3fMap());
01425       //axis(0)=1;
01426       //axis(1)=0;
01427       //axis(2)=0;
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     //a_avg=0;
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     //a_avg=0;
01492 
01493     int num_a=0, num_b=0;
01494     int num_ar=0, num_br=0;
01495     //while(!remR)
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 && /*a>=a_avg-border_a*2 && a>border_a*2+a_avg &&*/ cors[i].ind_o==cors[i].ind_n) {
01515           ROS_ERROR("wrong remove %f",a);
01516           remF++;
01517         }
01518 
01519         if( b /*a>=a_avg-border_a*2 && a>border_a*2+a_avg*/ ) {
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       //border_a*=0.5;
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   //getTF2ex(axis, pc_old,pc_new, cors, weight_o,weight_n, mid_old,mid_new); //testing
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   //int rem=10;
01584 
01585   border_a*=0.5f;
01586   border_t*=0.5f;
01587   border_a2*=0.5f;
01588 
01589   /*const pcl::PointCloud<Point> &outer_pc=pc_old;
01590   {
01591     GET_MIDS();
01592     axis=getAxis2(pc_old, pc_new, cors, mid_old.squaredNorm(), mid_old, prev_trans, weight_o, weight_n);
01593     tf=getTF2(axis, mid_oa,mid_ob,mid_old, mid_na,mid_nb,mid_new);
01594 
01595     pcl::PointCloud<Point> pc_old=outer_pc;
01596     pcl::transformPointCloud(pc_old,pc_old,tf);
01597     GET_MIDS();
01598 
01599     axis=getAxis2(pc_old, pc_new, cors, mid_old.squaredNorm(), mid_old, prev_trans, weight_o, weight_n);
01600 
01601 #if TESTING_
01602     ROS_ERROR("inverse check");
01603     getchar();
01604 #endif
01605     rem+=remByAxis(pc_old, pc_new, cors, Null3f(), Null3f(), axis, border_t*0.5, weight_o,weight_n);
01606     visualize(pc_old,pc_new, cors, mid_old,mid_new);
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>() );//0.5*(tf.col(3).head<3>()+prev_trans) );
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   /*int m=0;
01761   for(int i=0; i<pc_old.size(); i++) {
01762     float t = pc_old.points[i].getVector3fMap().norm();
01763     for(int j=0; j<tv.size(); j++) {
01764       if( std::abs(tv[j].dis-t) < tmax) {
01765         float dA;
01766         dA = acosf(pc_old.points[i].getVector3fMap().dot(pc_new.points[tv[j].ind].getVector3fMap())/(pc_old.points[i].getVector3fMap().norm()*pc_new.points[tv[j].ind].getVector3fMap().norm()));
01767 
01768         if(dA>=rmax) continue;
01769 
01770         avgT+=tv[j].dis-t;
01771         m++;
01772 
01773         if(i==0)
01774           std::cout<<j<<" ";
01775       }
01776     }
01777   }
01778   ROS_ERROR("NUM %d",m);
01779   avgT/=m;
01780   std::cout<<"avgT "<<avgT<<"\n";*/
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       //float dt=tv[j].dis-t;
01794       //if( std::abs(dt) < tmax && std::abs(dt-avgT)<tmax/4) {
01795       //std::cout<<j<<" "<<tv[j].dis-t<<"\n";
01796       float dT=std::abs(tv[j].dis-t);
01797       if( dT < tmax) {
01798         float dA;
01799         //dA = acosf(pc_old.points[i].getVector3fMap().dot(pc_new.points[tv[j].ind].getVector3fMap())/(pc_old.points[i].getVector3fMap().norm()*pc_new.points[tv[j].ind].getVector3fMap().norm()));
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         //if((pc_old.points[i].getVector3fMap()-pc_new.points[tv[j].ind].getVector3fMap()).squaredNorm()==0)
01804         //  continue;
01805 
01806         Eigen::Vector3f X;
01807         X(0)=1;X(1)=0;X(2)=0;
01808 
01809         //if((pc_new.points[tv[j].ind].getVector3fMap()-pc_old.points[i].getVector3fMap()).dot(X)<0) continue;
01810 
01811         //        if(i!=tv[j].ind) continue;
01812 
01813         ++num;
01814         /*if(num>1 &&
01815             (pc_new[cors.back().ind_n].getVector3fMap()-pc_new[tv[j].ind].getVector3fMap()).squaredNorm()>0.02 )//if(num>200)
01816         {
01817           --num;
01818           weight_o[i]-=num;
01819           for(int i=0; i<num; i++) {
01820             weight_n[cors[cors.size()-1-i].ind_n]--;
01821           }
01822           cors.resize(cors.size()-num);
01823           break;
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     int ok=0;
01856     for(int j=0; ok && j<num-1; j++) {
01857       Eigen::Vector3f v= pc_new[cors[cors.size()-j-1].ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap();
01858       v.normalize();
01859       for(int k=j+1; k<num; k++) {
01860         Eigen::Vector3f v2= pc_new[cors[cors.size()-k-1].ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap();
01861         v2.normalize();
01862 
01863         if(v2.dot(v)<-0) {
01864           ok++;
01865         }
01866 
01867       }
01868     }
01869     if(ok>num*(num+1)/16) {
01870       weight_o[i]-=num;
01871       for(int i=0; i<num; i++) {
01872         weight_n[cors[cors.size()-1-i].ind_n]--;
01873       }
01874       cors.resize(cors.size()-num);
01875     }
01876     /*else {
01877       for(int k=0; k<num-1; k++) {
01878         float a=(pc_new[cors[cors.size()-k-1].ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap()).squaredNorm();
01879         float b=(pc_new[cors[cors.size()-num].ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap()).squaredNorm();
01880         if(a<b)
01881           std::swap(cors[cors.size()-num],cors[cors.size()-k-1]);
01882       }
01883       --num;
01884         /*weight_o[i]-=num;
01885         for(int i=0; i<num; i++) {
01886           weight_n[cors[cors.size()-1-i].ind_n]--;
01887         }
01888         cors.resize(cors.size()-num);
01889     }*/
01890 
01891     //getchar();
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   //  visualize(pc_old,pc_new, cors);
01903   // pcl::transformPointCloud(pc_old,tpc,tf2);
01904   //cors.clear();
01905   //  visualize(tpc,pc_new, cors);
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         //dA = acosf(pc_old.points[i].getVector3fMap().dot(pc_new.points[tv[j].ind].getVector3fMap())/(pc_old.points[i].getVector3fMap().norm()*pc_new.points[tv[j].ind].getVector3fMap().norm()));
01929         dA = (((vn-vo).squaredNorm()
01930             /vo.squaredNorm()));
01931 
01932         if(dA>=rmax_) continue;
01933 
01934         /*
01935         if((tf2*pc_old.points[i].getVector4fMap()-pc_new.points[tv[j].ind].getVector4fMap()).squaredNorm()
01936             >=
01937             (pc_old.points[i].getVector3fMap()-pc_new.points[tv[j].ind].getVector3fMap()).squaredNorm()+tmax/2) {
01938           dbg_rem1++;
01939           continue;
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         //if(num==1) {
01959         bestd=dA*dA+dT*dT;
01960         cors.push_back(c);
01961         /*}
01962         else if(bestd>dA*dA+dT*dT) {
01963 
01964           if(
01965               (pc_new[c.ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap())
01966               .dot
01967               (pc_new[cors.back().ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap())<0. )
01968           {
01969             cors.resize(cors.size()-1);
01970             break;
01971           }
01972 
01973           bestd=dA*dA+dT*dT;
01974           cors.back()=c;
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     /*int ok=0;
01985     for(int j=0; j<num-1; j++) {
01986       Eigen::Vector3f v= pc_new[cors[cors.size()-j-1].ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap();
01987       //v.normalize();
01988       for(int k=j+1; k<num; k++) {
01989         Eigen::Vector3f v2= pc_new[cors[cors.size()-k-1].ind_n].getVector3fMap()-pc_old.points[i].getVector3fMap();
01990         //v2.normalize();
01991 
01992         if(v2.dot(v)<0) {
01993           ok++;
01994         }
01995 
01996       }
01997     }
01998     if(ok>num*(num+1)/8) {
01999       dbg_rem2+=num;
02000       weight_o[i]-=num;
02001       for(int i=0; i<num; i++) {
02002         weight_n[cors[cors.size()-1-i].ind_n]--;
02003       }
02004       cors.resize(cors.size()-num);
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   // visualize(pc_old,pc_new, cors);
02019   pcl::transformPointCloud(pc_old,tpc,tf2);
02020   //cors.clear();
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       //TODO: speed up   std::sort(inds.begin(),inds.end());
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           //remove
02180           done[found[j]]=true;
02181 
02182         }
02183 
02184         po.x/=s;
02185         po.y/=s;
02186         po.z/=s;
02187 
02188         //po=pc_old[inds[k]];
02189         pc_o.push_back(po);
02190 
02191         /*weight_o.clear();
02192       weight_n.clear();
02193       getWeights(found,weight_o, weight_n);
02194 
02195       Point po,pn;
02196       po.x=po.y=po.z=0;
02197       pn=po;
02198 
02199       float s=0;
02200       for(int i=0; i<weight_n.size(); i++) {
02201         if(weight_n[i]<1) continue;
02202 
02203         float w=1/(float)weight_n[i];
02204         s+=w;
02205         pn.x+=pc_new[i].x*w;
02206         pn.y+=pc_new[i].y*w;
02207         pn.z+=pc_new[i].z*w;
02208       }
02209       pn.x/=s;
02210       pn.y/=s;
02211       pn.z/=s;
02212       ROS_ERROR("s %f",s);
02213 
02214       s=0;
02215       for(int j=0; j<found.size(); j++) {
02216         int i=found[j];
02217         if(weight_o[i]>0) {
02218           float w=1/(float)weight_o[i];
02219           s+=w;
02220           po.x+=pc_old[i].x*w;
02221           po.y+=pc_old[i].y*w;
02222           po.z+=pc_old[i].z*w;
02223         }
02224         //remove
02225         done[i]=true;
02226 
02227       }
02228       ROS_ERROR("s %f",s);
02229 
02230       po.x/=s;
02231       po.y/=s;
02232       po.z/=s;
02233 
02234       std::cout<<po<<" "<<pn<<"\n";
02235       pc_o.push_back(po);
02236       pc_n.push_back(pn);*/
02237       }
02238     }
02239 
02240     ROS_ERROR("took %f", psw.precisionStop());
02241 
02242     ROS_INFO("%d -> %d",pc_old_.size(), pc_o.size());
02243 
02244     //return findTF(pc_o,pc_new_);
02245     //return findTF(pc_old_,pc_new_);
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           //      c.dis = (pco.points[i].getVector3fMap()-pcn.points[tv[j].ind].getVector3fMap()).norm();
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     //std::cout<<tf<<"\n";
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>() );//0.5*(tf.col(3).head<3>()+prev_trans) );
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       //v.normalize();
02454 
02455       if(pc_old[cors[i].ind_o].getVector3fMap().squaredNorm()<rel_old.squaredNorm()) v=-v;
02456 
02457       //v/=cors[i].dis;
02458       m[q]+=v;//  / (float)(weight_o[cors[i].ind_o]); //weight by I
02459       g[q]++;//=1.f/ (float)(weight_o[cors[i].ind_o]); //weight by I
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     /*Eigen::Matrix3f aX, aY, aZ;
02476 
02477     aY=aZ=aX=aX.Identity();
02478 
02479     aX(0,0)=0;
02480     aY(1,1)=0;
02481     aZ(2,2)=0;
02482 
02483     Eigen::Vector3f ax,ay,az;
02484     ax=(m[0]+m[1]).cross(m[2]+m[3]);
02485     ay=(m[0]+m[2]).cross(m[1]+m[3]);
02486     az=(m[0]-m[3]).cross(m[1]-m[3]);
02487 
02488     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))) );
02489     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))) );
02490     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))) );
02491 
02492     axis(0) = (std::abs(ax(0))+std::abs(ay(0))+std::abs(az(0))) ;
02493     axis(1) = (std::abs(ax(1))+std::abs(ay(1))+std::abs(az(1))) ;
02494     axis(2) = (std::abs(ax(2))+std::abs(ay(2))+std::abs(az(2))) ;*/
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     //std::cout<<pc_old.points[inds_old[i]]<<"\n";
02568     //std::cout<<mid_s<<"\n";
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   /*t=mid_s-R*mid_t;
02626   t+=mid_s2-R*mid_t2;
02627 
02628   t*=0.5;*/
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       //std::cout<<"- ";
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       //std::cout<<"- ";
02684       continue;
02685     }
02686 
02687     //k_distances[0]=(pc_old[i].getVector3fMap()-pc_new[k_indices[0]].getVector3fMap()).squaredNorm();
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     //std::cout<<sqrtf(k_distances[0])<<" ";
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       //std::cout<<"- ";
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   //pcl::transformPointCloud(pc_new,pc_new,transf);
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;//p.z;
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       // Create the filtering object
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       //addPoint(pc,rand()%pc.points.size(),0);
02811       //addPoint(pc,rand()%pc.points.size(),0);
02812 
02813       //find min dist. to line
02814       float max_dis, last_dis=10000;
02815       int iteration=0;
02816       //std::cout<<"pl: starting\n";
02817       do {
02818 
02819         //centroid(0)=centroid(1)=centroid(2)=centroid(3)=0;
02820 
02821         std::cout<<"pl: round "<<iteration<<"\n";
02822         for(int i=0; i<pl.size(); i++) {
02823           //centroid+=pl[i];
02824           std::cout<<"pl: \t"<<pl[i](0)<<", "<<pl[i](1)<<", "<<pl[i](2)<<"\n";
02825         }
02826         //centroid/=pl.size();
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             //if( pl.size()>4 && p.norm()>((a+b)*0.5).norm()/2 ) continue;
02850 
02851             //p(2)=a(2)=b(2)=0;
02852             p.normalize();
02853             b.normalize();
02854             a.normalize();
02855             m=(a+b)/2;
02856             m.normalize();
02857             float c = (a-m).norm();
02858             //ROS_INFO("pl: %f %f", (m-p).norm(),c);
02859             if( pl.size()>2 && ((m-p).norm()>c || p.dot(m)<0 ) ) continue;
02860             found++;
02861             //ROS_INFO("pl: %f %f", (m-p).norm(),c);
02862             //if( a>c+b || b>c+a) continue;*/
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               /*if(SameSide(_4to3_(centroid),_4to3_(v), _4to3_(pl[j]), _4to3_(pl[ (j+1)%pl.size() ]))) {
02869                 int num=0;
02870                 for(int k=0; k<pc.points.size(); k++) {
02871                   Eigen::Vector4f t;
02872                   point2eigen(t, pc.points[k]);
02873                   if(PointInTriangle(t, pl[j], (pl[ (j+1)%pl.size() ]), v))
02874                     num++;
02875                 }
02876                 if(num>3) {
02877                   ROS_INFO("pl: not accepted as %d inliers",num);
02878                   continue;
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             //if( pl_min<(a-b).norm() && seg_i[i]!=-1 && !blacklist[i] ) {
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           /*if(last_dis<max_f && pl.size()>2) {
02941             //pc.points.erase(pc.points.begin()+max_i);
02942             blacklist[max_j]=true;
02943             continue;
02944           }
02945           else {
02946             for(int i=0; i<blacklist.size(); i++)
02947               blacklist[i]=false;
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         /*if(iteration==0) {
02960           pl.insert(pl.end(), pl.front());
02961         }
02962         else if(iteration==1) {
02963           pl.erase(pl.begin());
02964           pl.erase(pl.begin());
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         //resort();
02977         publishLineMarker(pl,-343);
02978         if(g_step&&getchar()=='q')
02979           exit(0);
02980 
02981         //if(iteration==1) break;
02982 
02983       } while(last_dis>0.01*0.01&&pl.size()<16&&pc.size()>0);//max_dis>0.01);
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   // Constructor
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       /*p1a(0) = 1;
03188     p1a(1) = 0;
03189     p1a(2) = 0;
03190 
03191     p1b(0) = 0;
03192     p1b(1) = 1;
03193     p1b(2) = 0;
03194 
03195     p2a(0) = 0;
03196     p2a(1) = 1;
03197     p2a(2) = 0;
03198 
03199     p2b(0) = -1;
03200     p2b(1) = 0;
03201     p2b(2) = 0;*/
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   // Destructor
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       //diff
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           //if(!pcl_isfinite(pn.z)) pn.z=1000;
03278           //if(!pcl_isfinite(po.z)) po.z=1000;
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         //if(info<10) std::cout<<info<<" ";
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         //if(info<10) std::cout<<info<<" ";
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       //TODO: TESTING
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           //pcl::transformPointCloud(_p,_p,Stransf);
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         //do ICP
03557         pcl::IterativeClosestPoint<Point,Point> icp;
03558 
03559         icp.setInputCloud( tmp_pc_new.makeShared());
03560         //icp.setIndices(boost::make_shared<pcl::PointIndices>(indices));
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       //for(int i=0; i<10; i++)
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         // From the set of correspondences found, attempt to remove outliers
03627         // Create the registration model
03628         typedef typename pcl::SampleConsensusModelRegistration<Point>::Ptr SampleConsensusModelRegistrationPtr;
03629         SampleConsensusModelRegistrationPtr model;
03630         model.reset (new pcl::SampleConsensusModelRegistration<Point> (tmp_pc_new.makeShared ()));
03631         // Pass the target_indices
03632         model->setInputTarget (tmp_pc_old.makeShared());
03633         // Create a RANSAC model
03634         pcl::RandomSampleConsensus<Point> sac (model, 0.02);
03635         sac.setMaxIterations (1000);
03636 
03637         // Compute the set of inliers
03638         if (!sac.computeModel ())
03639         {
03640           return;
03641         }
03642         else
03643         {
03644           std::vector<int> inliers;
03645           // Get the inliers
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       //if(!source.size()) return;
03665 
03666       ROS_INFO("error before %f", calc_error(source, target));
03667       Eigen::Matrix4f transf=Eigen::Matrix4f::Identity();
03668 #if USE_SMART_GRID_
03669       //transf=findTF(tmp_pc_new,tmp_pc_old);
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       /*std::cout<<mid_s<<"\n";
03715       std::cout<<mid_t<<"\n";
03716       std::cout<<mid_s2<<"\n";
03717       std::cout<<mid_t2<<"\n";
03718 
03719       float rotationaxes[3]={};
03720       for(int i=0; i<source.size()/2-1; i++) {
03721         //mid_s = source.points[source.size()-1-i].getVector3fMap();
03722         //mid_t = target.points[target.size()-1-i].getVector3fMap();
03723 
03724         //std::cout<<source.points[i].getVector3fMap()-mid_s<<"\n";
03725         //std::cout<<target.points[i].getVector3fMap()-mid_t<<"\n";
03726 
03727         Eigen::Quaternionf q;
03728         q.setFromTwoVectors(target.points[i].getVector3fMap()-mid_t, source.points[i].getVector3fMap()-mid_s);
03729         Eigen::Matrix3f t =q.toRotationMatrix();
03730         float rx = atan2(t(2,1), t(2,2));
03731         float ry = asin(-t(2,0));
03732         float rz = atan2(t(1,0), t(0,0));
03733 
03734         rotationaxes[0]+=rx;
03735         rotationaxes[1]+=ry;
03736         rotationaxes[2]+=rz;
03737 
03738         ROS_INFO("rot %f %f %f (%f %f)", rotationaxes[0],rotationaxes[1],rotationaxes[2], (target.points[i].getVector3fMap()-mid_t).norm(), (source.points[i].getVector3fMap()-mid_s).norm());
03739         Eigen::Vector3f v;
03740         v(0)=v(1)=0;
03741         v(2)=1;
03742         v=t*v;
03743         ROS_INFO("v %f %f %f",v(0),v(1),v(2));
03744       }
03745       rotationaxes[0]/=source.size();
03746       rotationaxes[1]/=source.size();
03747       rotationaxes[2]/=source.size();*/
03748 
03749       Eigen::Matrix3f R;
03750       /*R = Eigen::AngleAxisf(rotationaxes[2], Eigen::Vector3f::UnitZ())
03751        * Eigen::AngleAxisf(rotationaxes[1], Eigen::Vector3f::UnitY())
03752        * Eigen::AngleAxisf(rotationaxes[0], Eigen::Vector3f::UnitX());*/
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         //ROS_INFO("v %f %f %f",v(0),v(1),v(2));
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     /*for(int i=0; i<indices_neg2.size(); i++) {
03836         Point pp=pc.points[indices_neg2[i]];
03837         pp.g=0;
03838         pp.r=255;
03839         pp.b=0;
03840         _p.push_back(pp);
03841       }
03842       for(int i=0; i<indices_pos2.size(); i++) {
03843         Point pp=pc_old.points[indices_pos2[i]];
03844         pp.g=255;
03845         pp.r=0;
03846         pp.b=0;
03847           _p.push_back(pp);
03848       }
03849       {
03850         sensor_msgs::PointCloud2 pc_out;
03851         //pcl::transformPointCloud(_p,_p,Stransf);
03852         pcl::toROSMsg(_p,pc_out);
03853         pc_out.header = header_;
03854         point_cloud_pub_.publish(pc_out);
03855       }
03856       return;*/
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     //try_pos=indices_pos2;
03864     //try_neg=indices_neg2;
03865     /*int tries=0;
03866         while(try_pos.size()<222&&tries<10000) {
03867           ++tries;
03868           int r=indices_pos[rand()%indices_pos.size()];
03869           r=getBest(pc_old,r,diff1);
03870           if(r!=-1)
03871             try_pos.push_back(r);
03872         }
03873 
03874         tries=0;
03875         while(try_neg.size()<222&&tries<10000) {
03876           ++tries;
03877           int r=indices_neg[rand()%indices_neg.size()];
03878           r=getBest(pc,r,diff1);
03879           if(r!=-1)
03880             try_neg.push_back(r);
03881         }*/
03882 
03883     ROS_INFO("edges %d %d", try_pos.size(), try_neg.size());
03884 
03885     /*for(int i=0; i<try_pos.size(); i++)
03886           try_posC.push_back( getNearest(pc,pc_old, try_pos[i], diff2) );
03887         for(int i=0; i<try_neg.size(); i++)
03888           try_negC.push_back( getNearest(pc_old,pc, try_neg[i], diff2) );*/
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     //debug output
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       //pcl::transformPointCloud(_p,_p,Stransf);
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           /*std::cout<<C(0)<<" "<<C(1)<<" "<<C(2)<<"\n";
04050             std::cout<<S(0)<<" "<<S(1)<<" "<<S(2)<<"\n";
04051             std::cout<<std::abs((S-m_new).squaredNorm()-(C-m_old).squaredNorm())<<"\n";*/
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           /*std::cout<<C(0)<<" "<<C(1)<<" "<<C(2)<<"\n";
04070             std::cout<<S(0)<<" "<<S(1)<<" "<<S(2)<<"\n";
04071             std::cout<<std::abs((S-m_new).squaredNorm()-(C-m_old).squaredNorm())<<"\n";*/
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       /*for(int i=0; i<dis_trans.size(); i++) {
04092           ROS_INFO("%f %f",dis_trans[i],dis_rot[i]);
04093         }*/
04094 
04095       float bo_t=dis_trans[dis_trans.size()*5/6], bo_r=dis_rot[dis_rot.size()*5/6];
04096       /*bo_t=bo_r=0;
04097         for(int i=0; i<dis_trans.size();i++) {
04098           bo_t+=dis_trans[i];
04099           bo_r+=dis_rot[i];
04100         }
04101         bo_t/=dis_trans.size();
04102         bo_r/=dis_trans.size();*/
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           {//if( std::abs(delta_trans-bo_t)<0.03 && std::abs(delta_rot-bo_r)<0.03 ) {
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           {//if( std::abs(delta_trans-bo_t)<0.03 && std::abs(delta_rot-bo_r)<0.03 ) {
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   //ROS_INFO("%f %f", v(2), pc.points[mi].z);
04305 
04306   /*if(mi!=-1) {
04307     Eigen::Vector3f C =pc2.points[ind].getVector3fMap();
04308     Eigen::Vector3f S =pc.points[mi].getVector3fMap();
04309 
04310     float delta_trans = std::abs(C.norm()-S.norm());
04311     if(delta_trans>0.05)
04312       return -1;
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 //pc... already filtered!!!!! (PERFORMANCE)
04339 float findCorr(pcl::PointCloud<Point> &pc_old, const pcl::PointCloud<Point> &pc_new, std::vector<int> &cor_inds) {
04340   //, std::vector<int> kp_old, std::vector<int> kp_new
04341   //2 for model, 1 for checking
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; //5cm, verify
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   //resort
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; //TODO: check this
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       ;//just nothing :)
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         //TODO: perhaps sorted with I, so that mor informative point is chosen preferably
04435         //TODO: prevent double selection
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         //get nearest to A -> A*
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         //TODO: this
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         //TODO: check plausability with dT<dTmax
04463 
04464         //TODO: perhaps sorted with I, so that mor informative point is chosen preferably
04465         //TODO: prevent double selection
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         //get nearest to O -> O*
04489         tree->nearestKSearch(pc_old.points[O],maxK_,k_indices,k_distances);
04490 
04491         //TODO: applay better filtering with dT
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         //ROS_INFO("tmp_min %f, %f", tmp_min, sqrtf(desiredD));
04502         if(tmp_min>matchingThreshold_) {
04503           //ROS_INFO("error: not good enough");
04504           continue;
04505         }
04506         vOc = pc_new.points[Oc].getVector4fMap();
04507 
04508 #else
04509 
04510         //TODO: perhaps sorted with I, so that mor informative point is chosen preferably
04511         //TODO: prevent double selection
04512         int Aind = (usingA++)%inds_size;//rand()%inds_size;
04513         A = inds[Aind];
04514         std::swap(inds[Aind], inds[inds_size-1]);
04515         vA = pc_old.points[A].getVector4fMap();
04516 
04517         //get nearest to A -> A*
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         //TODO: perhaps sorted with I, so that mor informative point is chosen preferably
04527         //TODO: prevent double selection
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         //get nearest to O -> O*
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         //O and A are known
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             /*d(0) = desiredD-(pc_new.points[k_indicesO[o]].getVector3fMap()-pc_new.points[k_indices[a]].getVector3fMap()).squaredNorm();
04572               d(1) = 0;//dT1-dT2;
04573               d(2) = 0;//dA1-dA2;
04574               float f= d.squaredNorm();*/
04575 
04576             //TODO: check sqrtf
04577             float f = std::abs( sqrtf(desiredD)-(pc_new.points[k_indicesO[o]].getVector3fMap()-pc_new.points[k_indices[a]].getVector3fMap()).norm() );
04578             //float f = std::abs( (desiredD)-(pc_new.points[k_indicesO[o]].getVector3fMap()-pc_new.points[k_indices[a]].getVector3fMap()).squaredNorm() );
04579             //ROS_INFO("mm %f",f);
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         //ROS_INFO("min %f",(tmp_min));
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       //DEBUG OUTPUT
04615       /*if(sample_selection_iteration_nr>=20) {
04616           ROS_INFO("ERROR: not found");
04617           break;
04618         }
04619 
04620         std::cout<<"A:  "<<pc_old.points[A]<<"\n";
04621         std::cout<<"A*: "<<pc_new.points[Ac]<<"\n";
04622         std::cout<<"O:  "<<pc_old.points[O]<<"\n";
04623         std::cout<<"O*: "<<pc_new.points[Oc]<<"\n";
04624 
04625         float dT, dA;
04626         getDis(vA, vAc, dT, dA);
04627         std::cout<<"own disA: "<<dT<<" "<<dA<<" "<<(vA-vAc).squaredNorm()<<"\n";
04628 
04629         getDis(vO, vOc, dT, dA);
04630         std::cout<<"own disO: "<<dT<<" "<<" "<<dA<<(vO-vOc).squaredNorm()<<"\n";*/
04631 
04632       //TODO: check plausability with dT<dTmax
04633 
04634       // OK, now we have good samples
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         //old samples should be explained by the new ones
04641         Eigen::Matrix4f tf=getTF(vA.head<3>(),vO.head<3>(),vAc.head<3>(),vOc.head<3>());
04642         //Eigen::Vector3f vP = pairs[0]-vA;
04643         //Eigen::Quaternionf q;
04644         //q.setFromTwoVectors(V, vP);
04645         Eigen::Vector4f vPc = tf*pairs[0];//(q.toRotationMatrix()*Vc)*sqrtf(vP.squaredNorm()/desiredD)+vAc;  //this is assumed!!!
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         //vP = pairs[1]-vA;
04660         //q.setFromTwoVectors(V, vP);
04661         vPc = tf*pairs[1];//(q.toRotationMatrix()*Vc)*sqrtf(vP.squaredNorm()/desiredD)+vAc;  //this is assumed!!!
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       /*Eigen::Quaternionf q;
04683       q.setFromTwoVectors(V, Vc);
04684       Eigen::Matrix3f R=q.toRotationMatrix();
04685       Eigen::Vector3f t=vAc-R*vA;*/
04686       for(int j=0; j<inds_size; j++) {
04687         if( (j>40 && supporters<4) || (j>100 && supporters<12)) //give up
04688           break;
04689 
04690         int i=inds[j];
04691 
04692         Eigen::Vector4f vP = pc_old[i].getVector4fMap();
04693         Eigen::Vector4f vPc = tf*vP;//t+R*vP;//(q.toRotationMatrix()*Vc)*sqrtf(vP.squaredNorm()/desiredD)+vAc;  //this is assumed!!!
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       //for testing purpose
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         /*Eigen::Quaternionf q;
04737         q.setFromTwoVectors(V, Vc);
04738         Eigen::Matrix3f R=q.toRotationMatrix();
04739         Eigen::Vector3f t=vAc-R*vA;*/
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;//t+R*vP;//(q.toRotationMatrix()*Vc)*sqrtf(vP.squaredNorm()/desiredD)+vAc;  //this is assumed!!!
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     //get corrs
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       /*Eigen::Vector4f vP = pc_old[i].getVector4fMap()-best_pairs[0];
04820       Eigen::Quaternionf q;
04821       q.setFromTwoVectors(V, vP);
04822       Eigen::Vector4f vPc = (q.toRotationMatrix()*Vc)*sqrtf(vP.squaredNorm()/desiredD)+best_pairs[2];  //this is assumed!!!
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       /*std::cout<<vP<<"\n";
04838           std::cout<<(q.toRotationMatrix()*Vc)*sqrtf(vP.squaredNorm()/desiredD)<<"\n\n";
04839           std::cout<<vP.squaredNorm()<<"\n";
04840           std::cout<<desiredD<<"\n";
04841           std::cout<<pairs[2]<<"\n";
04842           std::cout<<p<<"\n";
04843 
04844           float dT,dA;
04845           getDis(pc_old[i].getVector3fMap(), pc_new[k_indices[0]].getVector3fMap(), dT, dA);
04846           std::cout<<"own dis#: "<<dT<<" "<<dA<<" "<<(pc_old[i].getVector3fMap()-pc_new[k_indices[0]].getVector3fMap()).squaredNorm()<<"\n";
04847        */
04848 
04849       if(k_distances[0]<matchingThreshold_) {
04850 
04851         supporters++;
04852 
04853         /*if(against[k_indices[0]]!=-1) {
04854           if( k_distances[0]<againstD[k_indices[0]] ) { //we are better!!
04855             cor_inds[against[k_indices[0]]] = -1;
04856           }
04857           else {
04858             cor_inds.push_back(-1);
04859             continue;
04860           }
04861         }
04862         else*/
04863         real_supporters++;
04864 
04865         against[k_indices[0]] = i;
04866         againstD[k_indices[0]] = k_distances[0];
04867 
04868         //ROS_INFO("%d -> %d (%f)", cor_inds.size(), k_indices[0], k_distances[0]);
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   //marker.header.stamp = stamp;
04895 
04896   //create the marker in the table reference frame
04897   //the caller is responsible for setting the pose of the marker to match
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   //marker.header.stamp = stamp;
04928 
04929 
04930 
04931   //create the marker in the table reference frame
04932   //the caller is responsible for setting the pose of the marker to match
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   //marker.header.stamp = stamp;
04968 
04969 
04970 
04971   //create the marker in the table reference frame
04972   //the caller is responsible for setting the pose of the marker to match
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   //marker.header.stamp = stamp;
05008 
05009 
05010 
05011   //create the marker in the table reference frame
05012   //the caller is responsible for setting the pose of the marker to match
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_;             //subscriber for input pc
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_;             //subscriber for input pc
05069   ros::NodeHandle n_;
05070 
05071   bool first_, build_map_always_;
05072 
05073   //DEBUG
05074   int registered_fr_;
05075 public:
05076   // Constructor
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     //reg.setMinChanges(500);
05096     //reg.setUseICP(true);
05097 
05098     mutex2_.lock();
05099     pthread_ = new boost::thread(&TestNode2::createMap, this);
05100   }
05101 
05102 
05103 
05104   // Destructor
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;//std::numeric_limits<float>::quiet_NaN();
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     //std::cout<<reg.getTransformation()<<"\n";
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     //findTF(pcO,pcN).inverse();
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   //reg.setUseICP(true);
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         //calcTF<pcl::PointXYZ> ctf(pcO,pcN);
05408         tf=findTF_fast(pcO,pcN).inverse();
05409         //tf=findTF(pcO,pcN).inverse();
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       PrecisionStopWatch psw;
05434       //calcTF<pcl::PointXYZ> ctf(pcO,pcN);
05435       tf=findTF_fast(pcO,pcN).inverse();
05436       //tf=findTF(pcO,pcN).inverse();
05437       ROS_ERROR("took2 %f", psw.precisionStop());
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     /*std::cout<<"thr diff ";
05510     std::cin>>f;
05511     reg.setThresholdDiff(f);
05512 
05513     std::cout<<"thr step ";
05514     std::cin>>f;
05515     reg.setThresholdStep(f);
05516 
05517     std::cout<<"min i ";
05518     std::cin>>n;
05519     reg.setMinInfo(n);
05520 
05521     std::cout<<"max i ";
05522     std::cin>>n;
05523     reg.setMaxInfo(n);*/
05524 
05525     reg.setInputOginalCloud(pc1.makeShared());
05526     reg.compute_features();
05527 
05528     reg.setInputOginalCloud(pc2.makeShared());
05529     reg.compute_features();
05530 
05531     /*pcl::visualization::CloudViewer viewer("Cloud Viewer");
05532     viewer.showCloud(reg.getMarkers2(),"p1");
05533 
05534     while (!viewer.wasStopped ())
05535     {
05536       usleep(1000);
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     //voxel.filter(pcO);
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     //voxel.filter(pcN);
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   //pcl::io::loadPCDFile("Op"+std::string(argv[1])+".pcd",pc1);
05591   //pcl::io::loadPCDFile("Np"+std::string(argv[1])+".pcd",pc2);
05592   pcl::io::loadPCDFile("/home/josh/tmp/Op6.pcd",pc1);
05593   pcl::io::loadPCDFile("/home/josh/tmp/Np6.pcd",pc2);
05594   //pcl::io::loadPCDFile("pcn.pcd",pc1);
05595   //pcl::io::loadPCDFile("pco.pcd",pc2);
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   // Create the filtering object
05604   pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
05605   sor.setMeanK (5);
05606   sor.setStddevMulThresh (0.05);
05607   sor.setNegative(true);
05608 
05609   /*sor.setInputCloud (pc1.makeShared());
05610   sor.filter (pc1);
05611 
05612   sor.setInputCloud (pc2.makeShared());
05613   sor.filter (pc2);*/
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     /*pcl::io::loadPCDFile("/home/josh/svn/pcl-trunk/test/bunny.pcd",pc1);
05676     pcl::transformPointCloud(pc1,pc1,Eigen::Matrix4f::Identity()*3);
05677     for(int i=0; i<pc1.size(); i++) pc1[i].z+=3;
05678     pcl::VoxelGrid<pcl::PointXYZ> voxel;
05679     voxel.setInputCloud(pc1.makeShared());
05680     voxel.setLeafSize(0.02,0.02,0.02);
05681     voxel.filter(pc1);*/
05682 
05683     Eigen::Vector3f va,vb;
05684     //va(2)=0.5;va(1)=1;va(0)=0;
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     //R=qq.toRotationMatrix();
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     //std::cout<<findTF(pc1,pc2)<<"\n";
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     //std::cout<<"TRANS\n"<<getTF3(pc1[0].getVector3fMap(),pc1[10].getVector3fMap(),pc1[11].getVector3fMap(), pc2[0].getVector3fMap(),pc2[10].getVector3fMap(),pc2[11].getVector3fMap())<<"\n";
05747     std::cout<<"CORRECT TRANS\n"<<ttt<<"\n";
05748     //std::cout<<"CORRECT TRANS\n"<<ttt*ttt.transpose()<<"\n";
05749     getchar();
05750 
05751     //std::cout<<findTF(pc1,pc2)<<"\n";
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 }


cob_3d_registration
Author(s): Joshua Hampp
autogenerated on Wed Aug 26 2015 11:02:36