mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-03 01:50:24 +08:00
Making Rtabmap interface easier to use from c++ (Update c++ example usage)
git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@695 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
@@ -37,19 +37,17 @@ int main(int argc, char* argv[])
|
|||||||
ULOGGER_INFO("Program started...");
|
ULOGGER_INFO("Program started...");
|
||||||
|
|
||||||
/* Create tasks */
|
/* Create tasks */
|
||||||
Rtabmap * rtabmap = new Rtabmap();
|
|
||||||
QApplication * app = new QApplication(argc, argv);
|
QApplication * app = new QApplication(argc, argv);
|
||||||
MainWindow * mainWindow = new MainWindow();
|
MainWindow * mainWindow = new MainWindow();
|
||||||
|
|
||||||
/* Add handlers to the EventsManager */
|
|
||||||
UEventsManager::addHandler(mainWindow);
|
UEventsManager::addHandler(mainWindow);
|
||||||
UEventsManager::addHandler(rtabmap);
|
|
||||||
|
|
||||||
/* Start thread's task */
|
/* Start thread's task */
|
||||||
mainWindow->showNormal();
|
mainWindow->showNormal();
|
||||||
|
|
||||||
rtabmap->setWorkingDirectory(mainWindow->getWorkingDirectory().toStdString());
|
Rtabmap * rtabmap = new Rtabmap(mainWindow->getWorkingDirectory().toStdString(), false);
|
||||||
rtabmap->start();
|
rtabmap->start(); // start it not initialized... will be initialized by event from the gui
|
||||||
|
UEventsManager::addHandler(rtabmap);
|
||||||
|
|
||||||
// Now wait for application to finish
|
// Now wait for application to finish
|
||||||
app->connect( app, SIGNAL( lastWindowClosed() ),
|
app->connect( app, SIGNAL( lastWindowClosed() ),
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ public:
|
|||||||
double * dbAccessTime = 0) const;
|
double * dbAccessTime = 0) const;
|
||||||
|
|
||||||
//getters
|
//getters
|
||||||
unsigned int getWorkingMemSize() const {return _workingMem.size();}
|
|
||||||
unsigned int getStMemSize() const {return _stMem.size();};
|
|
||||||
const std::set<int> & getWorkingMem() const {return _workingMem;}
|
const std::set<int> & getWorkingMem() const {return _workingMem;}
|
||||||
const std::set<int> & getStMem() const {return _stMem;}
|
const std::set<int> & getStMem() const {return _stMem;}
|
||||||
int getMaxStMemSize() const {return _maxStMemSize;}
|
int getMaxStMemSize() const {return _maxStMemSize;}
|
||||||
|
|||||||
@@ -62,45 +62,40 @@ public:
|
|||||||
|
|
||||||
enum VhStrategy {kVhNone, kVhEpipolar, kVhUndef};
|
enum VhStrategy {kVhNone, kVhEpipolar, kVhUndef};
|
||||||
|
|
||||||
static const char * kDefaultIniFileName;
|
|
||||||
static const char * kDefaultIniFilePath;
|
|
||||||
static const char * kDefaultDatabaseName;
|
static const char * kDefaultDatabaseName;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static std::string getVersion();
|
static std::string getVersion();
|
||||||
static std::string getIniFilePath();
|
|
||||||
static void readParameters(const char * configFile, ParametersMap & parameters);
|
static void readParameters(const char * configFile, ParametersMap & parameters);
|
||||||
static void writeParameters(const char * configFile, const ParametersMap & parameters);
|
static void writeParameters(const char * configFile, const ParametersMap & parameters);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Rtabmap();
|
Rtabmap(const std::string & workingDirectory = ".", bool deleteMemory = true);
|
||||||
virtual ~Rtabmap();
|
virtual ~Rtabmap();
|
||||||
|
|
||||||
void process(const cv::Mat & image); // for convenience
|
void process(const cv::Mat & image); // for convenience
|
||||||
void process(const Image & image); // for convenience
|
void process(const Image & image); // for convenience
|
||||||
void dumpData();
|
|
||||||
void generateLocalGraph(const std::string & path, int id, int margin);
|
|
||||||
|
|
||||||
void init(const ParametersMap & param);
|
void init(const ParametersMap & param);
|
||||||
void init(const char * configFile = 0);
|
void init(const char * configFile = 0);
|
||||||
void clearBufferedSensors();
|
void clearBufferedSensors();
|
||||||
|
|
||||||
|
void close();
|
||||||
|
|
||||||
const std::string & getWorkingDir() const {return _wDir;}
|
const std::string & getWorkingDir() const {return _wDir;}
|
||||||
int getLoopClosureId() const;
|
int getLoopClosureId() const;
|
||||||
int getReactivatedId() const;
|
int getRetrievedId() const;
|
||||||
int getLastSignatureId() const;
|
int getLastLocationId() const;
|
||||||
float getLcHypValue() const {return _lastLcHypothesisValue;}
|
float getLcHypValue() const {return _lastLcHypothesisValue;}
|
||||||
std::list<int> getWorkingMem() const;
|
std::list<int> getWM() const; // working memory
|
||||||
std::set<int> getStMem() const;
|
std::set<int> getSTM() const; // short-term memory
|
||||||
|
int getWMSize() const; // working memory size
|
||||||
|
int getSTMSize() const; // short-term memory size
|
||||||
std::map<int, int> getWeights() const;
|
std::map<int, int> getWeights() const;
|
||||||
int getTotalMemSize() const;
|
int getTotalMemSize() const;
|
||||||
double getLastProcessTime() const {return _lastProcessTime;};
|
double getLastProcessTime() const {return _lastProcessTime;};
|
||||||
|
|
||||||
void setMaxTimeAllowed(float maxTimeAllowed); // in ms
|
void setTimeThreshold(float maxTimeAllowed); // in ms
|
||||||
void setDataBufferSize(int size);
|
|
||||||
void setWorkingDirectory(std::string path);
|
|
||||||
|
|
||||||
void deleteMemory();
|
|
||||||
|
|
||||||
void adjustLikelihood(std::map<int, float> & likelihood) const;
|
void adjustLikelihood(std::map<int, float> & likelihood) const;
|
||||||
std::pair<int, float> selectHypothesis(const std::map<int, float> & posterior,
|
std::pair<int, float> selectHypothesis(const std::map<int, float> & posterior,
|
||||||
@@ -122,7 +117,11 @@ private:
|
|||||||
void releaseAllStrategies();
|
void releaseAllStrategies();
|
||||||
void pushNewState(State newState, const ParametersMap & parameters = ParametersMap());
|
void pushNewState(State newState, const ParametersMap & parameters = ParametersMap());
|
||||||
void dumpPrediction() const;
|
void dumpPrediction() const;
|
||||||
|
void dumpData();
|
||||||
|
void generateLocalGraph(const std::string & path, int id, int margin);
|
||||||
void parseParameters(const ParametersMap & parameters);
|
void parseParameters(const ParametersMap & parameters);
|
||||||
|
void setWorkingDirectory(std::string path);
|
||||||
|
void setDataBufferSize(int size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Modifiable parameters
|
// Modifiable parameters
|
||||||
|
|||||||
@@ -2103,7 +2103,7 @@ Signature * Memory::createSignature(int id, const Image & image, bool keepRawDat
|
|||||||
std::vector<cv::KeyPoint> keypoints;
|
std::vector<cv::KeyPoint> keypoints;
|
||||||
cv::Mat descriptors;
|
cv::Mat descriptors;
|
||||||
|
|
||||||
int treeSize= this->getWorkingMemSize() + this->getStMemSize();
|
int treeSize= _workingMem.size() + _stMem.size();
|
||||||
int nbCommonWords = 0;
|
int nbCommonWords = 0;
|
||||||
if(treeSize > 0)
|
if(treeSize > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -54,10 +54,9 @@
|
|||||||
|
|
||||||
namespace rtabmap
|
namespace rtabmap
|
||||||
{
|
{
|
||||||
const char * Rtabmap::kDefaultIniFileName = "rtabmap.ini";
|
|
||||||
const char * Rtabmap::kDefaultDatabaseName = "LTM.db";
|
const char * Rtabmap::kDefaultDatabaseName = "LTM.db";
|
||||||
|
|
||||||
Rtabmap::Rtabmap() :
|
Rtabmap::Rtabmap(const std::string & workingDirectory, bool deleteMemory) :
|
||||||
_publishStats(Parameters::defaultRtabmapPublishStats()),
|
_publishStats(Parameters::defaultRtabmapPublishStats()),
|
||||||
_publishImage(Parameters::defaultRtabmapPublishImage()),
|
_publishImage(Parameters::defaultRtabmapPublishImage()),
|
||||||
_publishPdf(Parameters::defaultRtabmapPublishPdf()),
|
_publishPdf(Parameters::defaultRtabmapPublishPdf()),
|
||||||
@@ -82,8 +81,11 @@ Rtabmap::Rtabmap() :
|
|||||||
_foutFloat(0),
|
_foutFloat(0),
|
||||||
_foutInt(0)
|
_foutInt(0)
|
||||||
{
|
{
|
||||||
ULOGGER_DEBUG("Working directory=%s", Parameters::defaultRtabmapWorkingDirectory().c_str());
|
this->setWorkingDirectory(workingDirectory);
|
||||||
this->setWorkingDirectory(Parameters::defaultRtabmapWorkingDirectory());
|
if(deleteMemory)
|
||||||
|
{
|
||||||
|
this->resetMemory(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rtabmap::~Rtabmap() {
|
Rtabmap::~Rtabmap() {
|
||||||
@@ -139,6 +141,9 @@ void Rtabmap::setupLogFiles(bool overwrite)
|
|||||||
attributes = "w";
|
attributes = "w";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool addLogFHeader = overwrite || !UFile::exists(_wDir+LOG_F);
|
||||||
|
bool addLogIHeader = overwrite || !UFile::exists(_wDir+LOG_I);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
fopen_s(&_foutFloat, (_wDir+LOG_F).toStdString().c_str(), attributes.c_str());
|
fopen_s(&_foutFloat, (_wDir+LOG_F).toStdString().c_str(), attributes.c_str());
|
||||||
fopen_s(&_foutInt, (_wDir+LOG_I).toStdString().c_str(), attributes.c_str());
|
fopen_s(&_foutInt, (_wDir+LOG_I).toStdString().c_str(), attributes.c_str());
|
||||||
@@ -147,6 +152,55 @@ void Rtabmap::setupLogFiles(bool overwrite)
|
|||||||
_foutInt = fopen((_wDir+LOG_I).c_str(), attributes.c_str());
|
_foutInt = fopen((_wDir+LOG_I).c_str(), attributes.c_str());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
printf("addLogFHeader=%d\n", addLogFHeader?1:0);
|
||||||
|
|
||||||
|
// add header (column identification)
|
||||||
|
if(addLogFHeader && _foutFloat)
|
||||||
|
{
|
||||||
|
fprintf(_foutFloat, "Column headers:\n");
|
||||||
|
fprintf(_foutFloat, " 1-Total iteration time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 2-Memory update time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 3-Retrieval time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 4-Likelihood time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 5-Posterior time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 6-Hypothesis selection time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 7-Transfer time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 8-Statistics creation time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 9-Loop closure hypothesis value\n");
|
||||||
|
fprintf(_foutFloat, " 10-NAN\n");
|
||||||
|
fprintf(_foutFloat, " 11-Maximum likelihood\n");
|
||||||
|
fprintf(_foutFloat, " 12-Sum likelihood\n");
|
||||||
|
fprintf(_foutFloat, " 13-Mean likelihood\n");
|
||||||
|
fprintf(_foutFloat, " 14-Std dev likelihood\n");
|
||||||
|
fprintf(_foutFloat, " 15-Virtual place hypothesis\n");
|
||||||
|
fprintf(_foutFloat, " 16-Join trash time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 17-Weight Update (rehearsal) similarity\n");
|
||||||
|
fprintf(_foutFloat, " 18-Empty trash time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 19-Retrieval database access time (s)\n");
|
||||||
|
fprintf(_foutFloat, " 20-Add loop closure link time (s)\n");
|
||||||
|
}
|
||||||
|
if(addLogIHeader && _foutInt)
|
||||||
|
{
|
||||||
|
fprintf(_foutInt, "Column headers:\n");
|
||||||
|
fprintf(_foutInt, " 1-Loop closure ID\n");
|
||||||
|
fprintf(_foutInt, " 2-Highest loop closure hypothesis\n");
|
||||||
|
fprintf(_foutInt, " 3-Locations transferred\n");
|
||||||
|
fprintf(_foutInt, " 4-NAN\n");
|
||||||
|
fprintf(_foutInt, " 5-Words extracted from the last image\n");
|
||||||
|
fprintf(_foutInt, " 6-Vocabulary size\n");
|
||||||
|
fprintf(_foutInt, " 7-Working memory size\n");
|
||||||
|
fprintf(_foutInt, " 8-Is loop closure hypothesis rejected?\n");
|
||||||
|
fprintf(_foutInt, " 9-NAN\n");
|
||||||
|
fprintf(_foutInt, " 10-NAN\n");
|
||||||
|
fprintf(_foutInt, " 11-Locations retrieved\n");
|
||||||
|
fprintf(_foutInt, " 12-Retrieval location ID\n");
|
||||||
|
fprintf(_foutInt, " 13-Unique words extraced from last image\n");
|
||||||
|
fprintf(_foutInt, " 14-Retrieval ID\n");
|
||||||
|
fprintf(_foutInt, " 15-Non-null likelihood values\n");
|
||||||
|
fprintf(_foutInt, " 16-Weight Update ID\n");
|
||||||
|
fprintf(_foutInt, " 17-Is last location merged through Weight Update?\n");
|
||||||
|
}
|
||||||
|
|
||||||
ULOGGER_DEBUG("Log file (int)=%s", (_wDir+LOG_I).c_str());
|
ULOGGER_DEBUG("Log file (int)=%s", (_wDir+LOG_I).c_str());
|
||||||
ULOGGER_DEBUG("Log file (float)=%s", (_wDir+LOG_F).c_str());
|
ULOGGER_DEBUG("Log file (float)=%s", (_wDir+LOG_F).c_str());
|
||||||
}
|
}
|
||||||
@@ -220,32 +274,42 @@ void Rtabmap::init(const ParametersMap & parameters)
|
|||||||
setupLogFiles();
|
setupLogFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Rtabmap::getIniFilePath()
|
|
||||||
{
|
|
||||||
std::string privatePath = UDirectory::homeDir() + "/.rtabmap";
|
|
||||||
if(!UDirectory::exists(privatePath))
|
|
||||||
{
|
|
||||||
UDirectory::makeDir(privatePath);
|
|
||||||
}
|
|
||||||
return (privatePath + "/") + kDefaultIniFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rtabmap::init(const char * configFile)
|
void Rtabmap::init(const char * configFile)
|
||||||
{
|
{
|
||||||
std::string config = this->getIniFilePath();
|
|
||||||
if(configFile)
|
|
||||||
{
|
|
||||||
config = configFile;
|
|
||||||
}
|
|
||||||
ULOGGER_DEBUG("file path = %s", config.c_str());
|
|
||||||
|
|
||||||
// fill ctrl struct with values from the configuration file
|
// fill ctrl struct with values from the configuration file
|
||||||
ParametersMap param;// = Parameters::defaultParameters;
|
ParametersMap param;// = Parameters::defaultParameters;
|
||||||
this->readParameters(config.c_str(), param);
|
|
||||||
|
if(configFile)
|
||||||
|
{
|
||||||
|
ULOGGER_DEBUG("Read parameters from = %s", configFile);
|
||||||
|
this->readParameters(configFile, param);
|
||||||
|
}
|
||||||
|
|
||||||
this->init(param);
|
this->init(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rtabmap::close()
|
||||||
|
{
|
||||||
|
UEventsManager::removeHandler(this);
|
||||||
|
|
||||||
|
// Stop the thread first
|
||||||
|
join(true);
|
||||||
|
|
||||||
|
flushStatisticLogs();
|
||||||
|
if(_foutFloat)
|
||||||
|
{
|
||||||
|
fclose(_foutFloat);
|
||||||
|
_foutFloat = 0;
|
||||||
|
}
|
||||||
|
if(_foutInt)
|
||||||
|
{
|
||||||
|
fclose(_foutInt);
|
||||||
|
_foutInt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->releaseAllStrategies();
|
||||||
|
}
|
||||||
|
|
||||||
void Rtabmap::parseParameters(const ParametersMap & parameters)
|
void Rtabmap::parseParameters(const ParametersMap & parameters)
|
||||||
{
|
{
|
||||||
ULOGGER_DEBUG("");
|
ULOGGER_DEBUG("");
|
||||||
@@ -360,12 +424,12 @@ int Rtabmap::getLoopClosureId() const
|
|||||||
return _lcHypothesisId;
|
return _lcHypothesisId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Rtabmap::getReactivatedId() const
|
int Rtabmap::getRetrievedId() const
|
||||||
{
|
{
|
||||||
return _retrievedId;
|
return _retrievedId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Rtabmap::getLastSignatureId() const
|
int Rtabmap::getLastLocationId() const
|
||||||
{
|
{
|
||||||
int id = 0;
|
int id = 0;
|
||||||
if(_memory && _memory->getLastSignature())
|
if(_memory && _memory->getLastSignature())
|
||||||
@@ -375,9 +439,8 @@ int Rtabmap::getLastSignatureId() const
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<int> Rtabmap::getWorkingMem() const
|
std::list<int> Rtabmap::getWM() const
|
||||||
{
|
{
|
||||||
ULOGGER_DEBUG("");
|
|
||||||
std::list<int> mem;
|
std::list<int> mem;
|
||||||
if(_memory)
|
if(_memory)
|
||||||
{
|
{
|
||||||
@@ -387,9 +450,17 @@ std::list<int> Rtabmap::getWorkingMem() const
|
|||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Rtabmap::getWMSize() const
|
||||||
|
{
|
||||||
|
if(_memory)
|
||||||
|
{
|
||||||
|
return _memory->getWorkingMem().size()-1; // remove virtual place
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::map<int, int> Rtabmap::getWeights() const
|
std::map<int, int> Rtabmap::getWeights() const
|
||||||
{
|
{
|
||||||
ULOGGER_DEBUG("");
|
|
||||||
std::map<int, int> weights;
|
std::map<int, int> weights;
|
||||||
if(_memory)
|
if(_memory)
|
||||||
{
|
{
|
||||||
@@ -399,9 +470,8 @@ std::map<int, int> Rtabmap::getWeights() const
|
|||||||
return weights;
|
return weights;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<int> Rtabmap::getStMem() const
|
std::set<int> Rtabmap::getSTM() const
|
||||||
{
|
{
|
||||||
ULOGGER_DEBUG("");
|
|
||||||
std::set<int> mem;
|
std::set<int> mem;
|
||||||
if(_memory)
|
if(_memory)
|
||||||
{
|
{
|
||||||
@@ -410,6 +480,15 @@ std::set<int> Rtabmap::getStMem() const
|
|||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Rtabmap::getSTMSize() const
|
||||||
|
{
|
||||||
|
if(_memory)
|
||||||
|
{
|
||||||
|
return _memory->getStMem().size();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int Rtabmap::getTotalMemSize() const
|
int Rtabmap::getTotalMemSize() const
|
||||||
{
|
{
|
||||||
ULOGGER_DEBUG("");
|
ULOGGER_DEBUG("");
|
||||||
@@ -518,15 +597,6 @@ void Rtabmap::mainLoop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rtabmap::deleteMemory()
|
|
||||||
{
|
|
||||||
// Only if rtabmap's thread is not started...
|
|
||||||
if(!this->isRunning())
|
|
||||||
{
|
|
||||||
this->resetMemory(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rtabmap::resetMemory(bool dbOverwritten)
|
void Rtabmap::resetMemory(bool dbOverwritten)
|
||||||
{
|
{
|
||||||
if(_memory)
|
if(_memory)
|
||||||
@@ -726,7 +796,7 @@ void Rtabmap::process()
|
|||||||
// If the working memory is empty, don't do the detection. It happens when it
|
// If the working memory is empty, don't do the detection. It happens when it
|
||||||
// is the first time the detector is started (there needs some images to
|
// is the first time the detector is started (there needs some images to
|
||||||
// fill the short-time memory before a signature is added to the working memory).
|
// fill the short-time memory before a signature is added to the working memory).
|
||||||
if(_memory->getWorkingMemSize())
|
if(_memory->getWorkingMem().size())
|
||||||
{
|
{
|
||||||
//============================================================
|
//============================================================
|
||||||
// Likelihood computation
|
// Likelihood computation
|
||||||
@@ -1058,8 +1128,8 @@ void Rtabmap::process()
|
|||||||
stat->addStatistic(Statistics::kLoopReactivateId(), _retrievedId);
|
stat->addStatistic(Statistics::kLoopReactivateId(), _retrievedId);
|
||||||
stat->addStatistic(Statistics::kLoopHypothesis_ratio(), hypothesisRatio);
|
stat->addStatistic(Statistics::kLoopHypothesis_ratio(), hypothesisRatio);
|
||||||
|
|
||||||
stat->addStatistic(Statistics::kMemoryWorking_memory_size(), _memory->getWorkingMemSize());
|
stat->addStatistic(Statistics::kMemoryWorking_memory_size(), _memory->getWorkingMem().size());
|
||||||
stat->addStatistic(Statistics::kMemoryShort_time_memory_size(), _memory->getStMemSize());
|
stat->addStatistic(Statistics::kMemoryShort_time_memory_size(), _memory->getStMem().size());
|
||||||
stat->addStatistic(Statistics::kMemorySignatures_retrieved(), (float)signaturesRetrieved.size());
|
stat->addStatistic(Statistics::kMemorySignatures_retrieved(), (float)signaturesRetrieved.size());
|
||||||
stat->addStatistic(Statistics::kMemoryImages_buffered(), (float)_imageBuffer.size());
|
stat->addStatistic(Statistics::kMemoryImages_buffered(), (float)_imageBuffer.size());
|
||||||
|
|
||||||
@@ -1151,9 +1221,9 @@ void Rtabmap::process()
|
|||||||
ULOGGER_INFO("Total time processing = %fs...", totalTime);
|
ULOGGER_INFO("Total time processing = %fs...", totalTime);
|
||||||
timer.start();
|
timer.start();
|
||||||
if((_maxTimeAllowed != 0 && totalTime*1000>_maxTimeAllowed) ||
|
if((_maxTimeAllowed != 0 && totalTime*1000>_maxTimeAllowed) ||
|
||||||
(_maxMemoryAllowed != 0 && _memory->getWorkingMemSize() > _maxMemoryAllowed))
|
(_maxMemoryAllowed != 0 && _memory->getWorkingMem().size() > _maxMemoryAllowed))
|
||||||
{
|
{
|
||||||
ULOGGER_INFO("Removing old signatures because time limit is reached %f>%f or memory is reached %d>%d...", totalTime*1000, _maxTimeAllowed, _memory->getWorkingMemSize(), _maxMemoryAllowed);
|
ULOGGER_INFO("Removing old signatures because time limit is reached %f>%f or memory is reached %d>%d...", totalTime*1000, _maxTimeAllowed, _memory->getWorkingMem().size(), _maxMemoryAllowed);
|
||||||
signaturesRemoved = _memory->forget(immunizedLocations);
|
signaturesRemoved = _memory->forget(immunizedLocations);
|
||||||
}
|
}
|
||||||
_lastProcessTime = totalTime;
|
_lastProcessTime = totalTime;
|
||||||
@@ -1243,7 +1313,7 @@ void Rtabmap::process()
|
|||||||
0,
|
0,
|
||||||
refWordsCount,
|
refWordsCount,
|
||||||
dictionarySize,
|
dictionarySize,
|
||||||
int(_memory->getWorkingMemSize()),
|
int(_memory->getWorkingMem().size()),
|
||||||
rejectedHypothesis?1:0,
|
rejectedHypothesis?1:0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@@ -1322,7 +1392,7 @@ void Rtabmap::getImage(Image & image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SETTERS
|
// SETTERS
|
||||||
void Rtabmap::setMaxTimeAllowed(float maxTimeAllowed)
|
void Rtabmap::setTimeThreshold(float maxTimeAllowed)
|
||||||
{
|
{
|
||||||
//must be positive, 0 mean inf time allowed (no time limit)
|
//must be positive, 0 mean inf time allowed (no time limit)
|
||||||
_maxTimeAllowed = maxTimeAllowed;
|
_maxTimeAllowed = maxTimeAllowed;
|
||||||
|
|||||||
@@ -38,64 +38,82 @@ int main(int argc, char * argv[])
|
|||||||
std::string path = argv[1];
|
std::string path = argv[1];
|
||||||
|
|
||||||
// rtabmap::Camera is simply a convenience wrapper of OpenCV cv::VideoCapture and cv::imread
|
// rtabmap::Camera is simply a convenience wrapper of OpenCV cv::VideoCapture and cv::imread
|
||||||
float imageRate = 1.0f; // 1 Hz
|
rtabmap::CameraImages camera(path);
|
||||||
rtabmap::CameraImages camera(path, 1, false, imageRate);
|
|
||||||
|
|
||||||
if(!camera.init())
|
if(!camera.init())
|
||||||
{
|
{
|
||||||
printf("Camera init failed, using path \"%s\"\n", path.c_str());
|
printf("Camera init failed, using path \"%s\"\n", path.c_str());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create tasks
|
// Create RTAB-Map
|
||||||
rtabmap::Rtabmap rtabmap;
|
rtabmap::Rtabmap rtabmap;
|
||||||
|
|
||||||
// Where database is saved
|
// Set the time threshold
|
||||||
rtabmap.setWorkingDirectory(".");
|
rtabmap.setTimeThreshold(700.0f); // Time threshold : 700 ms, 0 ms means no limit
|
||||||
|
|
||||||
// Initialize rtabmap: load database...
|
// To set other parameters, the Parameters interface must be used (Parameters.h).
|
||||||
// It will automatically create config.ini
|
// Example here to change the loop closure threshold (default 0.15).
|
||||||
// with default parameters if it not exists
|
// Lower the threshold, more loop closures are detected but there is more chance of false positives.
|
||||||
rtabmap.init("./config.ini");
|
rtabmap::ParametersMap parameters;
|
||||||
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapLoopThr(), "0.11"));
|
||||||
|
|
||||||
// For this example, we want to delete the memory at each start.
|
// The time threshold set above is also a parameter, one could have set it the same way:
|
||||||
rtabmap.deleteMemory();
|
// parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRtabmapTimeThr(), "700"));
|
||||||
|
// Or SURF hessian treshold:
|
||||||
|
// parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kSURFHessianThreshold(), "150"));
|
||||||
|
|
||||||
rtabmap.setMaxTimeAllowed(700); // Time threshold : 700 ms
|
// Initialize rtabmap: load/create database...
|
||||||
|
rtabmap.init(parameters);
|
||||||
|
|
||||||
|
// Process each image of the directory...
|
||||||
|
printf("\nProcessing images... from directory \"%s\"\n", path.c_str());
|
||||||
|
|
||||||
// Start thread's task
|
|
||||||
int countLoopDetected=0;
|
int countLoopDetected=0;
|
||||||
|
|
||||||
printf("\nProcessing images at %f Hz... from directory \"%s\"\n", imageRate, path.c_str());
|
|
||||||
|
|
||||||
int imagesProcessed = 0;
|
|
||||||
|
|
||||||
cv::Mat img = camera.takeImage();
|
|
||||||
int i=0;
|
int i=0;
|
||||||
|
cv::Mat img = camera.takeImage();
|
||||||
while(!img.empty())
|
while(!img.empty())
|
||||||
{
|
{
|
||||||
++imagesProcessed;
|
// Process image : Main loop of RTAB-Map
|
||||||
rtabmap.process(rtabmap::Image(img));
|
rtabmap.process(img);
|
||||||
|
|
||||||
|
// Check if a loop closure is detected and print some info
|
||||||
if(rtabmap.getLoopClosureId())
|
if(rtabmap.getLoopClosureId())
|
||||||
{
|
{
|
||||||
++countLoopDetected;
|
++countLoopDetected;
|
||||||
}
|
}
|
||||||
img = camera.takeImage();
|
|
||||||
|
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
if(rtabmap.getLoopClosureId())
|
if(rtabmap.getLoopClosureId())
|
||||||
{
|
{
|
||||||
printf(" iteration(%d) ptime(%fs) loop(%d) hyp(%.2f)\n",
|
printf(" #%d ptime(%fs) STM(%d) WM(%d) hyp(%d) value(%.2f) *LOOP %d->%d*\n",
|
||||||
i, rtabmap.getLastProcessTime(), rtabmap.getLoopClosureId(), rtabmap.getLcHypValue());
|
i,
|
||||||
|
rtabmap.getLastProcessTime(),
|
||||||
|
rtabmap.getSTM().size(), // short-term memory
|
||||||
|
rtabmap.getWM().size(), // working memory
|
||||||
|
rtabmap.getLoopClosureId(),
|
||||||
|
rtabmap.getLcHypValue(),
|
||||||
|
rtabmap.getLastLocationId(),
|
||||||
|
rtabmap.getLoopClosureId());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf(" iteration(%d) ptime(%fs)\n", i, rtabmap.getLastProcessTime());
|
printf(" #%d ptime(%fs) STM(%d) WM(%d) hyp(%d) value(%.2f)\n",
|
||||||
|
i,
|
||||||
|
rtabmap.getLastProcessTime(),
|
||||||
|
rtabmap.getSTM().size(), // short-term memory
|
||||||
|
rtabmap.getWM().size(), // working memory
|
||||||
|
rtabmap.getRetrievedId(), // highest loop closure hypothesis
|
||||||
|
rtabmap.getLcHypValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Get next image
|
||||||
|
img = camera.takeImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Processing images completed. Loop closures found = %d\n", countLoopDetected);
|
printf("Processing images completed. Loop closures found = %d\n", countLoopDetected);
|
||||||
|
|
||||||
|
// Cleanup... save database and logs
|
||||||
|
printf("Saving Long-Term Memory to \"LTM.db\"...\n");
|
||||||
|
rtabmap.close();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -548,7 +548,12 @@ QString PreferencesDialog::getWorkingDirectory()
|
|||||||
|
|
||||||
QString PreferencesDialog::getIniFilePath()
|
QString PreferencesDialog::getIniFilePath()
|
||||||
{
|
{
|
||||||
return Rtabmap::getIniFilePath().c_str();
|
QString privatePath = QDir::homePath() + "/.rtabmap";
|
||||||
|
if(!QDir(privatePath).exists())
|
||||||
|
{
|
||||||
|
QDir::home().mkdir(".rtabmap");
|
||||||
|
}
|
||||||
|
return privatePath + "/rtabmap.ini";
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreferencesDialog::loadConfigFrom()
|
void PreferencesDialog::loadConfigFrom()
|
||||||
|
|||||||
@@ -57,10 +57,7 @@ void showUsage()
|
|||||||
" -SURF/HessianThreshold 150\n"
|
" -SURF/HessianThreshold 150\n"
|
||||||
" For parameters in table format, add ',' between values :\n"
|
" For parameters in table format, add ',' between values :\n"
|
||||||
" -Kp/RoiRatios 0,0,0.1,0\n"
|
" -Kp/RoiRatios 0,0,0.1,0\n"
|
||||||
" Default parameters can be found in ~/.rtabmap/rtabmap.ini\n"
|
" -default_params Show default RTAB-Map's parameters\n"
|
||||||
" -default_params Show default RTAB-Map's parameters (WARNING : \n"
|
|
||||||
" parameters from rtabmap.ini (if exists) overwrite the default \n"
|
|
||||||
" ones shown here)\n"
|
|
||||||
" -debug Set Log level to Debug (Default Error)\n"
|
" -debug Set Log level to Debug (Default Error)\n"
|
||||||
" -info Set Log level to Info (Default Error)\n"
|
" -info Set Log level to Info (Default Error)\n"
|
||||||
" -warn Set Log level to Warning (Default Error)\n"
|
" -warn Set Log level to Warning (Default Error)\n"
|
||||||
@@ -375,20 +372,18 @@ int main(int argc, char * argv[])
|
|||||||
|
|
||||||
std::map<int, int> groundTruth;
|
std::map<int, int> groundTruth;
|
||||||
|
|
||||||
// Create tasks
|
|
||||||
Rtabmap * rtabmap = new Rtabmap();
|
|
||||||
rtabmap->init();
|
|
||||||
rtabmap->setMaxTimeAllowed(timeThreshold); // in ms
|
|
||||||
|
|
||||||
ULogger::setType(ULogger::kTypeConsole);
|
ULogger::setType(ULogger::kTypeConsole);
|
||||||
//ULogger::setType(ULogger::kTypeFile, rtabmap->getWorkingDir()+"/LogConsole.txt", false);
|
//ULogger::setType(ULogger::kTypeFile, rtabmap.getWorkingDir()+"/LogConsole.txt", false);
|
||||||
//ULogger::setBuffered(true);
|
//ULogger::setBuffered(true);
|
||||||
ULogger::setLevel(logLevel);
|
ULogger::setLevel(logLevel);
|
||||||
ULogger::setExitLevel(exitLevel);
|
ULogger::setExitLevel(exitLevel);
|
||||||
|
|
||||||
|
// Create tasks : memory is deleted
|
||||||
|
Rtabmap rtabmap(Parameters::defaultRtabmapWorkingDirectory());
|
||||||
// Disable statistics (we don't need them)
|
// Disable statistics (we don't need them)
|
||||||
pm.insert(ParametersPair(Parameters::kRtabmapPublishStats(), uBool2Str(false)));
|
pm.insert(ParametersPair(Parameters::kRtabmapPublishStats(), uBool2Str(false)));
|
||||||
rtabmap->init(pm);
|
rtabmap.init(pm);
|
||||||
|
rtabmap.setTimeThreshold(timeThreshold); // in ms
|
||||||
|
|
||||||
printf("Avpd init time = %fs\n", timer.ticks());
|
printf("Avpd init time = %fs\n", timer.ticks());
|
||||||
|
|
||||||
@@ -409,7 +404,7 @@ int main(int argc, char * argv[])
|
|||||||
{
|
{
|
||||||
printf(" Creating the ground truth matrix.\n");
|
printf(" Creating the ground truth matrix.\n");
|
||||||
}
|
}
|
||||||
printf(" INFO: All other parameters are taken from the INI file located in \"~/.rtabmap\"\n");
|
printf(" INFO: All other parameters are set to defaults\n");
|
||||||
if(pm.size()>1)
|
if(pm.size()>1)
|
||||||
{
|
{
|
||||||
printf(" Overwritten parameters :\n");
|
printf(" Overwritten parameters :\n");
|
||||||
@@ -418,16 +413,13 @@ int main(int argc, char * argv[])
|
|||||||
printf(" %s=%s\n",iter->first.c_str(), iter->second.c_str());
|
printf(" %s=%s\n",iter->first.c_str(), iter->second.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(rtabmap->getWorkingMem().size() || rtabmap->getStMem().size())
|
if(rtabmap.getWM().size() || rtabmap.getSTM().size())
|
||||||
{
|
{
|
||||||
printf("[Warning] RTAB-Map database is not empty (%s)\n", (rtabmap->getWorkingDir()+Rtabmap::kDefaultDatabaseName).c_str());
|
printf("[Warning] RTAB-Map database is not empty (%s)\n", (rtabmap.getWorkingDir()+Rtabmap::kDefaultDatabaseName).c_str());
|
||||||
}
|
}
|
||||||
printf("\nProcessing images...\n");
|
printf("\nProcessing images...\n");
|
||||||
|
|
||||||
//setup camera
|
//setup camera
|
||||||
ParametersMap allParam;
|
|
||||||
Rtabmap::readParameters(rtabmap->getIniFilePath().c_str(), allParam);
|
|
||||||
pm.insert(allParam.begin(), allParam.end());
|
|
||||||
camera->setFeaturesExtracted(true);
|
camera->setFeaturesExtracted(true);
|
||||||
camera->parseParameters(pm);
|
camera->parseParameters(pm);
|
||||||
|
|
||||||
@@ -449,10 +441,10 @@ int main(int argc, char * argv[])
|
|||||||
++imagesProcessed;
|
++imagesProcessed;
|
||||||
iterationTimer.start();
|
iterationTimer.start();
|
||||||
rtabmapTimer.start();
|
rtabmapTimer.start();
|
||||||
rtabmap->process(img);
|
rtabmap.process(img);
|
||||||
double rtabmapTime = rtabmapTimer.elapsed();
|
double rtabmapTime = rtabmapTimer.elapsed();
|
||||||
loopClosureId = rtabmap->getLoopClosureId();
|
loopClosureId = rtabmap.getLoopClosureId();
|
||||||
if(rtabmap->getLoopClosureId())
|
if(rtabmap.getLoopClosureId())
|
||||||
{
|
{
|
||||||
++countLoopDetected;
|
++countLoopDetected;
|
||||||
}
|
}
|
||||||
@@ -464,7 +456,7 @@ int main(int argc, char * argv[])
|
|||||||
count, countLoopDetected, maxIterationTimeId, maxIterationTime);
|
count, countLoopDetected, maxIterationTimeId, maxIterationTime);
|
||||||
maxIterationTime = 0.0;
|
maxIterationTime = 0.0;
|
||||||
maxIterationTimeId = 0;
|
maxIterationTimeId = 0;
|
||||||
std::map<int, int> wm = rtabmap->getWeights();
|
std::map<int, int> wm = rtabmap.getWeights();
|
||||||
printf(" WM(%d)=[", (int)wm.size());
|
printf(" WM(%d)=[", (int)wm.size());
|
||||||
for(std::map<int, int>::iterator iter=wm.begin(); iter!=wm.end();++iter)
|
for(std::map<int, int>::iterator iter=wm.begin(); iter!=wm.end();++iter)
|
||||||
{
|
{
|
||||||
@@ -498,15 +490,15 @@ int main(int argc, char * argv[])
|
|||||||
|
|
||||||
ULogger::flush();
|
ULogger::flush();
|
||||||
|
|
||||||
if(rtabmap->getLoopClosureId())
|
if(rtabmap.getLoopClosureId())
|
||||||
{
|
{
|
||||||
printf(" iteration(%d) loop(%d) hyp(%.2f) time=%fs/%fs *\n",
|
printf(" iteration(%d) loop(%d) hyp(%.2f) time=%fs/%fs *\n",
|
||||||
count, rtabmap->getLoopClosureId(), rtabmap->getLcHypValue(), rtabmapTime, iterationTime);
|
count, rtabmap.getLoopClosureId(), rtabmap.getLcHypValue(), rtabmapTime, iterationTime);
|
||||||
}
|
}
|
||||||
else if(rtabmap->getReactivatedId())
|
else if(rtabmap.getRetrievedId())
|
||||||
{
|
{
|
||||||
printf(" iteration(%d) high(%d) hyp(%.2f) time=%fs/%fs\n",
|
printf(" iteration(%d) high(%d) hyp(%.2f) time=%fs/%fs\n",
|
||||||
count, rtabmap->getReactivatedId(), rtabmap->getLcHypValue(), rtabmapTime, iterationTime);
|
count, rtabmap.getRetrievedId(), rtabmap.getLcHypValue(), rtabmapTime, iterationTime);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -539,9 +531,9 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate the ground truth file
|
// Generate the ground truth file
|
||||||
printf("Generate ground truth to file %s, size of %d\n", (rtabmap->getWorkingDir()+GENERATED_GT_NAME).c_str(), groundTruthMat.rows);
|
printf("Generate ground truth to file %s, size of %d\n", (rtabmap.getWorkingDir()+GENERATED_GT_NAME).c_str(), groundTruthMat.rows);
|
||||||
IplImage img = groundTruthMat;
|
IplImage img = groundTruthMat;
|
||||||
cvSaveImage((rtabmap->getWorkingDir()+GENERATED_GT_NAME).c_str(), &img);
|
cvSaveImage((rtabmap.getWorkingDir()+GENERATED_GT_NAME).c_str(), &img);
|
||||||
printf(" Creating ground truth file = %fs\n", timer.ticks());
|
printf(" Creating ground truth file = %fs\n", timer.ticks());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,11 +543,7 @@ int main(int argc, char * argv[])
|
|||||||
camera = 0 ;
|
camera = 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rtabmap)
|
rtabmap.close();
|
||||||
{
|
|
||||||
delete rtabmap;
|
|
||||||
rtabmap = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(" Cleanup time = %fs\n", timer.ticks());
|
printf(" Cleanup time = %fs\n", timer.ticks());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user