tools/DetectMoreLoopClosures/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 <rtabmap/core/DBDriver.h>
29 #include <rtabmap/core/Rtabmap.h>
30 #include <rtabmap/core/Memory.h>
32 #include <rtabmap/core/util3d.h>
36 #include <rtabmap/utilite/UMath.h>
37 #include <rtabmap/utilite/UTimer.h>
38 #include <rtabmap/utilite/UFile.h>
39 #include <rtabmap/utilite/UStl.h>
40 #include <pcl/filters/filter.h>
41 #include <pcl/io/ply_io.h>
42 #include <pcl/io/obj_io.h>
43 #include <pcl/common/common.h>
44 #include <pcl/surface/poisson.h>
45 #include <stdio.h>
46 #include <signal.h>
47 
48 using namespace rtabmap;
49 
50 void showUsage()
51 {
52  printf("\nUsage:\n"
53  "rtabmap-detectMoreLoopClosures [options] database.db\n"
54  "Options:\n"
55  " -r # Cluster radius (default 1 m).\n"
56  " -rx # Cluster radius min (default 0 m).\n"
57  " -a # Cluster angle (default 30 deg).\n"
58  " -i # Iterations (default 1).\n"
59  " --intra Add only intra-session loop closures.\n"
60  " --inter Add only inter-session loop closures.\n"
61  "\n%s", Parameters::showUsage());
62  exit(1);
63 }
64 
65 // catch ctrl-c
66 bool g_loopForever = true;
67 void sighandler(int sig)
68 {
69  printf("\nSignal %d caught...\n", sig);
70  g_loopForever = false;
71 }
72 
74 {
75 public:
76  virtual bool callback(const std::string & msg) const
77  {
78  if(!msg.empty())
79  printf("%s \n", msg.c_str());
80  return g_loopForever;
81  }
82 };
83 
84 int main(int argc, char * argv[])
85 {
86  signal(SIGABRT, &sighandler);
87  signal(SIGTERM, &sighandler);
88  signal(SIGINT, &sighandler);
89 
92 
93  if(argc < 2)
94  {
95  showUsage();
96  }
97 
98  float clusterRadiusMin = 0.0f;
99  float clusterRadiusMax = 1.0f;
100  float clusterAngle = CV_PI/6.0f;
101  int iterations = 1;
102  bool intraSession = false;
103  bool interSession = false;
104  for(int i=1; i<argc-1; ++i)
105  {
106  if(std::strcmp(argv[i], "--help") == 0)
107  {
108  showUsage();
109  }
110  else if(std::strcmp(argv[i], "--intra") == 0)
111  {
112  intraSession = true;
113  if(interSession)
114  {
115  showUsage();
116  }
117  }
118  else if(std::strcmp(argv[i], "--inter") == 0)
119  {
120  interSession = true;
121  if(intraSession)
122  {
123  showUsage();
124  }
125  }
126  else if(std::strcmp(argv[i], "-r") == 0)
127  {
128  ++i;
129  if(i<argc-1)
130  {
131  clusterRadiusMax = uStr2Float(argv[i]);
132  }
133  else
134  {
135  showUsage();
136  }
137  }
138  else if(std::strcmp(argv[i], "-rx") == 0)
139  {
140  ++i;
141  if(i<argc-1)
142  {
143  clusterRadiusMin = uStr2Float(argv[i]);
144  }
145  else
146  {
147  showUsage();
148  }
149  }
150  else if(std::strcmp(argv[i], "-a") == 0)
151  {
152  ++i;
153  if(i<argc-1)
154  {
155  clusterAngle = uStr2Float(argv[i])*CV_PI/180.0f;
156  }
157  else
158  {
159  showUsage();
160  }
161  }
162  else if(std::strcmp(argv[i], "-i") == 0)
163  {
164  ++i;
165  if(i<argc-1)
166  {
167  iterations = uStr2Int(argv[i]);
168  }
169  else
170  {
171  showUsage();
172  }
173  }
174  }
175  ParametersMap inputParams = Parameters::parseArguments(argc, argv);
176 
177  std::string dbPath = argv[argc-1];
178  if(!UFile::exists(dbPath))
179  {
180  printf("Database %s doesn't exist!\n", dbPath.c_str());
181  }
182 
183  printf("\nDatabase: %s\n", dbPath.c_str());
184  printf("Cluster radius min = %f m\n", clusterRadiusMin);
185  printf("Cluster radius max = %f m\n", clusterRadiusMax);
186  printf("Cluster angle = %f deg\n", clusterAngle*180.0f/CV_PI);
187  if(intraSession)
188  {
189  printf("Intra-session only\n");
190  }
191  else if(interSession)
192  {
193  printf("Inter-session only\n");
194  }
195 
196  if(!intraSession && !interSession)
197  {
198  intraSession = true;
199  interSession = true;
200  }
201 
202  // Get parameters
203  ParametersMap parameters;
204  DBDriver * driver = DBDriver::create();
205  if(driver->openConnection(dbPath))
206  {
207  parameters = driver->getLastParameters();
208  driver->closeConnection(false);
209  }
210  else
211  {
212  UERROR("Cannot open database %s!", dbPath.c_str());
213  }
214  delete driver;
215 
216  for(ParametersMap::iterator iter=inputParams.begin(); iter!=inputParams.end(); ++iter)
217  {
218  printf(" Using parameter \"%s=%s\" from arguments\n", iter->first.c_str(), iter->second.c_str());
219  }
220 
221  // Get the global optimized map
223  printf("Initialization...\n");
224  uInsert(parameters, inputParams);
225  rtabmap.init(parameters, dbPath);
226 
227  float xMin, yMin, cellSize;
228  bool haveOptimizedMap = !rtabmap.getMemory()->load2DMap(xMin, yMin, cellSize).empty();
229 
230  PrintProgressState progress;
231  printf("Detecting...\n");
232  int detected = rtabmap.detectMoreLoopClosures(clusterRadiusMax, clusterAngle, iterations, intraSession, interSession, &progress, clusterRadiusMin);
233  if(detected < 0)
234  {
235  if(!g_loopForever)
236  {
237  printf("Detection interrupted. Loop closures found so far (if any) are not saved.\n");
238  }
239  else
240  {
241  printf("Loop closure detection failed!\n");
242  }
243  }
244  else if(detected > 0 && haveOptimizedMap)
245  {
246  printf("The database has a global occupancy grid, regenerating one with new optimized graph!\n");
247  OccupancyGrid grid(parameters);
248  std::map<int, Transform> optimizedPoses = rtabmap.getLocalOptimizedPoses();
249  for(std::map<int, Transform>::iterator iter=optimizedPoses.lower_bound(0); iter!=optimizedPoses.end(); ++iter)
250  {
251  cv::Mat occupancyGrid;
252  SensorData data = rtabmap.getMemory()->getNodeData(iter->first, false, false, false, true);
253  data.uncompressData();
254  grid.addToCache(iter->first, data.gridGroundCellsRaw(), data.gridObstacleCellsRaw(), data.gridEmptyCellsRaw());
255  }
256  grid.update(optimizedPoses);
257  cv::Mat map = grid.getMap(xMin, yMin);
258  if(map.empty())
259  {
260  printf("Could not generate the global occupancy grid!\n");
261  }
262  else
263  {
264  rtabmap.getMemory()->save2DMap(map, xMin, yMin, cellSize);
265  printf("Save new global occupancy grid!\n");
266  }
267  }
268 
269  rtabmap.close();
270 
271  return 0;
272 }
int UTILITE_EXP uStr2Int(const std::string &str)
bool update(const std::map< int, Transform > &poses)
virtual bool callback(const std::string &msg) const
f
static const char * showUsage()
Definition: Parameters.cpp:569
data
static ParametersMap parseArguments(int argc, char *argv[], bool onlyParameters=false)
Definition: Parameters.cpp:596
float UTILITE_EXP uStr2Float(const std::string &str)
std::map< std::string, std::string > ParametersMap
Definition: Parameters.h:43
Basic mathematics functions.
static void setLevel(ULogger::Level level)
Definition: ULogger.h:339
bool openConnection(const std::string &url, bool overwritten=false)
Definition: DBDriver.cpp:86
Wrappers of STL for convenient functions.
void closeConnection(bool save=true, const std::string &outputUrl="")
Definition: DBDriver.cpp:64
void addToCache(int nodeId, const cv::Mat &ground, const cv::Mat &obstacles, const cv::Mat &empty)
static void setType(Type type, const std::string &fileName=kDefaultLogFileName, bool append=true)
Definition: ULogger.cpp:176
int main(int argc, char *argv[])
cv::Mat getMap(float &xMin, float &yMin) const
static DBDriver * create(const ParametersMap &parameters=ParametersMap())
Definition: DBDriver.cpp:41
bool exists()
Definition: UFile.h:104
#define UERROR(...)
const cv::Mat & gridEmptyCellsRaw() const
Definition: SensorData.h:264
const cv::Mat & gridGroundCellsRaw() const
Definition: SensorData.h:260
ParametersMap getLastParameters() const
Definition: DBDriver.cpp:239
const cv::Mat & gridObstacleCellsRaw() const
Definition: SensorData.h:262
void sighandler(int sig)
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
Definition: UStl.h:443


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Jan 23 2023 03:37:29