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                         "  -v                              Get version of RTAB-Map\n"
00059                         "  -input \"path\"                 Load previous database if it exists.\n"
00060                         "%s\n",
00061                         rtabmap::Parameters::showUsage());
00062         exit(1);
00063 }
00064 
00065 // catch ctrl-c
00066 bool g_forever = true;
00067 void sighandler(int sig)
00068 {
00069         printf("\nSignal %d caught...\n", sig);
00070         g_forever = false;
00071 }
00072 
00073 int main(int argc, char * argv[])
00074 {
00075         signal(SIGABRT, &sighandler);
00076         signal(SIGTERM, &sighandler);
00077         signal(SIGINT, &sighandler);
00078 
00079         ULogger::setType(ULogger::kTypeConsole);
00080         ULogger::setLevel(ULogger::kWarning);
00081 
00082         ParametersMap pm = Parameters::parseArguments(argc, argv);
00083         pm.insert(ParametersPair(Parameters::kRtabmapWorkingDirectory(), "."));
00084 
00085         if(argc < 2)
00086         {
00087                 showUsage();
00088         }
00089         else if(argc == 2 && strcmp(argv[1], "-v") == 0)
00090         {
00091                 printf("%s\n", Parameters::getVersion().c_str());
00092                 exit(0);
00093         }
00094         printf("\n");
00095 
00096         std::string path;
00097         float rate = 0.0;
00098         int loopDataset = 0;
00099         int repeat = 0;
00100         bool createGT = false;
00101         std::string inputDbPath;
00102         int startAt = 0;
00103 
00104         for(int i=1; i<argc; ++i)
00105         {
00106                 if(i == argc-1)
00107                 {
00108                         // The last must be the path
00109                         path = argv[i];
00110                         if(!UDirectory::exists(path.c_str()) && !UFile::exists(path.c_str()))
00111                         {
00112                                 printf("Path not valid : %s\n", path.c_str());
00113                                 showUsage();
00114                                 exit(1);
00115                         }
00116                         break;
00117                 }
00118                 if(strcmp(argv[i], "-rate") == 0)
00119                 {
00120                         ++i;
00121                         if(i < argc)
00122                         {
00123                                 rate = uStr2Float(argv[i]);
00124                                 if(rate < 0)
00125                                 {
00126                                         showUsage();
00127                                 }
00128                         }
00129                         else
00130                         {
00131                                 showUsage();
00132                         }
00133                         continue;
00134                 }
00135                 if(strcmp(argv[i], "-rateHz") == 0)
00136                 {
00137                         ++i;
00138                         if(i < argc)
00139                         {
00140                                 rate = uStr2Float(argv[i]);
00141                                 if(rate < 0)
00142                                 {
00143                                         showUsage();
00144                                 }
00145                                 else if(rate)
00146                                 {
00147                                         rate = 1/rate;
00148                                 }
00149                         }
00150                         else
00151                         {
00152                                 showUsage();
00153                         }
00154                         continue;
00155                 }
00156                 if(strcmp(argv[i], "-repeat") == 0)
00157                 {
00158                         ++i;
00159                         if(i < argc)
00160                         {
00161                                 repeat = std::atoi(argv[i]);
00162                                 if(repeat < 1)
00163                                 {
00164                                         showUsage();
00165                                 }
00166                         }
00167                         else
00168                         {
00169                                 showUsage();
00170                         }
00171                         continue;
00172                 }
00173                 if(strcmp(argv[i], "-start_at") == 0)
00174                 {
00175                         ++i;
00176                         if(i < argc)
00177                         {
00178                                 startAt = std::atoi(argv[i]);
00179                                 if(startAt < 0)
00180                                 {
00181                                         showUsage();
00182                                 }
00183                         }
00184                         else
00185                         {
00186                                 showUsage();
00187                         }
00188                         continue;
00189                 }
00190                 if(strcmp(argv[i], "-createGT") == 0)
00191                 {
00192                         createGT = true;
00193                         continue;
00194                 }
00195                 if(strcmp(argv[i], "-input") == 0)
00196                 {
00197                         ++i;
00198                         if(i < argc)
00199                         {
00200                                 inputDbPath = argv[i];
00201                         }
00202                         else
00203                         {
00204                                 showUsage();
00205                         }
00206                         continue;
00207                 }
00208                 if(strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0)
00209                 {
00210                         showUsage();
00211                 }
00212         }
00213 
00214         if(repeat && createGT)
00215         {
00216                 printf("Cannot create a Ground truth if repeat is on.\n");
00217                 showUsage();
00218         }
00219 
00220         UTimer timer;
00221         timer.start();
00222         std::queue<double> iterationMeanTime;
00223 
00224         Camera * camera = 0;
00225         if(UDirectory::exists(path))
00226         {
00227                 camera = new CameraImages(path, rate>0.0f?1.0f/rate:0.0f);
00228                 ((CameraImages*)camera)->setStartIndex(startAt);
00229         }
00230         else
00231         {
00232                 camera = new CameraVideo(path, false, rate>0.0f?1.0f/rate:0.0f);
00233         }
00234 
00235         if(!camera || !camera->init())
00236         {
00237                 printf("Camera init failed, using path \"%s\"\n", path.c_str());
00238                 exit(1);
00239         }
00240 
00241         std::map<int, int> groundTruth;
00242 
00243         // Create tasks
00244         Rtabmap rtabmap;
00245         if(inputDbPath.empty())
00246         {
00247                 inputDbPath = "rtabmapconsole.db";
00248                 if(UFile::erase(inputDbPath) == 0)
00249                 {
00250                         printf("Deleted database \"%s\".\n", inputDbPath.c_str());
00251                 }
00252         }
00253         else
00254         {
00255                 printf("Loading database \"%s\".\n", inputDbPath.c_str());
00256         }
00257 
00258         // Disable statistics (we don't need them)
00259         uInsert(pm, ParametersPair(Parameters::kRtabmapPublishStats(), "false"));
00260         uInsert(pm, ParametersPair(Parameters::kRGBDEnabled(), "false"));
00261 
00262         rtabmap.init(pm, inputDbPath);
00263 
00264         printf("rtabmap init time = %fs\n", timer.ticks());
00265 
00266         // Start thread's task
00267         int loopClosureId;
00268         int count = 0;
00269         int countLoopDetected=0;
00270 
00271         printf("\nParameters : \n");
00272         printf(" Data set : %s\n", path.c_str());
00273         printf(" Time threshold = %1.2f ms\n", rtabmap.getTimeThreshold());
00274         printf(" Image rate = %1.2f s (%1.2f Hz)\n", rate, 1/rate);
00275         printf(" Repeating data set = %s\n", repeat?"true":"false");
00276         printf(" Camera starts at image %d (default 1)\n", startAt);
00277         if(createGT)
00278         {
00279                 printf(" Creating the ground truth matrix.\n");
00280         }
00281         printf(" INFO: All other parameters are set to defaults\n");
00282         if(pm.size()>1)
00283         {
00284                 printf("   Overwritten parameters :\n");
00285                 for(ParametersMap::iterator iter = pm.begin(); iter!=pm.end(); ++iter)
00286                 {
00287                         printf("    %s=%s\n",iter->first.c_str(), iter->second.c_str());
00288                 }
00289         }
00290         if(rtabmap.getWM().size() || rtabmap.getSTM().size())
00291         {
00292                 printf("[Warning] RTAB-Map database is not empty (%s)\n", inputDbPath.c_str());
00293         }
00294         printf("\nProcessing images...\n");
00295 
00296         UTimer iterationTimer;
00297         UTimer rtabmapTimer;
00298         int imagesProcessed = 0;
00299         std::list<std::vector<float> > teleopActions;
00300         while(loopDataset <= repeat && g_forever)
00301         {
00302                 SensorData data = camera->takeImage();
00303                 int i=0;
00304                 double maxIterationTime = 0.0;
00305                 int maxIterationTimeId = 0;
00306                 while(!data.imageRaw().empty() && g_forever)
00307                 {
00308                         ++imagesProcessed;
00309                         iterationTimer.start();
00310                         rtabmapTimer.start();
00311                         rtabmap.process(data.imageRaw());
00312                         double rtabmapTime = rtabmapTimer.elapsed();
00313                         loopClosureId = rtabmap.getLoopClosureId();
00314                         if(rtabmap.getLoopClosureId())
00315                         {
00316                                 ++countLoopDetected;
00317                         }
00318                         data = camera->takeImage();
00319                         if(++count % 100 == 0)
00320                         {
00321                                 printf(" count = %d, loop closures = %d, max time (at %d) = %fs\n",
00322                                                 count, countLoopDetected, maxIterationTimeId, maxIterationTime);
00323                                 maxIterationTime = 0.0;
00324                                 maxIterationTimeId = 0;
00325                                 std::map<int, int> wm = rtabmap.getWeights();
00326                                 printf(" WM(%d)=[", (int)wm.size());
00327                                 for(std::map<int, int>::iterator iter=wm.begin(); iter!=wm.end();++iter)
00328                                 {
00329                                         if(iter != wm.begin())
00330                                         {
00331                                                 printf(";");
00332                                         }
00333                                         printf("%d,%d", iter->first, iter->second);
00334                                 }
00335                                 printf("]\n");
00336                         }
00337 
00338                         // Update generated ground truth matrix
00339                         if(createGT)
00340                         {
00341                                 if(loopClosureId > 0)
00342                                 {
00343                                         groundTruth.insert(std::make_pair(i, loopClosureId-1));
00344                                 }
00345                         }
00346 
00347                         ++i;
00348 
00349                         double iterationTime = iterationTimer.ticks();
00350 
00351                         if(rtabmapTime > maxIterationTime)
00352                         {
00353                                 maxIterationTime = rtabmapTime;
00354                                 maxIterationTimeId = count;
00355                         }
00356 
00357                         ULogger::flush();
00358 
00359                         if(rtabmap.getLoopClosureId())
00360                         {
00361                                 printf(" iteration(%d) loop(%d) hyp(%.2f) time=%fs/%fs *\n",
00362                                                 count, rtabmap.getLoopClosureId(), rtabmap.getLoopClosureValue(), rtabmapTime, iterationTime);
00363                         }
00364                         else if(rtabmap.getHighestHypothesisId())
00365                         {
00366                                 printf(" iteration(%d) high(%d) hyp(%.2f) time=%fs/%fs\n",
00367                                                 count, rtabmap.getHighestHypothesisId(), rtabmap.getHighestHypothesisValue(), rtabmapTime, iterationTime);
00368                         }
00369                         else
00370                         {
00371                                 printf(" iteration(%d) time=%fs/%fs\n", count, rtabmapTime, iterationTime);
00372                         }
00373 
00374                         if(rtabmap.getTimeThreshold() && rtabmapTime > rtabmap.getTimeThreshold()*100.0f)
00375                         {
00376                                 printf(" ERROR,  there is  problem, too much time taken... %fs", rtabmapTime);
00377                                 break; // there is  problem, don't continue
00378                         }
00379                 }
00380                 ++loopDataset;
00381                 if(loopDataset <= repeat)
00382                 {
00383                         camera->init();
00384                         printf(" Beginning loop %d...\n", loopDataset);
00385                 }
00386         }
00387         printf("Processing images completed. Loop closures found = %d\n", countLoopDetected);
00388         printf(" Total time = %fs\n", timer.ticks());
00389 
00390         if(imagesProcessed && createGT)
00391         {
00392                 cv::Mat groundTruthMat = cv::Mat::zeros(imagesProcessed, imagesProcessed, CV_8U);
00393 
00394                 for(std::map<int, int>::iterator iter = groundTruth.begin(); iter!=groundTruth.end(); ++iter)
00395                 {
00396                         groundTruthMat.at<unsigned char>(iter->first, iter->second) = 255;
00397                 }
00398 
00399                 // Generate the ground truth file
00400                 printf("Generate ground truth to file %s, size of %d\n", GENERATED_GT_NAME, groundTruthMat.rows);
00401                 cv::imwrite(GENERATED_GT_NAME, groundTruthMat);
00402                 printf(" Creating ground truth file = %fs\n", timer.ticks());
00403         }
00404 
00405         if(camera)
00406         {
00407                 delete camera;
00408                 camera = 0 ;
00409         }
00410 
00411         rtabmap.close();
00412 
00413         printf(" Cleanup time = %fs\n", timer.ticks());
00414 
00415         printf("Database (\"%s\") and log files saved to current directory.\n", inputDbPath.c_str());
00416 
00417         return 0;
00418 }


rtabmap
Author(s): Mathieu Labbe
autogenerated on Sat Jul 23 2016 11:44:16