mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-04 00:57:46 +08:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
324ed72d68 | ||
|
|
e81c617386 | ||
|
|
481d2cc6c8 | ||
|
|
b5c3d8ef4c | ||
|
|
5e85e6192b | ||
|
|
3840a73dce | ||
|
|
a67876b3eb |
+2
-2
@@ -21,8 +21,8 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
|||||||
# VERSION
|
# VERSION
|
||||||
#######################
|
#######################
|
||||||
SET(RTABMAP_MAJOR_VERSION 0)
|
SET(RTABMAP_MAJOR_VERSION 0)
|
||||||
SET(RTABMAP_MINOR_VERSION 23)
|
SET(RTABMAP_MINOR_VERSION 24)
|
||||||
SET(RTABMAP_PATCH_VERSION 4)
|
SET(RTABMAP_PATCH_VERSION 0)
|
||||||
SET(RTABMAP_VERSION
|
SET(RTABMAP_VERSION
|
||||||
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
||||||
|
|
||||||
|
|||||||
@@ -300,6 +300,18 @@ protected:
|
|||||||
virtual void getNodeIdByLabelQuery(const std::string & label, int & id) const = 0;
|
virtual void getNodeIdByLabelQuery(const std::string & label, int & id) const = 0;
|
||||||
virtual void getAllLabelsQuery(std::map<int, std::string> & labels) const = 0;
|
virtual void getAllLabelsQuery(std::map<int, std::string> & labels) const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<unsigned char> serializeFeatures(
|
||||||
|
const std::vector<cv::KeyPoint> & keypoints,
|
||||||
|
const std::vector<cv::Point3f> & points3D,
|
||||||
|
const cv::Mat & descriptors) const;
|
||||||
|
bool deserializeFeatures(
|
||||||
|
const unsigned char * compressedData,
|
||||||
|
unsigned int compressedDataSize,
|
||||||
|
std::vector<cv::KeyPoint> & keypoints,
|
||||||
|
std::vector<cv::Point3f> & points3D,
|
||||||
|
cv::Mat & descriptors) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//non-abstract methods
|
//non-abstract methods
|
||||||
void saveOrUpdate(const std::vector<Signature *> & signatures);
|
void saveOrUpdate(const std::vector<Signature *> & signatures);
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ private:
|
|||||||
void stepSensorData(sqlite3_stmt * ppStmt, const SensorData & sensorData) const;
|
void stepSensorData(sqlite3_stmt * ppStmt, const SensorData & sensorData) const;
|
||||||
void stepLink(sqlite3_stmt * ppStmt, const Link & link) const;
|
void stepLink(sqlite3_stmt * ppStmt, const Link & link) const;
|
||||||
void stepWordsChanged(sqlite3_stmt * ppStmt, int signatureId, int oldWordId, int newWordId) const;
|
void stepWordsChanged(sqlite3_stmt * ppStmt, int signatureId, int oldWordId, int newWordId) const;
|
||||||
|
void stepKeypoint(sqlite3_stmt * ppStmt, int nodeId, int wordId, int kptIndex) const;
|
||||||
void stepKeypoint(sqlite3_stmt * ppStmt, int nodeID, int wordId, const cv::KeyPoint & kp, const cv::Point3f & pt, const cv::Mat & descriptor) const;
|
void stepKeypoint(sqlite3_stmt * ppStmt, int nodeID, int wordId, const cv::KeyPoint & kp, const cv::Point3f & pt, const cv::Mat & descriptor) const;
|
||||||
void stepGlobalDescriptor(sqlite3_stmt * ppStmt, int nodeId, const GlobalDescriptor & descriptor) const;
|
void stepGlobalDescriptor(sqlite3_stmt * ppStmt, int nodeId, const GlobalDescriptor & descriptor) const;
|
||||||
void stepOccupancyGridUpdate(sqlite3_stmt * ppStmt,
|
void stepOccupancyGridUpdate(sqlite3_stmt * ppStmt,
|
||||||
|
|||||||
@@ -815,6 +815,7 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql.in ${CMA
|
|||||||
|
|
||||||
SET(RESOURCES
|
SET(RESOURCES
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/DatabaseSchema.sql
|
${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_22_0.sql
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_20_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
|
${CMAKE_CURRENT_SOURCE_DIR}/resources/backward_compatibility/DatabaseSchema_0_18_3.sql
|
||||||
|
|||||||
+131
-2
@@ -30,6 +30,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "rtabmap/core/Signature.h"
|
#include "rtabmap/core/Signature.h"
|
||||||
#include "rtabmap/core/VisualWord.h"
|
#include "rtabmap/core/VisualWord.h"
|
||||||
#include "rtabmap/core/DBDriverSqlite3.h"
|
#include "rtabmap/core/DBDriverSqlite3.h"
|
||||||
|
#include "rtabmap/core/Compression.h"
|
||||||
#include "rtabmap/utilite/UConversion.h"
|
#include "rtabmap/utilite/UConversion.h"
|
||||||
#include "rtabmap/utilite/UMath.h"
|
#include "rtabmap/utilite/UMath.h"
|
||||||
#include "rtabmap/utilite/ULogger.h"
|
#include "rtabmap/utilite/ULogger.h"
|
||||||
@@ -703,11 +704,11 @@ void DBDriver::getNodeData(
|
|||||||
if(uContains(_trashSignatures, signatureId))
|
if(uContains(_trashSignatures, signatureId))
|
||||||
{
|
{
|
||||||
const Signature * s = _trashSignatures.at(signatureId);
|
const Signature * s = _trashSignatures.at(signatureId);
|
||||||
if((!s->isSaved() ||
|
if(!s->isSaved() ||
|
||||||
((!images || !s->sensorData().imageCompressed().empty()) &&
|
((!images || !s->sensorData().imageCompressed().empty()) &&
|
||||||
(!scan || !s->sensorData().laserScanCompressed().isEmpty()) &&
|
(!scan || !s->sensorData().laserScanCompressed().isEmpty()) &&
|
||||||
(!userData || !s->sensorData().userDataCompressed().empty()) &&
|
(!userData || !s->sensorData().userDataCompressed().empty()) &&
|
||||||
(!occupancyGrid || s->sensorData().gridCellSize() != 0.0f))))
|
(!occupancyGrid || s->sensorData().gridCellSize() != 0.0f)))
|
||||||
{
|
{
|
||||||
data = (SensorData)s->sensorData();
|
data = (SensorData)s->sensorData();
|
||||||
if(!images)
|
if(!images)
|
||||||
@@ -1513,4 +1514,132 @@ void DBDriver::generateGraph(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<unsigned char> DBDriver::serializeFeatures(
|
||||||
|
const std::vector<cv::KeyPoint> & keypoints,
|
||||||
|
const std::vector<cv::Point3f> & points3D,
|
||||||
|
const cv::Mat & descriptors) const
|
||||||
|
{
|
||||||
|
UTimer timer;
|
||||||
|
const int headerSize = 13;
|
||||||
|
int header[headerSize] = {
|
||||||
|
RTABMAP_VERSION_MAJOR, RTABMAP_VERSION_MINOR, RTABMAP_VERSION_PATCH, // 0,1,2
|
||||||
|
CV_MAJOR_VERSION, CV_MINOR_VERSION, CV_SUBMINOR_VERSION, // 3,4,5 (In case the format/order/size of KeyPoint and/or Point3f changes in the future)
|
||||||
|
sizeof(cv::KeyPoint), (int)keypoints.size(), // 6,7
|
||||||
|
sizeof(cv::Point3f), (int)points3D.size(), // 8,9
|
||||||
|
descriptors.type(), descriptors.cols, descriptors.rows}; // 10,11,12
|
||||||
|
UDEBUG("Header: %d %d %d %d %d %d %d %d %d %d %d %d %d",
|
||||||
|
header[0],header[1],header[2],header[3],header[4],header[5],header[6],header[7],header[8],header[9],header[10],header[11],header[12]);
|
||||||
|
std::vector<unsigned char> data(
|
||||||
|
sizeof(int)*headerSize +
|
||||||
|
keypoints.size()*sizeof(cv::KeyPoint) + // pos_x, pos_y, size, dir, response, octave
|
||||||
|
points3D.size()*sizeof(cv::Point3f) + // depth_x, depth_y, depth_z
|
||||||
|
descriptors.total()*descriptors.elemSize());
|
||||||
|
UDEBUG("Serialized total size = %ld bytes (header=%ld)", data.size(), sizeof(int)*headerSize);
|
||||||
|
memcpy(data.data(), header, sizeof(int)*headerSize);
|
||||||
|
size_t index = sizeof(int)*headerSize;
|
||||||
|
if(!keypoints.empty())
|
||||||
|
{
|
||||||
|
memcpy(data.data()+index, keypoints.data(), sizeof(cv::KeyPoint)*keypoints.size());
|
||||||
|
index += sizeof(cv::KeyPoint)*(keypoints.size());
|
||||||
|
}
|
||||||
|
if(!points3D.empty())
|
||||||
|
{
|
||||||
|
memcpy(data.data()+index, points3D.data(), sizeof(cv::Point3f)*points3D.size());
|
||||||
|
index += sizeof(cv::Point3f)*(points3D.size());
|
||||||
|
}
|
||||||
|
if(!descriptors.empty())
|
||||||
|
{
|
||||||
|
memcpy(data.data()+index, descriptors.data, descriptors.elemSize()*descriptors.total());
|
||||||
|
index+=descriptors.elemSize()*(descriptors.total());
|
||||||
|
}
|
||||||
|
double serializationTime = timer.ticks();
|
||||||
|
UASSERT_MSG(index == data.size(), uFormat("wrote=%ld expected=%ld", index, data.size()).c_str());
|
||||||
|
std::vector<unsigned char> compressedData = compressData(cv::Mat(1, data.size(), CV_8UC1, (void *)data.data()));
|
||||||
|
UWARN("Serialized %ld bytes in %f ms, Compressed %ld bytes in %f ms",
|
||||||
|
data.size(), serializationTime*1000.0f,
|
||||||
|
compressedData.size(), timer.ticks()*1000.0f);
|
||||||
|
return compressedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DBDriver::deserializeFeatures(
|
||||||
|
const unsigned char * compressedData,
|
||||||
|
unsigned int compressedDataSize,
|
||||||
|
std::vector<cv::KeyPoint> & keypoints,
|
||||||
|
std::vector<cv::Point3f> & points3D,
|
||||||
|
cv::Mat & descriptors) const
|
||||||
|
{
|
||||||
|
UTimer timer;
|
||||||
|
cv::Mat serializedData = uncompressData(compressedData, compressedDataSize);
|
||||||
|
double uncompressionTime = timer.ticks();
|
||||||
|
if(serializedData.empty())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
UDEBUG("Decompressed serialized data = %dx%d type=%d",
|
||||||
|
serializedData.cols, serializedData.rows, serializedData.type());
|
||||||
|
UASSERT(serializedData.type() == CV_8UC1);
|
||||||
|
int headerSize = 13;
|
||||||
|
if(serializedData.total() >= sizeof(int)*headerSize)
|
||||||
|
{
|
||||||
|
const int * header = (const int *)serializedData.data;
|
||||||
|
UASSERT(header[6] == sizeof(cv::KeyPoint));
|
||||||
|
int n_kpts = header[7];
|
||||||
|
UASSERT(header[8] == sizeof(cv::Point3f));
|
||||||
|
int n_pts = header[9];
|
||||||
|
int d_type = header[10];
|
||||||
|
int d_cols = header[11];
|
||||||
|
int d_rows = header[12];
|
||||||
|
|
||||||
|
UDEBUG("Serialized features header: version %d.%d.%d cv=%d.%d.%d kpts=%d (size=%d) pts=%d (size=%d) descriptors=%dx%d type=%d",
|
||||||
|
header[0], header[1], header[2],
|
||||||
|
header[3], header[4], header[5],
|
||||||
|
header[7], header[6],
|
||||||
|
header[9], header[8],
|
||||||
|
header[11], header[12], header[10]);
|
||||||
|
|
||||||
|
keypoints.resize(n_kpts);
|
||||||
|
points3D.resize(n_pts);
|
||||||
|
descriptors = cv::Mat(d_rows, d_cols, d_type);
|
||||||
|
unsigned int requiredDataSize = sizeof(int)*headerSize +
|
||||||
|
sizeof(cv::KeyPoint)*n_kpts +
|
||||||
|
sizeof(cv::Point3f)*n_pts +
|
||||||
|
descriptors.total() * descriptors.elemSize();
|
||||||
|
UASSERT_MSG(serializedData.total() == requiredDataSize,
|
||||||
|
uFormat("dataSize=%d != required=%d (header: version %d.%d.%d cv=%d.%d.%d kpts=%d (size=%d) pts=%d (size=%d) descriptors=%dx%d type=%d",
|
||||||
|
serializedData.total(),
|
||||||
|
requiredDataSize,
|
||||||
|
header[0], header[1], header[2],
|
||||||
|
header[3], header[4], header[5],
|
||||||
|
header[7], header[6],
|
||||||
|
header[9], header[8],
|
||||||
|
header[11], header[12], header[10]).c_str());
|
||||||
|
unsigned int index = sizeof(int)*headerSize;
|
||||||
|
if(n_kpts != 0)
|
||||||
|
{
|
||||||
|
memcpy(keypoints.data(), (void*)(serializedData.data+index), n_kpts*sizeof(cv::KeyPoint));
|
||||||
|
index += n_kpts*sizeof(cv::KeyPoint);
|
||||||
|
}
|
||||||
|
if(n_pts != 0)
|
||||||
|
{
|
||||||
|
memcpy(points3D.data(), (void*)(serializedData.data+index), n_pts*sizeof(cv::Point3f));
|
||||||
|
index += n_pts*sizeof(cv::Point3f);
|
||||||
|
}
|
||||||
|
if(d_rows > 0)
|
||||||
|
{
|
||||||
|
cv::Mat(d_rows, d_cols, d_type, (void*)(serializedData.data+index)).copyTo(descriptors);
|
||||||
|
index+=descriptors.elemSize()*(descriptors.total());
|
||||||
|
}
|
||||||
|
UASSERT(index == serializedData.total());
|
||||||
|
|
||||||
|
UWARN("Uncompressed %ld bytes in %f ms, deserialized %ld bytes in %f ms",
|
||||||
|
compressedDataSize, uncompressionTime*1000.0f,
|
||||||
|
serializedData.total(), timer.ticks()*1000.0f);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
UERROR("Wrong serialized features format detected (size in bytes=%ld)! Cannot deserialize the data.", serializedData.size());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rtabmap
|
} // namespace rtabmap
|
||||||
|
|||||||
+186
-15
@@ -34,6 +34,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "rtabmap/core/util3d.h"
|
#include "rtabmap/core/util3d.h"
|
||||||
#include "rtabmap/core/Compression.h"
|
#include "rtabmap/core/Compression.h"
|
||||||
#include "DatabaseSchema_sql.h"
|
#include "DatabaseSchema_sql.h"
|
||||||
|
#include "DatabaseSchema_0_23_0_sql.h"
|
||||||
#include "DatabaseSchema_0_22_0_sql.h"
|
#include "DatabaseSchema_0_22_0_sql.h"
|
||||||
#include "DatabaseSchema_0_20_0_sql.h"
|
#include "DatabaseSchema_0_20_0_sql.h"
|
||||||
#include "DatabaseSchema_0_18_3_sql.h"
|
#include "DatabaseSchema_0_18_3_sql.h"
|
||||||
@@ -406,6 +407,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.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.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.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));
|
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)
|
for(size_t i=0; i<schemas.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -881,7 +883,15 @@ long DBDriverSqlite3::getFeaturesMemoryUsedQuery() const
|
|||||||
if(_ppDb)
|
if(_ppDb)
|
||||||
{
|
{
|
||||||
std::string query;
|
std::string query;
|
||||||
if(uStrNumCmp(_version, "0.13.0") >= 0)
|
if(uStrNumCmp(_version, "0.24.0") >= 0)
|
||||||
|
{
|
||||||
|
query = "SELECT ("
|
||||||
|
"(SELECT sum(length(node_id) + length(word_id) + length(feature_index)) FROM Feature)"
|
||||||
|
" + "
|
||||||
|
"(SELECT total(length(features)) FROM Node)"
|
||||||
|
")";
|
||||||
|
}
|
||||||
|
else if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||||
{
|
{
|
||||||
query = "SELECT sum(length(node_id) + length(word_id) + length(pos_x) + length(pos_y) + length(size) + length(dir) + length(response) + length(octave) + ifnull(length(depth_x),0) + ifnull(length(depth_y),0) + ifnull(length(depth_z),0) + ifnull(length(descriptor_size),0) + ifnull(length(descriptor),0)) "
|
query = "SELECT sum(length(node_id) + length(word_id) + length(pos_x) + length(pos_y) + length(size) + length(dir) + length(response) + length(octave) + ifnull(length(depth_x),0) + ifnull(length(depth_y),0) + ifnull(length(depth_z),0) + ifnull(length(descriptor_size),0) + ifnull(length(descriptor),0)) "
|
||||||
"FROM Feature";
|
"FROM Feature";
|
||||||
@@ -1319,6 +1329,7 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures, boo
|
|||||||
{
|
{
|
||||||
std::stringstream fields;
|
std::stringstream fields;
|
||||||
|
|
||||||
|
bool fieldAdded = false;
|
||||||
if(images)
|
if(images)
|
||||||
{
|
{
|
||||||
if(uStrNumCmp(_version, "0.22.0") >= 0)
|
if(uStrNumCmp(_version, "0.22.0") >= 0)
|
||||||
@@ -1329,30 +1340,33 @@ void DBDriverSqlite3::loadNodeDataQuery(std::list<Signature *> & signatures, boo
|
|||||||
{
|
{
|
||||||
fields << "image, depth, calibration";
|
fields << "image, depth, calibration";
|
||||||
}
|
}
|
||||||
|
fieldAdded = true;
|
||||||
if(scan || userData || occupancyGrid)
|
|
||||||
{
|
|
||||||
fields << ", ";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(scan)
|
if(scan)
|
||||||
{
|
{
|
||||||
fields << "scan_info, scan";
|
if(fieldAdded)
|
||||||
if(userData || occupancyGrid)
|
|
||||||
{
|
{
|
||||||
fields << ", ";
|
fields << ", ";
|
||||||
}
|
}
|
||||||
|
fieldAdded = true;
|
||||||
|
fields << "scan_info, scan";
|
||||||
}
|
}
|
||||||
if(userData)
|
if(userData)
|
||||||
{
|
{
|
||||||
fields << "user_data";
|
if(fieldAdded)
|
||||||
if(occupancyGrid)
|
|
||||||
{
|
{
|
||||||
fields << ", ";
|
fields << ", ";
|
||||||
}
|
}
|
||||||
|
fieldAdded = true;
|
||||||
|
fields << "user_data";
|
||||||
}
|
}
|
||||||
if(occupancyGrid)
|
if(occupancyGrid)
|
||||||
{
|
{
|
||||||
|
if(fieldAdded)
|
||||||
|
{
|
||||||
|
fields << ", ";
|
||||||
|
}
|
||||||
|
fieldAdded = true;
|
||||||
if(uStrNumCmp(_version, "0.16.0") >= 0)
|
if(uStrNumCmp(_version, "0.16.0") >= 0)
|
||||||
{
|
{
|
||||||
fields << "ground_cells, obstacle_cells, empty_cells, cell_size, view_point_x, view_point_y, view_point_z";
|
fields << "ground_cells, obstacle_cells, empty_cells, cell_size, view_point_x, view_point_y, view_point_z";
|
||||||
@@ -3846,13 +3860,22 @@ void DBDriverSqlite3::loadWordIdsQuery(std::list<Signature *> & signatures) cons
|
|||||||
|
|
||||||
void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
||||||
{
|
{
|
||||||
|
UTimer totalTime;
|
||||||
if(_ppDb)
|
if(_ppDb)
|
||||||
{
|
{
|
||||||
|
bool before_v0_24 = uStrNumCmp(_version, "0.24.0") < 0;
|
||||||
|
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
sqlite3_stmt * ppStmt = 0;
|
sqlite3_stmt * ppStmt = 0;
|
||||||
std::stringstream query;
|
std::stringstream query;
|
||||||
|
|
||||||
if(uStrNumCmp(_version, "0.13.0") >= 0)
|
if(uStrNumCmp(_version, "0.24.0") >= 0)
|
||||||
|
{
|
||||||
|
query << "SELECT word_id, feature_index "
|
||||||
|
"FROM Feature "
|
||||||
|
"WHERE node_id = ? ";
|
||||||
|
}
|
||||||
|
else if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||||
{
|
{
|
||||||
query << "SELECT word_id, pos_x, pos_y, size, dir, response, octave, depth_x, depth_y, depth_z, descriptor_size, descriptor "
|
query << "SELECT word_id, pos_x, pos_y, size, dir, response, octave, depth_x, depth_y, depth_z, descriptor_size, descriptor "
|
||||||
"FROM Feature "
|
"FROM Feature "
|
||||||
@@ -3876,7 +3899,6 @@ void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
|||||||
"FROM Map_Node_Word "
|
"FROM Map_Node_Word "
|
||||||
"WHERE node_id = ? ";
|
"WHERE node_id = ? ";
|
||||||
}
|
}
|
||||||
|
|
||||||
query << " ORDER BY word_id"; // Needed for fast insertion below
|
query << " ORDER BY word_id"; // Needed for fast insertion below
|
||||||
query << ";";
|
query << ";";
|
||||||
|
|
||||||
@@ -3884,7 +3906,7 @@ void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
|||||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
float nanFloat = std::numeric_limits<float>::quiet_NaN ();
|
float nanFloat = std::numeric_limits<float>::quiet_NaN ();
|
||||||
|
std::vector<std::multimap<int, int> > allVisualWords;
|
||||||
for(std::list<Signature*>::const_iterator iter=signatures.begin(); iter!=signatures.end(); ++iter)
|
for(std::list<Signature*>::const_iterator iter=signatures.begin(); iter!=signatures.end(); ++iter)
|
||||||
{
|
{
|
||||||
//ULOGGER_DEBUG("Loading words of %d...", (*iter)->id());
|
//ULOGGER_DEBUG("Loading words of %d...", (*iter)->id());
|
||||||
@@ -3893,6 +3915,7 @@ void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
|||||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
int visualWordId = 0;
|
int visualWordId = 0;
|
||||||
|
int featureIndex = 0;
|
||||||
int descriptorSize = 0;
|
int descriptorSize = 0;
|
||||||
const void * descriptor = 0;
|
const void * descriptor = 0;
|
||||||
int dRealSize = 0;
|
int dRealSize = 0;
|
||||||
@@ -3910,6 +3933,13 @@ void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
|||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
visualWordId = sqlite3_column_int(ppStmt, index++);
|
visualWordId = sqlite3_column_int(ppStmt, index++);
|
||||||
|
if(!before_v0_24)
|
||||||
|
{
|
||||||
|
featureIndex = sqlite3_column_int(ppStmt, index++);
|
||||||
|
visualWords.insert(visualWords.end(), std::make_pair(visualWordId, featureIndex));
|
||||||
|
}
|
||||||
|
else if(before_v0_24)
|
||||||
|
{
|
||||||
kpt.pt.x = sqlite3_column_double(ppStmt, index++);
|
kpt.pt.x = sqlite3_column_double(ppStmt, index++);
|
||||||
kpt.pt.y = sqlite3_column_double(ppStmt, index++);
|
kpt.pt.y = sqlite3_column_double(ppStmt, index++);
|
||||||
kpt.size = sqlite3_column_int(ppStmt, index++);
|
kpt.size = sqlite3_column_int(ppStmt, index++);
|
||||||
@@ -3988,11 +4018,14 @@ void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
|||||||
descriptors.push_back(d);
|
descriptors.push_back(d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rc = sqlite3_step(ppStmt);
|
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", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
|
if(before_v0_24)
|
||||||
|
{
|
||||||
if(visualWords.size()==0)
|
if(visualWords.size()==0)
|
||||||
{
|
{
|
||||||
UDEBUG("Empty signature detected! (id=%d)", (*iter)->id());
|
UDEBUG("Empty signature detected! (id=%d)", (*iter)->id());
|
||||||
@@ -4006,6 +4039,75 @@ void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
|||||||
(*iter)->setWords(visualWords, visualWordsKpts, visualWords3, descriptors);
|
(*iter)->setWords(visualWords, visualWordsKpts, visualWords3, descriptors);
|
||||||
//ULOGGER_DEBUG("Add %d keypoints, %d 3d points and %d descriptors to node %d", (int)visualWords.size(), allWords3NaN?0:(int)visualWords3.size(), (int)descriptors.rows, (*iter)->id());
|
//ULOGGER_DEBUG("Add %d keypoints, %d 3d points and %d descriptors to node %d", (int)visualWords.size(), allWords3NaN?0:(int)visualWords3.size(), (int)descriptors.rows, (*iter)->id());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
allVisualWords.push_back(visualWords);
|
||||||
|
}
|
||||||
|
|
||||||
|
//reset
|
||||||
|
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());
|
||||||
|
|
||||||
|
if(!before_v0_24)
|
||||||
|
{
|
||||||
|
// Features are now in compressed field "features" of table Node
|
||||||
|
std::string queryStr = "SELECT features FROM Node WHERE id = ?;";
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2(_ppDb, queryStr.c_str(), -1, &ppStmt, 0);
|
||||||
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
|
UASSERT(allVisualWords.size() == signatures.size());
|
||||||
|
int w=0;
|
||||||
|
for(std::list<Signature*>::const_iterator iter=signatures.begin(); iter!=signatures.end(); ++iter, ++w)
|
||||||
|
{
|
||||||
|
if(allVisualWords[w].empty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ULOGGER_DEBUG("Loading compressed features of %d...", (*iter)->id());
|
||||||
|
// bind id
|
||||||
|
rc = sqlite3_bind_int(ppStmt, 1, (*iter)->id());
|
||||||
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
|
std::multimap<int, int> & visualWords = allVisualWords[w];
|
||||||
|
std::vector<cv::KeyPoint> visualWordsKpts;
|
||||||
|
std::vector<cv::Point3f> visualWords3;
|
||||||
|
cv::Mat descriptors;
|
||||||
|
|
||||||
|
// Process the result if one
|
||||||
|
rc = sqlite3_step(ppStmt);
|
||||||
|
if(rc == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
const void * data = sqlite3_column_blob(ppStmt, index);
|
||||||
|
int dataSize = sqlite3_column_bytes(ppStmt, index++);
|
||||||
|
if(dataSize > 0 && data)
|
||||||
|
{
|
||||||
|
if(!deserializeFeatures((const unsigned char *)data, dataSize, visualWordsKpts, visualWords3, descriptors))
|
||||||
|
{
|
||||||
|
UERROR("Failed deserializing features for node %d! (dataSize=%d)", (*iter)->id(), dataSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = sqlite3_step(ppStmt);
|
||||||
|
}
|
||||||
|
UASSERT_MSG(rc == SQLITE_DONE, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
|
UASSERT_MSG(visualWords.size() == visualWordsKpts.size(),
|
||||||
|
uFormat("visualWords=%ld visualWordsKpts=%ld", visualWords.size(), visualWordsKpts.size()).c_str());
|
||||||
|
UASSERT_MSG(visualWords3.empty() || visualWords.size() == visualWords3.size(),
|
||||||
|
uFormat("visualWords=%ld visualWordsKpts=%ld", visualWords.size(), visualWords3.size()).c_str());
|
||||||
|
UASSERT_MSG(descriptors.empty() || (int)visualWords.size() == descriptors.rows,
|
||||||
|
uFormat("visualWords=%ld visualWordsKpts=%d", visualWords.size(), descriptors.rows).c_str());
|
||||||
|
|
||||||
|
(*iter)->setWords(visualWords, visualWordsKpts, visualWords3, descriptors);
|
||||||
|
ULOGGER_DEBUG("Add %d keypoints, %d 3d points and %d descriptors to node %d", (int)visualWords.size(), (int)visualWords3.size(), (int)descriptors.rows, (*iter)->id());
|
||||||
|
|
||||||
//reset
|
//reset
|
||||||
rc = sqlite3_reset(ppStmt);
|
rc = sqlite3_reset(ppStmt);
|
||||||
@@ -4016,6 +4118,8 @@ void DBDriverSqlite3::loadWordsQuery(std::list<Signature *> & signatures) const
|
|||||||
rc = sqlite3_finalize(ppStmt);
|
rc = sqlite3_finalize(ppStmt);
|
||||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
UWARN("totalTime=%f ms", totalTime.ticks() *1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DBDriverSqlite3::loadLinksQuery(
|
void DBDriverSqlite3::loadLinksQuery(
|
||||||
@@ -4599,6 +4703,16 @@ void DBDriverSqlite3::saveQuery(const std::list<Signature *> & signatures)
|
|||||||
for(std::list<Signature *>::const_iterator i=signatures.begin(); i!=signatures.end(); ++i)
|
for(std::list<Signature *>::const_iterator i=signatures.begin(); i!=signatures.end(); ++i)
|
||||||
{
|
{
|
||||||
UASSERT((*i)->getWords().size() == (*i)->getWordsKpts().size());
|
UASSERT((*i)->getWords().size() == (*i)->getWordsKpts().size());
|
||||||
|
if(uStrNumCmp(_version, "0.24.0") >= 0)
|
||||||
|
{
|
||||||
|
// Only node -> word -> index are saved in Feature
|
||||||
|
for(std::multimap<int, int>::const_iterator w=(*i)->getWords().begin(); w!=(*i)->getWords().end(); ++w)
|
||||||
|
{
|
||||||
|
stepKeypoint(ppStmt, (*i)->id(), w->first, w->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
UASSERT((*i)->getWords3().empty() || (*i)->getWords().size() == (*i)->getWords3().size());
|
UASSERT((*i)->getWords3().empty() || (*i)->getWords().size() == (*i)->getWords3().size());
|
||||||
UASSERT((*i)->getWordsDescriptors().empty() || (int)(*i)->getWords().size() == (*i)->getWordsDescriptors().rows);
|
UASSERT((*i)->getWordsDescriptors().empty() || (int)(*i)->getWords().size() == (*i)->getWordsDescriptors().rows);
|
||||||
|
|
||||||
@@ -4619,6 +4733,7 @@ void DBDriverSqlite3::saveQuery(const std::list<Signature *> & signatures)
|
|||||||
stepKeypoint(ppStmt, (*i)->id(), w->first, (*i)->getWordsKpts()[w->second], pt, descriptor);
|
stepKeypoint(ppStmt, (*i)->id(), w->first, (*i)->getWordsKpts()[w->second], pt, descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Finalize (delete) the statement
|
// Finalize (delete) the statement
|
||||||
rc = sqlite3_finalize(ppStmt);
|
rc = sqlite3_finalize(ppStmt);
|
||||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
@@ -5791,7 +5906,11 @@ void DBDriverSqlite3::saveFlannIndexQuery(const std::vector<unsigned char> & dat
|
|||||||
|
|
||||||
std::string DBDriverSqlite3::queryStepNode() const
|
std::string DBDriverSqlite3::queryStepNode() const
|
||||||
{
|
{
|
||||||
if(uStrNumCmp(_version, "0.18.0") >= 0)
|
if(uStrNumCmp(_version, "0.24.0") >= 0)
|
||||||
|
{
|
||||||
|
return "INSERT INTO Node(id, map_id, weight, pose, stamp, label, ground_truth_pose, velocity, gps, env_sensors, features) VALUES(?,?,?,?,?,?,?,?,?,?,?);";
|
||||||
|
}
|
||||||
|
else if(uStrNumCmp(_version, "0.18.0") >= 0)
|
||||||
{
|
{
|
||||||
return "INSERT INTO Node(id, map_id, weight, pose, stamp, label, ground_truth_pose, velocity, gps, env_sensors) VALUES(?,?,?,?,?,?,?,?,?,?);";
|
return "INSERT INTO Node(id, map_id, weight, pose, stamp, label, ground_truth_pose, velocity, gps, env_sensors) VALUES(?,?,?,?,?,?,?,?,?,?);";
|
||||||
}
|
}
|
||||||
@@ -5823,6 +5942,7 @@ std::string DBDriverSqlite3::queryStepNode() const
|
|||||||
}
|
}
|
||||||
void DBDriverSqlite3::stepNode(sqlite3_stmt * ppStmt, const Signature * s) const
|
void DBDriverSqlite3::stepNode(sqlite3_stmt * ppStmt, const Signature * s) const
|
||||||
{
|
{
|
||||||
|
UTimer totalTime;
|
||||||
UDEBUG("Save node %d", s->id());
|
UDEBUG("Save node %d", s->id());
|
||||||
if(!ppStmt || !s)
|
if(!ppStmt || !s)
|
||||||
{
|
{
|
||||||
@@ -5859,6 +5979,7 @@ void DBDriverSqlite3::stepNode(sqlite3_stmt * ppStmt, const Signature * s) const
|
|||||||
|
|
||||||
std::vector<double> gps;
|
std::vector<double> gps;
|
||||||
std::vector<double> envSensors;
|
std::vector<double> envSensors;
|
||||||
|
std::vector<unsigned char> serializedFeatures;
|
||||||
if(uStrNumCmp(_version, "0.10.1") >= 0)
|
if(uStrNumCmp(_version, "0.10.1") >= 0)
|
||||||
{
|
{
|
||||||
// ignore user_data
|
// ignore user_data
|
||||||
@@ -5942,12 +6063,30 @@ void DBDriverSqlite3::stepNode(sqlite3_stmt * ppStmt, const Signature * s) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(uStrNumCmp(_version, "0.24.0") >= 0)
|
||||||
|
{
|
||||||
|
//features
|
||||||
|
serializedFeatures = serializeFeatures(s->getWordsKpts(), s->getWords3(), s->getWordsDescriptors());
|
||||||
|
if(serializedFeatures.empty())
|
||||||
|
{
|
||||||
|
rc = sqlite3_bind_null(ppStmt, index++);
|
||||||
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = sqlite3_bind_blob(ppStmt, index++, serializedFeatures.data(), (int)serializedFeatures.size(), SQLITE_STATIC);
|
||||||
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//step
|
//step
|
||||||
rc=sqlite3_step(ppStmt);
|
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", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
rc = sqlite3_reset(ppStmt);
|
rc = sqlite3_reset(ppStmt);
|
||||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
|
UWARN("totalTime=%f ms", totalTime.ticks()*1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DBDriverSqlite3::queryStepImage() const
|
std::string DBDriverSqlite3::queryStepImage() const
|
||||||
@@ -6893,7 +7032,11 @@ void DBDriverSqlite3::stepWordsChanged(sqlite3_stmt * ppStmt, int nodeId, int ol
|
|||||||
|
|
||||||
std::string DBDriverSqlite3::queryStepKeypoint() const
|
std::string DBDriverSqlite3::queryStepKeypoint() const
|
||||||
{
|
{
|
||||||
if(uStrNumCmp(_version, "0.13.0") >= 0)
|
if(uStrNumCmp(_version, "0.24.0") >= 0)
|
||||||
|
{
|
||||||
|
return "INSERT INTO Feature(node_id, word_id, feature_index) VALUES(?,?,?);";
|
||||||
|
}
|
||||||
|
else if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||||
{
|
{
|
||||||
return "INSERT INTO Feature(node_id, word_id, pos_x, pos_y, size, dir, response, octave, depth_x, depth_y, depth_z, descriptor_size, descriptor) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);";
|
return "INSERT INTO Feature(node_id, word_id, pos_x, pos_y, size, dir, response, octave, depth_x, depth_y, depth_z, descriptor_size, descriptor) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?);";
|
||||||
}
|
}
|
||||||
@@ -6907,6 +7050,32 @@ std::string DBDriverSqlite3::queryStepKeypoint() const
|
|||||||
}
|
}
|
||||||
return "INSERT INTO Map_Node_Word(node_id, word_id, pos_x, pos_y, size, dir, response, depth_x, depth_y, depth_z) VALUES(?,?,?,?,?,?,?,?,?,?);";
|
return "INSERT INTO Map_Node_Word(node_id, word_id, pos_x, pos_y, size, dir, response, depth_x, depth_y, depth_z) VALUES(?,?,?,?,?,?,?,?,?,?);";
|
||||||
}
|
}
|
||||||
|
void DBDriverSqlite3::stepKeypoint(sqlite3_stmt * ppStmt,
|
||||||
|
int nodeId,
|
||||||
|
int wordId,
|
||||||
|
int kptIndex) const
|
||||||
|
{
|
||||||
|
// Used with version >= 0.24
|
||||||
|
UASSERT(uStrNumCmp(_version, "0.24.0") >= 0);
|
||||||
|
if(!ppStmt)
|
||||||
|
{
|
||||||
|
UFATAL("");
|
||||||
|
}
|
||||||
|
int rc = SQLITE_OK;
|
||||||
|
int index = 1;
|
||||||
|
rc = sqlite3_bind_int(ppStmt, index++, nodeId);
|
||||||
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
rc = sqlite3_bind_int(ppStmt, index++, wordId);
|
||||||
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
rc = sqlite3_bind_double(ppStmt, index++, kptIndex);
|
||||||
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
void DBDriverSqlite3::stepKeypoint(sqlite3_stmt * ppStmt,
|
void DBDriverSqlite3::stepKeypoint(sqlite3_stmt * ppStmt,
|
||||||
int nodeId,
|
int nodeId,
|
||||||
int wordId,
|
int wordId,
|
||||||
@@ -6914,6 +7083,8 @@ void DBDriverSqlite3::stepKeypoint(sqlite3_stmt * ppStmt,
|
|||||||
const cv::Point3f & pt,
|
const cv::Point3f & pt,
|
||||||
const cv::Mat & descriptor) const
|
const cv::Mat & descriptor) const
|
||||||
{
|
{
|
||||||
|
// Used with version < 0.24
|
||||||
|
UASSERT(uStrNumCmp(_version, "0.24.0") < 0);
|
||||||
if(!ppStmt)
|
if(!ppStmt)
|
||||||
{
|
{
|
||||||
UFATAL("");
|
UFATAL("");
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ CREATE TABLE Node (
|
|||||||
label TEXT,
|
label TEXT,
|
||||||
gps BLOB, -- 1x6 double: stamp, longitude (DD), latitude (DD), altitude (m), accuracy (m), bearing (North 0->360 deg clockwise)
|
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, ...)
|
env_sensors BLOB, -- Variable 3xdouble: (sensorId1, value, stamp, sensorId2, value, stamp, ...)
|
||||||
|
features BLOB, -- compressed serialized data (pos_x, pos_y, size, dir, response, octave, depth_x, depth_y, depth_z, descriptor_size, descriptor)
|
||||||
time_enter DATE,
|
time_enter DATE,
|
||||||
PRIMARY KEY (id)
|
PRIMARY KEY (id)
|
||||||
);
|
);
|
||||||
@@ -74,17 +75,7 @@ CREATE TABLE Word (
|
|||||||
CREATE TABLE Feature (
|
CREATE TABLE Feature (
|
||||||
node_id INTEGER NOT NULL,
|
node_id INTEGER NOT NULL,
|
||||||
word_id INTEGER NOT NULL,
|
word_id INTEGER NOT NULL,
|
||||||
pos_x FLOAT NOT NULL,
|
feature_index INTEGER NOT NULL, -- index of the feature in "features" field of Node
|
||||||
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)
|
FOREIGN KEY (node_id) REFERENCES Node(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,185 @@
|
|||||||
|
-- *******************************************************************
|
||||||
|
-- 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
-1
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package format="2">
|
<package format="2">
|
||||||
<name>rtabmap</name>
|
<name>rtabmap</name>
|
||||||
<version>0.22.1</version>
|
<version>0.24.0</version>
|
||||||
<description>RTAB-Map's standalone library. RTAB-Map is a RGB-D SLAM approach with real-time constraints.</description>
|
<description>RTAB-Map's standalone library. RTAB-Map is a RGB-D SLAM approach with real-time constraints.</description>
|
||||||
<maintainer email="[email protected]">Mathieu Labbe</maintainer>
|
<maintainer email="[email protected]">Mathieu Labbe</maintainer>
|
||||||
<author>Mathieu Labbe</author>
|
<author>Mathieu Labbe</author>
|
||||||
|
|||||||
Reference in New Issue
Block a user