Added recovery feature to android

This commit is contained in:
matlabbe
2022-01-02 18:09:57 -05:00
parent 3147b4ab56
commit f3ace6c86a
9 changed files with 125 additions and 37 deletions

View File

@@ -20,7 +20,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
####################### #######################
SET(RTABMAP_MAJOR_VERSION 0) SET(RTABMAP_MAJOR_VERSION 0)
SET(RTABMAP_MINOR_VERSION 20) SET(RTABMAP_MINOR_VERSION 20)
SET(RTABMAP_PATCH_VERSION 16) SET(RTABMAP_PATCH_VERSION 17)
SET(RTABMAP_VERSION SET(RTABMAP_VERSION
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION}) ${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})

View File

@@ -89,13 +89,13 @@ Java_com_introlab_rtabmap_RTABMapLib_setScreenRotation(
JNIEXPORT int JNICALL JNIEXPORT int JNICALL
Java_com_introlab_rtabmap_RTABMapLib_openDatabase( Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
JNIEnv* env, jclass, jlong native_application, jstring databasePath, bool databaseInMemory, bool optimize) JNIEnv* env, jclass, jlong native_application, jstring databasePath, bool databaseInMemory, bool optimize, bool clearDatabase)
{ {
std::string databasePathC; std::string databasePathC;
GetJStringContent(env,databasePath,databasePathC); GetJStringContent(env,databasePath,databasePathC);
if(native_application) if(native_application)
{ {
return native(native_application)->openDatabase(databasePathC, databaseInMemory, optimize); return native(native_application)->openDatabase(databasePathC, databaseInMemory, optimize, clearDatabase);
} }
else else
{ {
@@ -104,17 +104,17 @@ Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
} }
} }
JNIEXPORT int JNICALL JNIEXPORT bool JNICALL
Java_com_introlab_rtabmap_RTABMapLib_openDatabase2( Java_com_introlab_rtabmap_RTABMapLib_recover(
JNIEnv* env, jclass, jlong native_application, jstring databaseSource, jstring databasePath, bool databaseInMemory, bool optimize) JNIEnv* env, jclass, jlong native_application, jstring from, jstring to)
{ {
if(native_application) if(native_application)
{ {
std::string databasePathC; std::string toC;
GetJStringContent(env,databasePath,databasePathC); GetJStringContent(env,to,toC);
std::string databaseSourceC; std::string fromC;
GetJStringContent(env,databaseSource,databaseSourceC); GetJStringContent(env,from,fromC);
return native(native_application)->openDatabase(databasePathC, databaseInMemory, optimize, databaseSourceC); return native(native_application)->recover(fromC, toC);
} }
else else
{ {

View File

@@ -108,7 +108,7 @@
<string name="pref_key_features_type">pref_key_features_type</string> <string name="pref_key_features_type">pref_key_features_type</string>
<string name="pref_default_features_type">6</string> <string name="pref_default_features_type">6</string>
<string name="pref_key_optimizer">pref_key_optimizer</string> <string name="pref_key_optimizer">pref_key_optimizer</string>
<string name="pref_default_optimizer">1</string> <string name="pref_default_optimizer">2</string>
<string name="pref_key_optimize_end">pref_key_optimize_end</string> <string name="pref_key_optimize_end">pref_key_optimize_end</string>
<string name="pref_default_optimize_end">true</string> <string name="pref_default_optimize_end">true</string>
<string name="pref_key_marker_detection">pref_key_marker_detection</string> <string name="pref_key_marker_detection">pref_key_marker_detection</string>

View File

@@ -595,12 +595,6 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
{ {
Log.i(TAG, "postCreate()"); Log.i(TAG, "postCreate()");
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
(new File(tmpDatabase)).delete();
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
boolean databaseInMemory = sharedPref.getBoolean(getString(R.string.pref_key_db_in_memory), Boolean.parseBoolean(getString(R.string.pref_default_db_in_memory)));
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false);
final String[] files = Util.loadFileList(mWorkingDirectory, true); final String[] files = Util.loadFileList(mWorkingDirectory, true);
if(files.length == 0) if(files.length == 0)
{ {
@@ -2626,7 +2620,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity()); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
boolean databaseInMemory = sharedPref.getBoolean(getString(R.string.pref_key_db_in_memory), Boolean.parseBoolean(getString(R.string.pref_default_db_in_memory))); boolean databaseInMemory = sharedPref.getBoolean(getString(R.string.pref_key_db_in_memory), Boolean.parseBoolean(getString(R.string.pref_default_db_in_memory)));
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB; String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false); RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false, true);
mItemLocalizationMode.setEnabled(!mItemDataRecorderMode.isChecked()); mItemLocalizationMode.setEnabled(!mItemDataRecorderMode.isChecked());
@@ -2780,16 +2774,110 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
mOpenedDatabasePath = ""; mOpenedDatabasePath = "";
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
boolean databaseInMemory = sharedPref.getBoolean(getString(R.string.pref_key_db_in_memory), Boolean.parseBoolean(getString(R.string.pref_default_db_in_memory))); boolean databaseInMemory = sharedPref.getBoolean(getString(R.string.pref_key_db_in_memory), Boolean.parseBoolean(getString(R.string.pref_default_db_in_memory)));
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB; final String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false);
File newFile = new File(tmpDatabase);
if(!(mState == State.STATE_CAMERA || mState ==State.STATE_MAPPING)) final int fileSizeMB = (int)newFile.length()/(1024 * 1024);
if(!(mState == State.STATE_CAMERA || mState ==State.STATE_MAPPING) &&
newFile.exists() &&
fileSizeMB>1) // >1MB
{ {
setCamera(1); AlertDialog d2 = new AlertDialog.Builder(getActivity())
startCamera(String.format("Hold Tight! Initializing Camera Service...\n" .setCancelable(false)
+ "Tip: If the camera is still drifting just after the mapping has started, do \"Reset\".")); .setTitle("Recovery")
.setMessage(String.format("The previous session (%d MB) was not correctly saved, do you want to recover it?", fileSizeMB))
.setNegativeButton("Ignore", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
(new File(tmpDatabase)).delete();
newScan();
}
})
.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final String fileName = new SimpleDateFormat("yyMMdd-HHmmss").format(new Date()) + ".db";
final String outputDbPath = mWorkingDirectory + fileName;
mExportProgressDialog.setTitle("Recovering");
mExportProgressDialog.setMessage(String.format("Please wait while recovering data..."));
mExportProgressDialog.setProgress(0);
final State previousState = mState;
mExportProgressDialog.show();
updateState(State.STATE_PROCESSING);
Thread exportThread = new Thread(new Runnable() {
public void run() {
final long startTime = System.currentTimeMillis()/1000;
final boolean success = RTABMapLib.recover(
nativeApplication,
tmpDatabase,
outputDbPath);
runOnUiThread(new Runnable() {
public void run() {
if(mExportProgressDialog.isShowing())
{
if(success)
{
AlertDialog d2 = new AlertDialog.Builder(getActivity())
.setCancelable(false)
.setTitle("Database saved!")
.setMessage(String.format("Database \"%s\" (%d MB) successfully saved!", fileName, fileSizeMB))
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
openDatabase(fileName, false);
}
})
.create();
d2.setCanceledOnTouchOutside(true);
d2.show();
}
else
{
updateState(previousState);
mToast.makeText(getActivity(), String.format("Recovery failed!"), mToast.LENGTH_LONG).show();
}
mExportProgressDialog.dismiss();
}
else
{
mToast.makeText(getActivity(), String.format("Recovery canceled"), mToast.LENGTH_LONG).show();
updateState(previousState);
}
}
});
}
});
exportThread.start();
refreshSystemMediaScanDataBase(getActivity(), outputDbPath);
}
})
.create();
d2.setCanceledOnTouchOutside(false);
d2.show();
}
else
{
RTABMapLib.openDatabase(nativeApplication, tmpDatabase, databaseInMemory, false, true);
if(!(mState == State.STATE_CAMERA || mState ==State.STATE_MAPPING))
{
setCamera(0);
startCamera(String.format("Hold Tight! Initializing Camera Service...\n"
+ "Tip: If the camera is still drifting just after the mapping has started, do \"Reset\"."));
}
} }
} }
private void openDatabase() private void openDatabase()
{ {
@@ -3280,7 +3368,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
AlertDialog d2 = new AlertDialog.Builder(getActivity()) AlertDialog d2 = new AlertDialog.Builder(getActivity())
.setCancelable(false) .setCancelable(false)
.setTitle("Database saved!") .setTitle("Database saved!")
.setMessage(String.format("Database \"%s\" (%d MB) successfully saved on the SD-CARD!", newDatabasePathHuman, fileSizeMB)) .setMessage(String.format("Database \"%s\" (%d MB) successfully saved!", newDatabasePathHuman, fileSizeMB))
.setPositiveButton("OK", new DialogInterface.OnClickListener() { .setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
resetNoTouchTimer(true); resetNoTouchTimer(true);
@@ -3371,7 +3459,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
{ {
Log.i(TAG, String.format("Write exported mesh to \"%s\"", fileName)); Log.i(TAG, String.format("Write exported mesh to \"%s\"", fileName));
mProgressDialog.setTitle("Saving to sd-card"); mProgressDialog.setTitle("Exporting");
mProgressDialog.setMessage(String.format("Compressing the files...")); mProgressDialog.setMessage(String.format("Compressing the files..."));
mProgressDialog.show(); mProgressDialog.show();
@@ -3443,7 +3531,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
AlertDialog d = new AlertDialog.Builder(getActivity()) AlertDialog d = new AlertDialog.Builder(getActivity())
.setCancelable(false) .setCancelable(false)
.setTitle("Mesh Saved!") .setTitle("Mesh Saved!")
.setMessage(String.format("Mesh \"%s\" (%d MB) successfully exported on the SD-CARD! Share it?", pathHuman, fileSizeMB)) .setMessage(String.format("Mesh \"%s\" (%d MB) successfully exported! Share it?", pathHuman, fileSizeMB))
.setPositiveButton("Yes", new DialogInterface.OnClickListener() { .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
// Send to... // Send to...
@@ -3498,8 +3586,7 @@ public class RTABMapActivity extends FragmentActivity implements OnClickListener
Thread openThread = new Thread(new Runnable() { Thread openThread = new Thread(new Runnable() {
public void run() { public void run() {
final String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB; final int status = RTABMapLib.openDatabase(nativeApplication, mOpenedDatabasePath, databaseInMemory, optimize, false);
final int status = RTABMapLib.openDatabase2(nativeApplication, mOpenedDatabasePath, tmpDatabase, databaseInMemory, optimize);
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {

View File

@@ -34,9 +34,10 @@ public class RTABMapLib
public static native void setScreenRotation(long nativeApplication, int displayRotation, int cameraRotation); public static native void setScreenRotation(long nativeApplication, int displayRotation, int cameraRotation);
public static native int openDatabase(long nativeApplication, String databasePath, boolean databaseInMemory, boolean optimize); public static native int openDatabase(long nativeApplication, String databasePath, boolean databaseInMemory, boolean optimize, boolean clearDatabase);
public static native int openDatabase2(long nativeApplication, String databaseSource, String databasePath, boolean databaseInMemory, boolean optimize);
public static native boolean recover(long nativeApplication, String from, String to);
public static native boolean isBuiltWith(long nativeApplication, int cameraDriver); public static native boolean isBuiltWith(long nativeApplication, int cameraDriver);
public static native boolean startCamera(long nativeApplication, IBinder binder, Context context, Activity activity, int driver); public static native boolean startCamera(long nativeApplication, IBinder binder, Context context, Activity activity, int driver);
public static native void stopCamera(long nativeApplication); public static native void stopCamera(long nativeApplication);

View File

@@ -1006,7 +1006,7 @@
"$(PROJECT_DIR)/RTABMapApp/Libraries/lib", "$(PROJECT_DIR)/RTABMapApp/Libraries/lib",
"$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib", "$(PROJECT_DIR)/RTABMapApp/Libraries/share/OpenCV/3rdparty/lib",
); );
MARKETING_VERSION = "0.20.16-2"; MARKETING_VERSION = "0.20.17";
OTHER_CFLAGS = ""; OTHER_CFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap; PRODUCT_BUNDLE_IDENTIFIER = com.introlab.rtabmap;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -13,7 +13,7 @@
<string> <string>
======= RTAB-Map ======= ======= RTAB-Map =======
RTAB-Map - https://github.com/introlab/rtabmap RTAB-Map - https://github.com/introlab/rtabmap
Copyright (c) 2010-2021, Mathieu Labbe - IntRoLab - Universite de Sherbrooke, all rights reserved. Copyright (c) 2010-2022, Mathieu Labbe - IntRoLab - Universite de Sherbrooke, all rights reserved.
Copyright (c) XXX, contributors, all rights reserved. Copyright (c) XXX, contributors, all rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@@ -454,7 +454,7 @@
</dict> </dict>
<dict> <dict>
<key>FooterText</key> <key>FooterText</key>
<string>Copyright (c) 2010-2021, Mathieu Labbe - IntRoLab - Université de Sherbrooke. All rights reserved.</string> <string>Copyright (c) 2010-2022, Mathieu Labbe - IntRoLab - Université de Sherbrooke. All rights reserved.</string>
<key>Title</key> <key>Title</key>
<string>About</string> <string>About</string>
<key>Type</key> <key>Type</key>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<package> <package>
<name>rtabmap</name> <name>rtabmap</name>
<version>0.20.16</version> <version>0.20.17</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="matlabbe@gmail.com">Mathieu Labbe</maintainer> <maintainer email="matlabbe@gmail.com">Mathieu Labbe</maintainer>
<author>Mathieu Labbe</author> <author>Mathieu Labbe</author>