00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <mrpt_localization/mrpt_localization.h>
00031 #include <mrpt_localization/mrpt_localization_defaults.h>
00032 #include <mrpt/base.h>
00033
00034
00035 #include <mrpt_bridge/map.h>
00036
00037 #include <mrpt/system/filesystem.h>
00038 #include <mrpt/opengl/CEllipsoid.h>
00039 #include <mrpt/opengl/CPointCloud.h>
00040
00041 using namespace mrpt;
00042 using namespace mrpt::slam;
00043 using namespace mrpt::opengl;
00044 using namespace mrpt::gui;
00045 using namespace mrpt::math;
00046 using namespace mrpt::system;
00047 using namespace mrpt::utils;
00048 using namespace std;
00049
00050
00051 PFLocalization::~PFLocalization()
00052 {
00053 }
00054
00055 PFLocalization::PFLocalization(Parameters *param)
00056 : PFLocalizationCore(), param_(param) {
00057 }
00058
00059 void PFLocalization::init() {
00060 printf("iniFile ready %s\n", param_->iniFile.c_str());
00061 ASSERT_FILE_EXISTS_(param_->iniFile);
00062 printf("ASSERT_FILE_EXISTS_ %s\n", param_->iniFile.c_str());
00063 mrpt::utils::CConfigFile iniFile;
00064 iniFile.setFileName(param_->iniFile);
00065 printf("CConfigFile %s\n", param_->iniFile.c_str());
00066
00067
00068 vector_int particles_count;
00069
00070
00071
00072 string iniSectionName ( "LocalizationExperiment" );
00073 update_counter_ = 0;
00074
00075
00076 iniFile.read_vector(iniSectionName, "particles_count", vector_int(1,0), particles_count, true );
00077
00078
00079 if (param_->mapFile.empty()) {
00080 param_->mapFile = iniFile.read_string(iniSectionName,"map_file","" );
00081 }
00082
00083
00084 SCENE3D_FREQ_ = iniFile.read_int(iniSectionName,"3DSceneFrequency",10);
00085 SCENE3D_FOLLOW_ = iniFile.read_bool(iniSectionName,"3DSceneFollowRobot",true);
00086
00087 SHOW_PROGRESS_3D_REAL_TIME_ = iniFile.read_bool(iniSectionName,"SHOW_PROGRESS_3D_REAL_TIME",false);
00088 SHOW_PROGRESS_3D_REAL_TIME_DELAY_MS_ = iniFile.read_int(iniSectionName,"SHOW_PROGRESS_3D_REAL_TIME_DELAY_MS",1);
00089
00090 #if !MRPT_HAS_WXWIDGETS
00091 SHOW_PROGRESS_3D_REAL_TIME_ = false;
00092 #endif
00093
00094
00095
00096 motion_model_default_options_.modelSelection = CActionRobotMovement2D::mmGaussian;
00097 motion_model_default_options_.gausianModel.minStdXY = iniFile.read_double("DummyOdometryParams","minStdXY",0.04);
00098 motion_model_default_options_.gausianModel.minStdPHI = DEG2RAD(iniFile.read_double("DefaultOdometryParams","minStdPHI", 2.0));
00099
00100
00101 if ( !iniFile.read_bool(iniSectionName,"init_PDF_mode",false, true) ) {
00102 float min_x = iniFile.read_float(iniSectionName,"init_PDF_min_x",0,true);
00103 float max_x = iniFile.read_float(iniSectionName,"init_PDF_max_x",0,true);
00104 float min_y = iniFile.read_float(iniSectionName,"init_PDF_min_y",0,true);
00105 float max_y = iniFile.read_float(iniSectionName,"init_PDF_max_y",0,true);
00106 float min_phi = DEG2RAD(iniFile.read_float(iniSectionName,"init_PDF_min_phi_deg",-180));
00107 float max_phi = DEG2RAD(iniFile.read_float(iniSectionName,"init_PDF_max_phi_deg",180));
00108 mrpt::poses::CPose2D p;
00109 mrpt::math::CMatrixDouble33 cov;
00110 cov(0,0) = fabs(max_x - min_x);
00111 cov(1,1) = fabs(max_x - min_x);
00112 cov(2,2) = min_phi<max_phi ? max_phi-min_phi : (max_phi+2*M_PI)-min_phi;
00113 p.x() = min_x + cov(0,0) / 2.0;
00114 p.y() = min_y + cov(1,1) / 2.0;
00115 p.phi() = min_phi + cov(2,2) / 2.0;
00116 printf("----------- phi: %4.3f: %4.3f <-> %4.3f, %4.3f\n", p.phi(), min_phi, max_phi, cov(2,2));
00117 initialPose_ = mrpt::utils::CPosePDFGaussian(p, cov);
00118 state_ = INIT;
00119 } else {
00120 log_error("no initial pose");
00121 }
00122
00123
00124 configureFilter(iniFile);
00125
00126
00127 if(!mrpt_bridge::MapHdl::loadMap(metric_map_, iniFile, param_->mapFile, "metricMap", param_->debug)) {
00128 waitForMap();
00129 }
00130
00131 initialParticleCount_ = *particles_count.begin();
00132
00133 if(param_->gui_mrpt) init3DDebug();
00134
00135 }
00136
00137 void PFLocalization::configureFilter(const mrpt::utils::CConfigFile &_configFile) {
00138
00139
00140
00141 CParticleFilter::TParticleFilterOptions pfOptions;
00142 pfOptions.loadFromConfigFile( _configFile, "PF_options" );
00143 pfOptions.dumpToConsole();
00144
00145
00146
00147 TMonteCarloLocalizationParams pdfPredictionOptions;
00148 pdfPredictionOptions.KLD_params.loadFromConfigFile( _configFile, "KLD_options");
00149
00150 pdf_.clear();
00151
00152
00153 pdf_.options = pdfPredictionOptions;
00154
00155 pdf_.options.metricMap = &metric_map_;
00156
00157
00158 pf_.m_options = pfOptions;
00159 }
00160
00161 void PFLocalization::init3DDebug() {
00162 log_info("init3DDebug");
00163 if (!SHOW_PROGRESS_3D_REAL_TIME_) return;
00164 if(!win3D_) {
00165 win3D_ = CDisplayWindow3D::Create("pf-localization - The MRPT project", 1000, 600);
00166 win3D_->setCameraZoom(20);
00167 win3D_->setCameraAzimuthDeg(-45);
00168
00169
00170
00171 mrpt::slam::COccupancyGridMap2D::TEntropyInfo gridInfo;
00172
00173 if (metric_map_.m_gridMaps.size())
00174 {
00175 metric_map_.m_gridMaps[0]->computeEntropy( gridInfo );
00176 printf("The gridmap has %.04fm2 observed area, %u observed cells\n", gridInfo.effectiveMappedArea, (unsigned) gridInfo.effectiveMappedCells );
00177
00178 {
00179 CSetOfObjectsPtr plane = CSetOfObjects::Create();
00180 metric_map_.m_gridMaps[0]->getAs3DObject( plane );
00181 scene_.insert( plane );
00182 }
00183
00184 if (SHOW_PROGRESS_3D_REAL_TIME_)
00185 {
00186 COpenGLScenePtr ptrScene = win3D_->get3DSceneAndLock();
00187
00188 CSetOfObjectsPtr plane = CSetOfObjects::Create();
00189 metric_map_.m_gridMaps[0]->getAs3DObject( plane );
00190 ptrScene->insert( plane );
00191
00192 ptrScene->enableFollowCamera(true);
00193
00194 win3D_->unlockAccess3DScene();
00195 }
00196 }
00197 printf("Initial PDF: %f particles/m2\n", initialParticleCount_/gridInfo.effectiveMappedArea);
00198 }
00199 if(param_->debug) printf(" --------------------------- init3DDebug done \n");
00200 if(param_->debug) fflush(stdout);
00201 }
00202
00203 void PFLocalization::show3DDebug(CSensoryFramePtr _observations) {
00204
00205 if (SHOW_PROGRESS_3D_REAL_TIME_)
00206 {
00207 TTimeStamp cur_obs_timestamp;
00208 if (_observations->size()>0)
00209 cur_obs_timestamp = _observations->getObservationByIndex(0)->timestamp;
00210
00211 CPose2D meanPose;
00212 CMatrixDouble33 cov;
00213 pdf_.getCovarianceAndMean(cov,meanPose);
00214
00215 COpenGLScenePtr ptrScene = win3D_->get3DSceneAndLock();
00216
00217 win3D_->setCameraPointingToPoint(meanPose.x(),meanPose.y(),0);
00218 win3D_->addTextMessage(
00219 10,10, mrpt::format("timestamp: %s", mrpt::system::dateTimeLocalToString(cur_obs_timestamp).c_str() ),
00220 mrpt::utils::TColorf(.8f,.8f,.8f),
00221 "mono", 15, mrpt::opengl::NICE, 6001 );
00222
00223 win3D_->addTextMessage(
00224 10,33, mrpt::format("#particles= %7u", static_cast<unsigned int>(pdf_.size()) ),
00225 mrpt::utils::TColorf(.8f,.8f,.8f),
00226 "mono", 15, mrpt::opengl::NICE, 6002 );
00227
00228 win3D_->addTextMessage(
00229 10,55, mrpt::format("mean pose (x y phi_deg)= %s", meanPose.asString().c_str() ),
00230 mrpt::utils::TColorf(.8f,.8f,.8f),
00231 "mono", 15, mrpt::opengl::NICE, 6003 );
00232
00233
00234 {
00235 CRenderizablePtr parts = ptrScene->getByName("particles");
00236 if (parts) ptrScene->removeObject(parts);
00237
00238 CSetOfObjectsPtr p = pdf_.getAs3DObject<CSetOfObjectsPtr>();
00239 p->setName("particles");
00240 ptrScene->insert(p);
00241 }
00242
00243
00244 {
00245 CRenderizablePtr ellip = ptrScene->getByName("parts_cov");
00246 if (!ellip)
00247 {
00248 ellip = CEllipsoid::Create();
00249 ellip->setName( "parts_cov");
00250 ellip->setColor(1,0,0, 0.6);
00251
00252 getAs<CEllipsoid>(ellip)->setLineWidth(2);
00253 getAs<CEllipsoid>(ellip)->setQuantiles(3);
00254 getAs<CEllipsoid>(ellip)->set2DsegmentsCount(60);
00255 ptrScene->insert( ellip );
00256 }
00257 ellip->setLocation(meanPose.x(), meanPose.y(), 0.05 );
00258
00259 getAs<CEllipsoid>(ellip)->setCovMatrix(cov,2);
00260 }
00261
00262
00263
00264 {
00265 CRenderizablePtr scanPts = ptrScene->getByName("scan");
00266 if (!scanPts)
00267 {
00268 scanPts = CPointCloud::Create();
00269 scanPts->setName( "scan" );
00270 scanPts->setColor(1,0,0, 0.9);
00271 getAs<CPointCloud>(scanPts)->enableColorFromZ(false);
00272 getAs<CPointCloud>(scanPts)->setPointSize(4);
00273 ptrScene->insert(scanPts);
00274 }
00275
00276 CSimplePointsMap map;
00277 static CSimplePointsMap last_map;
00278
00279 CPose3D robotPose3D( meanPose );
00280
00281 map.clear();
00282 _observations->insertObservationsInto( &map );
00283
00284 getAs<CPointCloud>(scanPts)->loadFromPointsMap( &last_map );
00285 getAs<CPointCloud>(scanPts)->setPose( robotPose3D );
00286 last_map = map;
00287 }
00288
00289
00290 ptrScene->enableFollowCamera(true);
00291
00292
00293 COpenGLViewportPtr view1= ptrScene->getViewport("main");
00294 {
00295 CCamera &cam = view1->getCamera();
00296 cam.setAzimuthDegrees(-90);
00297 cam.setElevationDegrees(90);
00298 cam.setPointingAt( meanPose );
00299 cam.setZoomDistance(5);
00300 cam.setOrthogonal();
00301 }
00302
00303 win3D_->unlockAccess3DScene();
00304
00305
00306
00307
00308
00309 win3D_->forceRepaint();
00310
00311 sleep( SHOW_PROGRESS_3D_REAL_TIME_DELAY_MS_ );
00312 }
00313 }
00314