registration_fastslam.h
Go to the documentation of this file.
00001 
00059 /*
00060  * registration_fastslam.h
00061  *
00062  *  Created on: Nov 17, 2011
00063  *      Author: goa-jh
00064  */
00065 
00066 #ifndef REGISTRATION_FASTSLAM_H_
00067 #define REGISTRATION_FASTSLAM_H_
00068 
00069 #include <cob_vision_slam/3DEnvReconstruction/EnvReconstructionControlFlow.h>
00070 #include <pcl/common/common.h>
00071 #include <pcl/point_types.h>
00072 #include <pcl/point_cloud.h>
00073 
00074 namespace cob_3d_registration {
00075 
00076 template <typename Point>
00077 class Registration_FastSLAM : public GeneralRegistration<Point>
00078 {
00079   BFL::AnalyticMeasurementModelGaussianUncertainty *m_MeasModel;
00080   BFL::SystemModel<BFL::ColumnVector> *m_SysModel;
00081   FastSLAM m_FastSLAM;
00082   BFL::ColumnVector m_RobotPose;
00083 
00084   MatrixWrapper::Matrix transformation_tof2base_pltf_;
00085   MatrixWrapper::Matrix transformation_camera2base_;
00086 
00087   boost::shared_ptr<AbstractFeatureVector> m_AllFeatures;
00088   KdTreeDataAssociation m_DataAssociation;
00089   AbstractLocalFeatureDetector* m_FeatureDetector;
00090   boost::shared_ptr<FastSLAMParticle> m_MapParticle;
00091   int step_;
00092 
00093   pcl::PointCloud<Point> register_;
00094   pcl::PointCloud<Point>  visual_pc_;
00095 
00096 public:
00097 
00098   Registration_FastSLAM()
00099   :m_FastSLAM(1000, 1/*numPoints*/),
00100    m_RobotPose(3),
00101    m_DataAssociation(1, 0.02),
00102    transformation_tof2base_pltf_(4,4),
00103    transformation_camera2base_(4,4), step_(1)
00104   {
00105     m_FeatureDetector = new SURFDetector();
00106     ((SURFDetector*)m_FeatureDetector)->Init(100); //500
00107 
00108     CreateMeasurementModel();
00109     CreateSystemModel();
00110   }
00111 
00112   virtual ~Registration_FastSLAM() {
00113     delete m_FeatureDetector;
00114   }
00115 
00116   virtual boost::shared_ptr<const pcl::PointCloud<Point> > getMarkers() {return visual_pc_.makeShared();}
00117 
00118 protected:
00119 
00120   virtual bool compute_features(){
00121     ROS_INFO("compute_features");
00122     m_AllFeatures.reset(new AbstractFeatureVector());
00123 
00124     ipa_SensorFusion::ColoredPointCloud cpc(this->input_image_->size());
00125 
00126     cpc.SetColorImage(*this->input_image_);
00127 
00128     m_FeatureDetector->DetectFeatures(cpc, *m_AllFeatures);
00129 
00130     if(this->register_.size()<1)
00131       AddFeaturesToGlobalMap(&*m_AllFeatures);
00132 
00133     visual_pc_.clear();
00134 
00135     //std::cout << "afl size:" << afl->size() << std::endl;
00136     //TODO: use colorImage0 but transform u and v to sharedImageSize
00137     //m_FeatureDetector->DetectFeatures(*colorImage0, afl);
00138     AbstractFeatureVector::iterator It;
00139     for (It=m_AllFeatures->begin(); It!=m_AllFeatures->end(); It++)
00140     {
00141       int x=(*It)->Get<double>(M_U);
00142       int y=(*It)->Get<double>(M_V);
00143 
00144       (*It)->Get<double>(M_X) = this->input_org_->points[ x+y*this->input_org_->width ].x;
00145       (*It)->Get<double>(M_Y) = this->input_org_->points[ x+y*this->input_org_->width ].z;
00146       (*It)->Get<double>(M_Z) = this->input_org_->points[ x+y*this->input_org_->width ].y;
00147 
00148       unsigned char R,G,B;
00149       cv::Mat3b m=*this->input_image_;
00150 
00151 
00152       visual_pc_.points.push_back(this->input_org_->points[ x+y*this->input_org_->width ]);
00153 
00154       R=m(y,x)[0];
00155       G=m(y,x)[1];
00156       B=m(y,x)[2];
00157 
00158       R=m(x,y)[0];
00159       G=m(x,y)[1];
00160       B=m(x,y)[2];
00161 
00162       (*It)->Get<double>(M_RED) = (double) R;
00163       (*It)->Get<double>(M_GREEN) = (double) G;
00164       (*It)->Get<double>(M_BLUE) = (double) B;
00165       (*It)->Get<int>(M_FEATUREID)=-1;
00166     }
00167     ((SURFDetector*)m_FeatureDetector)->FilterFeatures(&*m_AllFeatures, 3);
00168 
00169     return m_AllFeatures->size()>3;
00170   }
00171 
00172   virtual bool compute_corrospondences() {
00173     ROS_INFO("compute_corrospondences");
00174     BFL::ColumnVector input(3);
00175     input(1) = m_RobotPose(1);
00176     input(2) = m_RobotPose(2);
00177     input(3) = m_RobotPose(3);
00178     m_FastSLAM.UpdatePosition(*m_SysModel, input);
00179     int associationCtr = 0;
00180     unsigned int ctrAssociations = 0;
00181     m_DataAssociation.AssociateData(&*m_AllFeatures);
00182 
00183     ColumnVector theta(3);
00184     AbstractFeatureVector::iterator It;
00185     for (It=m_AllFeatures->begin(); It!=m_AllFeatures->end(); It++)
00186     {
00187       //Transformation from camera to robot coordinate system
00188       //TransformCameraToPltfBase(*It);
00189       Eigen::Vector4f v;
00190       v(0)=(*It)->Get<double>(M_X);
00191       v(1)=(*It)->Get<double>(M_Y);
00192       v(2)=(*It)->Get<double>(M_Z);
00193       v(3)=0;
00194 
00195       v = this->transformation_ * v;
00196 
00197       (*It)->Get<double>(M_X) = v(0);
00198       (*It)->Get<double>(M_Y) = v(1);
00199       (*It)->Get<double>(M_Z) = v(2);
00200 
00201       if((*It)->Get<int>(M_FEATUREID) != -1)
00202       {
00203         associationCtr++;
00204         //m_DataAssociation.AddFeature(*It);
00205         m_FastSLAM.UpdateKnownFeature(*m_MeasModel, *m_SysModel, *It, ctrAssociations);
00206 
00207       }
00208       /*else
00209                     {
00210                             //m_DataAssociation.AddFeature(*It);
00211                             m_FastSLAM.UpdateUnknownFeature(*m_MeasModel, theta, (*It)->Get<int>(M_FEATUREID), height);
00212                     }*/
00213     }
00214 
00215     for(int i=0; i<m_FastSLAM.m_Particles.size(); i++) {
00216       std::cout<<m_FastSLAM.m_Particles[i].WeightGet()<<" "<<(*m_FastSLAM.m_Particles[i].ValueGet()->GetPose())<<std::endl;
00217     }
00218 
00219     m_MapParticle = m_FastSLAM.Resample(ctrAssociations);
00220     //m_MapParticle = m_FastSLAM.GetBestParticle();
00221 
00222     std::cout << "ctrAssociations: " << ctrAssociations << std::endl;
00223     std::cout << m_AllFeatures->size() << " features extracted" << std::endl;
00224     std::cout << associationCtr << " associated by descriptor" << std::endl;
00225     std::cout << m_MapParticle->m_RejectedFeatures.size() << " rejected in particle" << std::endl;
00226     std::cout << associationCtr - m_MapParticle->m_RejectedFeatures.size() << " remaining associations" << std::endl;
00227     //std::cout << "map size: " << m_MapParticle->GetMap()->size() << std::endl;
00228     std::cout << "Original robot pose: " << m_RobotPose << std::endl;
00229 
00231     for (unsigned int i=0; i<m_MapParticle->m_RejectedFeatures.size(); i++)
00232     {
00234       m_MapParticle->m_RejectedFeatures[i]->Get<int>(M_FEATUREID) = -1;
00235     }
00236 
00237     unsigned int i = 0;
00238     std::vector<int> mask(m_AllFeatures->size(),0);
00239     for (It=m_AllFeatures->begin(), i=0; It!=m_AllFeatures->end(); It++, i++)
00240     {
00241       //TransformCameraToPltfBase(*It);
00242 
00246       if((*It)->Get<int>(M_FEATUREID) == -1)
00247       {
00248         if ( mask[i] == 0) m_FastSLAM.AddUnknownFeature(*m_MeasModel, *It, step_);
00249       }
00250       //              multimap<int,boost::shared_ptr<AbstractEKF> >* map = m_MapParticle->GetMap();
00251       //              multimap<int,boost::shared_ptr<AbstractEKF> >::iterator bla;
00252       /*(*It)->Get<double>(M_X) = m_FastSLAM.m_Particles[0].ValueGet()->GetMap()->find((*It)->Get<int>(M_FEATUREID))->second->PostGet()->ExpectedValueGet()(1);
00253                     (*It)->Get<double>(M_Y) = m_FastSLAM.m_Particles[0].ValueGet()->GetMap()->find((*It)->Get<int>(M_FEATUREID))->second->PostGet()->ExpectedValueGet()(2);
00254                     (*It)->Get<double>(M_Z) = ((EKF2DLandmark*)(m_FastSLAM.m_Particles[0].ValueGet()->GetMap()->find((*It)->Get<int>(M_FEATUREID))->second.get()))->m_Height;*/
00255 
00256     }
00257     //RenderCorrespondences2D(*afl);
00258     m_DataAssociation.AddNewFeatures(&*m_AllFeatures, mask);
00259     step_++;
00260     return true;
00261   }
00262 
00263   virtual bool compute_transformation() {
00264     ROS_INFO("compute_transformation");
00265     BFL::ColumnVector* position = m_MapParticle->GetPose();
00266 
00267     Eigen::Matrix2f rot=Eigen::Matrix2f::Identity();
00268 
00269     rot(0,0) =  cosf((*position)(3));
00270     rot(0,1) = -sinf((*position)(3));
00271     rot(1,0) =  sinf((*position)(3));
00272     rot(1,1) =  cosf((*position)(3));
00273 
00274     //if(this->register_.size()>0)
00275     {
00276       m_RobotPose = *position;
00277       this->transformation_.row(0)(0) = rot.col(0)(0);
00278       this->transformation_.row(0)(1) = rot.col(0)(1);
00279       this->transformation_.row(1)(0) = rot.col(1)(0);
00280       this->transformation_.row(1)(1) = rot.col(1)(1);
00281       this->transformation_.col(3)(0) = (*position)(1);
00282       this->transformation_.col(3)(1) = (*position)(2);
00283     }
00284 
00285     ROS_INFO("phi %f", (*position)(3));
00286     std::cout << this->transformation_<<"\n";
00287 static bool first=true;
00288     if(!first)
00289     {
00290     Eigen::Matrix4f T = Eigen::Matrix4f::Identity();
00291 
00292     T.row(0)(0) = rot.col(0)(0);
00293     T.row(0)(2) = rot.col(0)(1);
00294     T.row(2)(0) = rot.col(1)(0);
00295     T.row(2)(2) = rot.col(1)(1);
00296     T.col(3)(0) = (*position)(1);
00297     T.col(3)(2) = (*position)(2);
00298 
00299     boost::shared_ptr<pcl::PointCloud<Point> > transformed_pc(new pcl::PointCloud<Point>);
00300     pcl::transformPointCloud(*this->input_, *transformed_pc, T);
00301     register_ += *transformed_pc;
00302 
00303     //this->transformation_.col(3)(0) = -(*position)(1);
00304     //this->transformation_.col(3)(2) = -(*position)(2);
00305     }
00306     first=false;
00307 
00308     //*phi = (*position)(3);
00309     return true;
00310   }
00311 
00312   virtual boost::shared_ptr<pcl::PointCloud<Point> > getMap() {
00313     return register_.makeShared(); //dummy
00314   }
00315 
00316 private:
00317 
00318   unsigned long CreateMeasurementModel()
00319   {
00320     BFL::ColumnVector measNoise_Mu(2);
00321     measNoise_Mu(1) = 0.0;
00322     measNoise_Mu(2) = 0.0;
00323 
00324     BFL::SymmetricMatrix measNoise_Cov(2);
00325     measNoise_Cov(1,1) = pow(0.1,2); //0.5
00326     measNoise_Cov(1,2) = 0;
00327     measNoise_Cov(2,1) = 0;
00328     measNoise_Cov(2,2) = pow(0.1,2); //0.5
00329     BFL::Gaussian measurement_Uncertainty(measNoise_Mu, measNoise_Cov);
00330 
00332     MeasPDF2DLandmark *meas_pdf = new MeasPDF2DLandmark(measurement_Uncertainty);
00333 
00334     m_MeasModel = new BFL::AnalyticMeasurementModelGaussianUncertainty(meas_pdf);
00335     return ipa_CameraSensors::RET_OK;
00336   }
00337 
00338   unsigned long CreateSystemModel()
00339   {
00340     BFL::ColumnVector sysNoise_Mu(3);
00341     sysNoise_Mu(1) = 0.0;
00342     sysNoise_Mu(2) = 0.0;
00343     sysNoise_Mu(3) = 0.0;
00344 
00345     BFL::SymmetricMatrix sysNoise_Cov(3);
00346     sysNoise_Cov(1,1) = pow(0.05,2); //0.01
00347     sysNoise_Cov(1,2) = 0.0;
00348     sysNoise_Cov(1,3) = 0.0;
00349     sysNoise_Cov(2,1) = 0.0;
00350     sysNoise_Cov(2,2) = pow(0.05,2); //0.01
00351     sysNoise_Cov(2,3) = 0.0;
00352     sysNoise_Cov(3,1) = 0.0;
00353     sysNoise_Cov(3,2) = 0.0;
00354     //sysNoise_Cov(3,3) = pow(0.025,2);
00355     sysNoise_Cov(3,3) = pow(0.017*3,2); //0.017
00356 
00357 
00358     BFL::Gaussian system_Uncertainty(sysNoise_Mu, sysNoise_Cov);
00360     SysPDF2DLaserNav *sys_pdf = new SysPDF2DLaserNav(system_Uncertainty);
00361     m_SysModel = new BFL::SystemModel<BFL::ColumnVector>(sys_pdf);
00362     return ipa_CameraSensors::RET_OK;
00363   }
00364 
00365   unsigned long AddFeaturesToGlobalMap(AbstractFeatureVector *afl)
00366   {
00367     std::cout << "AddFeaturesToGlobalMap" << std::endl;
00368 
00369     for (unsigned int i=0; i<m_FastSLAM.m_Particles.size(); i++)
00370     {
00371       m_FastSLAM.m_Particles[i].ValueGet()->SetPose(m_RobotPose);
00372     }
00373     //transformation_camera2base_ = m_RobotSim.GetTrafo();
00374     //CalculateTransformationTOF2PltfBase();
00375 
00376     AbstractFeatureVector::iterator It;
00377     std::vector<int> mask(afl->size(),0);
00378     for (It=afl->begin(); It!=afl->end(); It++)
00379     {
00380       ColumnVector theta(3);
00381 
00382       Eigen::Vector4f v;
00383       v(0)=(*It)->Get<double>(M_X);
00384       v(1)=(*It)->Get<double>(M_Y);
00385       v(2)=(*It)->Get<double>(M_Z);
00386       v(3)=0;
00387 
00388       v = this->transformation_ * v;
00389 
00390       (*It)->Get<double>(M_X) = v(0);
00391       (*It)->Get<double>(M_Y) = v(1);
00392       (*It)->Get<double>(M_Z) = v(2);
00393 
00394       //TransformCameraToPltfBase(*It);
00395       //cout<<(*It)->Get<double>(M_X) <<" " <<(*It)->Get<double>(M_Y) <<std::endl;
00396       (*It)->Get<int>(M_FEATUREID)=-1;
00397       m_FastSLAM.AddUnknownFeature(*m_MeasModel, *It, 0);
00398       (*It)->Get<double>(M_X) = m_FastSLAM.m_Particles[0].ValueGet()->GetMap()->find((*It)->Get<int>(M_FEATUREID))->second.operator->()->PostGet()->ExpectedValueGet()(1);
00399       (*It)->Get<double>(M_Y) = m_FastSLAM.m_Particles[0].ValueGet()->GetMap()->find((*It)->Get<int>(M_FEATUREID))->second.operator->()->PostGet()->ExpectedValueGet()(2);
00400       (*It)->Get<double>(M_Z) = ((EKF2DLandmark*)(m_FastSLAM.m_Particles[0].ValueGet()->GetMap()->find((*It)->Get<int>(M_FEATUREID))->second.get()))->m_Height;
00401     }
00402     m_MapParticle = m_FastSLAM.m_Particles[0].ValueGet();
00403     m_DataAssociation.AddNewFeatures(afl, mask);
00404     return ipa_CameraSensors::RET_OK;
00405   }
00406 
00407 
00408 };
00409 }
00410 
00411 #endif /* REGISTRATION_FASTSLAM_H_ */


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