mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 09:30:25 +08:00
Read-only localization mode (#1643)
* Read-only localization mode * Localization: don't update map's node timestamps if statistic after run are not saved * Updated Mem/LocalizationReadOnly description * Updated description of Kp/FlannIndexSaved
This commit is contained in:
@@ -45,7 +45,7 @@ DBDriver * DBDriver::create(const ParametersMap & parameters)
|
||||
|
||||
DBDriver::DBDriver(const ParametersMap & parameters) :
|
||||
_emptyTrashesTime(0),
|
||||
_timestampUpdate(true)
|
||||
_timestampUpdate(false)
|
||||
{
|
||||
this->parseParameters(parameters);
|
||||
}
|
||||
@@ -73,7 +73,15 @@ void DBDriver::closeConnection(bool save, const std::string & outputUrl)
|
||||
else
|
||||
{
|
||||
_trashesMutex.lock();
|
||||
for(auto & iter: _trashSignatures)
|
||||
{
|
||||
delete iter.second;
|
||||
}
|
||||
_trashSignatures.clear();
|
||||
for(auto & iter: _trashVisualWords)
|
||||
{
|
||||
delete iter.second;
|
||||
}
|
||||
_trashVisualWords.clear();
|
||||
_trashesMutex.unlock();
|
||||
}
|
||||
@@ -83,12 +91,12 @@ void DBDriver::closeConnection(bool save, const std::string & outputUrl)
|
||||
UDEBUG("");
|
||||
}
|
||||
|
||||
bool DBDriver::openConnection(const std::string & url, bool overwritten)
|
||||
bool DBDriver::openConnection(const std::string & url, bool overwritten, bool readOnly)
|
||||
{
|
||||
UDEBUG("");
|
||||
_url = url;
|
||||
_dbSafeAccessMutex.lock();
|
||||
if(this->connectDatabaseQuery(url, overwritten))
|
||||
if(this->connectDatabaseQuery(url, overwritten, readOnly))
|
||||
{
|
||||
_dbSafeAccessMutex.unlock();
|
||||
return true;
|
||||
|
||||
@@ -320,7 +320,7 @@ bool DBDriverSqlite3::getDatabaseVersionQuery(std::string & version) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwritten)
|
||||
bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwritten, bool readOnly)
|
||||
{
|
||||
this->disconnectDatabaseQuery();
|
||||
// Open a database connection
|
||||
@@ -332,7 +332,7 @@ bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwri
|
||||
if(!url.empty())
|
||||
{
|
||||
dbFileExist = UFile::exists(url.c_str());
|
||||
if(dbFileExist && overwritten)
|
||||
if(dbFileExist && overwritten && !readOnly)
|
||||
{
|
||||
UINFO("Deleting database %s...", url.c_str());
|
||||
UASSERT(UFile::erase(url.c_str()) == 0);
|
||||
@@ -354,12 +354,12 @@ bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwri
|
||||
{
|
||||
ULOGGER_INFO("Using empty database in the memory.");
|
||||
}
|
||||
rc = sqlite3_open_v2(":memory:", &_ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
||||
rc = sqlite3_open_v2(":memory:", &_ppDb, readOnly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ULOGGER_INFO("Using database \"%s\" from the hard drive.", url.c_str());
|
||||
rc = sqlite3_open_v2(url.c_str(), &_ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
||||
rc = sqlite3_open_v2(url.c_str(), &_ppDb, readOnly ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
||||
}
|
||||
if(rc != SQLITE_OK)
|
||||
{
|
||||
@@ -4343,7 +4343,7 @@ void DBDriverSqlite3::loadLinksQuery(std::list<Signature *> & signatures) const
|
||||
|
||||
void DBDriverSqlite3::updateQuery(const std::list<Signature *> & nodes, bool updateTimestamp) const
|
||||
{
|
||||
UDEBUG("nodes = %d", nodes.size());
|
||||
UDEBUG("nodes = %d, updateTimestamp = %s", nodes.size(), updateTimestamp?"true":"false");
|
||||
if(_ppDb && nodes.size())
|
||||
{
|
||||
UTimer timer;
|
||||
@@ -4382,7 +4382,7 @@ void DBDriverSqlite3::updateQuery(const std::list<Signature *> & nodes, bool upd
|
||||
{
|
||||
s = *i;
|
||||
int index = 1;
|
||||
if(s)
|
||||
if(s && (s->isModified() || updateTimestamp))
|
||||
{
|
||||
rc = sqlite3_bind_int(ppStmt, index++, s->getWeight());
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
@@ -4406,7 +4406,7 @@ void DBDriverSqlite3::updateQuery(const std::list<Signature *> & nodes, bool upd
|
||||
|
||||
//step
|
||||
rc=sqlite3_step(ppStmt);
|
||||
UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error (%s): %s (node id = %d map=%d)", _version.c_str(), sqlite3_errmsg(_ppDb), s->id(), s->mapId()).c_str());
|
||||
|
||||
rc = sqlite3_reset(ppStmt);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
@@ -5751,7 +5751,7 @@ cv::Mat DBDriverSqlite3::loadOptimizedMeshQuery(
|
||||
|
||||
void DBDriverSqlite3::saveFlannIndexQuery(const std::vector<unsigned char> & data) const
|
||||
{
|
||||
UDEBUG("");
|
||||
UDEBUG("data size = %ld bytes", data.size());
|
||||
if(_ppDb && uStrNumCmp(_version, "0.23.0") >= 0)
|
||||
{
|
||||
UTimer timer;
|
||||
|
||||
@@ -83,6 +83,7 @@ Memory::Memory(const ParametersMap & parameters) :
|
||||
_rgbCompressionFormat(Parameters::defaultMemImageCompressionFormat()),
|
||||
_depthCompressionFormat(Parameters::defaultMemDepthCompressionFormat()),
|
||||
_incrementalMemory(Parameters::defaultMemIncrementalMemory()),
|
||||
_localizationReadOnly(Parameters::defaultMemLocalizationReadOnly()),
|
||||
_localizationDataSaved(Parameters::defaultMemLocalizationDataSaved()),
|
||||
_flannIndexSaved(Parameters::defaultKpFlannIndexSaved()),
|
||||
_reduceGraph(Parameters::defaultMemReduceGraph()),
|
||||
@@ -185,10 +186,6 @@ bool Memory::init(const std::string & dbUrl, bool dbOverwritten, const Parameter
|
||||
_dbDriver = 0; // HACK for the clear() below to think that there is no db
|
||||
}
|
||||
}
|
||||
else if(!_memoryChanged && _linksChanged)
|
||||
{
|
||||
_dbDriver->setTimestampUpdateEnabled(false); // update links only
|
||||
}
|
||||
this->clear();
|
||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit("Clearing memory, done!"));
|
||||
|
||||
@@ -212,10 +209,10 @@ bool Memory::init(const std::string & dbUrl, bool dbOverwritten, const Parameter
|
||||
bool success = true;
|
||||
if(_dbDriver)
|
||||
{
|
||||
_dbDriver->setTimestampUpdateEnabled(true); // make sure that timestamp update is enabled (may be disabled above)
|
||||
|
||||
success = false;
|
||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(std::string("Connecting to database \"") + dbUrl + "\"..."));
|
||||
if(_dbDriver->openConnection(dbUrl, dbOverwritten))
|
||||
if(_dbDriver->openConnection(dbUrl, dbOverwritten, isReadOnly()))
|
||||
{
|
||||
success = true;
|
||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(std::string("Connecting to database \"") + dbUrl + "\", done!"));
|
||||
@@ -245,6 +242,7 @@ void Memory::loadDataFromDb(bool postInitClosingEvents)
|
||||
|
||||
if(loadAllNodesInWM)
|
||||
{
|
||||
UDEBUG("Loading all nodes to WM...");
|
||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(std::string("Loading all nodes to WM...")));
|
||||
std::set<int> ids;
|
||||
_dbDriver->getAllNodeIds(ids, true);
|
||||
@@ -252,6 +250,7 @@ void Memory::loadDataFromDb(bool postInitClosingEvents)
|
||||
}
|
||||
else
|
||||
{
|
||||
UDEBUG("Loading last nodes to WM...");
|
||||
// load previous session working memory
|
||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(std::string("Loading last nodes to WM...")));
|
||||
_dbDriver->loadLastNodes(dbSignatures, !_loadVisualLocalFeaturesOnInit);
|
||||
@@ -531,16 +530,23 @@ void Memory::close(bool databaseSaved, bool postInitClosingEvents, const std::st
|
||||
|
||||
UDEBUG("_memoryChanged=%d _linksChanged=%d databaseNameChanged=%d", _memoryChanged?1:0, _linksChanged?1:0, databaseNameChanged?1:0);
|
||||
|
||||
if(!databaseSaved || (!_memoryChanged && !_linksChanged && !databaseNameChanged))
|
||||
if(!databaseSaved || (!_memoryChanged && !_linksChanged && !databaseNameChanged) || this->isReadOnly())
|
||||
{
|
||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(uFormat("No changes added to database.")));
|
||||
|
||||
UINFO("No changes added to database.");
|
||||
if(_dbDriver)
|
||||
{
|
||||
saveFlannIndex(postInitClosingEvents);
|
||||
if(!this->isReadOnly()) {
|
||||
saveFlannIndex(postInitClosingEvents);
|
||||
}
|
||||
else if(_memoryChanged || _linksChanged || databaseNameChanged)
|
||||
{
|
||||
UWARN("Memory has been modified (nodes=%s links=%s name=%s) but the database is read-only, changes are not saved to database.",
|
||||
_memoryChanged?"true":"false", _linksChanged?"true":"false", databaseNameChanged?"true":"false");
|
||||
}
|
||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(uFormat("Closing database \"%s\"...", _dbDriver->getUrl().c_str())));
|
||||
_dbDriver->closeConnection(false, ouputDatabasePath);
|
||||
_dbDriver->closeConnection(false);
|
||||
delete _dbDriver;
|
||||
_dbDriver = 0;
|
||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit("Closing database, done!"));
|
||||
@@ -556,12 +562,6 @@ void Memory::close(bool databaseSaved, bool postInitClosingEvents, const std::st
|
||||
if(!_memoryChanged && _dbDriver)
|
||||
{
|
||||
saveFlannIndex(postInitClosingEvents);
|
||||
|
||||
if(_linksChanged) {
|
||||
// don't update the time stamps!
|
||||
UDEBUG("");
|
||||
_dbDriver->setTimestampUpdateEnabled(false);
|
||||
}
|
||||
}
|
||||
this->clear();
|
||||
if(_dbDriver)
|
||||
@@ -663,6 +663,7 @@ void Memory::parseParameters(const ParametersMap & parameters)
|
||||
Parameters::parse(params, Parameters::kMarkerVarianceOrientationIgnored(), _markerOrientationIgnored);
|
||||
Parameters::parse(params, Parameters::kMemLocalizationDataSaved(), _localizationDataSaved);
|
||||
Parameters::parse(params, Parameters::kKpFlannIndexSaved(), _flannIndexSaved);
|
||||
Parameters::parse(params, Parameters::kMemLocalizationReadOnly(), _localizationReadOnly);
|
||||
|
||||
if(_markerAngVariance>=9999)
|
||||
{
|
||||
@@ -1865,6 +1866,7 @@ void Memory::clear()
|
||||
uInsert(parameters, parameters_);
|
||||
parameters.erase(Parameters::kRtabmapWorkingDirectory()); // don't save working directory as it is machine dependent
|
||||
UDEBUG("");
|
||||
_dbDriver->setTimestampUpdateEnabled(true); // Only re-stamp if we updated the memory
|
||||
_dbDriver->addInfoAfterRun(memSize,
|
||||
_lastSignature?_lastSignature->id():0,
|
||||
UProcessInfo::getMemoryUsage(),
|
||||
@@ -1938,6 +1940,7 @@ void Memory::clear()
|
||||
_dbDriver->join(true);
|
||||
cleanUnusedWords();
|
||||
_dbDriver->emptyTrashes();
|
||||
_dbDriver->setTimestampUpdateEnabled(false);
|
||||
}
|
||||
_vwd->clear(_dbDriver!=NULL);
|
||||
UDEBUG("");
|
||||
@@ -3626,7 +3629,7 @@ void Memory::updateLink(const Link & link, bool updateInDatabase)
|
||||
|
||||
if(oldType!=Link::kVirtualClosure || link.type()!=Link::kVirtualClosure)
|
||||
{
|
||||
_linksChanged = true;
|
||||
_linksChanged = _incrementalMemory || (fromS->isSaved() && toS->isSaved());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -507,6 +507,11 @@ void Rtabmap::close(bool databaseSaved, const std::string & ouputDatabasePath)
|
||||
}
|
||||
if(_memory)
|
||||
{
|
||||
if(_memory->isReadOnly() && databaseSaved)
|
||||
{
|
||||
UWARN("Database is read-only, latest optimized poses, latest localization pose and latest state of the memory are not saved.");
|
||||
databaseSaved = false;
|
||||
}
|
||||
if(databaseSaved)
|
||||
{
|
||||
if(_memory->isGraphReduced() && _memory->isIncremental())
|
||||
|
||||
Reference in New Issue
Block a user