mirror of
https://github.com/introlab/rtabmap_ros.git
synced 2026-10-04 00:37:46 +08:00
0.14: added gps field to Node table in database (#226). Tango: saving gps if enabled, added Rename/Remove/Share on long click in Open dialog (fixed #233)
This commit is contained in:
+2
-2
@@ -20,8 +20,8 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
||||
# VERSION
|
||||
#######################
|
||||
SET(RTABMAP_MAJOR_VERSION 0)
|
||||
SET(RTABMAP_MINOR_VERSION 13)
|
||||
SET(RTABMAP_PATCH_VERSION 3)
|
||||
SET(RTABMAP_MINOR_VERSION 14)
|
||||
SET(RTABMAP_PATCH_VERSION 0)
|
||||
SET(RTABMAP_VERSION
|
||||
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-feature android:name="android.hardware.location.gps" />
|
||||
<uses-feature android:glEsVersion="0x00020000" />
|
||||
|
||||
<!-- This is the platform API where NativeActivity was introduced. -->
|
||||
|
||||
@@ -116,7 +116,8 @@ CameraTango::CameraTango(bool colorCamera, int decimation, bool publishRawScan,
|
||||
cloudStamp_(0),
|
||||
tangoColorType_(0),
|
||||
tangoColorStamp_(0),
|
||||
colorCameraToDisplayRotation_(ROTATION_0)
|
||||
colorCameraToDisplayRotation_(ROTATION_0),
|
||||
lastKnownGPS_(std::vector<double>(6,0))
|
||||
{
|
||||
UASSERT(decimation >= 1);
|
||||
}
|
||||
@@ -189,6 +190,8 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
|
||||
{
|
||||
close();
|
||||
|
||||
lastKnownGPS_ = std::vector<double>(6,0);
|
||||
|
||||
TangoSupport_initialize(TangoService_getPoseAtTime, TangoService_getCameraIntrinsics);
|
||||
|
||||
// Connect to Tango
|
||||
@@ -513,6 +516,21 @@ std::string CameraTango::getSerial() const
|
||||
return "Tango";
|
||||
}
|
||||
|
||||
void CameraTango::setGPS(double stamp,
|
||||
double longitude,
|
||||
double latitude,
|
||||
double altitude,
|
||||
double accuracy,
|
||||
double bearing)
|
||||
{
|
||||
lastKnownGPS_[0] = stamp;
|
||||
lastKnownGPS_[1] = longitude;
|
||||
lastKnownGPS_[2] = latitude;
|
||||
lastKnownGPS_[3] = altitude;
|
||||
lastKnownGPS_[4] = accuracy;
|
||||
lastKnownGPS_[5] = bearing;
|
||||
}
|
||||
|
||||
rtabmap::Transform CameraTango::tangoPoseToTransform(const TangoPoseData * tangoPose) const
|
||||
{
|
||||
UASSERT(tangoPose);
|
||||
@@ -837,6 +855,15 @@ SensorData CameraTango::captureImage(CameraInfo * info)
|
||||
data = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp);
|
||||
}
|
||||
data.setGroundTruth(odom);
|
||||
|
||||
if(lastKnownGPS_[0] > 0.0 && rgbStamp-lastKnownGPS_[0]<2.0)
|
||||
{
|
||||
data.setGPS(lastKnownGPS_[0], lastKnownGPS_[1], lastKnownGPS_[2], lastKnownGPS_[3], lastKnownGPS_[4], lastKnownGPS_[5]);
|
||||
}
|
||||
else if(lastKnownGPS_[0]>0.0)
|
||||
{
|
||||
LOGD("GPS too old (current time=%f, gps time = %f)", rgbStamp, lastKnownGPS_[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -89,6 +89,12 @@ public:
|
||||
void setSmoothing(bool enabled) {smoothing_ = enabled;}
|
||||
void setRawScanPublished(bool enabled) {rawScanPublished_ = enabled;}
|
||||
void setScreenRotation(TangoSupportRotation colorCameraToDisplayRotation) {colorCameraToDisplayRotation_ = colorCameraToDisplayRotation;}
|
||||
void setGPS(double stamp,
|
||||
double longitude,
|
||||
double latitude,
|
||||
double altitude,
|
||||
double accuracy,
|
||||
double bearing);
|
||||
|
||||
void cloudReceived(const cv::Mat & cloud, double timestamp);
|
||||
void rgbReceived(const cv::Mat & tangoImage, int type, double timestamp);
|
||||
@@ -126,6 +132,7 @@ private:
|
||||
TangoSupportRotation colorCameraToDisplayRotation_;
|
||||
cv::Mat fisheyeRectifyMapX_;
|
||||
cv::Mat fisheyeRectifyMapY_;
|
||||
std::vector<double> lastKnownGPS_;
|
||||
};
|
||||
|
||||
} /* namespace rtabmap */
|
||||
|
||||
@@ -1975,6 +1975,19 @@ int RTABMapApp::setMappingParameter(const std::string & key, const std::string &
|
||||
}
|
||||
}
|
||||
|
||||
void RTABMapApp::setGPS(double stamp,
|
||||
double longitude,
|
||||
double latitude,
|
||||
double altitude,
|
||||
double accuracy,
|
||||
double bearing)
|
||||
{
|
||||
if(camera_)
|
||||
{
|
||||
camera_->setGPS(stamp, longitude, latitude, altitude, accuracy, bearing);
|
||||
}
|
||||
}
|
||||
|
||||
void RTABMapApp::resetMapping()
|
||||
{
|
||||
LOGW("Reset!");
|
||||
|
||||
@@ -147,6 +147,12 @@ class RTABMapApp : public UEventsHandler {
|
||||
void setRenderingTextureDecimation(int value);
|
||||
void setBackgroundColor(float gray);
|
||||
int setMappingParameter(const std::string & key, const std::string & value);
|
||||
void setGPS(double stamp,
|
||||
double longitude,
|
||||
double latitude,
|
||||
double altitude,
|
||||
double accuracy,
|
||||
double bearing);
|
||||
|
||||
void resetMapping();
|
||||
void save(const std::string & databasePath);
|
||||
|
||||
@@ -339,6 +339,24 @@ Java_com_introlab_rtabmap_RTABMapLib_setMappingParameter(
|
||||
return app.setMappingParameter(keyC, valueC);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_setGPS(
|
||||
JNIEnv*, jobject,
|
||||
double stamp,
|
||||
double longitude,
|
||||
double latitude,
|
||||
double altitude,
|
||||
double accuracy,
|
||||
double bearing)
|
||||
{
|
||||
return app.setGPS(stamp,
|
||||
longitude,
|
||||
latitude,
|
||||
altitude,
|
||||
accuracy,
|
||||
bearing);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_introlab_rtabmap_RTABMapLib_resetMapping(
|
||||
JNIEnv*, jobject)
|
||||
|
||||
@@ -197,6 +197,11 @@
|
||||
android:title="@string/pref_title_raw_scan_saved"
|
||||
android:summary="@string/pref_summary_raw_scan_saved"
|
||||
android:defaultValue="@string/pref_default_raw_scan_saved"/>
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_gps_saved"
|
||||
android:title="@string/pref_title_gps_saved"
|
||||
android:summary="@string/pref_summary_gps_saved"
|
||||
android:defaultValue="@string/pref_default_gps_saved"/>
|
||||
<SwitchPreference
|
||||
android:key="@string/pref_key_db_in_memory"
|
||||
android:title="@string/pref_title_db_in_memory"
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
<string name="memory">"Used Memory (MB): "</string>
|
||||
<string name="hypothesis">"Hypothesis (%): "</string>
|
||||
<string name="fps">"FPS (rendering): "</string>
|
||||
<string name="gps">"GPS (long,lat,alt,bearing,acc): "</string>
|
||||
<string name="time">"Time: "</string>
|
||||
|
||||
<!-- Preference keys: BEGIN -->
|
||||
<string name="pref_key_tags">pref_key_tags</string>
|
||||
@@ -101,6 +103,8 @@
|
||||
<string name="pref_default_keep_all_db">true</string>
|
||||
<string name="pref_key_raw_scan_saved">pref_key_raw_scan_saved</string>
|
||||
<string name="pref_default_raw_scan_saved">false</string>
|
||||
<string name="pref_key_gps_saved">pref_key_gps_saved</string>
|
||||
<string name="pref_default_gps_saved">false</string>
|
||||
<string name="pref_key_db_in_memory">pref_key_db_in_memory</string>
|
||||
<string name="pref_default_db_in_memory">true</string>
|
||||
|
||||
@@ -339,6 +343,8 @@
|
||||
<string name="pref_summary_keep_all_db">Discarded frames while not moving are still saved in database. Useful to replay exactly the scanning on RTAB-Map Desktop.</string>
|
||||
<string name="pref_title_raw_scan_saved">Save Raw Scan</string>
|
||||
<string name="pref_summary_raw_scan_saved">Save raw point clouds in database.</string>
|
||||
<string name="pref_title_gps_saved">Save GPS</string>
|
||||
<string name="pref_summary_gps_saved">Save GPS in database.</string>
|
||||
<string name="pref_title_db_in_memory">Database In Memory</string>
|
||||
<string name="pref_summary_db_in_memory">The database is kept in RAM for fast access. Set to false to reduce RAM used at the cost of slower access. This parameter is applied on reset or when a database is opened.</string>
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.app.ProgressDialog;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnShowListener;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.SharedPreferences;
|
||||
@@ -50,8 +51,15 @@ import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.hardware.Camera;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
import android.hardware.SensorManager;
|
||||
import android.graphics.Point;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.Uri;
|
||||
@@ -74,15 +82,19 @@ import android.text.method.LinkMovementMethod;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.Display;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MenuItem.OnMenuItemClickListener;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnCreateContextMenuListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
@@ -90,11 +102,13 @@ import android.view.inputmethod.EditorInfo;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.NumberPicker;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.SeekBar;
|
||||
@@ -108,7 +122,7 @@ import com.google.atap.tangoservice.Tango;
|
||||
|
||||
// The main activity of the application. This activity shows debug information
|
||||
// and a glSurfaceView that renders graphic content.
|
||||
public class RTABMapActivity extends Activity implements OnClickListener, OnItemSelectedListener {
|
||||
public class RTABMapActivity extends Activity implements OnClickListener, OnItemSelectedListener, SensorEventListener {
|
||||
|
||||
// Tag for debug logging.
|
||||
public static final String TAG = RTABMapActivity.class.getSimpleName();
|
||||
@@ -206,6 +220,12 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
private String mLoopThr;
|
||||
private String mMinInliers;
|
||||
private String mMaxOptimizationError;
|
||||
|
||||
private LocationManager mLocationManager;
|
||||
private LocationListener mLocationListener;
|
||||
private Location mLastKnownLocation;
|
||||
private SensorManager mSensorManager;
|
||||
private float mCompassDeg = 0.0f;
|
||||
|
||||
private int mTotalLoopClosures = 0;
|
||||
private boolean mMapIsEmpty = false;
|
||||
@@ -454,30 +474,69 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
RTABMapLib.openDatabase(tmpDatabase, databaseInMemory, false);
|
||||
|
||||
DisplayManager displayManager = (DisplayManager) getSystemService(DISPLAY_SERVICE);
|
||||
if (displayManager != null) {
|
||||
displayManager.registerDisplayListener(new DisplayManager.DisplayListener() {
|
||||
@Override
|
||||
public void onDisplayAdded(int displayId) {
|
||||
if (displayManager != null) {
|
||||
displayManager.registerDisplayListener(new DisplayManager.DisplayListener() {
|
||||
@Override
|
||||
public void onDisplayAdded(int displayId) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayChanged(int displayId) {
|
||||
synchronized (this) {
|
||||
setAndroidOrientation();
|
||||
Display display = getWindowManager().getDefaultDisplay();
|
||||
display.getSize(mScreenSize);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onDisplayChanged(int displayId) {
|
||||
synchronized (this) {
|
||||
setAndroidOrientation();
|
||||
Display display = getWindowManager().getDefaultDisplay();
|
||||
display.getSize(mScreenSize);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayRemoved(int displayId) {}
|
||||
}, null);
|
||||
}
|
||||
|
||||
DISABLE_LOG = !( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );
|
||||
@Override
|
||||
public void onDisplayRemoved(int displayId) {}
|
||||
}, null);
|
||||
}
|
||||
|
||||
// Acquire a reference to the system Location Manager
|
||||
mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
|
||||
|
||||
// Define a listener that responds to location updates
|
||||
mLocationListener = new LocationListener() {
|
||||
public void onLocationChanged(Location location) {
|
||||
mLastKnownLocation = location;
|
||||
double stamp = location.getTime()/1000.0;
|
||||
if(!DISABLE_LOG) Log.d(TAG, String.format("GPS received at %f (%d)", stamp, location.getTime()));
|
||||
RTABMapLib.setGPS(
|
||||
stamp,
|
||||
(double)location.getLongitude(),
|
||||
(double)location.getLatitude(),
|
||||
(double)location.getAltitude(),
|
||||
(double)location.getAccuracy(),
|
||||
(double)mCompassDeg);
|
||||
}
|
||||
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {}
|
||||
|
||||
public void onProviderEnabled(String provider) {}
|
||||
|
||||
public void onProviderDisabled(String provider) {}
|
||||
};
|
||||
|
||||
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
|
||||
|
||||
DISABLE_LOG = !( 0 != ( getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
// get the angle around the z-axis rotated
|
||||
mCompassDeg = event.values[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {
|
||||
// not in use
|
||||
}
|
||||
|
||||
|
||||
public int getStatusBarHeight() {
|
||||
int result = 0;
|
||||
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||
@@ -580,6 +639,10 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
if(!DISABLE_LOG) Log.i(TAG, "onPause()");
|
||||
mOnPause = true;
|
||||
|
||||
mLocationManager.removeUpdates(mLocationListener);
|
||||
mSensorManager.unregisterListener(this);
|
||||
|
||||
|
||||
// This deletes OpenGL context!
|
||||
mGLView.onPause();
|
||||
|
||||
@@ -619,9 +682,8 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
}
|
||||
mProgressDialog.show();
|
||||
mOnPause = false;
|
||||
|
||||
setAndroidOrientation();
|
||||
|
||||
|
||||
// update preferences
|
||||
try
|
||||
{
|
||||
@@ -640,6 +702,12 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
boolean keepAllDb = sharedPref.getBoolean(getString(R.string.pref_key_keep_all_db), Boolean.parseBoolean(getString(R.string.pref_default_keep_all_db)));
|
||||
boolean optimizeFromGraphEnd = sharedPref.getBoolean(getString(R.string.pref_key_optimize_end), Boolean.parseBoolean(getString(R.string.pref_default_optimize_end)));
|
||||
String optimizer = sharedPref.getString(getString(R.string.pref_key_optimizer), getString(R.string.pref_default_optimizer));
|
||||
boolean gpsSaved = sharedPref.getBoolean(getString(R.string.pref_key_gps_saved), Boolean.parseBoolean(getString(R.string.pref_default_gps_saved)));
|
||||
if(gpsSaved)
|
||||
{
|
||||
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
|
||||
mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME);
|
||||
}
|
||||
|
||||
if(!DISABLE_LOG) Log.d(TAG, "set mapping parameters");
|
||||
RTABMapLib.setOnlineBlending(sharedPref.getBoolean(getString(R.string.pref_key_blending), Boolean.parseBoolean(getString(R.string.pref_default_blending))));
|
||||
@@ -1065,7 +1133,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
{
|
||||
if(!DISABLE_LOG) Log.i(TAG, String.format("updateStatsCallback()"));
|
||||
|
||||
final String[] statusTexts = new String[16];
|
||||
final String[] statusTexts = new String[17];
|
||||
if(mButtonPause!=null && !mButtonPause.isChecked())
|
||||
{
|
||||
String updateValue = mUpdateRate.compareTo("0")==0?"Max":mUpdateRate;
|
||||
@@ -1101,8 +1169,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
statusTexts[1] = mStatusTexts[1];
|
||||
}
|
||||
statusTexts[2] = getString(R.string.free_memory)+getFreeMemory();
|
||||
|
||||
|
||||
|
||||
if(loopClosureId > 0)
|
||||
{
|
||||
++mTotalLoopClosures;
|
||||
@@ -1110,7 +1177,29 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
|
||||
mMapNodes = nodes;
|
||||
|
||||
int index = 4;
|
||||
if(mLastKnownLocation != null)
|
||||
{
|
||||
long millisec = System.currentTimeMillis() - mLastKnownLocation.getTime();
|
||||
if(millisec > 2000)
|
||||
{
|
||||
statusTexts[3] = getString(R.string.gps)+String.format("[too old, %d ms]", millisec);
|
||||
}
|
||||
else
|
||||
{
|
||||
statusTexts[3] = getString(R.string.gps)+
|
||||
String.format("%.2f %.2f %.2fm %.0fdeg %.0fm",
|
||||
mLastKnownLocation.getLongitude(),
|
||||
mLastKnownLocation.getLatitude(),
|
||||
mLastKnownLocation.getAltitude(),
|
||||
mCompassDeg,
|
||||
mLastKnownLocation.getAccuracy());
|
||||
}
|
||||
}
|
||||
|
||||
String formattedDate = new SimpleDateFormat("HH:mm:ss.SSS").format(new Date());
|
||||
statusTexts[4] = getString(R.string.time)+formattedDate;
|
||||
|
||||
int index = 5;
|
||||
statusTexts[index++] = getString(R.string.nodes)+nodes+" (" + nodesDrawn + " shown)";
|
||||
statusTexts[index++] = getString(R.string.words)+words;
|
||||
statusTexts[index++] = getString(R.string.database_size)+databaseMemoryUsed;
|
||||
@@ -1123,7 +1212,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
statusTexts[index++] = getString(R.string.inliers)+inliers;
|
||||
statusTexts[index++] = getString(R.string.hypothesis)+(int)(hypothesis*100.0f) +" / " + (int)(Float.parseFloat(mLoopThr)*100.0f) + " (" + (loopClosureId>0?loopClosureId:highestHypId)+")";
|
||||
statusTexts[index++] = getString(R.string.fps)+(int)fps+" Hz";
|
||||
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
updateStatsUI(adjustedMemoryUsed, loopClosureId, inliers, matches, rejected, optimizationMaxError, statusTexts);
|
||||
@@ -1489,7 +1578,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
|
||||
mMapIsEmpty = false;
|
||||
mDateOnPause = new Date();
|
||||
|
||||
|
||||
long memoryFree = getFreeMemory();
|
||||
if(!mOnPause && !mItemLocalizationMode.isChecked() && !mItemDataRecorderMode.isChecked() && memoryFree >= 100 && mMapNodes>2)
|
||||
{
|
||||
@@ -1943,54 +2032,7 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
}
|
||||
else if(itemId == R.id.open)
|
||||
{
|
||||
final String[] files = Util.loadFileList(mWorkingDirectory, true);
|
||||
if(files.length > 0)
|
||||
{
|
||||
String[] filesWithSize = new String[files.length];
|
||||
for(int i = 0; i<filesWithSize.length; ++i)
|
||||
{
|
||||
File filePath = new File(mWorkingDirectory+files[i]);
|
||||
long mb = filePath.length()/(1024*1024);
|
||||
filesWithSize[i] = files[i] + " ("+mb+" MB)";
|
||||
}
|
||||
|
||||
ArrayList<HashMap<String, String> > arrayList = new ArrayList<HashMap<String, String> >();
|
||||
for (int i = 0; i < filesWithSize.length; i++) {
|
||||
HashMap<String, String> hashMap = new HashMap<String, String>();//create a hashmap to store the data in key value pair
|
||||
hashMap.put("name", filesWithSize[i]);
|
||||
hashMap.put("path", mWorkingDirectory + files[i]);
|
||||
arrayList.add(hashMap);//add the hashmap into arrayList
|
||||
}
|
||||
String[] from = {"name", "path"};//string array
|
||||
int[] to = {R.id.textView, R.id.imageView};//int array of views id's
|
||||
DatabaseListArrayAdapter simpleAdapter = new DatabaseListArrayAdapter(this, arrayList, R.layout.database_list, from, to);//Create object and set the parameters for simpleAdapter
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Choose Your File (*.db)");
|
||||
builder.setAdapter(simpleAdapter, new DialogInterface.OnClickListener() {
|
||||
//builder.setItems(filesWithSize, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, final int which) {
|
||||
|
||||
// Adjust color now?
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle("Opening database...")
|
||||
.setMessage("Do you want to adjust colors now?\nThis can be done later under Optimize menu.")
|
||||
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichIn) {
|
||||
openDatabase(files[which], true);
|
||||
}
|
||||
})
|
||||
.setNeutralButton("No", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichIn) {
|
||||
openDatabase(files[which], false);
|
||||
}
|
||||
})
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
openDatabase();
|
||||
}
|
||||
else if(itemId == R.id.settings)
|
||||
{
|
||||
@@ -2008,6 +2050,170 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
return true;
|
||||
}
|
||||
|
||||
private void openDatabase()
|
||||
{
|
||||
final String[] files = Util.loadFileList(mWorkingDirectory, true);
|
||||
if(files.length > 0)
|
||||
{
|
||||
String[] filesWithSize = new String[files.length];
|
||||
for(int i = 0; i<filesWithSize.length; ++i)
|
||||
{
|
||||
File filePath = new File(mWorkingDirectory+files[i]);
|
||||
long mb = filePath.length()/(1024*1024);
|
||||
filesWithSize[i] = files[i] + " ("+mb+" MB)";
|
||||
}
|
||||
|
||||
ArrayList<HashMap<String, String> > arrayList = new ArrayList<HashMap<String, String> >();
|
||||
for (int i = 0; i < filesWithSize.length; i++) {
|
||||
HashMap<String, String> hashMap = new HashMap<String, String>();//create a hashmap to store the data in key value pair
|
||||
hashMap.put("name", filesWithSize[i]);
|
||||
hashMap.put("path", mWorkingDirectory + files[i]);
|
||||
arrayList.add(hashMap);//add the hashmap into arrayList
|
||||
}
|
||||
String[] from = {"name", "path"};//string array
|
||||
int[] to = {R.id.textView, R.id.imageView};//int array of views id's
|
||||
DatabaseListArrayAdapter simpleAdapter = new DatabaseListArrayAdapter(this, arrayList, R.layout.database_list, from, to);//Create object and set the parameters for simpleAdapter
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Choose Your File (*.db)");
|
||||
builder.setAdapter(simpleAdapter, new DialogInterface.OnClickListener() {
|
||||
//builder.setItems(filesWithSize, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, final int which) {
|
||||
|
||||
// Adjust color now?
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle("Opening database...")
|
||||
.setMessage("Do you want to adjust colors now?\nThis can be done later under Optimize menu.")
|
||||
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichIn) {
|
||||
openDatabase(files[which], true);
|
||||
}
|
||||
})
|
||||
.setNeutralButton("No", new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int whichIn) {
|
||||
openDatabase(files[which], false);
|
||||
}
|
||||
})
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
final AlertDialog ad = builder.create(); //don't show dialog yet
|
||||
ad.setOnShowListener(new OnShowListener()
|
||||
{
|
||||
@Override
|
||||
public void onShow(DialogInterface dialog)
|
||||
{
|
||||
ListView lv = ad.getListView();
|
||||
ad.registerForContextMenu(lv);
|
||||
lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||
|
||||
if (v.getId()==ad.getListView().getId()) {
|
||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
|
||||
final int position = info.position;
|
||||
menu.setHeaderTitle(files[position]);
|
||||
menu.add(Menu.NONE, 0, 0, "Rename").setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
AlertDialog.Builder builderRename = new AlertDialog.Builder(getActivity());
|
||||
builderRename.setTitle("RTAB-Map Database Name (*.db):");
|
||||
final EditText input = new EditText(getActivity());
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
input.setText("");
|
||||
input.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||
input.setSelectAllOnFocus(true);
|
||||
input.selectAll();
|
||||
builderRename.setView(input);
|
||||
builderRename.setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
final String fileName = input.getText().toString();
|
||||
dialog.dismiss();
|
||||
if(!fileName.isEmpty())
|
||||
{
|
||||
File newFile = new File(mWorkingDirectory + fileName + ".db");
|
||||
if(newFile.exists())
|
||||
{
|
||||
new AlertDialog.Builder(getActivity())
|
||||
.setTitle("File Already Exists")
|
||||
.setMessage(String.format("Name %s already used, choose another name.", fileName))
|
||||
.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
File from = new File(mWorkingDirectory, files[position]);
|
||||
File to = new File(mWorkingDirectory, fileName + ".db");
|
||||
from.renameTo(to);
|
||||
ad.dismiss();
|
||||
resetNoTouchTimer(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog alertToShow = builderRename.create();
|
||||
alertToShow.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||
alertToShow.show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
menu.add(Menu.NONE, 1, 1, "Delete").setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which){
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
Log.e(TAG, String.format("Yes delete %s!", files[position]));
|
||||
(new File(mWorkingDirectory+files[position])).delete();
|
||||
ad.dismiss();
|
||||
resetNoTouchTimer(true);
|
||||
break;
|
||||
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
//No button clicked
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setTitle(String.format("Delete %s", files[position]))
|
||||
.setMessage("Are you sure?")
|
||||
.setPositiveButton("Yes", dialogClickListener)
|
||||
.setNegativeButton("No", dialogClickListener).show();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
menu.add(Menu.NONE, 2, 2, "Share").setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
// Send to...
|
||||
File f = new File(mWorkingDirectory+files[position]);
|
||||
final int fileSizeMB = (int)f.length()/(1024 * 1024);
|
||||
Intent shareIntent = new Intent();
|
||||
shareIntent.setAction(Intent.ACTION_SEND);
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));
|
||||
shareIntent.setType("application/octet-stream");
|
||||
startActivity(Intent.createChooser(shareIntent, String.format("Sharing database \"%s\" (%d MB)...", files[position], fileSizeMB)));
|
||||
ad.dismiss();
|
||||
resetNoTouchTimer(true);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
ad.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void export(final boolean isOBJ, final boolean meshing, final boolean regenerateCloud, final boolean optimized, final int optimizedMaxPolygons)
|
||||
{
|
||||
final String extension = isOBJ? ".obj" : ".ply";
|
||||
@@ -2211,8 +2417,6 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
msg = String.format("Database saved to \"%s\".", newDatabasePathHuman);
|
||||
}
|
||||
|
||||
mToast.makeText(getActivity(), msg, mToast.LENGTH_LONG).show();
|
||||
|
||||
// build notification
|
||||
Intent intent = new Intent(getActivity(), RTABMapActivity.class);
|
||||
// use System.currentTimeMillis() to have a unique ID for the pending intent
|
||||
@@ -2232,6 +2436,15 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
|
||||
notificationManager.notify(0, n);
|
||||
|
||||
// Send to...
|
||||
File f = new File(newDatabasePath);
|
||||
final int fileSizeMB = (int)f.length()/(1024 * 1024);
|
||||
Intent shareIntent = new Intent();
|
||||
shareIntent.setAction(Intent.ACTION_SEND);
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));
|
||||
shareIntent.setType("application/octet-stream");
|
||||
startActivity(Intent.createChooser(shareIntent, String.format("Database \"%s\" (%d MB) successfully saved on the SD-CARD! Share it?", newDatabasePathHuman, fileSizeMB)));
|
||||
|
||||
resetNoTouchTimer(true);
|
||||
if(!mItemDataRecorderMode.isChecked())
|
||||
{
|
||||
@@ -2385,11 +2598,13 @@ public class RTABMapActivity extends Activity implements OnClickListener, OnItem
|
||||
mProgressDialog.dismiss();
|
||||
|
||||
// Send to...
|
||||
File f = new File(zipOutput);
|
||||
final int fileSizeMB = (int)f.length()/(1024 * 1024);
|
||||
Intent shareIntent = new Intent();
|
||||
shareIntent.setAction(Intent.ACTION_SEND);
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(zipOutput)));
|
||||
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f));
|
||||
shareIntent.setType("application/zip");
|
||||
startActivity(Intent.createChooser(shareIntent, String.format("Mesh \"%s\" successfully exported! Share it?", pathHuman)));
|
||||
startActivity(Intent.createChooser(shareIntent, String.format("Mesh \"%s\" (%d MB) successfully exported on the SD-CARD! Share it?", pathHuman, fileSizeMB)));
|
||||
|
||||
resetNoTouchTimer(true);
|
||||
}
|
||||
|
||||
@@ -92,6 +92,13 @@ public class RTABMapLib
|
||||
public static native void setRenderingTextureDecimation(int value);
|
||||
public static native void setBackgroundColor(float gray);
|
||||
public static native int setMappingParameter(String key, String value);
|
||||
public static native void setGPS(
|
||||
double stamp,
|
||||
double longitude,
|
||||
double latitude,
|
||||
double altitude,
|
||||
double accuracy,
|
||||
double bearing);
|
||||
|
||||
public static native void resetMapping();
|
||||
public static native void save(String outputDatabasePath);
|
||||
|
||||
@@ -159,7 +159,7 @@ public:
|
||||
void getNodeData(int signatureId, SensorData & data, bool images = true, bool scan = true, bool userData = true, bool occupancyGrid = true) const;
|
||||
bool getCalibration(int signatureId, std::vector<CameraModel> & models, StereoCameraModel & stereoModel) const;
|
||||
bool getLaserScanInfo(int signatureId, LaserScanInfo & info) const;
|
||||
bool getNodeInfo(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity) const;
|
||||
bool getNodeInfo(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, std::vector<double> & gps) const;
|
||||
void loadLinks(int signatureId, std::map<int, Link> & links, Link::Type type = Link::kUndef) const;
|
||||
void getWeight(int signatureId, int & weight) const;
|
||||
void getAllNodeIds(std::set<int> & ids, bool ignoreChildren = false, bool ignoreBadSignatures = false) const;
|
||||
@@ -253,7 +253,7 @@ private:
|
||||
virtual void loadNodeDataQuery(std::list<Signature *> & signatures, bool images=true, bool scan=true, bool userData=true, bool occupancyGrid=true) const = 0;
|
||||
virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, StereoCameraModel & stereoModel) const = 0;
|
||||
virtual bool getLaserScanInfoQuery(int signatureId, LaserScanInfo & info) const = 0;
|
||||
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity) const = 0;
|
||||
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, std::vector<double> & gps) const = 0;
|
||||
virtual void getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren, bool ignoreBadSignatures) const = 0;
|
||||
virtual void getAllLinksQuery(std::multimap<int, Link> & links, bool ignoreNullLinks) const = 0;
|
||||
virtual void getLastIdQuery(const std::string & tableName, int & id) const = 0;
|
||||
|
||||
@@ -177,6 +177,7 @@ public:
|
||||
double & stamp,
|
||||
Transform & groundTruth,
|
||||
std::vector<float> & velocity,
|
||||
std::vector<double> & gps,
|
||||
bool lookInDatabase = false) const;
|
||||
cv::Mat getImageCompressed(int signatureId) const;
|
||||
SensorData getNodeData(int nodeId, bool uncompressedData = false) const;
|
||||
|
||||
@@ -225,6 +225,18 @@ public:
|
||||
const Transform & globalPose() const {return globalPose_;}
|
||||
const cv::Mat & globalPoseCovariance() const {return globalPoseCovariance_;}
|
||||
|
||||
void setGPS(double stamp, double longitude, double latitude, double altitude, double accuracy, double bearing)
|
||||
{
|
||||
gps_ = std::vector<double>(6,0.0);
|
||||
gps_[0]=stamp;
|
||||
gps_[1]=longitude;
|
||||
gps_[2]=latitude;
|
||||
gps_[3]=altitude;
|
||||
gps_[4]=accuracy;
|
||||
gps_[5]=bearing;
|
||||
}
|
||||
const std::vector<double> & gps() const {return gps_;}
|
||||
|
||||
long getMemoryUsed() const; // Return memory usage in Bytes
|
||||
|
||||
private:
|
||||
@@ -265,6 +277,8 @@ private:
|
||||
|
||||
Transform globalPose_;
|
||||
cv::Mat globalPoseCovariance_; // 6x6 double
|
||||
|
||||
std::vector<double> gps_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -712,7 +712,8 @@ bool DBDriver::getNodeInfo(
|
||||
std::string & label,
|
||||
double & stamp,
|
||||
Transform & groundTruthPose,
|
||||
std::vector<float> & velocity) const
|
||||
std::vector<float> & velocity,
|
||||
std::vector<double> & gps) const
|
||||
{
|
||||
bool found = false;
|
||||
// look in the trash
|
||||
@@ -725,6 +726,7 @@ bool DBDriver::getNodeInfo(
|
||||
label = _trashSignatures.at(signatureId)->getLabel();
|
||||
stamp = _trashSignatures.at(signatureId)->getStamp();
|
||||
groundTruthPose = _trashSignatures.at(signatureId)->getGroundTruthPose();
|
||||
gps = _trashSignatures.at(signatureId)->sensorData().gps();
|
||||
found = true;
|
||||
}
|
||||
_trashesMutex.unlock();
|
||||
@@ -732,7 +734,7 @@ bool DBDriver::getNodeInfo(
|
||||
if(!found)
|
||||
{
|
||||
_dbSafeAccessMutex.lock();
|
||||
found = this->getNodeInfoQuery(signatureId, pose, mapId, weight, label, stamp, groundTruthPose, velocity);
|
||||
found = this->getNodeInfoQuery(signatureId, pose, mapId, weight, label, stamp, groundTruthPose, velocity, gps);
|
||||
_dbSafeAccessMutex.unlock();
|
||||
}
|
||||
return found;
|
||||
|
||||
@@ -497,7 +497,11 @@ long DBDriverSqlite3::getNodesMemoryUsedQuery() const
|
||||
if(_ppDb)
|
||||
{
|
||||
std::string query;
|
||||
if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||
if(uStrNumCmp(_version, "0.14.0") >= 0)
|
||||
{
|
||||
query = "SELECT sum(length(id) + length(map_id) + length(weight) + length(pose) + length(stamp) + ifnull(length(label),0) + length(ground_truth_pose) + ifnull(length(velocity),0) + ifnull(length(gps),0) + length(time_enter)) from Node;";
|
||||
}
|
||||
else if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||
{
|
||||
query = "SELECT sum(length(id) + length(map_id) + length(weight) + length(pose) + length(stamp) + ifnull(length(label),0) + length(ground_truth_pose) + ifnull(length(velocity),0) + length(time_enter)) from Node;";
|
||||
}
|
||||
@@ -1751,7 +1755,8 @@ bool DBDriverSqlite3::getNodeInfoQuery(int signatureId,
|
||||
std::string & label,
|
||||
double & stamp,
|
||||
Transform & groundTruthPose,
|
||||
std::vector<float> & velocity) const
|
||||
std::vector<float> & velocity,
|
||||
std::vector<double> & gps) const
|
||||
{
|
||||
bool found = false;
|
||||
if(_ppDb && signatureId)
|
||||
@@ -1760,7 +1765,14 @@ bool DBDriverSqlite3::getNodeInfoQuery(int signatureId,
|
||||
sqlite3_stmt * ppStmt = 0;
|
||||
std::stringstream query;
|
||||
|
||||
if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||
if(uStrNumCmp(_version, "0.14.0") >= 0)
|
||||
{
|
||||
query << "SELECT pose, map_id, weight, label, stamp, ground_truth_pose, velocity, gps "
|
||||
"FROM Node "
|
||||
"WHERE id = " << signatureId <<
|
||||
";";
|
||||
}
|
||||
else if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||
{
|
||||
query << "SELECT pose, map_id, weight, label, stamp, ground_truth_pose, velocity "
|
||||
"FROM Node "
|
||||
@@ -1839,6 +1851,17 @@ bool DBDriverSqlite3::getNodeInfoQuery(int signatureId,
|
||||
memcpy(velocity.data(), data, dataSize);
|
||||
}
|
||||
}
|
||||
|
||||
if(uStrNumCmp(_version, "0.14.0") >= 0)
|
||||
{
|
||||
gps.resize(6,0);
|
||||
data = sqlite3_column_blob(ppStmt, index); // velocity
|
||||
dataSize = sqlite3_column_bytes(ppStmt, index++);
|
||||
if((unsigned int)dataSize == gps.size()*sizeof(double) && data)
|
||||
{
|
||||
memcpy(gps.data(), data, dataSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2239,7 +2262,13 @@ void DBDriverSqlite3::loadSignaturesQuery(const std::list<int> & ids, std::list<
|
||||
unsigned int loaded = 0;
|
||||
|
||||
// Load nodes information
|
||||
if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||
if(uStrNumCmp(_version, "0.14.0") >= 0)
|
||||
{
|
||||
query << "SELECT id, map_id, weight, pose, stamp, label, ground_truth_pose, velocity, gps "
|
||||
<< "FROM Node "
|
||||
<< "WHERE id=?;";
|
||||
}
|
||||
else if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||
{
|
||||
query << "SELECT id, map_id, weight, pose, stamp, label, ground_truth_pose, velocity "
|
||||
<< "FROM Node "
|
||||
@@ -2281,6 +2310,7 @@ void DBDriverSqlite3::loadSignaturesQuery(const std::list<int> & ids, std::list<
|
||||
Transform pose;
|
||||
Transform groundTruthPose;
|
||||
std::vector<float> velocity;
|
||||
std::vector<double> gps;
|
||||
const void * data = 0;
|
||||
int dataSize = 0;
|
||||
std::string label;
|
||||
@@ -2329,6 +2359,17 @@ void DBDriverSqlite3::loadSignaturesQuery(const std::list<int> & ids, std::list<
|
||||
memcpy(velocity.data(), data, dataSize);
|
||||
}
|
||||
}
|
||||
|
||||
if(uStrNumCmp(_version, "0.14.0") >= 0)
|
||||
{
|
||||
gps.resize(6,0);
|
||||
data = sqlite3_column_blob(ppStmt, index); // gps
|
||||
dataSize = sqlite3_column_bytes(ppStmt, index++);
|
||||
if((unsigned int)dataSize == gps.size()*sizeof(double) && data)
|
||||
{
|
||||
memcpy(gps.data(), data, dataSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2352,6 +2393,10 @@ void DBDriverSqlite3::loadSignaturesQuery(const std::list<int> & ids, std::list<
|
||||
{
|
||||
s->setVelocity(velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5]);
|
||||
}
|
||||
if(gps.size() == 6)
|
||||
{
|
||||
s->sensorData().setGPS(gps[0], gps[1], gps[2], gps[3], gps[4], gps[5]);
|
||||
}
|
||||
s->setSaved(true);
|
||||
nodes.push_back(s);
|
||||
++loaded;
|
||||
@@ -4213,7 +4258,11 @@ cv::Mat DBDriverSqlite3::loadOptimizedMeshQuery(
|
||||
|
||||
std::string DBDriverSqlite3::queryStepNode() const
|
||||
{
|
||||
if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||
if(uStrNumCmp(_version, "0.14.0") >= 0)
|
||||
{
|
||||
return "INSERT INTO Node(id, map_id, weight, pose, stamp, label, ground_truth_pose, velocity, gps) VALUES(?,?,?,?,?,?,?,?,?);";
|
||||
}
|
||||
else if(uStrNumCmp(_version, "0.13.0") >= 0)
|
||||
{
|
||||
return "INSERT INTO Node(id, map_id, weight, pose, stamp, label, ground_truth_pose, velocity) VALUES(?,?,?,?,?,?,?,?);";
|
||||
}
|
||||
@@ -4293,6 +4342,20 @@ void DBDriverSqlite3::stepNode(sqlite3_stmt * ppStmt, const Signature * s) const
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if(uStrNumCmp(_version, "0.14.0") >= 0)
|
||||
{
|
||||
if(s->sensorData().gps().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++, s->sensorData().gps().data(), s->sensorData().gps().size()*sizeof(double), SQLITE_STATIC);
|
||||
UASSERT_MSG(rc == SQLITE_OK, uFormat("DB error (%s): %s", _version.c_str(), sqlite3_errmsg(_ppDb)).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(uStrNumCmp(_version, "0.8.8") >= 0)
|
||||
|
||||
@@ -127,7 +127,7 @@ private:
|
||||
virtual void loadNodeDataQuery(std::list<Signature *> & signatures, bool images=true, bool scan=true, bool userData=true, bool occupancyGrid=true) const;
|
||||
virtual bool getCalibrationQuery(int signatureId, std::vector<CameraModel> & models, StereoCameraModel & stereoModel) const;
|
||||
virtual bool getLaserScanInfoQuery(int signatureId, LaserScanInfo & info) const;
|
||||
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity) const;
|
||||
virtual bool getNodeInfoQuery(int signatureId, Transform & pose, int & mapId, int & weight, std::string & label, double & stamp, Transform & groundTruthPose, std::vector<float> & velocity, std::vector<double> & gps) const;
|
||||
virtual void getAllNodeIdsQuery(std::set<int> & ids, bool ignoreChildren, bool ignoreBadSignatures) const;
|
||||
virtual void getAllLinksQuery(std::multimap<int, Link> & links, bool ignoreNullLinks) const;
|
||||
virtual void getLastIdQuery(const std::string & tableName, int & id) const;
|
||||
|
||||
@@ -268,7 +268,8 @@ SensorData DBReader::captureImage(CameraInfo * info)
|
||||
int mapId;
|
||||
Transform localTransform, pose, groundTruth;
|
||||
std::vector<float> velocity;
|
||||
_dbDriver->getNodeInfo(*_currentId, pose, mapId, weight, label, stamp, groundTruth, velocity);
|
||||
std::vector<double> gps;
|
||||
_dbDriver->getNodeInfo(*_currentId, pose, mapId, weight, label, stamp, groundTruth, velocity, gps);
|
||||
if(previousStamp && stamp && stamp > previousStamp)
|
||||
{
|
||||
delay = stamp - previousStamp;
|
||||
@@ -322,7 +323,8 @@ SensorData DBReader::getNextData(CameraInfo * info)
|
||||
double stamp;
|
||||
Transform groundTruth;
|
||||
std::vector<float> velocity;
|
||||
_dbDriver->getNodeInfo(*_currentId, pose, mapId, weight, label, stamp, groundTruth, velocity);
|
||||
std::vector<double> gps;
|
||||
_dbDriver->getNodeInfo(*_currentId, pose, mapId, weight, label, stamp, groundTruth, velocity, gps);
|
||||
|
||||
cv::Mat infMatrix = cv::Mat::eye(6,6,CV_64FC1);
|
||||
if(!_odometryIgnored)
|
||||
|
||||
+11
-3
@@ -3051,7 +3051,8 @@ Transform Memory::getOdomPose(int signatureId, bool lookInDatabase) const
|
||||
std::string label;
|
||||
double stamp;
|
||||
std::vector<float> velocity;
|
||||
getNodeInfo(signatureId, pose, mapId, weight, label, stamp, groundTruth, velocity, lookInDatabase);
|
||||
std::vector<double> gps;
|
||||
getNodeInfo(signatureId, pose, mapId, weight, label, stamp, groundTruth, velocity, gps, lookInDatabase);
|
||||
return pose;
|
||||
}
|
||||
|
||||
@@ -3062,7 +3063,8 @@ Transform Memory::getGroundTruthPose(int signatureId, bool lookInDatabase) const
|
||||
std::string label;
|
||||
double stamp;
|
||||
std::vector<float> velocity;
|
||||
getNodeInfo(signatureId, pose, mapId, weight, label, stamp, groundTruth, velocity, lookInDatabase);
|
||||
std::vector<double> gps;
|
||||
getNodeInfo(signatureId, pose, mapId, weight, label, stamp, groundTruth, velocity, gps, lookInDatabase);
|
||||
return groundTruth;
|
||||
}
|
||||
|
||||
@@ -3074,6 +3076,7 @@ bool Memory::getNodeInfo(int signatureId,
|
||||
double & stamp,
|
||||
Transform & groundTruth,
|
||||
std::vector<float> & velocity,
|
||||
std::vector<double> & gps,
|
||||
bool lookInDatabase) const
|
||||
{
|
||||
const Signature * s = this->getSignature(signatureId);
|
||||
@@ -3086,11 +3089,12 @@ bool Memory::getNodeInfo(int signatureId,
|
||||
stamp = s->getStamp();
|
||||
groundTruth = s->getGroundTruthPose();
|
||||
velocity = s->getVelocity();
|
||||
gps = s->sensorData().gps();
|
||||
return true;
|
||||
}
|
||||
else if(lookInDatabase && _dbDriver)
|
||||
{
|
||||
return _dbDriver->getNodeInfo(signatureId, odomPose, mapId, weight, label, stamp, groundTruth, velocity);
|
||||
return _dbDriver->getNodeInfo(signatureId, odomPose, mapId, weight, label, stamp, groundTruth, velocity, gps);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -3963,6 +3967,10 @@ Signature * Memory::createSignature(const SensorData & data, const Transform & p
|
||||
s->sensorData().setUserDataRaw(data.userDataRaw());
|
||||
|
||||
s->sensorData().setGroundTruth(data.groundTruth());
|
||||
if(!data.gps().empty())
|
||||
{
|
||||
s->sensorData().setGPS(data.gps()[0], data.gps()[1], data.gps()[2], data.gps()[3], data.gps()[4], data.gps()[5]);
|
||||
}
|
||||
|
||||
t = timer.ticks();
|
||||
if(stats) stats->addStatistic(Statistics::kTimingMemCompressing_data(), t*1000.0f);
|
||||
|
||||
+20
-4
@@ -761,7 +761,8 @@ void Rtabmap::exportPoses(const std::string & path, bool optimized, bool global,
|
||||
std::string l;
|
||||
double stamp = 0.0;
|
||||
std::vector<float> v;
|
||||
_memory->getNodeInfo(iter->first, o, m, w, l, stamp, g, v, true);
|
||||
std::vector<double> gps;
|
||||
_memory->getNodeInfo(iter->first, o, m, w, l, stamp, g, v, gps, true);
|
||||
stamps.insert(std::make_pair(iter->first, stamp));
|
||||
}
|
||||
}
|
||||
@@ -2650,7 +2651,8 @@ bool Rtabmap::process(
|
||||
double stamp = 0;
|
||||
Transform groundTruth;
|
||||
std::vector<float> velocity;
|
||||
_memory->getNodeInfo(iter->first, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, false);
|
||||
std::vector<double> gps;
|
||||
_memory->getNodeInfo(iter->first, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, gps, false);
|
||||
signatures.insert(std::make_pair(iter->first,
|
||||
Signature(iter->first,
|
||||
mapId,
|
||||
@@ -2663,6 +2665,10 @@ bool Rtabmap::process(
|
||||
{
|
||||
signatures.at(iter->first).setVelocity(velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5]);
|
||||
}
|
||||
if(!gps.empty())
|
||||
{
|
||||
signatures.at(iter->first).sensorData().setGPS(gps[0], gps[1], gps[2], gps[3], gps[4], gps[5]);
|
||||
}
|
||||
}
|
||||
localGraphSize = (int)poses.size();
|
||||
if(!lastSignatureLocalizedPose.isNull())
|
||||
@@ -3340,7 +3346,8 @@ void Rtabmap::get3DMap(
|
||||
double stamp = 0;
|
||||
Transform groundTruth;
|
||||
std::vector<float> velocity;
|
||||
_memory->getNodeInfo(*iter, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, true);
|
||||
std::vector<double> gps;
|
||||
_memory->getNodeInfo(*iter, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, gps, true);
|
||||
SensorData data = _memory->getNodeData(*iter);
|
||||
data.setId(*iter);
|
||||
std::multimap<int, cv::KeyPoint> words;
|
||||
@@ -3363,6 +3370,10 @@ void Rtabmap::get3DMap(
|
||||
{
|
||||
signatures.at(*iter).setVelocity(velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5]);
|
||||
}
|
||||
if(!gps.empty())
|
||||
{
|
||||
signatures.at(*iter).sensorData().setGPS(gps[0], gps[1], gps[2], gps[3], gps[4], gps[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(_memory && (_memory->getStMem().size() || _memory->getWorkingMem().size() > 1))
|
||||
@@ -3415,7 +3426,8 @@ void Rtabmap::getGraph(
|
||||
double stamp = 0;
|
||||
Transform groundTruth;
|
||||
std::vector<float> velocity;
|
||||
_memory->getNodeInfo(iter->first, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, global);
|
||||
std::vector<double> gps;
|
||||
_memory->getNodeInfo(iter->first, odomPoseLocal, mapId, weight, label, stamp, groundTruth, velocity, gps, global);
|
||||
signatures->insert(std::make_pair(iter->first,
|
||||
Signature(iter->first,
|
||||
mapId,
|
||||
@@ -3443,6 +3455,10 @@ void Rtabmap::getGraph(
|
||||
{
|
||||
signatures->at(iter->first).setVelocity(velocity[0], velocity[1], velocity[2], velocity[3], velocity[4], velocity[5]);
|
||||
}
|
||||
if(!gps.empty())
|
||||
{
|
||||
signatures->at(iter->first).sensorData().setGPS(gps[0], gps[1], gps[2], gps[3], gps[4], gps[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ CREATE TABLE Node (
|
||||
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)
|
||||
|
||||
time_enter DATE,
|
||||
PRIMARY KEY (id)
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<package>
|
||||
<name>rtabmap</name>
|
||||
<version>0.13.3</version>
|
||||
<version>0.14.0</version>
|
||||
<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>
|
||||
<author>Mathieu Labbe</author>
|
||||
|
||||
Reference in New Issue
Block a user