mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-01 17:10:26 +08:00
Reprocess: added -track_changes option. Added rtabmap-dpupdate.
This commit is contained in:
@@ -21,8 +21,8 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
||||
# VERSION
|
||||
#######################
|
||||
SET(RTABMAP_MAJOR_VERSION 0)
|
||||
SET(RTABMAP_MINOR_VERSION 23)
|
||||
SET(RTABMAP_PATCH_VERSION 8)
|
||||
SET(RTABMAP_MINOR_VERSION 24)
|
||||
SET(RTABMAP_PATCH_VERSION 0)
|
||||
SET(RTABMAP_VERSION
|
||||
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
||||
|
||||
|
||||
@@ -72,6 +72,14 @@ public:
|
||||
const std::string & getUrl() const {return _url;}
|
||||
const std::string & getTargetVersion() const {return _targetVersion;}
|
||||
|
||||
// Start recording changes made to the database until it is closed, then write a compact
|
||||
// delta of those changes to outputUrl (empty disables). Returns true if recording is
|
||||
// active. Only the SQLite backend supports it (session extension + database version
|
||||
// >= 0.24); other backends return false.
|
||||
// NOTE: recorded changes are held in RAM until the database is closed, so only enable
|
||||
// this when the expected set of changes is small.
|
||||
virtual bool trackDatabaseChanges(const std::string & outputUrl) {(void)outputUrl; return false;}
|
||||
|
||||
void beginTransaction() const;
|
||||
void commit() const;
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
typedef struct sqlite3_stmt sqlite3_stmt;
|
||||
typedef struct sqlite3 sqlite3;
|
||||
typedef struct sqlite3_session sqlite3_session;
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
@@ -49,6 +50,26 @@ public:
|
||||
void setCacheSize(unsigned int cacheSize);
|
||||
void setSynchronous(int synchronous);
|
||||
void setTempStore(int tempStore);
|
||||
// Start recording changes made to the database from now until it is closed, then write
|
||||
// a compact patchset delta to outputUrl (empty disables). Can be called before the
|
||||
// connection is opened or on an already-open connection (e.g. after init(), so the
|
||||
// baseline is the current content). Returns true if recording is active. Only effective
|
||||
// if the build/runtime SQLite has the session extension and the database is version >= 0.24.
|
||||
// NOTE: the SQLite session extension holds ALL recorded changes in RAM until the database
|
||||
// is closed (there is no incremental spill to disk), so only enable this when the expected
|
||||
// set of changes is small (e.g. appending a few sessions), not for rewriting a whole map.
|
||||
virtual bool trackDatabaseChanges(const std::string & outputUrl);
|
||||
|
||||
// Apply a change delta previously written by setTrackChangesOutput() onto the database
|
||||
// at databasePath (which must be the same database, at the same state, the delta was
|
||||
// generated from). The file is decompressed (same codec as the other rtabmap blobs) then
|
||||
// applied with the SQLite session extension. Returns true on success; on failure returns
|
||||
// false and, if errorMsg is not null, sets a human-readable message. Requires a SQLite
|
||||
// library built with the session extension (both at build and runtime).
|
||||
static bool applyChangesFromFile(
|
||||
const std::string & databasePath,
|
||||
const std::string & patchsetPath,
|
||||
std::string * errorMsg = 0);
|
||||
|
||||
protected:
|
||||
virtual bool connectDatabaseQuery(const std::string & url, bool overwritten = false, bool readOnly = false);
|
||||
@@ -197,6 +218,7 @@ private:
|
||||
void loadWordIdsQuery(std::list<Signature *> & signatures) const;
|
||||
void loadLinksQuery(std::list<Signature *> & signatures) const;
|
||||
int loadOrSaveDb(sqlite3 *pInMemory, const std::string & fileName, int isSave) const;
|
||||
void startChangeTracking(); // attach the change-tracking session on the open connection
|
||||
|
||||
protected:
|
||||
sqlite3 * _ppDb;
|
||||
@@ -209,6 +231,12 @@ private:
|
||||
int _journalMode;
|
||||
int _synchronous;
|
||||
int _tempStore;
|
||||
|
||||
// DB change tracking (SQLite session extension). Members are always present to keep
|
||||
// the class layout stable regardless of RTABMAP_WITH_SQLITE3_SESSION; the session is
|
||||
// only created/used when the feature is compiled in and enabled.
|
||||
sqlite3_session * _session;
|
||||
std::string _trackChangesOutput;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -182,6 +182,9 @@ public:
|
||||
int getDatabaseMemoryUsed() const; // in bytes
|
||||
std::string getDatabaseVersion() const;
|
||||
std::string getDatabaseUrl() const;
|
||||
// Record changes made to the database until it is closed, then write a compact delta
|
||||
// to outputUrl (empty disables). Returns true if recording started. See DBDriver.
|
||||
bool trackDatabaseChanges(const std::string & outputUrl);
|
||||
double getDbSavingTime() const;
|
||||
int getMapId(int id, bool lookInDatabase = false) const;
|
||||
Transform getOdomPose(int signatureId, bool lookInDatabase = false) const;
|
||||
|
||||
@@ -146,6 +146,13 @@ public:
|
||||
Transform getPose(int locationId) const;
|
||||
Transform getMapCorrection() const {return _mapCorrection;}
|
||||
const Memory * getMemory() const {return _memory;}
|
||||
// Record changes made to the working database from now until it is closed, then write a
|
||||
// compact delta to outputUrl (empty disables). Call after init(), so the delta reflects
|
||||
// only what is added/modified afterwards. Returns true if recording started (requires the
|
||||
// SQLite session extension and a database version >= 0.24). See DBDriver.
|
||||
// NOTE: recorded changes are held in RAM until the database is closed, so only enable this
|
||||
// when the expected set of changes is small (e.g. appending a few sessions).
|
||||
bool trackDatabaseChanges(const std::string & outputUrl);
|
||||
float getGoalReachedRadius() const {return _goalReachedRadius;}
|
||||
float getLocalRadius() const {return _localRadius;}
|
||||
const Transform & getLastLocalizationPose() const {return _lastLocalizationPose;}
|
||||
|
||||
@@ -196,6 +196,16 @@ IF(SQLite3_FOUND)
|
||||
${LIBRARIES}
|
||||
${SQLite3_LIBRARIES}
|
||||
)
|
||||
# The SQLite session extension (used to track DB diffs) needs SQLite >= 3.13.0.
|
||||
# Defining SQLITE_ENABLE_SESSION here only exposes the session declarations in the
|
||||
# system sqlite3.h; whether the linked library was actually built with the extension
|
||||
# is verified at runtime with sqlite3_compileoption_used("ENABLE_SESSION").
|
||||
IF(SQLite3_VERSION VERSION_GREATER_EQUAL "3.13.0")
|
||||
SET(SQLITE3_SESSION_DEFINITIONS SQLITE_ENABLE_SESSION SQLITE_ENABLE_PREUPDATE_HOOK RTABMAP_WITH_SQLITE3_SESSION)
|
||||
MESSAGE(STATUS " With SQLite3 session ext = YES (system SQLite3 ${SQLite3_VERSION}, verified at runtime)")
|
||||
ELSE()
|
||||
MESSAGE(STATUS " With SQLite3 session ext = NO (system SQLite3 ${SQLite3_VERSION} < 3.13.0)")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(SRC_FILES
|
||||
${SRC_FILES}
|
||||
@@ -205,6 +215,9 @@ ELSE()
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/sqlite3
|
||||
${INCLUDE_DIRS}
|
||||
)
|
||||
# We compile the bundled amalgamation ourselves, so enable the session extension in it.
|
||||
SET(SQLITE3_SESSION_DEFINITIONS SQLITE_ENABLE_SESSION SQLITE_ENABLE_PREUPDATE_HOOK RTABMAP_WITH_SQLITE3_SESSION)
|
||||
MESSAGE(STATUS " With SQLite3 session ext = YES (bundled SQLite3)")
|
||||
ENDIF()
|
||||
|
||||
IF(TORCH_FOUND)
|
||||
@@ -830,6 +843,7 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql.in ${CMA
|
||||
|
||||
SET(RESOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_23_0.sql
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_22_0.sql
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_20_0.sql
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_3.sql
|
||||
@@ -893,6 +907,13 @@ TARGET_LINK_LIBRARIES(rtabmap_core
|
||||
PRIVATE
|
||||
${LIBRARIES})
|
||||
|
||||
# Enable the SQLite session extension for the core sources (bundled sqlite3.c and
|
||||
# DBDriverSqlite3.cpp). Kept PRIVATE so it only affects rtabmap_core's own TUs and
|
||||
# never changes the public header layout for downstream consumers.
|
||||
IF(SQLITE3_SESSION_DEFINITIONS)
|
||||
target_compile_definitions(rtabmap_core PRIVATE ${SQLITE3_SESSION_DEFINITIONS})
|
||||
ENDIF()
|
||||
|
||||
SET_TARGET_PROPERTIES(
|
||||
rtabmap_core
|
||||
PROPERTIES
|
||||
|
||||
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "rtabmap/core/util3d.h"
|
||||
#include "rtabmap/core/Compression.h"
|
||||
#include "DatabaseSchema_sql.h"
|
||||
#include "DatabaseSchema_0_23_0_sql.h"
|
||||
#include "DatabaseSchema_0_22_0_sql.h"
|
||||
#include "DatabaseSchema_0_20_0_sql.h"
|
||||
#include "DatabaseSchema_0_18_3_sql.h"
|
||||
@@ -45,6 +46,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
#include <set>
|
||||
#include <cstdio>
|
||||
|
||||
#include "rtabmap/utilite/UtiLite.h"
|
||||
|
||||
@@ -59,7 +61,8 @@ DBDriverSqlite3::DBDriverSqlite3(const ParametersMap & parameters) :
|
||||
_cacheSize(Parameters::defaultDbSqlite3CacheSize()),
|
||||
_journalMode(Parameters::defaultDbSqlite3JournalMode()),
|
||||
_synchronous(Parameters::defaultDbSqlite3Synchronous()),
|
||||
_tempStore(Parameters::defaultDbSqlite3TempStore())
|
||||
_tempStore(Parameters::defaultDbSqlite3TempStore()),
|
||||
_session(0)
|
||||
{
|
||||
ULOGGER_DEBUG("treadSafe=%d", sqlite3_threadsafe());
|
||||
this->parseParameters(parameters);
|
||||
@@ -218,6 +221,149 @@ void DBDriverSqlite3::setDbInMemory(bool dbInMemory)
|
||||
}
|
||||
}
|
||||
|
||||
void DBDriverSqlite3::startChangeTracking()
|
||||
{
|
||||
#ifdef RTABMAP_WITH_SQLITE3_SESSION
|
||||
if(_session != 0 || _trackChangesOutput.empty() || _ppDb == 0)
|
||||
{
|
||||
// Already tracking, nothing requested, or not connected yet.
|
||||
return;
|
||||
}
|
||||
if(uStrNumCmp(_version, "0.24.0") < 0)
|
||||
{
|
||||
UWARN("Database change tracking to \"%s\" was requested but the database "
|
||||
"version is %s (< 0.24.0). Older schemas lack the primary keys required "
|
||||
"by the SQLite session extension, so change tracking is disabled.",
|
||||
_trackChangesOutput.c_str(), _version.c_str());
|
||||
}
|
||||
else if(!sqlite3_compileoption_used("ENABLE_SESSION"))
|
||||
{
|
||||
UWARN("Database change tracking to \"%s\" was requested but the linked SQLite "
|
||||
"library was not built with the session extension (ENABLE_SESSION); "
|
||||
"change tracking is disabled.", _trackChangesOutput.c_str());
|
||||
}
|
||||
else if(sqlite3session_create(_ppDb, "main", &_session) == SQLITE_OK)
|
||||
{
|
||||
sqlite3session_attach(_session, 0); // 0 = track all tables
|
||||
UINFO("Tracking database changes; a patchset will be written to \"%s\" on close.",
|
||||
_trackChangesOutput.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
UWARN("Could not create a SQLite session to track database changes to \"%s\".",
|
||||
_trackChangesOutput.c_str());
|
||||
_session = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DBDriverSqlite3::trackDatabaseChanges(const std::string & outputUrl)
|
||||
{
|
||||
UDEBUG("outputUrl=%s", outputUrl.c_str());
|
||||
_trackChangesOutput = outputUrl;
|
||||
#ifdef RTABMAP_WITH_SQLITE3_SESSION
|
||||
// If the connection is already open (e.g. set after connect(), as rtabmap-reprocess
|
||||
// does after init()), start tracking now on the current baseline state. Otherwise it
|
||||
// will start automatically when the connection is opened.
|
||||
if(!outputUrl.empty() && _ppDb != 0)
|
||||
{
|
||||
this->startChangeTracking();
|
||||
}
|
||||
return _session != 0;
|
||||
#else
|
||||
if(!outputUrl.empty())
|
||||
{
|
||||
UWARN("Database change tracking to \"%s\" was requested but rtabmap was built "
|
||||
"against a SQLite library without the session extension; it is disabled.",
|
||||
outputUrl.c_str());
|
||||
}
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef RTABMAP_WITH_SQLITE3_SESSION
|
||||
static int rtabmapChangesetConflict(void * pCtx, int eConflict, sqlite3_changeset_iter * pIter)
|
||||
{
|
||||
// A patchset upgrade must apply cleanly onto the exact database it was generated from.
|
||||
// Any conflict means the wrong base database (or an already-applied delta), so abort
|
||||
// rather than silently produce an inconsistent result.
|
||||
return SQLITE_CHANGESET_ABORT;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool DBDriverSqlite3::applyChangesFromFile(
|
||||
const std::string & databasePath,
|
||||
const std::string & patchsetPath,
|
||||
std::string * errorMsg)
|
||||
{
|
||||
#ifdef RTABMAP_WITH_SQLITE3_SESSION
|
||||
if(!sqlite3_compileoption_used("ENABLE_SESSION"))
|
||||
{
|
||||
if(errorMsg) *errorMsg = "The linked SQLite library was not built with the session extension.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read the compressed patchset file.
|
||||
FILE * fp = fopen(patchsetPath.c_str(), "rb");
|
||||
if(!fp)
|
||||
{
|
||||
if(errorMsg) *errorMsg = uFormat("Could not open patchset file \"%s\".", patchsetPath.c_str());
|
||||
return false;
|
||||
}
|
||||
fseek(fp, 0, SEEK_END);
|
||||
long fileSize = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
if(fileSize <= 0)
|
||||
{
|
||||
fclose(fp);
|
||||
if(errorMsg) *errorMsg = uFormat("Patchset file \"%s\" is empty or unreadable.", patchsetPath.c_str());
|
||||
return false;
|
||||
}
|
||||
std::vector<unsigned char> fileBytes((size_t)fileSize);
|
||||
size_t bytesRead = fread(fileBytes.data(), 1, (size_t)fileSize, fp);
|
||||
fclose(fp);
|
||||
if((long)bytesRead != fileSize)
|
||||
{
|
||||
if(errorMsg) *errorMsg = uFormat("Could not read patchset file \"%s\".", patchsetPath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Decompress to the raw patchset (same codec used to write it).
|
||||
cv::Mat patch = uncompressData(fileBytes.data(), (unsigned long)fileSize);
|
||||
if(patch.empty())
|
||||
{
|
||||
if(errorMsg) *errorMsg = uFormat("Could not decompress patchset file \"%s\".", patchsetPath.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Apply onto the target database.
|
||||
sqlite3 * db = 0;
|
||||
int rc = sqlite3_open_v2(databasePath.c_str(), &db, SQLITE_OPEN_READWRITE, 0);
|
||||
if(rc != SQLITE_OK)
|
||||
{
|
||||
if(errorMsg) *errorMsg = uFormat("Could not open database \"%s\": %s", databasePath.c_str(), sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
return false;
|
||||
}
|
||||
|
||||
int nPatch = (int)(patch.total()*patch.elemSize());
|
||||
rc = sqlite3changeset_apply(db, nPatch, patch.data, 0, rtabmapChangesetConflict, 0);
|
||||
if(rc != SQLITE_OK)
|
||||
{
|
||||
if(errorMsg) *errorMsg = uFormat("Failed to apply patchset to \"%s\" (SQLite error %d: %s). Make "
|
||||
"sure it is applied to the exact database state the delta was generated from.",
|
||||
databasePath.c_str(), rc, sqlite3_errstr(rc));
|
||||
sqlite3_close(db);
|
||||
return false;
|
||||
}
|
||||
sqlite3_close(db);
|
||||
return true;
|
||||
#else
|
||||
if(errorMsg) *errorMsg = "rtabmap was built without SQLite session support.";
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used to load the contents of a database file on disk
|
||||
** into the "main" database of open database connection pInMemory, or
|
||||
@@ -406,6 +552,7 @@ bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwri
|
||||
schemas.push_back(std::make_pair("0.18.3", DATABASESCHEMA_0_18_3_SQL));
|
||||
schemas.push_back(std::make_pair("0.20.0", DATABASESCHEMA_0_20_0_SQL));
|
||||
schemas.push_back(std::make_pair("0.22.0", DATABASESCHEMA_0_22_0_SQL));
|
||||
schemas.push_back(std::make_pair("0.23.0", DATABASESCHEMA_0_23_0_SQL));
|
||||
schemas.push_back(std::make_pair(uNumber2Str(RTABMAP_VERSION_MAJOR)+"."+uNumber2Str(RTABMAP_VERSION_MINOR), DATABASESCHEMA_SQL));
|
||||
for(size_t i=0; i<schemas.size(); ++i)
|
||||
{
|
||||
@@ -446,6 +593,14 @@ bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwri
|
||||
this->setSynchronous(_synchronous); // this will call the SQL
|
||||
this->setTempStore(_tempStore); // this will call the SQL
|
||||
|
||||
// Start tracking database changes if a recording path was already set (before the
|
||||
// connection was opened). Done here, after any initial load and once the version is
|
||||
// known, so the delta reflects only the changes made between open and close.
|
||||
if(!readOnly)
|
||||
{
|
||||
this->startChangeTracking();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void DBDriverSqlite3::disconnectDatabaseQuery(bool save, const std::string & outputUrl)
|
||||
@@ -489,6 +644,56 @@ void DBDriverSqlite3::disconnectDatabaseQuery(bool save, const std::string & out
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RTABMAP_WITH_SQLITE3_SESSION
|
||||
// If change tracking is active, emit the accumulated patchset before closing.
|
||||
if(_session)
|
||||
{
|
||||
int nBuf = 0;
|
||||
void * pBuf = 0;
|
||||
int rcp = sqlite3session_patchset(_session, &nBuf, &pBuf);
|
||||
if(rcp == SQLITE_OK && pBuf && nBuf > 0)
|
||||
{
|
||||
// Compress the patchset with the same zlib-based codec used for every other
|
||||
// rtabmap blob, so the delta is compact for transfer. To apply it later,
|
||||
// uncompressData() the file and pass the bytes to sqlite3changeset_apply().
|
||||
cv::Mat compressed = compressData2(cv::Mat(1, nBuf, CV_8UC1, pBuf));
|
||||
FILE * fp = fopen(_trackChangesOutput.c_str(), "wb");
|
||||
if(fp)
|
||||
{
|
||||
size_t toWrite = compressed.total()*compressed.elemSize();
|
||||
size_t written = fwrite(compressed.data, 1, toWrite, fp);
|
||||
fclose(fp);
|
||||
if(written == toWrite)
|
||||
{
|
||||
UINFO("Wrote compressed database patchset (%d -> %d bytes) to \"%s\".",
|
||||
nBuf, (int)toWrite, _trackChangesOutput.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("Could only write %d/%d bytes of the database patchset to \"%s\".",
|
||||
(int)written, (int)toWrite, _trackChangesOutput.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("Could not open \"%s\" to write the database patchset.", _trackChangesOutput.c_str());
|
||||
}
|
||||
}
|
||||
else if(rcp != SQLITE_OK)
|
||||
{
|
||||
UERROR("Could not generate the database patchset for \"%s\" (SQLite error %d).",
|
||||
_trackChangesOutput.c_str(), rcp);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINFO("No database changes to write; \"%s\" was not created.", _trackChangesOutput.c_str());
|
||||
}
|
||||
sqlite3_free(pBuf);
|
||||
sqlite3session_delete(_session);
|
||||
_session = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Then close (delete) the database connection
|
||||
UINFO("Disconnecting database %s...", this->getUrl().c_str());
|
||||
sqlite3_close(_ppDb);
|
||||
|
||||
@@ -1994,6 +1994,11 @@ double Memory::getDbSavingTime() const
|
||||
return _dbDriver?_dbDriver->getEmptyTrashesTime():0;
|
||||
}
|
||||
|
||||
bool Memory::trackDatabaseChanges(const std::string & outputUrl)
|
||||
{
|
||||
return _dbDriver?_dbDriver->trackDatabaseChanges(outputUrl):false;
|
||||
}
|
||||
|
||||
std::set<int> Memory::getAllSignatureIds(bool ignoreChildren) const
|
||||
{
|
||||
std::set<int> ids;
|
||||
|
||||
@@ -885,6 +885,11 @@ Transform Rtabmap::getPose(int locationId) const
|
||||
return uValue(_optimizedPoses, locationId, Transform());
|
||||
}
|
||||
|
||||
bool Rtabmap::trackDatabaseChanges(const std::string & outputUrl)
|
||||
{
|
||||
return _memory?_memory->trackDatabaseChanges(outputUrl):false;
|
||||
}
|
||||
|
||||
void Rtabmap::setInitialPose(const Transform & initialPose)
|
||||
{
|
||||
if(_memory)
|
||||
|
||||
@@ -52,6 +52,7 @@ CREATE TABLE Data (
|
||||
);
|
||||
|
||||
CREATE TABLE Link (
|
||||
id INTEGER PRIMARY KEY, -- required by the SQLite session extension (DB diff tracking); (from_id,to_id) is not unique (a node pair can have several links)
|
||||
from_id INTEGER NOT NULL,
|
||||
to_id INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL, -- kNeighbor=0, kGlobalClosure=1, kLocalSpaceClosure=2, kLocalTimeClosure=3, kUserClosure=4, kVirtualClosure=5, kNeighborMerged=6, kPosePrior=7, kLandmark=8
|
||||
@@ -72,6 +73,7 @@ CREATE TABLE Word (
|
||||
);
|
||||
|
||||
CREATE TABLE Feature (
|
||||
id INTEGER PRIMARY KEY, -- required by the SQLite session extension (DB diff tracking)
|
||||
node_id INTEGER NOT NULL,
|
||||
word_id INTEGER NOT NULL,
|
||||
pos_x FLOAT NOT NULL,
|
||||
@@ -89,6 +91,7 @@ CREATE TABLE Feature (
|
||||
);
|
||||
|
||||
CREATE TABLE GlobalDescriptor (
|
||||
id INTEGER PRIMARY KEY, -- required by the SQLite session extension (DB diff tracking)
|
||||
node_id INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL,
|
||||
info BLOB,
|
||||
@@ -99,6 +102,7 @@ CREATE TABLE GlobalDescriptor (
|
||||
--
|
||||
|
||||
CREATE TABLE Info (
|
||||
id INTEGER PRIMARY KEY, -- required by the SQLite session extension (DB diff tracking)
|
||||
STM_size INTEGER,
|
||||
last_sign_added INTEGER,
|
||||
process_mem_used INTEGER,
|
||||
@@ -113,11 +117,12 @@ CREATE TABLE Statistics (
|
||||
stamp FLOAT,
|
||||
data BLOB, -- compressed string
|
||||
wm_state BLOB, -- compressed data
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (id) REFERENCES Node(id)
|
||||
);
|
||||
|
||||
CREATE TABLE Admin (
|
||||
version TEXT,
|
||||
version TEXT PRIMARY KEY,
|
||||
preview_image BLOB, -- compressed image
|
||||
|
||||
opt_cloud BLOB, -- compressed data
|
||||
@@ -176,7 +181,6 @@ CREATE INDEX IDX_Feature_node_id on Feature (node_id);
|
||||
CREATE INDEX IDX_GlobalDescriptor_node_id on GlobalDescriptor (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
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
-- *******************************************************************
|
||||
-- DatabaseSchema: Script for creating the database
|
||||
-- Usage:
|
||||
-- $ sqlite3 LTM.db < DatabaseSchema.sql
|
||||
--
|
||||
-- *******************************************************************
|
||||
|
||||
-- *******************************************************************
|
||||
-- CLEAN
|
||||
-- *******************************************************************
|
||||
/*DROP TABLE Node;*/
|
||||
|
||||
-- *******************************************************************
|
||||
-- CREATE
|
||||
-- *******************************************************************
|
||||
CREATE TABLE Node (
|
||||
id INTEGER NOT NULL,
|
||||
map_id INTEGER NOT NULL,
|
||||
weight INTEGER,
|
||||
stamp FLOAT,
|
||||
pose BLOB, -- 3x4 float
|
||||
ground_truth_pose BLOB, -- 3x4 float
|
||||
velocity BLOB, -- 6 float (vx,vy,vz,vroll,vpitch,vyaw) m/s and rad/s
|
||||
label TEXT,
|
||||
gps BLOB, -- 1x6 double: stamp, longitude (DD), latitude (DD), altitude (m), accuracy (m), bearing (North 0->360 deg clockwise)
|
||||
env_sensors BLOB, -- Variable 3xdouble: (sensorId1, value, stamp, sensorId2, value, stamp, ...)
|
||||
time_enter DATE,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE Data (
|
||||
id INTEGER NOT NULL,
|
||||
image BLOB, -- compressed image (Grayscale or RGB)
|
||||
depth BLOB, -- compressed image (Depth or Right image)
|
||||
depth_confidence BLOB, -- compressed data (low=0 high=100)
|
||||
calibration BLOB, -- fx, fy, cx, cy, [baseline,] width, height, local_transform
|
||||
|
||||
scan BLOB, -- compressed data (Laser scan)
|
||||
scan_info BLOB, -- scan_max_pts, scan_max_range, scan_format, local_transform
|
||||
|
||||
ground_cells BLOB, -- compressed data (occupancy grid)
|
||||
obstacle_cells BLOB, -- compressed data (occupancy grid)
|
||||
empty_cells BLOB, -- compressed data (occupancy grid)
|
||||
cell_size FLOAT,
|
||||
view_point_x FLOAT,
|
||||
view_point_y FLOAT,
|
||||
view_point_z FLOAT,
|
||||
|
||||
user_data BLOB, -- compressed data (User data)
|
||||
time_enter DATE,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE Link (
|
||||
from_id INTEGER NOT NULL,
|
||||
to_id INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL, -- kNeighbor=0, kGlobalClosure=1, kLocalSpaceClosure=2, kLocalTimeClosure=3, kUserClosure=4, kVirtualClosure=5, kNeighborMerged=6, kPosePrior=7, kLandmark=8
|
||||
information_matrix BLOB NOT NULL, -- 6x6 double (inverse covariance)
|
||||
transform BLOB, -- 3x4 float
|
||||
user_data BLOB, -- compressed data (User data)
|
||||
FOREIGN KEY (from_id) REFERENCES Node(id),
|
||||
FOREIGN KEY (to_id) REFERENCES Node(id)
|
||||
);
|
||||
|
||||
--
|
||||
CREATE TABLE Word (
|
||||
id INTEGER NOT NULL,
|
||||
descriptor_size INTEGER NOT NULL,
|
||||
descriptor BLOB NOT NULL,
|
||||
time_enter DATE,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE Feature (
|
||||
node_id INTEGER NOT NULL,
|
||||
word_id INTEGER NOT NULL,
|
||||
pos_x FLOAT NOT NULL,
|
||||
pos_y FLOAT NOT NULL,
|
||||
size INTEGER NOT NULL,
|
||||
dir FLOAT NOT NULL,
|
||||
response FLOAT NOT NULL,
|
||||
octave INTEGER NOT NULL,
|
||||
depth_x FLOAT,
|
||||
depth_y FLOAT,
|
||||
depth_z FLOAT,
|
||||
descriptor_size INTEGER,
|
||||
descriptor BLOB,
|
||||
FOREIGN KEY (node_id) REFERENCES Node(id)
|
||||
);
|
||||
|
||||
CREATE TABLE GlobalDescriptor (
|
||||
node_id INTEGER NOT NULL,
|
||||
type INTEGER NOT NULL,
|
||||
info BLOB,
|
||||
data BLOB NOT NULL,
|
||||
FOREIGN KEY (node_id) REFERENCES Node(id)
|
||||
);
|
||||
|
||||
--
|
||||
|
||||
CREATE TABLE Info (
|
||||
STM_size INTEGER,
|
||||
last_sign_added INTEGER,
|
||||
process_mem_used INTEGER,
|
||||
database_mem_used INTEGER,
|
||||
dictionary_size INTEGER,
|
||||
parameters TEXT,
|
||||
time_enter DATE
|
||||
);
|
||||
|
||||
CREATE TABLE Statistics (
|
||||
id INTEGER NOT NULL,
|
||||
stamp FLOAT,
|
||||
data BLOB, -- compressed string
|
||||
wm_state BLOB, -- compressed data
|
||||
FOREIGN KEY (id) REFERENCES Node(id)
|
||||
);
|
||||
|
||||
CREATE TABLE Admin (
|
||||
version TEXT,
|
||||
preview_image BLOB, -- compressed image
|
||||
|
||||
opt_cloud BLOB, -- compressed data
|
||||
opt_ids BLOB, -- Node ids used to generate the optimized cloud/mesh
|
||||
opt_poses BLOB, -- compressed N*3x4 float
|
||||
opt_last_localization BLOB, -- 3x4 float
|
||||
opt_polygons_size INTEGER, -- e.g., 3
|
||||
opt_polygons BLOB, -- compressed data [length_v0, i0,i1,i3, length_v1, i0,i1,i3]
|
||||
opt_tex_coords BLOB, -- compressed data [length_v0, u0,v0,u1,v1,u2,v2, length_v1, u0,v0,u1,v1,u2,v2]
|
||||
opt_tex_materials BLOB, -- compressed image
|
||||
opt_map BLOB, -- compressed CV_8SC1 occupancy grid
|
||||
opt_map_x_min FLOAT,
|
||||
opt_map_y_min FLOAT,
|
||||
opt_map_resolution FLOAT,
|
||||
|
||||
dictionary_index BLOB, -- serialized dictionary index
|
||||
|
||||
time_enter DATE
|
||||
);
|
||||
|
||||
-- *******************************************************************
|
||||
-- TRIGGERS
|
||||
-- *******************************************************************
|
||||
CREATE TRIGGER insert_Feature BEFORE INSERT ON Feature
|
||||
WHEN NOT EXISTS (SELECT Node.id FROM Node WHERE Node.id = NEW.node_id)
|
||||
BEGIN
|
||||
SELECT RAISE(ABORT, 'Foreign key constraint failed in Feature table');
|
||||
END;
|
||||
|
||||
-- Creating a trigger for time_enter
|
||||
CREATE TRIGGER insert_Node_timeEnter AFTER INSERT ON Node
|
||||
BEGIN
|
||||
UPDATE Node SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER insert_Data_timeEnter AFTER INSERT ON Data
|
||||
BEGIN
|
||||
UPDATE Node SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER insert_Word_timeEnter AFTER INSERT ON Word
|
||||
BEGIN
|
||||
UPDATE Word SET time_enter = DATETIME('NOW') WHERE rowid = new.rowid;
|
||||
END;
|
||||
|
||||
CREATE TRIGGER insert_Info_timeEnter AFTER INSERT ON Info
|
||||
BEGIN
|
||||
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_Feature_node_id on Feature (node_id);
|
||||
CREATE INDEX IDX_GlobalDescriptor_node_id on GlobalDescriptor (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
|
||||
-- *******************************************************************
|
||||
INSERT INTO Admin(version) VALUES('0.23.0');
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
Version 3.53.3
|
||||
Info: https://www.sqlite.org/
|
||||
License: Public domain (https://www.sqlite.org/copyright.html)
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -15,12 +15,10 @@
|
||||
** as extensions by SQLite should #include this file instead of
|
||||
** sqlite3.h.
|
||||
*/
|
||||
#ifndef _SQLITE3EXT_H_
|
||||
#define _SQLITE3EXT_H_
|
||||
#ifndef SQLITE3EXT_H
|
||||
#define SQLITE3EXT_H
|
||||
#include "sqlite3.h"
|
||||
|
||||
typedef struct sqlite3_api_routines sqlite3_api_routines;
|
||||
|
||||
/*
|
||||
** The following structure holds pointers to all of the SQLite API
|
||||
** routines.
|
||||
@@ -28,7 +26,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
|
||||
** WARNING: In order to maintain backwards compatibility, add new
|
||||
** interfaces to the end of this structure only. If you insert new
|
||||
** interfaces in the middle of this structure, then older different
|
||||
** versions of SQLite will not be able to load each others' shared
|
||||
** versions of SQLite will not be able to load each other's shared
|
||||
** libraries!
|
||||
*/
|
||||
struct sqlite3_api_routines {
|
||||
@@ -136,7 +134,7 @@ struct sqlite3_api_routines {
|
||||
int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
|
||||
const char*,const char*),void*);
|
||||
void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
|
||||
char * (*snprintf)(int,char*,const char*,...);
|
||||
char * (*xsnprintf)(int,char*,const char*,...);
|
||||
int (*step)(sqlite3_stmt*);
|
||||
int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
|
||||
char const**,char const**,int*,int*,int*);
|
||||
@@ -248,13 +246,151 @@ struct sqlite3_api_routines {
|
||||
int (*uri_boolean)(const char*,const char*,int);
|
||||
sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
|
||||
const char *(*uri_parameter)(const char*,const char*);
|
||||
char *(*vsnprintf)(int,char*,const char*,va_list);
|
||||
char *(*xvsnprintf)(int,char*,const char*,va_list);
|
||||
int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
|
||||
/* Version 3.8.7 and later */
|
||||
int (*auto_extension)(void(*)(void));
|
||||
int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
|
||||
void(*)(void*),unsigned char);
|
||||
int (*cancel_auto_extension)(void(*)(void));
|
||||
int (*load_extension)(sqlite3*,const char*,const char*,char**);
|
||||
void *(*malloc64)(sqlite3_uint64);
|
||||
sqlite3_uint64 (*msize)(void*);
|
||||
void *(*realloc64)(void*,sqlite3_uint64);
|
||||
void (*reset_auto_extension)(void);
|
||||
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
|
||||
void(*)(void*));
|
||||
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
|
||||
void(*)(void*), unsigned char);
|
||||
int (*strglob)(const char*,const char*);
|
||||
/* Version 3.8.11 and later */
|
||||
sqlite3_value *(*value_dup)(const sqlite3_value*);
|
||||
void (*value_free)(sqlite3_value*);
|
||||
int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
|
||||
int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
|
||||
/* Version 3.9.0 and later */
|
||||
unsigned int (*value_subtype)(sqlite3_value*);
|
||||
void (*result_subtype)(sqlite3_context*,unsigned int);
|
||||
/* Version 3.10.0 and later */
|
||||
int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
int (*strlike)(const char*,const char*,unsigned int);
|
||||
int (*db_cacheflush)(sqlite3*);
|
||||
/* Version 3.12.0 and later */
|
||||
int (*system_errno)(sqlite3*);
|
||||
/* Version 3.14.0 and later */
|
||||
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
|
||||
char *(*expanded_sql)(sqlite3_stmt*);
|
||||
/* Version 3.18.0 and later */
|
||||
void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64);
|
||||
/* Version 3.20.0 and later */
|
||||
int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
|
||||
sqlite3_stmt**,const char**);
|
||||
int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
|
||||
sqlite3_stmt**,const void**);
|
||||
int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
|
||||
void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
|
||||
void *(*value_pointer)(sqlite3_value*,const char*);
|
||||
int (*vtab_nochange)(sqlite3_context*);
|
||||
int (*value_nochange)(sqlite3_value*);
|
||||
const char *(*vtab_collation)(sqlite3_index_info*,int);
|
||||
/* Version 3.24.0 and later */
|
||||
int (*keyword_count)(void);
|
||||
int (*keyword_name)(int,const char**,int*);
|
||||
int (*keyword_check)(const char*,int);
|
||||
sqlite3_str *(*str_new)(sqlite3*);
|
||||
char *(*str_finish)(sqlite3_str*);
|
||||
void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);
|
||||
void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);
|
||||
void (*str_append)(sqlite3_str*, const char *zIn, int N);
|
||||
void (*str_appendall)(sqlite3_str*, const char *zIn);
|
||||
void (*str_appendchar)(sqlite3_str*, int N, char C);
|
||||
void (*str_reset)(sqlite3_str*);
|
||||
int (*str_errcode)(sqlite3_str*);
|
||||
int (*str_length)(sqlite3_str*);
|
||||
char *(*str_value)(sqlite3_str*);
|
||||
/* Version 3.25.0 and later */
|
||||
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||
void (*xFinal)(sqlite3_context*),
|
||||
void (*xValue)(sqlite3_context*),
|
||||
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||
void(*xDestroy)(void*));
|
||||
/* Version 3.26.0 and later */
|
||||
const char *(*normalized_sql)(sqlite3_stmt*);
|
||||
/* Version 3.28.0 and later */
|
||||
int (*stmt_isexplain)(sqlite3_stmt*);
|
||||
int (*value_frombind)(sqlite3_value*);
|
||||
/* Version 3.30.0 and later */
|
||||
int (*drop_modules)(sqlite3*,const char**);
|
||||
/* Version 3.31.0 and later */
|
||||
sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64);
|
||||
const char *(*uri_key)(const char*,int);
|
||||
const char *(*filename_database)(const char*);
|
||||
const char *(*filename_journal)(const char*);
|
||||
const char *(*filename_wal)(const char*);
|
||||
/* Version 3.32.0 and later */
|
||||
const char *(*create_filename)(const char*,const char*,const char*,
|
||||
int,const char**);
|
||||
void (*free_filename)(const char*);
|
||||
sqlite3_file *(*database_file_object)(const char*);
|
||||
/* Version 3.34.0 and later */
|
||||
int (*txn_state)(sqlite3*,const char*);
|
||||
/* Version 3.36.1 and later */
|
||||
sqlite3_int64 (*changes64)(sqlite3*);
|
||||
sqlite3_int64 (*total_changes64)(sqlite3*);
|
||||
/* Version 3.37.0 and later */
|
||||
int (*autovacuum_pages)(sqlite3*,
|
||||
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
|
||||
void*, void(*)(void*));
|
||||
/* Version 3.38.0 and later */
|
||||
int (*error_offset)(sqlite3*);
|
||||
int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**);
|
||||
int (*vtab_distinct)(sqlite3_index_info*);
|
||||
int (*vtab_in)(sqlite3_index_info*,int,int);
|
||||
int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
|
||||
int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
|
||||
/* Version 3.39.0 and later */
|
||||
int (*deserialize)(sqlite3*,const char*,unsigned char*,
|
||||
sqlite3_int64,sqlite3_int64,unsigned);
|
||||
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
|
||||
unsigned int);
|
||||
const char *(*db_name)(sqlite3*,int);
|
||||
/* Version 3.40.0 and later */
|
||||
int (*value_encoding)(sqlite3_value*);
|
||||
/* Version 3.41.0 and later */
|
||||
int (*is_interrupted)(sqlite3*);
|
||||
/* Version 3.43.0 and later */
|
||||
int (*stmt_explain)(sqlite3_stmt*,int);
|
||||
/* Version 3.44.0 and later */
|
||||
void *(*get_clientdata)(sqlite3*,const char*);
|
||||
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
|
||||
/* Version 3.50.0 and later */
|
||||
int (*setlk_timeout)(sqlite3*,int,int);
|
||||
/* Version 3.51.0 and later */
|
||||
int (*set_errmsg)(sqlite3*,int,const char*);
|
||||
int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
|
||||
/* Version 3.52.0 and later */
|
||||
void (*str_truncate)(sqlite3_str*,int);
|
||||
void (*str_free)(sqlite3_str*);
|
||||
int (*carray_bind)(sqlite3_stmt*,int,void*,int,int,void(*)(void*));
|
||||
int (*carray_bind_v2)(sqlite3_stmt*,int,void*,int,int,void(*)(void*),void*);
|
||||
};
|
||||
|
||||
/*
|
||||
** This is the function signature used for all extension entry points. It
|
||||
** is also defined in the file "loadext.c".
|
||||
*/
|
||||
typedef int (*sqlite3_loadext_entry)(
|
||||
sqlite3 *db, /* Handle to the database. */
|
||||
char **pzErrMsg, /* Used to set error string on failure. */
|
||||
const sqlite3_api_routines *pThunk /* Extension API function pointers. */
|
||||
);
|
||||
|
||||
/*
|
||||
** The following macros redefine the API routines so that they are
|
||||
** redirected throught the global sqlite3_api structure.
|
||||
** redirected through the global sqlite3_api structure.
|
||||
**
|
||||
** This header file is also used by the loadext.c source file
|
||||
** (part of the main SQLite library - not an extension) so that
|
||||
@@ -263,7 +399,7 @@ struct sqlite3_api_routines {
|
||||
** the API. So the redefinition macros are only valid if the
|
||||
** SQLITE_CORE macros is undefined.
|
||||
*/
|
||||
#ifndef SQLITE_CORE
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
#define sqlite3_aggregate_context sqlite3_api->aggregate_context
|
||||
#ifndef SQLITE_OMIT_DEPRECATED
|
||||
#define sqlite3_aggregate_count sqlite3_api->aggregate_count
|
||||
@@ -366,7 +502,7 @@ struct sqlite3_api_routines {
|
||||
#define sqlite3_rollback_hook sqlite3_api->rollback_hook
|
||||
#define sqlite3_set_authorizer sqlite3_api->set_authorizer
|
||||
#define sqlite3_set_auxdata sqlite3_api->set_auxdata
|
||||
#define sqlite3_snprintf sqlite3_api->snprintf
|
||||
#define sqlite3_snprintf sqlite3_api->xsnprintf
|
||||
#define sqlite3_step sqlite3_api->step
|
||||
#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata
|
||||
#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup
|
||||
@@ -390,6 +526,7 @@ struct sqlite3_api_routines {
|
||||
#define sqlite3_value_text16le sqlite3_api->value_text16le
|
||||
#define sqlite3_value_type sqlite3_api->value_type
|
||||
#define sqlite3_vmprintf sqlite3_api->vmprintf
|
||||
#define sqlite3_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_overload_function sqlite3_api->overload_function
|
||||
#define sqlite3_prepare_v2 sqlite3_api->prepare_v2
|
||||
#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2
|
||||
@@ -465,11 +602,126 @@ struct sqlite3_api_routines {
|
||||
#define sqlite3_uri_boolean sqlite3_api->uri_boolean
|
||||
#define sqlite3_uri_int64 sqlite3_api->uri_int64
|
||||
#define sqlite3_uri_parameter sqlite3_api->uri_parameter
|
||||
#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf
|
||||
#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf
|
||||
#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
|
||||
#endif /* SQLITE_CORE */
|
||||
/* Version 3.8.7 and later */
|
||||
#define sqlite3_auto_extension sqlite3_api->auto_extension
|
||||
#define sqlite3_bind_blob64 sqlite3_api->bind_blob64
|
||||
#define sqlite3_bind_text64 sqlite3_api->bind_text64
|
||||
#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension
|
||||
#define sqlite3_load_extension sqlite3_api->load_extension
|
||||
#define sqlite3_malloc64 sqlite3_api->malloc64
|
||||
#define sqlite3_msize sqlite3_api->msize
|
||||
#define sqlite3_realloc64 sqlite3_api->realloc64
|
||||
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
|
||||
#define sqlite3_result_blob64 sqlite3_api->result_blob64
|
||||
#define sqlite3_result_text64 sqlite3_api->result_text64
|
||||
#define sqlite3_strglob sqlite3_api->strglob
|
||||
/* Version 3.8.11 and later */
|
||||
#define sqlite3_value_dup sqlite3_api->value_dup
|
||||
#define sqlite3_value_free sqlite3_api->value_free
|
||||
#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64
|
||||
#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64
|
||||
/* Version 3.9.0 and later */
|
||||
#define sqlite3_value_subtype sqlite3_api->value_subtype
|
||||
#define sqlite3_result_subtype sqlite3_api->result_subtype
|
||||
/* Version 3.10.0 and later */
|
||||
#define sqlite3_status64 sqlite3_api->status64
|
||||
#define sqlite3_strlike sqlite3_api->strlike
|
||||
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
|
||||
/* Version 3.12.0 and later */
|
||||
#define sqlite3_system_errno sqlite3_api->system_errno
|
||||
/* Version 3.14.0 and later */
|
||||
#define sqlite3_trace_v2 sqlite3_api->trace_v2
|
||||
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
|
||||
/* Version 3.18.0 and later */
|
||||
#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid
|
||||
/* Version 3.20.0 and later */
|
||||
#define sqlite3_prepare_v3 sqlite3_api->prepare_v3
|
||||
#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3
|
||||
#define sqlite3_bind_pointer sqlite3_api->bind_pointer
|
||||
#define sqlite3_result_pointer sqlite3_api->result_pointer
|
||||
#define sqlite3_value_pointer sqlite3_api->value_pointer
|
||||
/* Version 3.22.0 and later */
|
||||
#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange
|
||||
#define sqlite3_value_nochange sqlite3_api->value_nochange
|
||||
#define sqlite3_vtab_collation sqlite3_api->vtab_collation
|
||||
/* Version 3.24.0 and later */
|
||||
#define sqlite3_keyword_count sqlite3_api->keyword_count
|
||||
#define sqlite3_keyword_name sqlite3_api->keyword_name
|
||||
#define sqlite3_keyword_check sqlite3_api->keyword_check
|
||||
#define sqlite3_str_new sqlite3_api->str_new
|
||||
#define sqlite3_str_finish sqlite3_api->str_finish
|
||||
#define sqlite3_str_appendf sqlite3_api->str_appendf
|
||||
#define sqlite3_str_vappendf sqlite3_api->str_vappendf
|
||||
#define sqlite3_str_append sqlite3_api->str_append
|
||||
#define sqlite3_str_appendall sqlite3_api->str_appendall
|
||||
#define sqlite3_str_appendchar sqlite3_api->str_appendchar
|
||||
#define sqlite3_str_reset sqlite3_api->str_reset
|
||||
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
||||
#define sqlite3_str_length sqlite3_api->str_length
|
||||
#define sqlite3_str_value sqlite3_api->str_value
|
||||
/* Version 3.25.0 and later */
|
||||
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
||||
/* Version 3.26.0 and later */
|
||||
#define sqlite3_normalized_sql sqlite3_api->normalized_sql
|
||||
/* Version 3.28.0 and later */
|
||||
#define sqlite3_stmt_isexplain sqlite3_api->stmt_isexplain
|
||||
#define sqlite3_value_frombind sqlite3_api->value_frombind
|
||||
/* Version 3.30.0 and later */
|
||||
#define sqlite3_drop_modules sqlite3_api->drop_modules
|
||||
/* Version 3.31.0 and later */
|
||||
#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64
|
||||
#define sqlite3_uri_key sqlite3_api->uri_key
|
||||
#define sqlite3_filename_database sqlite3_api->filename_database
|
||||
#define sqlite3_filename_journal sqlite3_api->filename_journal
|
||||
#define sqlite3_filename_wal sqlite3_api->filename_wal
|
||||
/* Version 3.32.0 and later */
|
||||
#define sqlite3_create_filename sqlite3_api->create_filename
|
||||
#define sqlite3_free_filename sqlite3_api->free_filename
|
||||
#define sqlite3_database_file_object sqlite3_api->database_file_object
|
||||
/* Version 3.34.0 and later */
|
||||
#define sqlite3_txn_state sqlite3_api->txn_state
|
||||
/* Version 3.36.1 and later */
|
||||
#define sqlite3_changes64 sqlite3_api->changes64
|
||||
#define sqlite3_total_changes64 sqlite3_api->total_changes64
|
||||
/* Version 3.37.0 and later */
|
||||
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
|
||||
/* Version 3.38.0 and later */
|
||||
#define sqlite3_error_offset sqlite3_api->error_offset
|
||||
#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value
|
||||
#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct
|
||||
#define sqlite3_vtab_in sqlite3_api->vtab_in
|
||||
#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first
|
||||
#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next
|
||||
/* Version 3.39.0 and later */
|
||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||
#define sqlite3_deserialize sqlite3_api->deserialize
|
||||
#define sqlite3_serialize sqlite3_api->serialize
|
||||
#endif
|
||||
#define sqlite3_db_name sqlite3_api->db_name
|
||||
/* Version 3.40.0 and later */
|
||||
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||
/* Version 3.41.0 and later */
|
||||
#define sqlite3_is_interrupted sqlite3_api->is_interrupted
|
||||
/* Version 3.43.0 and later */
|
||||
#define sqlite3_stmt_explain sqlite3_api->stmt_explain
|
||||
/* Version 3.44.0 and later */
|
||||
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
|
||||
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
|
||||
/* Version 3.50.0 and later */
|
||||
#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
|
||||
/* Version 3.51.0 and later */
|
||||
#define sqlite3_set_errmsg sqlite3_api->set_errmsg
|
||||
#define sqlite3_db_status64 sqlite3_api->db_status64
|
||||
/* Version 3.52.0 and later */
|
||||
#define sqlite3_str_truncate sqlite3_api->str_truncate
|
||||
#define sqlite3_str_free sqlite3_api->str_free
|
||||
#define sqlite3_carray_bind sqlite3_api->carray_bind
|
||||
#define sqlite3_carray_bind_v2 sqlite3_api->carray_bind_v2
|
||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||
|
||||
#ifndef SQLITE_CORE
|
||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||
/* This case when the file really is being compiled as a loadable
|
||||
** extension */
|
||||
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
|
||||
@@ -484,4 +736,4 @@ struct sqlite3_api_routines {
|
||||
# define SQLITE_EXTENSION_INIT3 /*no-op*/
|
||||
#endif
|
||||
|
||||
#endif /* _SQLITE3EXT_H_ */
|
||||
#endif /* SQLITE3EXT_H */
|
||||
|
||||
@@ -10,6 +10,7 @@ ADD_SUBDIRECTORY( EurocDataset )
|
||||
ADD_SUBDIRECTORY( CidSimsDataset )
|
||||
ADD_SUBDIRECTORY( Recovery )
|
||||
ADD_SUBDIRECTORY( Reprocess )
|
||||
ADD_SUBDIRECTORY( DatabaseUpdate )
|
||||
ADD_SUBDIRECTORY( DetectMoreLoopClosures )
|
||||
ADD_SUBDIRECTORY( Export )
|
||||
ADD_SUBDIRECTORY( Report )
|
||||
|
||||
11
tools/DatabaseUpdate/CMakeLists.txt
Normal file
11
tools/DatabaseUpdate/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
ADD_EXECUTABLE(dbupdate main.cpp)
|
||||
|
||||
TARGET_LINK_LIBRARIES(dbupdate rtabmap_core)
|
||||
|
||||
SET_TARGET_PROPERTIES( dbupdate
|
||||
PROPERTIES OUTPUT_NAME ${PROJECT_PREFIX}-dbupdate)
|
||||
|
||||
INSTALL(TARGETS dbupdate
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT runtime
|
||||
BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}" COMPONENT runtime)
|
||||
87
tools/DatabaseUpdate/main.cpp
Normal file
87
tools/DatabaseUpdate/main.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Universite de Sherbrooke nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <rtabmap/core/DBDriverSqlite3.h>
|
||||
#include <rtabmap/utilite/ULogger.h>
|
||||
#include <rtabmap/utilite/UFile.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
using namespace rtabmap;
|
||||
|
||||
void showUsage()
|
||||
{
|
||||
printf("\nUpdate a database with a set of changes recorded while another database was opened with\n"
|
||||
"change tracking enabled (i.e. DBDriverSqlite3::setTrackChangesOutput()). This applies the\n"
|
||||
"data changes only; it does NOT upgrade the database schema/version.\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
" rtabmap-dbupdate \"database.db\" \"changes.update\"\n"
|
||||
"\n"
|
||||
"The changes must be applied to the exact database state they were recorded from; otherwise\n"
|
||||
"the operation is aborted and the database is left unchanged.\n"
|
||||
"\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
ULogger::setType(ULogger::kTypeConsole);
|
||||
ULogger::setLevel(ULogger::kWarning);
|
||||
|
||||
if(argc < 3)
|
||||
{
|
||||
showUsage();
|
||||
}
|
||||
|
||||
std::string databasePath = argv[argc-2];
|
||||
std::string updatePath = argv[argc-1];
|
||||
|
||||
if(!UFile::exists(databasePath))
|
||||
{
|
||||
printf("Database \"%s\" does not exist.\n", databasePath.c_str());
|
||||
return 1;
|
||||
}
|
||||
if(!UFile::exists(updatePath))
|
||||
{
|
||||
printf("Update file \"%s\" does not exist.\n", updatePath.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Updating database \"%s\" with changes from \"%s\"...\n", databasePath.c_str(), updatePath.c_str());
|
||||
|
||||
std::string error;
|
||||
if(DBDriverSqlite3::applyChangesFromFile(databasePath, updatePath, &error))
|
||||
{
|
||||
printf("Done! Database \"%s\" was updated successfully.\n", databasePath.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("Error: %s\n", error.c_str());
|
||||
return 1;
|
||||
}
|
||||
@@ -85,6 +85,11 @@ void showUsage()
|
||||
" -stop_loop Stop after the first loop closure is detected.\n"
|
||||
" -a Append mode: if Mem/IncrementalMemory is true, RTAB-Map is initialized with the first input database,\n"
|
||||
" then next databases are reprocessed on top of the first one.\n"
|
||||
" --track-changes \"changes.update\"\n"
|
||||
" Only with append mode (-a): record the changes made on top of the first (copied) database and\n"
|
||||
" write a compact delta to the given file. Apply it later on the original database with\n"
|
||||
" rtabmap-dbupdate. Requires the database to be version 0.24 or newer. Note: the recorded\n"
|
||||
" changes are held in memory until closing, so use this only when appending a small amount.\n"
|
||||
" -cam # Camera index to stream. Ignored if a database doesn't contain multi-camera data. Can also be multiple \n"
|
||||
" indices split by spaces in a string like \"0 2\" to stream cameras 0 and 2 only.\n"
|
||||
" -cam_tf \"x y z roll pitch yaw\" Camera local transform override(s) without optical rotation. For multi-cameras, \n"
|
||||
@@ -274,6 +279,7 @@ int main(int argc, char * argv[])
|
||||
int stopMapId = -1;
|
||||
bool stopOnLoopClosure = false;
|
||||
bool appendMode = false;
|
||||
std::string trackChangesOutput;
|
||||
std::vector<unsigned int> cameraIndices;
|
||||
std::vector<Transform> cameraLocalTransformOverrides;
|
||||
std::vector<float> cameraLocalTransformOffsetOverrides;
|
||||
@@ -430,6 +436,20 @@ int main(int argc, char * argv[])
|
||||
appendMode = true;
|
||||
printf("Append mode enabled (initialize with first database then reprocess next ones)\n");
|
||||
}
|
||||
else if (strcmp(argv[i], "--track-changes") == 0)
|
||||
{
|
||||
++i;
|
||||
if(i < argc - 2)
|
||||
{
|
||||
trackChangesOutput = argv[i];
|
||||
printf("Change tracking enabled, delta will be written to \"%s\" (apply later with rtabmap-dbupdate).\n", trackChangesOutput.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Missing value for --track-changes option!\n");
|
||||
showUsage();
|
||||
}
|
||||
}
|
||||
else if (strcmp(argv[i], "-cam") == 0 || strcmp(argv[i], "--cam") == 0)
|
||||
{
|
||||
++i;
|
||||
@@ -886,6 +906,22 @@ int main(int argc, char * argv[])
|
||||
Rtabmap rtabmap;
|
||||
rtabmap.init(parameters, outputDatabasePath);
|
||||
|
||||
// Start change tracking now, after init loaded the copied baseline database, so the
|
||||
// delta captures only what reprocessing appends. Only meaningful in append mode, where
|
||||
// the output starts as a copy of the first input database.
|
||||
if(!trackChangesOutput.empty())
|
||||
{
|
||||
if(appendMode)
|
||||
{
|
||||
rtabmap.trackDatabaseChanges(trackChangesOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Warning: --track-changes requires append mode (-a); it is ignored because "
|
||||
"append mode is not enabled.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if(!incrementalMemory && locNull)
|
||||
{
|
||||
rtabmap.setInitialPose(Transform());
|
||||
|
||||
Reference in New Issue
Block a user