mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
0.11.11: changed Statistics table name to Info and added new Statistics table containing detection statistics. StatisticsToolBox can cache statistics (true by default). DatabaseViewer: new Statistics panel to see all statistics contained in the database.
This commit is contained in:
@@ -197,6 +197,15 @@ ParametersMap DBDriver::getLastParameters() const
|
||||
return parameters;
|
||||
}
|
||||
|
||||
std::map<std::string, float> DBDriver::getStatistics(int nodeId, double & stamp) const
|
||||
{
|
||||
std::map<std::string, float> statistics;
|
||||
_dbSafeAccessMutex.lock();
|
||||
statistics = getStatisticsQuery(nodeId, stamp);
|
||||
_dbSafeAccessMutex.unlock();
|
||||
return statistics;
|
||||
}
|
||||
|
||||
std::string DBDriver::getDatabaseVersion() const
|
||||
{
|
||||
std::string version = "0.0.0";
|
||||
@@ -866,7 +875,7 @@ void DBDriver::getAllLabels(std::map<int, std::string> & labels) const
|
||||
_dbSafeAccessMutex.unlock();
|
||||
}
|
||||
|
||||
void DBDriver::addStatisticsAfterRun(
|
||||
void DBDriver::addInfoAfterRun(
|
||||
int stMemSize,
|
||||
int lastSignAdded,
|
||||
int processMemUsed,
|
||||
@@ -881,13 +890,26 @@ void DBDriver::addStatisticsAfterRun(
|
||||
if(uStrNumCmp(this->getDatabaseVersion(), "0.11.8") >= 0)
|
||||
{
|
||||
std::string param = Parameters::serialize(parameters);
|
||||
query << "INSERT INTO Statistics(STM_size,last_sign_added,process_mem_used,database_mem_used,dictionary_size,parameters) values("
|
||||
<< stMemSize << ","
|
||||
<< lastSignAdded << ","
|
||||
<< processMemUsed << ","
|
||||
<< databaseMemUsed << ","
|
||||
<< dictionarySize << ","
|
||||
"\"" << param.c_str() << "\");";
|
||||
if(uStrNumCmp(this->getDatabaseVersion(), "0.11.11") >= 0)
|
||||
{
|
||||
query << "INSERT INTO Info(STM_size,last_sign_added,process_mem_used,database_mem_used,dictionary_size,parameters) values("
|
||||
<< stMemSize << ","
|
||||
<< lastSignAdded << ","
|
||||
<< processMemUsed << ","
|
||||
<< databaseMemUsed << ","
|
||||
<< dictionarySize << ","
|
||||
"\"" << param.c_str() << "\");";
|
||||
}
|
||||
else
|
||||
{
|
||||
query << "INSERT INTO Statistics(STM_size,last_sign_added,process_mem_used,database_mem_used,dictionary_size,parameters) values("
|
||||
<< stMemSize << ","
|
||||
<< lastSignAdded << ","
|
||||
<< processMemUsed << ","
|
||||
<< databaseMemUsed << ","
|
||||
<< dictionarySize << ","
|
||||
"\"" << param.c_str() << "\");";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -903,6 +925,13 @@ void DBDriver::addStatisticsAfterRun(
|
||||
}
|
||||
}
|
||||
|
||||
void DBDriver::addStatistics(const Statistics & statistics) const
|
||||
{
|
||||
_dbSafeAccessMutex.lock();
|
||||
addStatisticsQuery(statistics);
|
||||
_dbSafeAccessMutex.unlock();
|
||||
}
|
||||
|
||||
void DBDriver::generateGraph(
|
||||
const std::string & fileName,
|
||||
const std::set<int> & idsInput,
|
||||
|
||||
@@ -617,7 +617,15 @@ int DBDriverSqlite3::getLastNodesSizeQuery() const
|
||||
int size = 0;
|
||||
if(_ppDb)
|
||||
{
|
||||
std::string query = "SELECT count(id) from Node WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics);";
|
||||
std::string query;
|
||||
if(uStrNumCmp(_version, "0.11.11") >= 0)
|
||||
{
|
||||
query = "SELECT count(id) from Node WHERE time_enter >= (SELECT MAX(time_enter) FROM Info);";
|
||||
}
|
||||
else
|
||||
{
|
||||
query = "SELECT count(id) from Node WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics);";
|
||||
}
|
||||
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt * ppStmt = 0;
|
||||
@@ -641,7 +649,15 @@ int DBDriverSqlite3::getLastDictionarySizeQuery() const
|
||||
int size = 0;
|
||||
if(_ppDb)
|
||||
{
|
||||
std::string query = "SELECT count(id) from Word WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics);";
|
||||
std::string query;
|
||||
if(uStrNumCmp(_version, "0.11.11") >= 0)
|
||||
{
|
||||
query = "SELECT count(id) from Word WHERE time_enter >= (SELECT MAX(time_enter) FROM Info);";
|
||||
}
|
||||
else
|
||||
{
|
||||
query = "SELECT count(id) from Word WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics);";
|
||||
}
|
||||
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt * ppStmt = 0;
|
||||
@@ -716,9 +732,19 @@ ParametersMap DBDriverSqlite3::getLastParametersQuery() const
|
||||
{
|
||||
if(uStrNumCmp(_version, "0.11.8") >= 0)
|
||||
{
|
||||
std::string query = "SELECT parameters "
|
||||
"FROM Statistics "
|
||||
"WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics);";
|
||||
std::string query;
|
||||
if(uStrNumCmp(_version, "0.11.11") >= 0)
|
||||
{
|
||||
query = "SELECT parameters "
|
||||
"FROM Info "
|
||||
"WHERE time_enter >= (SELECT MAX(time_enter) FROM Info);";
|
||||
}
|
||||
else
|
||||
{
|
||||
query = "SELECT parameters "
|
||||
"FROM Statistics "
|
||||
"WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics);";
|
||||
}
|
||||
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt * ppStmt = 0;
|
||||
@@ -744,6 +770,44 @@ ParametersMap DBDriverSqlite3::getLastParametersQuery() const
|
||||
return parameters;
|
||||
}
|
||||
|
||||
std::map<std::string, float> DBDriverSqlite3::getStatisticsQuery(int nodeId, double & stamp) const
|
||||
{
|
||||
UDEBUG("");
|
||||
std::map<std::string, float> data;
|
||||
if(_ppDb)
|
||||
{
|
||||
if(uStrNumCmp(_version, "0.11.11") >= 0)
|
||||
{
|
||||
std::stringstream query;
|
||||
|
||||
query << "SELECT stamp, data "
|
||||
<< "FROM Statistics "
|
||||
<< "WHERE id=" << nodeId << ";";
|
||||
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt * ppStmt = 0;
|
||||
rc = sqlite3_prepare_v2(_ppDb, query.str().c_str(), -1, &ppStmt, 0);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
rc = sqlite3_step(ppStmt);
|
||||
if(rc == SQLITE_ROW)
|
||||
{
|
||||
stamp = sqlite3_column_double(ppStmt, 0);
|
||||
std::string text((const char *)sqlite3_column_text(ppStmt, 1));
|
||||
if(text.size())
|
||||
{
|
||||
data = Statistics::deserializeData(text);
|
||||
}
|
||||
|
||||
rc = sqlite3_step(ppStmt);
|
||||
}
|
||||
UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
rc = sqlite3_finalize(ppStmt);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures, bool images, bool scan, bool userData, bool occupancyGrid) const
|
||||
{
|
||||
UDEBUG("load data for %d signatures", (int)signatures.size());
|
||||
@@ -2127,10 +2191,20 @@ void DBDriverSqlite3::loadLastNodesQuery(std::list<Signature *> & nodes) const
|
||||
std::string query;
|
||||
std::list<int> ids;
|
||||
|
||||
query = "SELECT n.id "
|
||||
"FROM Node AS n "
|
||||
"WHERE n.time_enter >= (SELECT MAX(time_enter) FROM Statistics) "
|
||||
"ORDER BY n.id;";
|
||||
if(uStrNumCmp(_version, "0.11.11") >= 0)
|
||||
{
|
||||
query = "SELECT n.id "
|
||||
"FROM Node AS n "
|
||||
"WHERE n.time_enter >= (SELECT MAX(time_enter) FROM Info) "
|
||||
"ORDER BY n.id;";
|
||||
}
|
||||
else
|
||||
{
|
||||
query = "SELECT n.id "
|
||||
"FROM Node AS n "
|
||||
"WHERE n.time_enter >= (SELECT MAX(time_enter) FROM Statistics) "
|
||||
"ORDER BY n.id;";
|
||||
}
|
||||
|
||||
rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
@@ -2169,10 +2243,20 @@ void DBDriverSqlite3::loadQuery(VWDictionary * dictionary) const
|
||||
std::list<VisualWord *> visualWords;
|
||||
|
||||
// Get the visual words
|
||||
query = "SELECT id, descriptor_size, descriptor "
|
||||
"FROM Word "
|
||||
"WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics) "
|
||||
"ORDER BY id;";
|
||||
if(uStrNumCmp(_version, "0.11.11") >= 0)
|
||||
{
|
||||
query = "SELECT id, descriptor_size, descriptor "
|
||||
"FROM Word "
|
||||
"WHERE time_enter >= (SELECT MAX(time_enter) FROM Info) "
|
||||
"ORDER BY id;";
|
||||
}
|
||||
else
|
||||
{
|
||||
query = "SELECT id, descriptor_size, descriptor "
|
||||
"FROM Word "
|
||||
"WHERE time_enter >= (SELECT MAX(time_enter) FROM Statistics) "
|
||||
"ORDER BY id;";
|
||||
}
|
||||
|
||||
rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
@@ -3077,6 +3161,52 @@ void DBDriverSqlite3::updateOccupancyGridQuery(
|
||||
}
|
||||
}
|
||||
|
||||
void DBDriverSqlite3::addStatisticsQuery(const Statistics & statistics) const
|
||||
{
|
||||
UDEBUG("");
|
||||
if(_ppDb)
|
||||
{
|
||||
std::string type;
|
||||
UTimer timer;
|
||||
timer.start();
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt * ppStmt = 0;
|
||||
|
||||
// Create query
|
||||
if(uStrNumCmp(this->getDatabaseVersion(), "0.11.11") >= 0)
|
||||
{
|
||||
std::string param = Statistics::serializeData(statistics.data());
|
||||
if(param.size() && statistics.refImageId()>0)
|
||||
{
|
||||
std::string query = "INSERT INTO Statistics(id, stamp, data) values(?,?,?);";
|
||||
rc = sqlite3_prepare_v2(_ppDb, query.c_str(), -1, &ppStmt, 0);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
|
||||
int index = 1;
|
||||
rc = sqlite3_bind_int(ppStmt, index++, statistics.refImageId());
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
rc = sqlite3_bind_double(ppStmt, index++, statistics.stamp());
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
rc = sqlite3_bind_text(ppStmt, index++, param.c_str(), -1, SQLITE_STATIC);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
|
||||
//step
|
||||
rc=sqlite3_step(ppStmt);
|
||||
UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
|
||||
rc = sqlite3_reset(ppStmt);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
|
||||
// Finalize (delete) the statement
|
||||
rc = sqlite3_finalize(ppStmt);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
|
||||
UDEBUG("Time=%fs", timer.ticks());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string DBDriverSqlite3::queryStepNode() const
|
||||
{
|
||||
if(uStrNumCmp(_version, "0.11.1") >= 0)
|
||||
|
||||
@@ -63,6 +63,7 @@ private:
|
||||
virtual int getTotalNodesSizeQuery() const;
|
||||
virtual int getTotalDictionarySizeQuery() const;
|
||||
virtual ParametersMap getLastParametersQuery() const;
|
||||
virtual std::map<std::string, float> getStatisticsQuery(int nodeId, double & stamp) const;
|
||||
|
||||
virtual void executeNoResultQuery(const std::string & sql) const;
|
||||
|
||||
@@ -83,6 +84,8 @@ private:
|
||||
float cellSize,
|
||||
const cv::Point3f & viewpoint) const;
|
||||
|
||||
virtual void addStatisticsQuery(const Statistics & statistics) const;
|
||||
|
||||
// Load objects
|
||||
virtual void loadQuery(VWDictionary * dictionary) const;
|
||||
virtual void loadLastNodesQuery(std::list<Signature *> & signatures) const;
|
||||
|
||||
@@ -1285,7 +1285,7 @@ void Memory::clear()
|
||||
if(_memoryChanged)
|
||||
{
|
||||
UDEBUG("");
|
||||
_dbDriver->addStatisticsAfterRun(memSize,
|
||||
_dbDriver->addInfoAfterRun(memSize,
|
||||
_lastSignature?_lastSignature->id():0,
|
||||
UProcessInfo::getMemoryUsage(),
|
||||
_dbDriver->getMemoryUsed(),
|
||||
@@ -1582,6 +1582,14 @@ int Memory::cleanup()
|
||||
return signatureRemoved;
|
||||
}
|
||||
|
||||
void Memory::saveStatistics(const Statistics & statistics)
|
||||
{
|
||||
if(_dbDriver)
|
||||
{
|
||||
_dbDriver->addStatistics(statistics);
|
||||
}
|
||||
}
|
||||
|
||||
void Memory::emptyTrash()
|
||||
{
|
||||
if(_dbDriver)
|
||||
|
||||
@@ -2557,6 +2557,9 @@ bool Rtabmap::process(
|
||||
UDEBUG("");
|
||||
}
|
||||
|
||||
//Save statistics to database
|
||||
_memory->saveStatistics(statistics_);
|
||||
|
||||
//Start trashing
|
||||
UDEBUG("Empty trash...");
|
||||
_memory->emptyTrash();
|
||||
|
||||
@@ -27,6 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "rtabmap/core/Statistics.h"
|
||||
#include <rtabmap/utilite/UStl.h>
|
||||
#include <rtabmap/utilite/UConversion.h>
|
||||
|
||||
namespace rtabmap {
|
||||
std::map<std::string, float> Statistics::_defaultData;
|
||||
@@ -38,11 +39,44 @@ const std::map<std::string, float> & Statistics::defaultData()
|
||||
return _defaultData;
|
||||
}
|
||||
|
||||
std::string Statistics::serializeData(const std::map<std::string, float> & data)
|
||||
{
|
||||
std::stringstream output;
|
||||
for(std::map<std::string, float>::const_iterator iter=data.begin(); iter!=data.end(); ++iter)
|
||||
{
|
||||
if(iter != data.begin())
|
||||
{
|
||||
output << ";";
|
||||
}
|
||||
// make sure there are no commas instead of dots
|
||||
output << iter->first << ":" << uReplaceChar(uNumber2Str(iter->second), ',', '.');
|
||||
}
|
||||
return output.str();
|
||||
}
|
||||
|
||||
std::map<std::string, float> Statistics::deserializeData(const std::string & data)
|
||||
{
|
||||
std::map<std::string, float> output;
|
||||
std::list<std::string> tuplets = uSplit(data, ';');
|
||||
for(std::list<std::string>::iterator iter=tuplets.begin(); iter!=tuplets.end(); ++iter)
|
||||
{
|
||||
std::list<std::string> p = uSplit(*iter, ':');
|
||||
if(p.size() == 2)
|
||||
{
|
||||
std::string key = p.front();
|
||||
std::string value = p.back();
|
||||
uInsert(output, std::make_pair(key, uStr2Float(value)));
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
Statistics::Statistics() :
|
||||
_extended(0),
|
||||
_refImageId(0),
|
||||
_loopClosureId(0),
|
||||
_proximiyDetectionId(0),
|
||||
_stamp(0.0f),
|
||||
_currentGoalId(0)
|
||||
{
|
||||
_defaultDataInitialized = true;
|
||||
|
||||
@@ -85,7 +85,7 @@ CREATE TABLE Map_Node_Word (
|
||||
FOREIGN KEY (word_id) REFERENCES Word(id)
|
||||
);
|
||||
|
||||
CREATE TABLE Statistics (
|
||||
CREATE TABLE Info (
|
||||
STM_size INTEGER,
|
||||
last_sign_added INTEGER,
|
||||
process_mem_used INTEGER,
|
||||
@@ -95,6 +95,13 @@ CREATE TABLE Statistics (
|
||||
time_enter DATE
|
||||
);
|
||||
|
||||
CREATE TABLE Statistics (
|
||||
id INTEGER NOT NULL,
|
||||
stamp FLOAT,
|
||||
data TEXT,
|
||||
FOREIGN KEY (id) REFERENCES Node(id)
|
||||
);
|
||||
|
||||
CREATE TABLE Admin (
|
||||
version TEXT,
|
||||
time_enter DATE
|
||||
@@ -120,18 +127,19 @@ BEGIN
|
||||
UPDATE Word SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER insert_Statistics_timeEnter AFTER INSERT ON Statistics
|
||||
CREATE TRIGGER insert_Info_timeEnter AFTER INSERT ON Info
|
||||
BEGIN
|
||||
UPDATE Statistics SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
|
||||
UPDATE Info SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
|
||||
END;
|
||||
|
||||
|
||||
-- *******************************************************************
|
||||
-- INDEXES
|
||||
-- *******************************************************************
|
||||
CREATE UNIQUE INDEX IDX_Node_id on Node (id);
|
||||
CREATE INDEX IDX_Map_Node_Word_node_id on Map_Node_Word (node_id);
|
||||
CREATE INDEX IDX_Link_from_id on Link (from_id);
|
||||
CREATE UNIQUE INDEX IDX_node_label on Node (label);
|
||||
CREATE UNIQUE INDEX IDX_Statistics_id on Statistics (id);
|
||||
|
||||
-- *******************************************************************
|
||||
-- VERSION
|
||||
|
||||
Reference in New Issue
Block a user