main.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007     * Redistributions of source code must retain the above copyright
00008       notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright
00010       notice, this list of conditions and the following disclaimer in the
00011       documentation and/or other materials provided with the distribution.
00012     * Neither the name of the Universite de Sherbrooke nor the
00013       names of its contributors may be used to endorse or promote products
00014       derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00017 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
00020 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00021 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00022 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00023 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00025 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00028 #include <rtabmap/utilite/ULogger.h>
00029 #include <rtabmap/utilite/UTimer.h>
00030 #include "rtabmap/core/Rtabmap.h"
00031 #include "rtabmap/core/CameraRGB.h"
00032 #include <rtabmap/utilite/UDirectory.h>
00033 #include <rtabmap/utilite/UFile.h>
00034 #include <rtabmap/utilite/UConversion.h>
00035 #include <rtabmap/utilite/UStl.h>
00036 #include <fstream>
00037 #include <queue>
00038 #include <opencv2/core/core.hpp>
00039 #include <signal.h>
00040 
00041 using namespace rtabmap;
00042 
00043 #define GENERATED_GT_NAME "GroundTruth_generated.bmp"
00044 
00045 void showUsage()
00046 {
00047         printf("\nUsage:\n"
00048                         "rtabmap-console [options] \"path\"\n"
00049                         "  path                            For images, use the directory path. For videos or databases, use full\n "
00050                         "                                  path name\n"
00051                         "Options:\n"
00052                         "  -rate #.##                      Acquisition time (seconds)\n"
00053                         "  -rateHz #.##                    Acquisition rate (Hz), for convenience\n"
00054                         "  -repeat #                       Repeat the process on the data set # times (minimum of 1)\n"
00055                         "  -createGT                       Generate a ground truth file\n"
00056                         "  -start_at #                     When \"path\" is a directory of images, set this parameter\n"
00057                         "                                   to start processing at image # (default 0).\n"
00058                         "  -skip #                         Skip X images while reading directory (default 0).\n"
00059                         "  -v                              Get version of RTAB-Map\n"
00060                         "  -input \"path\"                 Load previous database if it exists.\n"
00061                         "%s\n",
00062                         rtabmap::Parameters::showUsage());
00063         exit(1);
00064 }
00065 
00066 // catch ctrl-c
00067 bool g_forever = true;
00068 void sighandler(int sig)
00069 {
00070         printf("\nSignal %d caught...\n", sig);
00071         g_forever = false;
00072 }
00073 
00074 int main(int argc, char * argv[])
00075 {
00076         signal(SIGABRT, &sighandler);
00077         signal(SIGTERM, &sighandler);
00078         signal(SIGINT, &sighandler);
00079 
00080         ULogger::setType(ULogger::kTypeConsole);
00081         ULogger::setLevel(ULogger::kWarning);
00082 
00083         ParametersMap pm = Parameters::parseArguments(argc, argv);
00084         pm.insert(ParametersPair(Parameters::kRtabmapWorkingDirectory(), "."));
00085 
00086         if(argc < 2)
00087         {
00088                 showUsage();
00089         }
00090         else if(argc == 2 && strcmp(argv[1], "-v") == 0)
00091         {
00092                 printf("%s\n", Parameters::getVersion().c_str());
00093                 exit(0);
00094         }
00095         printf("\n");
00096 
00097         std::string path;
00098         float rate = 0.0;
00099         int loopDataset = 0;
00100         int repeat = 0;
00101         bool createGT = false;
00102         std::string inputDbPath;
00103         int startAt = 0;
00104         int skip = 0;
00105 
00106         for(int i=1; i<argc; ++i)
00107         {
00108                 if(i == argc-1)
00109                 {
00110                         // The last must be the path
00111                         path = argv[i];
00112                         if(!UDirectory::exists(path.c_str()) && !UFile::exists(path.c_str()))
00113                         {
00114                                 printf("Path not valid : %s\n", path.c_str());
00115                                 showUsage();
00116                                 exit(1);
00117                         }
00118                         break;
00119                 }
00120                 if(strcmp(argv[i], "-rate") == 0)
00121                 {
00122                         ++i;
00123                         if(i < argc)
00124                         {
00125                                 rate = uStr2Float(argv[i]);
00126                                 if(rate < 0)
00127                                 {
00128                                         showUsage();
00129                                 }
00130                         }
00131                         else
00132                         {
00133                                 showUsage();
00134                         }
00135                         continue;
00136                 }
00137                 if(strcmp(argv[i], "-rateHz") == 0)
00138                 {
00139                         ++i;
00140                         if(i < argc)
00141                         {
00142                                 rate = uStr2Float(argv[i]);
00143                                 if(rate < 0)
00144                                 {
00145                                         showUsage();
00146                                 }
00147                                 else if(rate)
00148                                 {
00149                                         rate = 1/rate;
00150                                 }
00151                         }
00152                         else
00153                         {
00154                                 showUsage();
00155                         }
00156                         continue;
00157                 }
00158                 if(strcmp(argv[i], "-repeat") == 0)
00159                 {
00160                         ++i;
00161                         if(i < argc)
00162                         {
00163                                 repeat = std::atoi(argv[i]);
00164                                 if(repeat < 1)
00165                                 {
00166                                         showUsage();
00167                                 }
00168                         }
00169                         else
00170                         {
00171                                 showUsage();
00172                         }
00173                         continue;
00174                 }
00175                 if(strcmp(argv[i], "-start_at") == 0)
00176                 {
00177                         ++i;
00178                         if(i < argc)
00179                         {
00180                                 startAt = std::atoi(argv[i]);
00181                                 if(startAt < 0)
00182                                 {
00183                                         showUsage();
00184                                 }
00185                         }
00186                         else
00187                         {
00188                                 showUsage();
00189                         }
00190                         continue;
00191                 }
00192                 if (strcmp(argv[i], "-skip") == 0)
00193                 {
00194                         ++i;
00195                         if (i < argc)
00196                         {
00197                                 skip = std::atoi(argv[i]);
00198                                 if (skip < 0)
00199                                 {
00200                                         showUsage();
00201                                 }
00202                         }
00203                         else
00204                         {
00205                                 showUsage();
00206                         }
00207                         continue;
00208                 }
00209                 if(strcmp(argv[i], "-createGT") == 0)
00210                 {
00211                         createGT = true;
00212                         continue;
00213                 }
00214                 if(strcmp(argv[i], "-input") == 0)
00215                 {
00216                         ++i;
00217                         if(i < argc)
00218                         {
00219                                 inputDbPath = argv[i];
00220                         }
00221                         else
00222                         {
00223                                 showUsage();
00224                         }
00225                         continue;
00226                 }
00227                 if(strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0)
00228                 {
00229                         showUsage();
00230                 }
00231         }
00232 
00233         if(repeat && createGT)
00234         {
00235                 printf("Cannot create a Ground truth if repeat is on.\n");
00236                 showUsage();
00237         }
00238 
00239         UTimer timer;
00240         timer.start();
00241         std::queue<double> iterationMeanTime;
00242 
00243         Camera * camera = 0;
00244         if(UDirectory::exists(path))
00245         {
00246                 camera = new CameraImages(path, rate>0.0f?1.0f/rate:0.0f);
00247                 ((CameraImages*)camera)->setStartIndex(startAt);
00248         }
00249         else
00250         {
00251                 camera = new CameraVideo(path, false, rate>0.0f?1.0f/rate:0.0f);
00252         }
00253 
00254         if(!camera || !camera->init())
00255         {
00256                 printf("Camera init failed, using path \"%s\"\n", path.c_str());
00257                 exit(1);
00258         }
00259 
00260         std::map<int, int> groundTruth;
00261 
00262         // Create tasks
00263         Rtabmap rtabmap;
00264         if(inputDbPath.empty())
00265         {
00266                 inputDbPath = "rtabmapconsole.db";
00267                 if(UFile::erase(inputDbPath) == 0)
00268                 {
00269                         printf("Deleted database \"%s\".\n", inputDbPath.c_str());
00270                 }
00271         }
00272         else
00273         {
00274                 printf("Loading database \"%s\".\n", inputDbPath.c_str());
00275         }
00276 
00277         // Disable statistics (we don't need them)
00278         uInsert(pm, ParametersPair(Parameters::kRtabmapPublishStats(), "false"));
00279         uInsert(pm, ParametersPair(Parameters::kRGBDEnabled(), "false"));
00280 
00281         // Process an empty image to make sure every libraries are loaded.
00282         ULogger::Level level = ULogger::level();
00283         ULogger::setLevel(ULogger::kError);
00284         cv::Mat tmp = cv::Mat::zeros(640,480,CV_8UC1);
00285         rtabmap.init(pm);
00286         rtabmap.process(tmp);
00287         rtabmap.close(false);
00288         ULogger::setLevel(level);
00289 
00290         rtabmap.init(pm, inputDbPath);
00291 
00292         printf("rtabmap init time = %fs\n", timer.ticks());
00293 
00294         // Start thread's task
00295         int loopClosureId;
00296         int count = 0;
00297         int countLoopDetected=0;
00298 
00299         printf("\nParameters : \n");
00300         printf(" Data set : %s\n", path.c_str());
00301         printf(" Time threshold = %1.2f ms\n", rtabmap.getTimeThreshold());
00302         printf(" Image rate = %1.2f s (%1.2f Hz)\n", rate, 1/rate);
00303         printf(" Repeating data set = %s\n", repeat?"true":"false");
00304         printf(" Camera starts at image %d (default 0)\n", startAt);
00305         printf(" Skip image = %d\n", skip);
00306         if(createGT)
00307         {
00308                 printf(" Creating the ground truth matrix.\n");
00309         }
00310         printf(" INFO: All other parameters are set to defaults\n");
00311         if(pm.size()>1)
00312         {
00313                 printf("   Overwritten parameters :\n");
00314                 for(ParametersMap::iterator iter = pm.begin(); iter!=pm.end(); ++iter)
00315                 {
00316                         printf("    %s=%s\n",iter->first.c_str(), iter->second.c_str());
00317                 }
00318         }
00319         if(rtabmap.getWM().size() || rtabmap.getSTM().size())
00320         {
00321                 printf("[Warning] RTAB-Map database is not empty (%s)\n", inputDbPath.c_str());
00322         }
00323         printf("\nProcessing images...\n");
00324 
00325         UTimer iterationTimer;
00326         UTimer rtabmapTimer;
00327         int imagesProcessed = 0;
00328         std::list<std::vector<float> > teleopActions;
00329         while(loopDataset <= repeat && g_forever)
00330         {
00331                 SensorData data = camera->takeImage();
00332                 int i=0;
00333                 double maxIterationTime = 0.0;
00334                 int maxIterationTimeId = 0;
00335                 while(!data.imageRaw().empty() && g_forever)
00336                 {
00337                         ++imagesProcessed;
00338                         iterationTimer.start();
00339                         rtabmapTimer.start();
00340                         rtabmap.process(data.imageRaw());
00341                         double rtabmapTime = rtabmapTimer.elapsed();
00342                         loopClosureId = rtabmap.getLoopClosureId();
00343                         if(rtabmap.getLoopClosureId())
00344                         {
00345                                 ++countLoopDetected;
00346                         }
00347                         for(int j=0; j<=skip; ++j)
00348                         {
00349                                 data = camera->takeImage();
00350                         }
00351                         if(++count % 100 == 0)
00352                         {
00353                                 printf(" count = %d, loop closures = %d, max time (at %d) = %fs\n",
00354                                                 count, countLoopDetected, maxIterationTimeId, maxIterationTime);
00355                                 maxIterationTime = 0.0;
00356                                 maxIterationTimeId = 0;
00357                                 std::map<int, int> wm = rtabmap.getWeights();
00358                                 printf(" WM(%d)=[", (int)wm.size());
00359                                 for(std::map<int, int>::iterator iter=wm.begin(); iter!=wm.end();++iter)
00360                                 {
00361                                         if(iter != wm.begin())
00362                                         {
00363                                                 printf(";");
00364                                         }
00365                                         printf("%d,%d", iter->first, iter->second);
00366                                 }
00367                                 printf("]\n");
00368                         }
00369 
00370                         // Update generated ground truth matrix
00371                         if(createGT)
00372                         {
00373                                 if(loopClosureId > 0)
00374                                 {
00375                                         groundTruth.insert(std::make_pair(i, loopClosureId-1));
00376                                 }
00377                         }
00378 
00379                         ++i;
00380 
00381                         double iterationTime = iterationTimer.ticks();
00382 
00383                         if(rtabmapTime > maxIterationTime)
00384                         {
00385                                 maxIterationTime = rtabmapTime;
00386                                 maxIterationTimeId = count;
00387                         }
00388 
00389                         ULogger::flush();
00390 
00391                         if(rtabmap.getLoopClosureId())
00392                         {
00393                                 printf(" iteration(%d) loop(%d) hyp(%.2f) time=%fs/%fs *\n",
00394                                                 count, rtabmap.getLoopClosureId(), rtabmap.getLoopClosureValue(), rtabmapTime, iterationTime);
00395                         }
00396                         else if(rtabmap.getHighestHypothesisId())
00397                         {
00398                                 printf(" iteration(%d) high(%d) hyp(%.2f) time=%fs/%fs\n",
00399                                                 count, rtabmap.getHighestHypothesisId(), rtabmap.getHighestHypothesisValue(), rtabmapTime, iterationTime);
00400                         }
00401                         else
00402                         {
00403                                 printf(" iteration(%d) time=%fs/%fs\n", count, rtabmapTime, iterationTime);
00404                         }
00405 
00406                         if(rtabmap.getTimeThreshold() && rtabmapTime > rtabmap.getTimeThreshold()*100.0f)
00407                         {
00408                                 printf(" ERROR,  there is  problem, too much time taken... %fs", rtabmapTime);
00409                                 break; // there is  problem, don't continue
00410                         }
00411                 }
00412                 ++loopDataset;
00413                 if(loopDataset <= repeat)
00414                 {
00415                         camera->init();
00416                         printf(" Beginning loop %d...\n", loopDataset);
00417                 }
00418         }
00419         printf("Processing images completed. Loop closures found = %d\n", countLoopDetected);
00420         printf(" Total time = %fs\n", timer.ticks());
00421 
00422         if(imagesProcessed && createGT)
00423         {
00424                 cv::Mat groundTruthMat = cv::Mat::zeros(imagesProcessed, imagesProcessed, CV_8U);
00425 
00426                 for(std::map<int, int>::iterator iter = groundTruth.begin(); iter!=groundTruth.end(); ++iter)
00427                 {
00428                         groundTruthMat.at<unsigned char>(iter->first, iter->second) = 255;
00429                 }
00430 
00431                 // Generate the ground truth file
00432                 printf("Generate ground truth to file %s, size of %d\n", GENERATED_GT_NAME, groundTruthMat.rows);
00433                 cv::imwrite(GENERATED_GT_NAME, groundTruthMat);
00434                 printf(" Creating ground truth file = %fs\n", timer.ticks());
00435         }
00436 
00437         if(camera)
00438         {
00439                 delete camera;
00440                 camera = 0 ;
00441         }
00442 
00443         rtabmap.close();
00444 
00445         printf(" Cleanup time = %fs\n", timer.ticks());
00446 
00447         printf("Database (\"%s\") and log files saved to current directory.\n", inputDbPath.c_str());
00448 
00449         return 0;
00450 }


rtabmap
Author(s): Mathieu Labbe
autogenerated on Thu Jun 6 2019 21:59:20