mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-03 01:50:24 +08:00
DBDriver: when an empty database url is provided, an empty database "in memory" is used by default. Tango: fixed second database not recorded in Data Recorder mode (now creating a new one on save). Mapping parameters are saved in database instead of the one used to record data (Data Recorder mode).
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<!-- BEGIN_INCLUDE(manifest) -->
|
<!-- BEGIN_INCLUDE(manifest) -->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.introlab.rtabmap"
|
package="com.introlab.rtabmap"
|
||||||
android:versionCode="22"
|
android:versionCode="23"
|
||||||
android:versionName="@RTABMAP_VERSION@">
|
android:versionName="@RTABMAP_VERSION@">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|||||||
@@ -1020,9 +1020,24 @@ void RTABMapApp::resetMapping()
|
|||||||
void RTABMapApp::save(const std::string & databasePath)
|
void RTABMapApp::save(const std::string & databasePath)
|
||||||
{
|
{
|
||||||
rtabmapThread_->join(true);
|
rtabmapThread_->join(true);
|
||||||
|
|
||||||
|
if(dataRecorderMode_)
|
||||||
|
{
|
||||||
|
// to save mapping parameters in the database
|
||||||
|
dataRecorderMode_ = false;
|
||||||
|
rtabmap::ParametersMap parameters = getRtabmapParameters();
|
||||||
|
rtabmap_->parseParameters(parameters);
|
||||||
|
dataRecorderMode_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
rtabmap_->close(true, databasePath);
|
rtabmap_->close(true, databasePath);
|
||||||
rtabmap_->init(getRtabmapParameters(), databasePath);
|
rtabmap_->init(getRtabmapParameters(), dataRecorderMode_?"":databasePath);
|
||||||
|
if(dataRecorderMode_)
|
||||||
|
{
|
||||||
|
clearSceneOnNextRender_ = true;
|
||||||
|
}
|
||||||
rtabmapThread_->start();
|
rtabmapThread_->start();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RTABMapApp::exportMesh(const std::string & filePath)
|
bool RTABMapApp::exportMesh(const std::string & filePath)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
|
|
||||||
void onCreate(JNIEnv* env, jobject caller_activity);
|
void onCreate(JNIEnv* env, jobject caller_activity);
|
||||||
|
|
||||||
void openDatabase(const std::string & databasePath);
|
void openDatabase(const std::string & databasePath = "");
|
||||||
|
|
||||||
bool onTangoServiceConnected(JNIEnv* env, jobject iBinder);
|
bool onTangoServiceConnected(JNIEnv* env, jobject iBinder);
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ Java_com_introlab_rtabmap_RTABMapLib_onCreate(
|
|||||||
return app.onCreate(env, activity);
|
return app.onCreate(env, activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_com_introlab_rtabmap_RTABMapLib_openEmptyDatabase(
|
||||||
|
JNIEnv* env, jobject)
|
||||||
|
{
|
||||||
|
return app.openDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
|
Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
|
||||||
JNIEnv* env, jobject, jstring databasePath)
|
JNIEnv* env, jobject, jstring databasePath)
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
|
|
||||||
private String mOpenedDatabasePath = "";
|
private String mOpenedDatabasePath = "";
|
||||||
private String mTempDatabasePath = "";
|
|
||||||
private String mWorkingDirectory = "";
|
private String mWorkingDirectory = "";
|
||||||
|
|
||||||
private int mMaxDepthIndex = 5;
|
private int mMaxDepthIndex = 5;
|
||||||
@@ -177,7 +176,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mOpenedDatabasePath = "";
|
mOpenedDatabasePath = "";
|
||||||
mTempDatabasePath = "";
|
|
||||||
mWorkingDirectory = "";
|
mWorkingDirectory = "";
|
||||||
mTotalLoopClosures = 0;
|
mTotalLoopClosures = 0;
|
||||||
|
|
||||||
@@ -187,13 +185,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mWorkingDirectory = extStore.getAbsolutePath() + "/" + getString(R.string.app_name) + "/";
|
mWorkingDirectory = extStore.getAbsolutePath() + "/" + getString(R.string.app_name) + "/";
|
||||||
extStore = new File(mWorkingDirectory);
|
extStore = new File(mWorkingDirectory);
|
||||||
extStore.mkdirs();
|
extStore.mkdirs();
|
||||||
mTempDatabasePath = mWorkingDirectory + "rtabmap.tmp.db";
|
|
||||||
extStore = new File(mTempDatabasePath);
|
|
||||||
|
|
||||||
if(extStore.exists())
|
|
||||||
{
|
|
||||||
extStore.delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -204,7 +195,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RTABMapLib.onCreate(this);
|
RTABMapLib.onCreate(this);
|
||||||
RTABMapLib.openDatabase(mTempDatabasePath);
|
RTABMapLib.openEmptyDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -908,7 +899,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
if(which >=0 && which < mUpdateRateValues.length)
|
if(which >=0 && which < mUpdateRateValues.length)
|
||||||
{
|
{
|
||||||
mParamUpdateRateHzIndex = which;
|
mParamUpdateRateHzIndex = which;
|
||||||
if(RTABMapLib.setMappingParameter("Rtabmap/DetectionRate", mUpdateRateValues[which]) != 0)
|
if(RTABMapLib.setMappingParameter("Rtabmap/DetectionRate", which == mUpdateRateValues.length-1?"0":mUpdateRateValues[which]) != 0)
|
||||||
{
|
{
|
||||||
mToast.makeText(getActivity(), "Failed to set parameter \"Rtabmap/DetectionRate\"!", mToast.LENGTH_LONG).show();
|
mToast.makeText(getActivity(), "Failed to set parameter \"Rtabmap/DetectionRate\"!", mToast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
@@ -1082,7 +1073,10 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
notificationManager.notify(0, n);
|
notificationManager.notify(0, n);
|
||||||
}
|
}
|
||||||
mOpenedDatabasePath = newDatabasePath;
|
if(!mItemDataRecorderMode.isChecked())
|
||||||
|
{
|
||||||
|
mOpenedDatabasePath = newDatabasePath;
|
||||||
|
}
|
||||||
mProgressDialog.dismiss();
|
mProgressDialog.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1144,7 +1138,10 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
notificationManager.notify(0, n);
|
notificationManager.notify(0, n);
|
||||||
}
|
}
|
||||||
mOpenedDatabasePath = newDatabasePath;
|
if(!mItemDataRecorderMode.isChecked())
|
||||||
|
{
|
||||||
|
mOpenedDatabasePath = newDatabasePath;
|
||||||
|
}
|
||||||
mProgressDialog.dismiss();
|
mProgressDialog.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1180,7 +1177,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
mOpenedDatabasePath = "";
|
mOpenedDatabasePath = "";
|
||||||
RTABMapLib.openDatabase(mTempDatabasePath);
|
RTABMapLib.openEmptyDatabase();
|
||||||
}
|
}
|
||||||
mMapIsEmpty = true;
|
mMapIsEmpty = true;
|
||||||
}
|
}
|
||||||
@@ -1211,7 +1208,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
RTABMapLib.setDataRecorderMode(mItemDataRecorderMode.isChecked());
|
RTABMapLib.setDataRecorderMode(mItemDataRecorderMode.isChecked());
|
||||||
|
|
||||||
mOpenedDatabasePath = "";
|
mOpenedDatabasePath = "";
|
||||||
RTABMapLib.openDatabase(mTempDatabasePath);
|
RTABMapLib.openEmptyDatabase();
|
||||||
|
|
||||||
mItemOpen.setEnabled(!mItemDataRecorderMode.isChecked() && mItemPause.isChecked());
|
mItemOpen.setEnabled(!mItemDataRecorderMode.isChecked() && mItemPause.isChecked());
|
||||||
mItemPostProcessing.setEnabled(!mItemDataRecorderMode.isChecked() && mItemPause.isChecked());
|
mItemPostProcessing.setEnabled(!mItemDataRecorderMode.isChecked() && mItemPause.isChecked());
|
||||||
@@ -1437,12 +1434,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
RTABMapLib.openDatabase(mOpenedDatabasePath);
|
RTABMapLib.openDatabase(mOpenedDatabasePath);
|
||||||
RTABMapLib.setCamera(1);
|
RTABMapLib.setCamera(1);
|
||||||
|
|
||||||
File extStore = new File(mTempDatabasePath);
|
|
||||||
if(extStore.exists())
|
|
||||||
{
|
|
||||||
extStore.delete();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.show();
|
builder.show();
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public class RTABMapLib
|
|||||||
// The activity object is used for checking if the API version is outdated.
|
// The activity object is used for checking if the API version is outdated.
|
||||||
public static native void onCreate(RTABMapActivity activity);
|
public static native void onCreate(RTABMapActivity activity);
|
||||||
|
|
||||||
|
public static native void openEmptyDatabase();
|
||||||
public static native void openDatabase(String databasePath);
|
public static native void openDatabase(String databasePath);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -314,24 +314,29 @@ bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwri
|
|||||||
// Open a database connection
|
// Open a database connection
|
||||||
_ppDb = 0;
|
_ppDb = 0;
|
||||||
|
|
||||||
if(url.empty())
|
|
||||||
{
|
|
||||||
UERROR("url is empty...");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
bool dbFileExist = UFile::exists(url.c_str());
|
bool dbFileExist = false;
|
||||||
if(dbFileExist && overwritten)
|
if(!url.empty())
|
||||||
{
|
{
|
||||||
UINFO("Deleting database %s...", url.c_str());
|
dbFileExist = UFile::exists(url.c_str());
|
||||||
UASSERT(UFile::erase(url.c_str()) == 0);
|
if(dbFileExist && overwritten)
|
||||||
dbFileExist = false;
|
{
|
||||||
|
UINFO("Deleting database %s...", url.c_str());
|
||||||
|
UASSERT(UFile::erase(url.c_str()) == 0);
|
||||||
|
dbFileExist = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_dbInMemory)
|
if(_dbInMemory || url.empty())
|
||||||
{
|
{
|
||||||
ULOGGER_INFO("Using database \"%s\" in the memory.", url.c_str());
|
if(!url.empty())
|
||||||
|
{
|
||||||
|
ULOGGER_INFO("Using database \"%s\" in the memory.", url.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ULOGGER_INFO("Using empty database in the memory.");
|
||||||
|
}
|
||||||
rc = sqlite3_open_v2(":memory:", &_ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
rc = sqlite3_open_v2(":memory:", &_ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -364,7 +369,10 @@ bool DBDriverSqlite3::connectDatabaseQuery(const std::string & url, bool overwri
|
|||||||
|
|
||||||
if(!dbFileExist)
|
if(!dbFileExist)
|
||||||
{
|
{
|
||||||
ULOGGER_INFO("Database \"%s\" doesn't exist, creating a new one...", url.c_str());
|
if(!url.empty())
|
||||||
|
{
|
||||||
|
ULOGGER_INFO("Database \"%s\" doesn't exist, creating a new one...", url.c_str());
|
||||||
|
}
|
||||||
// Create the database
|
// Create the database
|
||||||
std::string schema = DATABASESCHEMA_SQL;
|
std::string schema = DATABASESCHEMA_SQL;
|
||||||
schema = uHex2Str(schema);
|
schema = uHex2Str(schema);
|
||||||
@@ -407,7 +415,7 @@ void DBDriverSqlite3::disconnectDatabaseQuery(bool save, const std::string & out
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(save && _dbInMemory)
|
if(save && (_dbInMemory || this->getUrl().empty()))
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
@@ -416,10 +424,18 @@ void DBDriverSqlite3::disconnectDatabaseQuery(bool save, const std::string & out
|
|||||||
{
|
{
|
||||||
outputFile = outputUrl;
|
outputFile = outputUrl;
|
||||||
}
|
}
|
||||||
UINFO("Saving database to %s ...", outputFile.c_str());
|
if(outputFile.empty())
|
||||||
rc = loadOrSaveDb(_ppDb, outputFile, 1); // Save memory to file
|
{
|
||||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
UERROR("Database was initialized with an empty url (in memory). To save it "
|
||||||
ULOGGER_DEBUG("Saving DB time = %fs", timer.ticks());
|
"the output url should not be empty. The database is thus closed without being saved!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINFO("Saving database to %s ...", outputFile.c_str());
|
||||||
|
rc = loadOrSaveDb(_ppDb, outputFile, 1); // Save memory to file
|
||||||
|
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||||
|
ULOGGER_DEBUG("Saving DB time = %fs", timer.ticks());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(save && !outputUrl.empty() && outputUrl.compare(this->getUrl()) != 0)
|
else if(save && !outputUrl.empty() && outputUrl.compare(this->getUrl()) != 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ bool Memory::init(const std::string & dbUrl, bool dbOverwritten, const Parameter
|
|||||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit("Closing database connection, done!"));
|
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit("Closing database connection, done!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_dbDriver == 0 && !dbUrl.empty())
|
if(_dbDriver == 0)
|
||||||
{
|
{
|
||||||
_dbDriver = DBDriver::create(parameters);
|
_dbDriver = DBDriver::create(parameters);
|
||||||
}
|
}
|
||||||
@@ -161,11 +161,11 @@ bool Memory::init(const std::string & dbUrl, bool dbOverwritten, const Parameter
|
|||||||
{
|
{
|
||||||
_dbDriver->setTimestampUpdateEnabled(true); // make sure that timestamp update is enabled (may be disabled above)
|
_dbDriver->setTimestampUpdateEnabled(true); // make sure that timestamp update is enabled (may be disabled above)
|
||||||
success = false;
|
success = false;
|
||||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(std::string("Connecting to database ") + dbUrl + "..."));
|
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(std::string("Connecting to database \"") + dbUrl + "\"..."));
|
||||||
if(_dbDriver->openConnection(dbUrl, dbOverwritten))
|
if(_dbDriver->openConnection(dbUrl, dbOverwritten))
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(std::string("Connecting to database ") + dbUrl + ", done!"));
|
if(postInitClosingEvents) UEventsManager::post(new RtabmapEventInit(std::string("Connecting to database \"") + dbUrl + "\", done!"));
|
||||||
|
|
||||||
// Load the last working memory...
|
// Load the last working memory...
|
||||||
std::list<Signature*> dbSignatures;
|
std::list<Signature*> dbSignatures;
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ void Rtabmap::init(const ParametersMap & parameters, const std::string & databas
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UWARN("Using empty database. Mapping session will not be saved.");
|
UWARN("Using empty database. Mapping session will not be saved unless it is closed with an output database path.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool newDatabase = _databasePath.empty() || !UFile::exists(_databasePath);
|
bool newDatabase = _databasePath.empty() || !UFile::exists(_databasePath);
|
||||||
|
|||||||
Reference in New Issue
Block a user