mrpt_localization.cpp
Go to the documentation of this file.
00001 /***********************************************************************************
00002  * Revised BSD License                                                             *
00003  * Copyright (c) 2014, Markus Bader <markus.bader@tuwien.ac.at>                    *
00004  * All rights reserved.                                                            *
00005  *                                                                                 *
00006  * Redistribution and use in source and binary forms, with or without              *
00007  * modification, are permitted provided that the following conditions are met:     *
00008  *     * Redistributions of source code must retain the above copyright            *
00009  *       notice, this list of conditions and the following disclaimer.             *
00010  *     * Redistributions in binary form must reproduce the above copyright         *
00011  *       notice, this list of conditions and the following disclaimer in the       *
00012  *       documentation and/or other materials provided with the distribution.      *
00013  *     * Neither the name of the Vienna University of Technology nor the           *
00014  *       names of its contributors may be used to endorse or promote products      *
00015  *       derived from this software without specific prior written permission.     *
00016  *                                                                                 *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND *
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED   *
00019  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE          *
00020  * DISCLAIMED. IN NO EVENT SHALL Markus Bader BE LIABLE FOR ANY                    *
00021  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      *
00022  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    *
00023  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND     *
00024  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT      *
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   *
00026  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                    *                       *
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;    // Number of initial particles (if size>1, run the experiments N times)
00069 
00070     // Load configuration:
00071     // -----------------------------------------
00072     string iniSectionName ( "LocalizationExperiment" );
00073     update_counter_ = 0;
00074 
00075     // Mandatory entries:
00076     iniFile.read_vector(iniSectionName, "particles_count", vector_int(1,0), particles_count, /*Fail if not found*/true );
00077 
00078 
00079     if (param_->mapFile.empty()) {
00080         param_->mapFile = iniFile.read_string(iniSectionName,"map_file","" );
00081     }
00082 
00083     // Non-mandatory entries:
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     // Default odometry uncertainty parameters in "odom_params_default_" depending on how fast the robot moves, etc...
00095     //  Only used for observations-only rawlogs:
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, /*Fail if not found*/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     // Metric map options:
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     // PF-algorithm Options:
00140     // ---------------------------
00141     CParticleFilter::TParticleFilterOptions     pfOptions;
00142     pfOptions.loadFromConfigFile( _configFile, "PF_options" );
00143     pfOptions.dumpToConsole();
00144 
00145     // PDF Options:
00146     // ------------------
00147     TMonteCarloLocalizationParams   pdfPredictionOptions;
00148     pdfPredictionOptions.KLD_params.loadFromConfigFile( _configFile, "KLD_options");
00149 
00150     pdf_.clear();
00151 
00152     // PDF Options:
00153     pdf_.options = pdfPredictionOptions;
00154 
00155     pdf_.options.metricMap = &metric_map_;
00156 
00157     // Create the PF object:
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         //win3D_->waitForKey();
00169 
00170         // Create the 3D scene and get the map only once, later we'll modify only the particles, etc..
00171         mrpt::slam::COccupancyGridMap2D::TEntropyInfo gridInfo;
00172         // The gridmap:
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     } // Show 3D?
00199     if(param_->debug) printf(" --------------------------- init3DDebug done \n");
00200     if(param_->debug) fflush(stdout);
00201 }
00202 
00203 void PFLocalization::show3DDebug(CSensoryFramePtr _observations) {
00204     // Create 3D window if requested:
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         // The particles:
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         // The particles' cov:
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         // The laser scan:
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         // The camera:
00290         ptrScene->enableFollowCamera(true);
00291 
00292         // Views:
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         // Move camera:
00306         //win3D_->setCameraPointingToPoint( curRobotPose.x, curRobotPose.y, curRobotPose.z );
00307 
00308         // Update:
00309         win3D_->forceRepaint();
00310 
00311         sleep( SHOW_PROGRESS_3D_REAL_TIME_DELAY_MS_ );
00312     }
00313 }
00314 


mrpt_localization
Author(s): Markus Bader
autogenerated on Mon Aug 11 2014 11:23:29