00001
00059
00060
00061
00062
00063
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),
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);
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
00136
00137
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
00188
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
00205 m_FastSLAM.UpdateKnownFeature(*m_MeasModel, *m_SysModel, *It, ctrAssociations);
00206
00207 }
00208
00209
00210
00211
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
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
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
00242
00246 if((*It)->Get<int>(M_FEATUREID) == -1)
00247 {
00248 if ( mask[i] == 0) m_FastSLAM.AddUnknownFeature(*m_MeasModel, *It, step_);
00249 }
00250
00251
00252
00253
00254
00255
00256 }
00257
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
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
00304
00305 }
00306 first=false;
00307
00308
00309 return true;
00310 }
00311
00312 virtual boost::shared_ptr<pcl::PointCloud<Point> > getMap() {
00313 return register_.makeShared();
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);
00326 measNoise_Cov(1,2) = 0;
00327 measNoise_Cov(2,1) = 0;
00328 measNoise_Cov(2,2) = pow(0.1,2);
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);
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);
00351 sysNoise_Cov(2,3) = 0.0;
00352 sysNoise_Cov(3,1) = 0.0;
00353 sysNoise_Cov(3,2) = 0.0;
00354
00355 sysNoise_Cov(3,3) = pow(0.017*3,2);
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
00374
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
00395
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