test_svd.cpp
Go to the documentation of this file.
00001 
00064 // ROS includes
00065 #include <ros/ros.h>
00066 #include <pcl/point_types.h>
00067 #define PCL_MINOR (PCL_VERSION[2] - '0')
00068 
00069 #include <pcl_ros/transforms.h>
00070 #include <pcl_ros/point_cloud.h>
00071 #include <pcl/io/pcd_io.h>
00072 #include <pcl/kdtree/kdtree.h>
00073 #include <pcl/kdtree/kdtree_flann.h>
00074 #include <pcl/registration/transformation_estimation_svd.h>
00075 //#include <registration/registration_correspondence.h>
00076 #include <boost/random.hpp>
00077 #include <boost/random/normal_distribution.hpp>
00078 
00079 #define ADD_NOISE() \
00080     p.x+=var_nor();\
00081     p.y+=var_nor();\
00082     p.z+=var_nor();
00083 
00084 pcl::PointCloud<pcl::PointXYZ> generateData(int data) {
00085   //normal distribution
00086   boost::mt19937 rng;
00087   rng.seed(clock());
00088 
00089   boost::normal_distribution<> nd(0, 0.1*data);
00090 
00091   boost::variate_generator<boost::mt19937&,
00092   boost::normal_distribution<> > var_nor(rng, nd);
00093 
00094   pcl::PointCloud<pcl::PointXYZ> pc;
00095   for(int i=0; i<100; i++) {
00096     pcl::PointXYZ p;
00097 
00098     p.x=(i-50)/50.;
00099     p.y=0;
00100     p.z=1;
00101     ADD_NOISE();
00102     pc.push_back(p);
00103 
00104     p.y=1;
00105     ADD_NOISE();
00106     pc.push_back(p);
00107 
00108     p.z=2;
00109     ADD_NOISE();
00110     pc.push_back(p);
00111 
00112     p.y=0;
00113     ADD_NOISE();
00114     pc.push_back(p);
00115   }
00116   for(int i=1; i<99; i++) {
00117     pcl::PointXYZ p;
00118 
00119     p.x=-1;
00120     p.y=0;
00121     p.z=1+i/100.;
00122     ADD_NOISE();
00123     pc.push_back(p);
00124 
00125     p.x=1;
00126     ADD_NOISE();
00127     pc.push_back(p);
00128 
00129     p.y=1;
00130     ADD_NOISE();
00131     pc.push_back(p);
00132 
00133     p.x=-1;
00134     ADD_NOISE();
00135     pc.push_back(p);
00136   }
00137 
00138   return pc;
00139 }
00140 
00141 void generateTF(int trans, Eigen::Quaternionf &R,  Eigen::Vector3f &t, Eigen::Matrix3f &mR)
00142 {
00143   float strengthR=(trans%3)*0.05;
00144   trans/=3;
00145   float strengthT=(trans%3)*0.05;
00146   trans/=3;
00147 
00148   int temp=trans%8;
00149   Eigen::Vector3f axis;
00150   axis(0) = temp&1?1:0;
00151   axis(1) = temp&2?1:0;
00152   axis(2) = temp&4?1:0;
00153   trans/=8;
00154 
00155   Eigen::AngleAxisf aa(strengthR,axis);
00156   R = aa.toRotationMatrix();
00157   mR= R.toRotationMatrix();
00158   R = mR;
00159 
00160   t(0) = temp&1?1:0;
00161   if(temp&2) t(0)=-t(0);
00162   t(1) = temp&4?1:0;
00163   if(temp&8) t(1)=-t(1);
00164   t(2) = temp&16?1:0;
00165   if(temp&32) t(2)=-t(2);
00166   trans/=64;
00167 
00168   t*=strengthT;
00169 }
00170 
00171 void transform(pcl::PointCloud<pcl::PointXYZ> &pc, Eigen::Quaternionf &R,  Eigen::Vector3f &t)
00172 {
00173   Eigen::Matrix4f m = Eigen::Matrix4f::Identity();
00174   for(int i=0; i<3; i++)
00175     for(int j=0; j<3; j++)
00176       m(i,j) = R.toRotationMatrix()(i,j);
00177   m.col(3).head<3>() = t;
00178 
00179   pcl::transformPointCloud(pc,pc,m);
00180 }
00181 
00182 void addNoise(pcl::PointCloud<pcl::PointXYZ> &pc, int noise)
00183 {
00184   //normal distribution
00185   boost::mt19937 rng;
00186   rng.seed(clock());
00187 
00188   boost::normal_distribution<> nd(0, 0.02*noise);
00189 
00190   boost::variate_generator<boost::mt19937&,
00191   boost::normal_distribution<> > var_nor(rng, nd);
00192 
00193   for(int i=0; i<pc.size(); i++) {
00194     pcl::PointXYZ &p = pc[i];
00195     ADD_NOISE();
00196   }
00197 
00198 }
00199 
00200 FILE *fp = NULL;
00201 void write(const char *str)
00202 {
00203   ROS_ASSERT(fp);
00204   fputs(str,fp);
00205 }
00206 void write(const int n)
00207 {
00208   char str[128];
00209   sprintf(str,"%d",n);
00210   write(str);
00211 }
00212 void write(const float n)
00213 {
00214   char str[128];
00215   sprintf(str,"%f",n);
00216   write(str);
00217 }
00218 
00219 int main(int argc, char **argv) {
00220   if(argc<2) {
00221     printf("specify output path");
00222     return 1;
00223   }
00224 
00225   fp = fopen(argv[1],"w");
00226 
00227   write("<svd>");
00228 
00229   pcl::PointCloud<pcl::PointXYZ> pc1, pc2;
00230 
00231   std::cout<<"\n";
00232   for(int trans=0; trans<3*3*8*64; trans++) {
00233           if( !(trans/(3*3*8))&1 && (trans/(3*3*8))&2 )
00234                   continue;
00235           if( !(trans/(3*3*8))&4 && (trans/(3*3*8))&8 )
00236                   continue;
00237           if( !(trans/(3*3*8))&16 && (trans/(3*3*8))&32 )
00238                   continue;
00239     std::cout<<(trans*100/(10*10*8*64))<<"%\r";
00240     Eigen::Quaternionf R;
00241     Eigen::Vector3f t;
00242         
00243     Eigen::Matrix3f mR_cmp;
00244     generateTF(trans, R,t,mR_cmp);
00245 
00246     for(int data=0; data<10; data++) {
00247       pc1=generateData(data);
00248 
00249       pc2=pc1;
00250       transform(pc2,R,t);
00251 
00252       for(int noise=0; noise<=10; noise++)
00253       {
00254         addNoise(pc2, noise);
00255 
00256         //get transformation
00257         pcl::registration::TransformationEstimationSVD<pcl::PointXYZ, pcl::PointXYZ> trans_est;
00258         Eigen::Matrix4f m=Eigen::Matrix4f::Identity();
00259         trans_est.estimateRigidTransformation (pc1, pc2, m);
00260 
00261         Eigen::Matrix3f m2;
00262         for(int i=0; i<3; i++)
00263           for(int j=0; j<3; j++)
00264             m2(i,j)=m(i,j);
00265 
00266         //compare to desired tf
00267         Eigen::Quaternionf Rn(m2);
00268         Eigen::Vector3f tn = m.col(3).head<3>();
00269 
00270         float error_r = Rn.angularDistance(R);
00271         float error_d = (tn-t).norm();
00272                 
00273                 /*if(error_r>0.01) {
00274   std::cout<<mR_cmp<<"\n";
00275   Rn=mR_cmp;
00276   std::cout<<Rn.toRotationMatrix()<<"\n";
00277   Rn.normalize();
00278   std::cout<<Rn.toRotationMatrix()<<"\n";
00279   std::cout<<m2<<"\n";
00280   std::cout<<"e: "<<error_r<<"\n";}*/
00281 
00282         //write
00283         write("<set>");
00284 
00285         write("<trans>");
00286         write((trans));
00287         write("</trans>");
00288 
00289         write("<data>");
00290         write((data));
00291         write("</data>");
00292 
00293         write("<noise>");
00294         write((noise));
00295         write("</noise>");
00296 
00297         write("<error_r>");
00298         write((error_r));
00299         write("</error_r>");
00300 
00301         write("<error_d>");
00302         write((error_d));
00303         write("</error_d>");
00304 
00305         write("</set>");
00306       }
00307     }
00308   }
00309 
00310   write("</svd>");
00311 
00312   fclose(fp);
00313   return 0;
00314 }


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