tools/Info/main.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <signal.h>
32 
33 #include <rtabmap/core/DBDriver.h>
36 #include "rtabmap/utilite/UFile.h"
37 #include "rtabmap/utilite/UStl.h"
38 
39 using namespace rtabmap;
40 
41 #ifdef _WIN32
42 #include <Windows.h>
43 #define COLOR_NORMAL FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
44 #define COLOR_RED FOREGROUND_RED | FOREGROUND_INTENSITY
45 #define COLOR_GREEN FOREGROUND_GREEN
46 #define COLOR_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
47 #else
48 #define COLOR_NORMAL "\033[0m"
49 #define COLOR_RED "\033[31m"
50 #define COLOR_GREEN "\033[32m"
51 #define COLOR_YELLOW "\033[33m"
52 #endif
53 
54 void showUsage()
55 {
56  printf("\nUsage:\n"
57  "rtabmap-info [options] \"map.db\"\n"
58  " Options:\n"
59  " --diff Show only modified parameters.\n"
60  " --diff \"other_map.db\" Compare parameters with other database.\n"
61  "\n");
62  exit(1);
63 }
64 
65 std::string pad(const std::string & title, int padding = 20)
66 {
67  int emptySize = padding - (int)title.size();
68  if(emptySize>0)
69  {
70  return title + std::string(emptySize, ' ');
71  }
72  return title;
73 }
74 
75 int main(int argc, char * argv[])
76 {
77  if(argc < 2)
78  {
79  showUsage();
80  }
81 
82  std::string otherDatabasePath;
83  bool diff = false;
84  for(int i=1; i<argc-1; ++i)
85  {
86  if(strcmp(argv[i], "--diff") == 0)
87  {
88  ++i;
89  if(i<argc-1)
90  {
91  otherDatabasePath = uReplaceChar(argv[i], '~', UDirectory::homeDir());
92  printf("Comparing with other database \"%s\"...\n", otherDatabasePath.c_str());
93  }
94  diff = true;
95  }
96  }
97 
98  std::string databasePath = uReplaceChar(argv[argc-1], '~', UDirectory::homeDir());
99  if(!UFile::exists(databasePath))
100  {
101  printf("Database \"%s\" doesn't exist!\n", databasePath.c_str());
102  return -1;
103  }
104 
105  DBDriver * driver = DBDriver::create();
106  if(!driver->openConnection(databasePath))
107  {
108  printf("Cannot open database \"%s\".\n", databasePath.c_str());
109  delete driver;
110  return -1;
111  }
112 
113  ParametersMap parameters = driver->getLastParameters();
114  ParametersMap defaultParameters = Parameters::getDefaultParameters();
116  std::string otherDatabasePathName;
117  if(!otherDatabasePath.empty())
118  {
119  driver->closeConnection(false);
120 
121  if(!UFile::exists(otherDatabasePath))
122  {
123  printf("Database \"%s\" doesn't exist!\n", otherDatabasePath.c_str());
124  delete driver;
125  return -1;
126  }
127 
128  if(!driver->openConnection(otherDatabasePath))
129  {
130  printf("Cannot open database \"%s\".\n", otherDatabasePath.c_str());
131  delete driver;
132  return -1;
133  }
134  otherDatabasePathName = UFile::getName(otherDatabasePath);
135  defaultParameters = driver->getLastParameters();
136  removedParameters.clear();
137  }
138 
139 #ifdef _WIN32
140  HANDLE H = GetStdHandle(STD_OUTPUT_HANDLE);
141 #endif
142  int padding = 35;
143  std::cout << ("Parameters (Yellow=modified, Red=old parameter not used anymore):\n");
144  for(ParametersMap::iterator iter=parameters.begin(); iter!=parameters.end(); ++iter)
145  {
146  ParametersMap::const_iterator jter = defaultParameters.find(iter->first);
147  std::string defaultValue;
148  bool defaultValueSet = false;
149  if(jter == defaultParameters.end())
150  {
151  jter = removedParameters.find(iter->first);
152  if(jter != removedParameters.end())
153  {
154  defaultValue = jter->second;
155  defaultValueSet = true;
156  }
157  }
158  else
159  {
160  defaultValue = jter->second;
161  defaultValueSet = true;
162  }
163 
164  if(defaultValueSet &&
165  iter->second.compare(defaultValue) != 0 &&
166  iter->first.compare(Parameters::kRtabmapWorkingDirectory()) != 0)
167  {
168  bool different = true;
169  if(Parameters::getType(iter->first).compare("double") ==0 ||
170  Parameters::getType(iter->first).compare("float") == 0)
171  {
172  if(uStr2Double(iter->second) == uStr2Double(defaultValue))
173  {
174  different = false;
175  }
176  }
177 
178  if(different)
179  {
180  //yellow
181 #ifdef _WIN32
182  SetConsoleTextAttribute(H,COLOR_YELLOW);
183 #else
184  printf("%s", COLOR_YELLOW);
185 #endif
186  std::cout << (uFormat("%s%s (%s=%s)\n", pad(iter->first + "=", padding).c_str(), iter->second.c_str(), otherDatabasePath.empty()?"default":otherDatabasePathName.c_str(), defaultValue.c_str()));
187  }
188  else if(!diff)
189  {
190  //green
191 #ifdef _WIN32
192  SetConsoleTextAttribute(H,COLOR_NORMAL);
193 #else
194  printf("%s", COLOR_NORMAL);
195 #endif
196  std::cout << (uFormat("%s%s\n", pad(iter->first + "=", padding).c_str(), iter->second.c_str()));
197  }
198  }
199  else if(!defaultValueSet && otherDatabasePath.empty())
200  {
201  //red
202 #ifdef _WIN32
203  SetConsoleTextAttribute(H,COLOR_RED);
204 #else
205  printf("%s", COLOR_RED);
206 #endif
207  std::cout << (uFormat("%s%s\n", pad(iter->first + "=", padding).c_str(), iter->second.c_str()));
208  }
209  else if(!diff)
210  {
211  //green
212 #ifdef _WIN32
213  SetConsoleTextAttribute(H,COLOR_NORMAL);
214 #else
215  printf("%s", COLOR_NORMAL);
216 #endif
217  std::cout << (uFormat("%s%s\n", pad(iter->first + "=", padding).c_str(), iter->second.c_str()));
218  }
219 #ifdef _WIN32
220  SetConsoleTextAttribute(H,COLOR_NORMAL);
221 #else
222  printf("%s", COLOR_NORMAL);
223 #endif
224  }
225 
226  if(otherDatabasePath.empty())
227  {
228  printf("\nInfo:\n\n");
229  std::string info;
230  std::set<int> ids;
231  driver->getAllNodeIds(ids);
232  Transform lastLocalization;
233  std::map<int, Transform> optimizedPoses = driver->loadOptimizedPoses(&lastLocalization);
234  std::multimap<int, int> mapIdsLinkedToLastGraph;
235  int lastMapId=0;
236  double previousStamp = 0.0f;
237  Transform previousPose;
238  float infoTotalOdom = 0.0f;
239  double infoTotalTime = 0.0f;
240  int sessions = !ids.empty()?1:0;
241  int odomPoses = 0;
242  int gtPoses = 0;
243  int gpsValues = 0;
244  for(std::set<int>::iterator iter=ids.begin(); iter!=ids.end(); ++iter)
245  {
246  Transform p, g;
247  int w;
248  std::string l;
249  double s;
250  int mapId;
251  std::vector<float> v;
252  GPS gps;
253  EnvSensors sensors;
254  int id = *iter;
255  driver->getNodeInfo(id, p, mapId, w, l, s, g, v, gps, sensors);
256  if(!p.isNull())
257  {
258  ++odomPoses;
259  }
260  if(!g.isNull())
261  {
262  ++gtPoses;
263  }
264  if(gps.stamp()>0.0)
265  {
266  ++gpsValues;
267  }
268  if(optimizedPoses.find(id) != optimizedPoses.end())
269  {
270  mapIdsLinkedToLastGraph.insert(std::make_pair(mapId, id));
271  }
272  if(iter!=ids.begin())
273  {
274  if(lastMapId == mapId)
275  {
276  if(!p.isNull() && !previousPose.isNull())
277  {
278  infoTotalOdom += p.getDistance(previousPose);
279  }
280 
281  if(previousStamp > 0.0 && s > 0.0)
282  {
283  infoTotalTime += s-previousStamp;
284  }
285  }
286  else
287  {
288  ++sessions;
289  }
290  }
291  lastMapId = mapId;
292  previousStamp=s;
293  previousPose=p;
294  }
295  std::cout << (uFormat("%s%s\n", pad("Path:").c_str(), driver->getUrl().c_str()));
296  std::cout << (uFormat("%s%s\n", pad("Version:").c_str(), driver->getDatabaseVersion().c_str()));
297  std::cout << (uFormat("%s%d\n", pad("Sessions:").c_str(), sessions));
298  std::multimap<int, Link> links;
299  driver->getAllLinks(links, true, true);
300  bool reducedGraph = false;
301  std::vector<int> linkTypes(Link::kEnd, 0);
302  for(std::multimap<int, Link>::iterator iter=links.begin(); iter!=links.end(); ++iter)
303  {
304  if(iter->second.type() == Link::kNeighborMerged)
305  {
306  reducedGraph = true;
307  }
308  if(iter->second.type()>=0 && iter->second.type()<Link::kEnd)
309  {
310  ++linkTypes[iter->second.type()];
311  }
312  }
313  if(reducedGraph)
314  {
315  std::cout << (uFormat("%s%f m (approx. as graph has been reduced)\n", pad("Total odom:").c_str(), infoTotalOdom));
316  }
317  else
318  {
319  std::cout << (uFormat("%s%f m\n", pad("Total odometry length:").c_str(), infoTotalOdom));
320  }
321 
322  std::stringstream sessionsInOptGraphStr;
323  std::list<int> mapsLinkedToLastGraph = uUniqueKeys(mapIdsLinkedToLastGraph);
324  for(std::list<int>::iterator iter=mapsLinkedToLastGraph.begin(); iter!=mapsLinkedToLastGraph.end(); ++iter)
325  {
326  if(iter!=mapsLinkedToLastGraph.begin())
327  {
328  sessionsInOptGraphStr << ", ";
329  }
330  sessionsInOptGraphStr << *iter << "(" << mapIdsLinkedToLastGraph.count(*iter) << ")";
331  }
332 
333  int lastWordIdId = 0;
334  int wordsDim = 0;
335  int wordsType = 0;
336  driver->getLastWordId(lastWordIdId);
337  if(lastWordIdId>0)
338  {
339  std::set<int> ids;
340  ids.insert(lastWordIdId);
341  std::list<VisualWord *> vws;
342  driver->loadWords(ids, vws);
343  if(!vws.empty())
344  {
345  wordsDim = vws.front()->getDescriptor().cols;
346  wordsType = vws.front()->getDescriptor().type();
347  delete vws.front();
348  vws.clear();
349  }
350  }
351 
352  std::cout << (uFormat("%s%fs\n", pad("Total time:").c_str(), infoTotalTime));
353  std::cout << (uFormat("%s%d nodes and %d words (dim=%d type=%s)\n", pad("LTM:").c_str(), (int)ids.size(), driver->getTotalDictionarySize(), wordsDim, wordsType==CV_8UC1?"8U":wordsType==CV_32FC1?"32F":uNumber2Str(wordsType).c_str()));
354  std::cout << (uFormat("%s%d nodes and %d words\n", pad("WM:").c_str(), driver->getLastNodesSize(), driver->getLastDictionarySize()));
355  std::cout << (uFormat("%s%d poses and %d links\n", pad("Global graph:").c_str(), odomPoses, links.size()));
356  std::cout << (uFormat("%s%d poses\n", pad("Optimized graph:").c_str(), (int)optimizedPoses.size(), links.size()));
357  std::cout << (uFormat("%s%d/%d [%s]\n", pad("Maps in graph:").c_str(), (int)mapsLinkedToLastGraph.size(), sessions, sessionsInOptGraphStr.str().c_str()));
358  std::cout << (uFormat("%s%d poses\n", pad("Ground truth:").c_str(), gtPoses));
359  std::cout << (uFormat("%s%d poses\n", pad("GPS:").c_str(), gpsValues));
360  std::cout << (uFormat("Links:\n"));
361  for(size_t i=0; i<linkTypes.size(); ++i)
362  {
363  std::cout << (uFormat("%s%d\n", pad(uFormat(" %s:", Link::typeName((Link::Type)i).c_str())).c_str(), linkTypes[i]));
364  }
365  std::cout << ("\n");
366  long total = 0;
367  long dbSize = UFile::length(driver->getUrl());
368  long mem = dbSize;
369  std::cout << (uFormat("%s%d %s\n", pad("Database size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes"));
370  mem = driver->getNodesMemoryUsed();
371  total+=mem;
372  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Nodes size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
373  mem = driver->getLinksMemoryUsed();
374  total+=mem;
375  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Links size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
376  mem = driver->getImagesMemoryUsed();
377  total+=mem;
378  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("RGB Images size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
379  mem = driver->getDepthImagesMemoryUsed();
380  total+=mem;
381  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Depth Images size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
382  mem = driver->getCalibrationsMemoryUsed();
383  total+=mem;
384  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Calibrations size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
385  mem = driver->getGridsMemoryUsed();
386  total+=mem;
387  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Grids size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
388  mem = driver->getLaserScansMemoryUsed();
389  total+=mem;
390  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Scans size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
391  mem = driver->getUserDataMemoryUsed();
392  total+=mem;
393  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("User data size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
394  mem = driver->getWordsMemoryUsed();
395  total+=mem;
396  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Dictionary size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
397  mem = driver->getFeaturesMemoryUsed();
398  total+=mem;
399  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Features size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
400  mem = driver->getStatisticsMemoryUsed();
401  total+=mem;
402  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Statistics size:").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
403  mem = dbSize - total;
404  std::cout << (uFormat("%s%d %s\t(%.2f%%)\n", pad("Other (indexing, unused):").c_str(), mem>1000000?mem/1000000:mem>1000?mem/1000:mem, mem>1000000?"MB":mem>1000?"KB":"Bytes", dbSize>0?double(mem)/double(dbSize)*100.0:0.0));
405  std::cout << ("\n");
406  }
407 
408  return 0;
409 }
static std::string homeDir()
Definition: UDirectory.cpp:355
std::list< K > uUniqueKeys(const std::multimap< K, V > &mm)
Definition: UStl.h:46
#define COLOR_NORMAL
long getFeaturesMemoryUsed() const
Definition: DBDriver.cpp:191
long getGridsMemoryUsed() const
Definition: DBDriver.cpp:159
long getImagesMemoryUsed() const
Definition: DBDriver.cpp:135
std::string getName()
Definition: UFile.h:135
long length()
Definition: UFile.h:110
void showUsage()
long getUserDataMemoryUsed() const
Definition: DBDriver.cpp:175
double UTILITE_EXP uStr2Double(const std::string &str)
void getAllNodeIds(std::set< int > &ids, bool ignoreChildren=false, bool ignoreBadSignatures=false) const
Definition: DBDriver.cpp:876
long getWordsMemoryUsed() const
Definition: DBDriver.cpp:183
std::map< std::string, std::string > ParametersMap
Definition: Parameters.h:43
void loadWords(const std::set< int > &wordIds, std::list< VisualWord * > &vws)
Definition: DBDriver.cpp:606
int main(int argc, char *argv[])
const std::string & getUrl() const
Definition: DBDriver.h:72
bool openConnection(const std::string &url, bool overwritten=false)
Definition: DBDriver.cpp:86
Wrappers of STL for convenient functions.
bool isNull() const
Definition: Transform.cpp:107
void getAllLinks(std::multimap< int, Link > &links, bool ignoreNullLinks=true, bool withLandmarks=false) const
Definition: DBDriver.cpp:915
static const ParametersMap & getBackwardCompatibilityMap()
Definition: Parameters.cpp:426
long getLaserScansMemoryUsed() const
Definition: DBDriver.cpp:167
void closeConnection(bool save=true, const std::string &outputUrl="")
Definition: DBDriver.cpp:64
int getLastDictionarySize() const
Definition: DBDriver.cpp:215
long getStatisticsMemoryUsed() const
Definition: DBDriver.cpp:199
std::string UTILITE_EXP uReplaceChar(const std::string &str, char before, char after)
Definition: UConversion.cpp:32
long getCalibrationsMemoryUsed() const
Definition: DBDriver.cpp:151
long getDepthImagesMemoryUsed() const
Definition: DBDriver.cpp:143
static DBDriver * create(const ParametersMap &parameters=ParametersMap())
Definition: DBDriver.cpp:41
bool getNodeInfo(int signatureId, Transform &pose, int &mapId, int &weight, std::string &label, double &stamp, Transform &groundTruthPose, std::vector< float > &velocity, GPS &gps, EnvSensors &sensors) const
Definition: DBDriver.cpp:776
static std::string getType(const std::string &paramKey)
Definition: Parameters.cpp:446
static const ParametersMap & getDefaultParameters()
Definition: Parameters.h:778
float getDistance(const Transform &t) const
Definition: Transform.cpp:262
bool exists()
Definition: UFile.h:104
#define COLOR_YELLOW
ParametersMap getLastParameters() const
Definition: DBDriver.cpp:239
int getTotalDictionarySize() const
Definition: DBDriver.cpp:231
std::string getDatabaseVersion() const
Definition: DBDriver.cpp:275
std::map< EnvSensor::Type, EnvSensor > EnvSensors
Definition: EnvSensor.h:81
std::string pad(const std::string &title, int padding=20)
#define COLOR_RED
std::string UTILITE_EXP uFormat(const char *fmt,...)
std::string UTILITE_EXP uNumber2Str(unsigned int number)
Definition: UConversion.cpp:90
long getLinksMemoryUsed() const
Definition: DBDriver.cpp:127
void getLastWordId(int &id) const
Definition: DBDriver.cpp:993
int getLastNodesSize() const
Definition: DBDriver.cpp:207
long getNodesMemoryUsed() const
Definition: DBDriver.cpp:119
std::map< int, Transform > loadOptimizedPoses(Transform *lastlocalizationPose=0) const
Definition: DBDriver.cpp:1187
const double & stamp() const
Definition: GPS.h:59


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Dec 14 2020 03:34:59