Tango: update to 0.11.14

This commit is contained in:
matlabbe
2017-02-05 17:24:45 -05:00
parent ce8bd9ac40
commit f7616f6e94
27 changed files with 2284 additions and 1575 deletions

View File

@@ -29,7 +29,8 @@
<activity android:name="RTABMapActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="landscape">
android:screenOrientation="landscape"
android:configChanges="orientation|screenSize|keyboardHidden">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name"
android:value="NativeRTABMap" />

View File

@@ -94,13 +94,14 @@ void onTangoEventAvailableRouter(void* context, const TangoEvent* event)
//////////////////////////////
// CameraTango
//////////////////////////////
CameraTango::CameraTango(int decimation, bool autoExposure) :
CameraTango::CameraTango(int decimation, bool autoExposure, bool publishRawScan) :
Camera(0),
tango_config_(0),
firstFrame_(true),
stampEpochOffset_(0.0),
decimation_(decimation),
autoExposure_(autoExposure),
rawScanPublished_(publishRawScan),
cloudStamp_(0),
tangoColorType_(0),
tangoColorStamp_(0)
@@ -577,18 +578,19 @@ SensorData CameraTango::captureImage(CameraInfo * info)
// The Color Camera frame at timestamp t0 with respect to Depth
// Camera frame at timestamp t1.
//LOGD("colorToDepth=%s", colorToDepth.prettyPrint().c_str());
LOGD("rgb=%dx%d cloud size=%d", rgb.cols, rgb.rows, (int)cloud.total());
int pixelsSet = 0;
depth = cv::Mat::zeros(model_.imageHeight()/8, model_.imageWidth()/8, CV_16UC1); // mm
CameraModel depthModel = model_.scaled(1.0f/8.0f);
std::vector<cv::Point3f> scanData(cloud.total());
std::vector<cv::Point3f> scanData(rawScanPublished_?cloud.total():0);
int oi=0;
for(unsigned int i=0; i<cloud.total(); ++i)
{
float * p = cloud.ptr<float>(0,i);
cv::Point3f pt = util3d::transformPoint(cv::Point3f(p[0], p[1], p[2]), colorToDepth);
if(pt.z > 0.0f && i%scanDownsampling == 0)
if(pt.z > 0.0f && i%scanDownsampling == 0 && rawScanPublished_)
{
scanData.at(oi++) = pt;
}
@@ -639,7 +641,14 @@ SensorData CameraTango::captureImage(CameraInfo * info)
//LOGD("rtabmap = %s", odom.prettyPrint().c_str());
//LOGD("opengl(r)= %s", (opengl_world_T_rtabmap_world * odom * rtabmap_device_T_opengl_device).prettyPrint().c_str());
data = SensorData(scan, LaserScanInfo(cloud.total()/scanDownsampling, 0, model.localTransform()), rgb, depth, model, this->getNextSeqID(), rgbStamp);
if(rawScanPublished_)
{
data = SensorData(scan, LaserScanInfo(cloud.total()/scanDownsampling, 0, model.localTransform()), rgb, depth, model, this->getNextSeqID(), rgbStamp);
}
else
{
data = SensorData(rgb, depth, model, this->getNextSeqID(), rgbStamp);
}
data.setGroundTruth(odom);
}
else

View File

@@ -70,7 +70,7 @@ private:
class CameraTango : public Camera, public UThread, public UEventsSender {
public:
CameraTango(int decimation, bool autoExposure);
CameraTango(int decimation, bool autoExposure, bool publishRawScan);
virtual ~CameraTango();
virtual bool init(const std::string & calibrationFolder = ".", const std::string & cameraName = "");
@@ -81,6 +81,7 @@ public:
rtabmap::Transform tangoPoseToTransform(const TangoPoseData * tangoPose) const;
void setDecimation(int value) {decimation_ = value;}
void setAutoExposure(bool enabled) {autoExposure_ = enabled;}
void setRawScanPublished(bool enabled) {rawScanPublished_ = enabled;}
void cloudReceived(const cv::Mat & cloud, double timestamp);
void rgbReceived(const cv::Mat & tangoImage, int type, double timestamp);
@@ -103,6 +104,7 @@ private:
double stampEpochOffset_;
int decimation_;
bool autoExposure_;
bool rawScanPublished_;
cv::Mat cloud_;
double cloudStamp_;
cv::Mat tangoColor_;

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,9 @@ class RTABMapApp : public UEventsHandler {
void onCreate(JNIEnv* env, jobject caller_activity);
void openDatabase(const std::string & databasePath = "");
void setScreenRotation(int displayRotation, int cameraRotation);
void openDatabase(const std::string & databasePath, bool databaseInMemory, bool optimize);
bool onTangoServiceConnected(JNIEnv* env, jobject iBinder);
@@ -120,10 +122,10 @@ class RTABMapApp : public UEventsHandler {
void setTrajectoryMode(bool enabled);
void setGraphOptimization(bool enabled);
void setNodesFiltering(bool enabled);
void setDriftCorrection(bool enabled);
void setGraphVisible(bool visible);
void setGridVisible(bool visible);
void setAutoExposure(bool enabled);
void setRawScanSaved(bool enabled);
void setFullResolution(bool enabled);
void setAppendMode(bool enabled);
void setDataRecorderMode(bool enabled);
@@ -144,6 +146,7 @@ class RTABMapApp : public UEventsHandler {
bool meshing,
int textureSize,
int normalK,
float maxTextureDistance,
bool optimized,
float optimizedVoxelSize,
int optimizedDepth,
@@ -171,10 +174,10 @@ class RTABMapApp : public UEventsHandler {
bool odomCloudShown_;
bool graphOptimization_;
bool nodesFiltering_;
bool driftCorrection_;
bool localizationMode_;
bool trajectoryMode_;
bool autoExposure_;
bool rawScanSaved_;
bool fullResolution_;
bool appendMode_;
float maxCloudDepth_;
@@ -189,6 +192,7 @@ class RTABMapApp : public UEventsHandler {
bool paused_;
bool dataRecorderMode_;
bool clearSceneOnNextRender_;
bool optimizeOpenedDatabase_;
bool filterPolygonsOnNextRender_;
int gainCompensationOnNextRender_;
bool bilateralFilteringOnNextRender_;

View File

@@ -56,19 +56,19 @@ Java_com_introlab_rtabmap_RTABMapLib_onCreate(
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_openEmptyDatabase(
JNIEnv* env, jobject)
Java_com_introlab_rtabmap_RTABMapLib_setScreenRotation(
JNIEnv* env, jobject, int displayRotation, int cameraRotation)
{
return app.openDatabase();
return app.setScreenRotation(displayRotation, cameraRotation);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_openDatabase(
JNIEnv* env, jobject, jstring databasePath)
JNIEnv* env, jobject, jstring databasePath, bool databaseInMemory, bool optimize)
{
std::string databasePathC;
GetJStringContent(env,databasePath,databasePathC);
return app.openDatabase(databasePathC);
return app.openDatabase(databasePathC, databaseInMemory, optimize);
}
JNIEXPORT bool JNICALL
@@ -181,12 +181,6 @@ Java_com_introlab_rtabmap_RTABMapLib_setNodesFiltering(
return app.setNodesFiltering(enabled);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setDriftCorrection(
JNIEnv*, jobject, bool enabled)
{
return app.setDriftCorrection(enabled);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setGraphVisible(
JNIEnv*, jobject, bool visible)
{
@@ -205,6 +199,12 @@ Java_com_introlab_rtabmap_RTABMapLib_setAutoExposure(
return app.setAutoExposure(enabled);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setRawScanSaved(
JNIEnv*, jobject, bool enabled)
{
return app.setRawScanSaved(enabled);
}
JNIEXPORT void JNICALL
Java_com_introlab_rtabmap_RTABMapLib_setFullResolution(
JNIEnv*, jobject, bool enabled)
{
@@ -292,6 +292,7 @@ Java_com_introlab_rtabmap_RTABMapLib_exportMesh(
bool meshing,
int textureSize,
int normalK,
float maxTextureDistance,
bool optimized,
float optimizedVoxelSize,
int optimizedDepth,
@@ -309,6 +310,7 @@ Java_com_introlab_rtabmap_RTABMapLib_exportMesh(
meshing,
textureSize,
normalK,
maxTextureDistance,
optimized,
optimizedVoxelSize,
optimizedDepth,

View File

@@ -59,6 +59,7 @@ class PointCloudDrawable {
void updateMesh(const Mesh & mesh, const cv::Mat & texture);
void setPose(const rtabmap::Transform & pose);
void setVisible(bool visible) {visible_=visible;}
void setGain(float gain) {gain_ = gain;}
rtabmap::Transform getPose() const {return glmToTransform(pose_);}
bool isVisible() const {return visible_;}
bool hasMesh() const {return polygons_.size()!=0;}

View File

@@ -21,6 +21,8 @@
#include <rtabmap/utilite/UStl.h>
#include <rtabmap/core/util3d_filtering.h>
#include <glm/gtx/transform.hpp>
#include "scene.h"
#include "util.h"
@@ -60,7 +62,7 @@ const std::string kPointCloudVertexShader =
" gl_Position = uMVP*vec4(aVertex.x, aVertex.y, aVertex.z, 1.0);\n"
" gl_PointSize = uPointSize;\n"
" if (!uUseLighting) {\n"
" vLightWeighting = vec3(1.0, 1.0, 1.0);\n"
" vLightWeighting = 1.0;\n"
" } else {\n"
" vec3 transformedNormal = uN * aNormal;\n"
" vLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);\n"
@@ -106,7 +108,7 @@ const std::string kTextureMeshVertexShader =
" }\n"
" if (!uUseLighting) {\n"
" vLightWeighting = vec3(1.0, 1.0, 1.0);\n"
" vLightWeighting = 1.0;\n"
" } else {\n"
" vec3 transformedNormal = uN * aNormal;\n"
" vLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);\n"
@@ -156,6 +158,7 @@ Scene::Scene() :
graphVisible_(true),
gridVisible_(true),
traceVisible_(true),
color_camera_to_display_rotation_(ROTATION_0),
currentPose_(0),
cloud_shader_program_(0),
texture_mesh_shader_program_(0),
@@ -165,7 +168,10 @@ Scene::Scene() :
meshRenderingTexture_(true),
pointSize_(5.0f),
frustumCulling_(true),
lighting_(true)
lighting_(true),
r_(0.0f),
g_(0.0f),
b_(0.0f)
{
gesture_camera_ = new tango_gl::GestureCamera();
gesture_camera_->SetCameraType(
@@ -249,6 +255,14 @@ void Scene::DeleteResources() {
clear();
}
void Scene::setScreenRotation(int displayOrientation, int cameraOrientation)
{
color_camera_to_display_rotation_ =
tango_gl::util::GetAndroidRotationFromColorCameraToDisplay(
displayOrientation, cameraOrientation);
LOGI("color_camera_to_display_rotation_=%d", color_camera_to_display_rotation_);
}
//Should only be called in OpenGL thread!
void Scene::clear()
{
@@ -284,56 +298,61 @@ void Scene::SetupViewPort(int w, int h) {
int Scene::Render() {
UASSERT(gesture_camera_ != 0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClearColor(r_, g_, b_, 1.0f);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
if(!currentPose_->isNull())
{
glm::vec3 position(currentPose_->x(), currentPose_->y(), currentPose_->z());
Eigen::Quaternionf quat = currentPose_->getQuaternionf();
glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
glm::mat4 rotateM;
if(gesture_camera_->GetCameraType() == tango_gl::GestureCamera::kFirstPerson)
{
rotateM = glm::rotate<float>(float(color_camera_to_display_rotation_)*1.57079632679489661923132169163975144, glm::vec3(0.0f, 0.0f, 1.0f));
}
if(!currentPose_->isNull())
{
glm::vec3 position(currentPose_->x(), currentPose_->y(), currentPose_->z());
Eigen::Quaternionf quat = currentPose_->getQuaternionf();
glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
if (gesture_camera_->GetCameraType() == tango_gl::GestureCamera::kFirstPerson)
{
// In first person mode, we directly control camera's motion.
gesture_camera_->SetPosition(position);
gesture_camera_->SetRotation(rotation);
}
else
{
// In third person or top down mode, we follow the camera movement.
gesture_camera_->SetAnchorPosition(position, rotation);
if (gesture_camera_->GetCameraType() == tango_gl::GestureCamera::kFirstPerson)
{
// In first person mode, we directly control camera's motion.
gesture_camera_->SetPosition(position);
gesture_camera_->SetRotation(rotation);
}
else
{
// In third person or top down mode, we follow the camera movement.
gesture_camera_->SetAnchorPosition(position, rotation);
frustum_->SetPosition(position);
frustum_->SetRotation(rotation);
// Set the frustum scale to 4:3, this doesn't necessarily match the physical
// camera's aspect ratio, this is just for visualization purposes.
frustum_->SetScale(kFrustumScale);
frustum_->Render(gesture_camera_->GetProjectionMatrix(),
gesture_camera_->GetViewMatrix());
frustum_->SetPosition(position);
frustum_->SetRotation(rotation);
// Set the frustum scale to 4:3, this doesn't necessarily match the physical
// camera's aspect ratio, this is just for visualization purposes.
frustum_->SetScale(kFrustumScale);
frustum_->Render(gesture_camera_->GetProjectionMatrix(),
rotateM*gesture_camera_->GetViewMatrix());
axis_->SetPosition(position);
axis_->SetRotation(rotation);
axis_->Render(gesture_camera_->GetProjectionMatrix(),
gesture_camera_->GetViewMatrix());
}
axis_->SetPosition(position);
axis_->SetRotation(rotation);
axis_->Render(gesture_camera_->GetProjectionMatrix(),
rotateM*gesture_camera_->GetViewMatrix());
}
trace_->UpdateVertexArray(position);
if(traceVisible_)
{
trace_->Render(gesture_camera_->GetProjectionMatrix(),
gesture_camera_->GetViewMatrix());
}
}
trace_->UpdateVertexArray(position);
if(traceVisible_)
{
trace_->Render(gesture_camera_->GetProjectionMatrix(),
rotateM*gesture_camera_->GetViewMatrix());
}
if(gridVisible_)
{
grid_->Render(gesture_camera_->GetProjectionMatrix(),
gesture_camera_->GetViewMatrix());
}
if(gridVisible_)
{
grid_->Render(gesture_camera_->GetProjectionMatrix(),
rotateM*gesture_camera_->GetViewMatrix());
}
}
int cloudDrawn=0;
if(mapRendering_ && frustumCulling_)
@@ -382,7 +401,7 @@ int Scene::Render() {
for(unsigned int i=0; i<indices->size(); ++i)
{
++cloudDrawn;
pointClouds_.find(ids[indices->at(i)])->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_, lighting_);
pointClouds_.find(ids[indices->at(i)])->second->Render(gesture_camera_->GetProjectionMatrix(), rotateM*gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_, lighting_);
}
}
}
@@ -393,14 +412,14 @@ int Scene::Render() {
if((mapRendering_ || iter->first < 0) && iter->second->isVisible())
{
++cloudDrawn;
iter->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_, lighting_);
iter->second->Render(gesture_camera_->GetProjectionMatrix(), rotateM*gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_, meshRenderingTexture_, lighting_);
}
}
}
if(graphVisible_ && graph_)
{
graph_->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix());
graph_->Render(gesture_camera_->GetProjectionMatrix(), rotateM*gesture_camera_->GetViewMatrix());
}
return cloudDrawn;
@@ -574,3 +593,12 @@ void Scene::updateMesh(int id, const Mesh & mesh, const cv::Mat & texture)
iter->second->updateMesh(mesh, texture);
}
}
void Scene::updateGain(int id, float gain)
{
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
if(iter != pointClouds_.end())
{
iter->second->setGain(gain);
}
}

View File

@@ -57,6 +57,8 @@ class Scene {
// Setup GL view port.
void SetupViewPort(int w, int h);
void setScreenRotation(int displayRotation, int cameraRotation);
void clear(); // removed all point clouds
// Render loop.
@@ -116,12 +118,14 @@ class Scene {
std::set<int> getAddedClouds() const;
void updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons);
void updateMesh(int id, const Mesh & mesh, const cv::Mat & texture);
void updateGain(int id, float gain);
void setMapRendering(bool enabled) {mapRendering_ = enabled;}
void setMeshRendering(bool enabled, bool withTexture) {meshRendering_ = enabled; meshRenderingTexture_ = withTexture;}
void setPointSize(float size) {pointSize_ = size;}
void setFrustumCulling(bool enabled) {frustumCulling_ = enabled;}
void setLighting(bool enabled) {lighting_ = enabled;}
void setBackgroundColor(float r, float g, float b) {r_=r; g_=g; b_=b;} // 0.0f <> 1.0f
bool isMeshRendering() const {return meshRendering_;}
bool isMeshTexturing() const {return meshRendering_ && meshRenderingTexture_;}
@@ -149,6 +153,8 @@ class Scene {
bool gridVisible_;
bool traceVisible_;
TangoSupportDisplayRotation color_camera_to_display_rotation_;
std::map<int, PointCloudDrawable*> pointClouds_;
rtabmap::Transform * currentPose_;
@@ -164,6 +170,9 @@ class Scene {
float pointSize_;
bool frustumCulling_;
bool lighting_;
float r_;
float g_;
float b_;
};
#endif // TANGO_POINT_CLOUD_SCENE_H_

View File

@@ -25,6 +25,7 @@
#include <android/log.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <tango_support_api.h>
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
@@ -76,6 +77,33 @@ namespace util {
const glm::vec3& start, const glm::vec3& end);
glm::vec3 ApplyTransform(const glm::mat4& mat, const glm::vec3& vec);
// Get the Android rotation integer value from color camera to display.
// This function is used to compute the orientation difference to handle
// the portrait and landscape mode for color camera display.
//
// @param display: integer value of display orientation, values available
// are 0, 1, 2 ,3. Followed by Android display orientation standard:
// https://developer.android.com/reference/android/view/Display.html#getRotation()
// @param color_camera: integer value of color camera oreintation, values
// available are 0, 90, 180, 270. Followed by Android camera orientation
// standard:
// https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#orientation
TangoSupportDisplayRotation GetAndroidRotationFromColorCameraToDisplay(
int display_rotation, int color_camera_rotation);
// Get the Android rotation integer value from color camera to display.
// This function is used to compute the orientation difference to handle
// the portrait and landscape mode for color camera display.
//
// @param display: the device display orientation.
// @param color_camera: integer value of color camera oreintation, values
// available are 0, 90, 180, 270. Followed by Android camera orientation
// standard:
// https://developer.android.com/reference/android/hardware/Camera.CameraInfo.html#orientation
TangoSupportDisplayRotation GetAndroidRotationFromColorCameraToDisplay(
TangoSupportDisplayRotation display_rotation, int color_camera_rotation);
} // namespace util
} // namespace tango_gl
#endif // TANGO_GL_RENDERER_GL_UTIL

View File

@@ -19,6 +19,27 @@
namespace tango_gl {
namespace {
int NormalizedColorCameraRotation(int camera_rotation) {
int camera_n = 0;
switch (camera_rotation) {
case 90:
camera_n = 1;
break;
case 180:
camera_n = 2;
break;
case 270:
camera_n = 3;
break;
default:
camera_n = 0;
break;
}
return camera_n;
}
} // annonymous namespace
void util::CheckGlError(const char* operation) {
for (GLint error = glGetError(); error; error = glGetError()) {
LOGE("after %s() glError (0x%x)\n", operation, error);
@@ -217,4 +238,23 @@ glm::vec3 util::ApplyTransform(const glm::mat4& mat, const glm::vec3& vec) {
return glm::vec3(mat * glm::vec4(vec, 1.0f));
}
TangoSupportDisplayRotation util::GetAndroidRotationFromColorCameraToDisplay(
int display_rotation, int color_camera_rotation) {
TangoSupportDisplayRotation r =
static_cast<TangoSupportDisplayRotation>(display_rotation);
return util::GetAndroidRotationFromColorCameraToDisplay(
r, color_camera_rotation);
}
TangoSupportDisplayRotation util::GetAndroidRotationFromColorCameraToDisplay(
TangoSupportDisplayRotation display_rotation, int color_camera_rotation) {
int color_camera_n = NormalizedColorCameraRotation(color_camera_rotation);
int ret = static_cast<int>(display_rotation) - color_camera_n;
if (ret < 0) {
ret += 4;
}
return static_cast<TangoSupportDisplayRotation>(ret % 4);
}
} // namespace tango_gl

View File

@@ -23,15 +23,15 @@
android:layout_height="fill_parent"
android:layout_gravity="top" />
<LinearLayout
android:id="@+id/debug_layout"
<LinearLayout
android:id="@+id/status_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:orientation="vertical"
android:paddingLeft="5dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -47,6 +47,48 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/memory" />
<TextView
android:id="@+id/memory"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/free_memory" />
<TextView
android:id="@+id/free_memory"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/debug_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:orientation="vertical"
android:layout_below="@+id/status_layout"
android:paddingLeft="5dp" >
<LinearLayout
android:layout_width="wrap_content"
@@ -88,29 +130,14 @@
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/memory" />
android:text="@string/database_size" />
<TextView
android:id="@+id/memory"
android:id="@+id/database_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/db_size" />
<TextView
android:id="@+id/db_size"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
@@ -178,6 +205,21 @@
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rehearsal" />
<TextView
android:id="@+id/rehearsal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -3,12 +3,12 @@
<PreferenceCategory
android:title="@string/pref_title_rendering">
<ListPreference
android:key="@string/pref_key_decimation"
android:title="@string/pref_title_decimation"
android:summary="@string/pref_summary_decimation"
android:entries="@array/pref_decimation_keys"
android:entryValues="@array/pref_decimation_values"
android:defaultValue="@string/pref_default_decimation"/>
android:key="@string/pref_key_density"
android:title="@string/pref_title_density"
android:summary="@string/pref_summary_density"
android:entries="@array/pref_density_keys"
android:entryValues="@array/pref_density_values"
android:defaultValue="@string/pref_default_density"/>
<ListPreference
android:key="@string/pref_key_depth"
android:title="@string/pref_title_depth"
@@ -43,160 +43,199 @@
android:summary="@string/pref_summary_nodes_filtering"
android:defaultValue="@string/pref_default_nodes_filtering"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/pref_title_mapping">
<PreferenceScreen
android:key="pref_button_mapping"
android:title="@string/pref_title_mapping"
android:summary="@string/pref_summary_mapping"
android:persistent="false">
<SwitchPreference
android:key="@string/pref_key_append"
android:title="@string/pref_title_append"
android:summary="@string/pref_summary_append"
android:defaultValue="@string/pref_default_append"/>
<SwitchPreference
android:key="@string/pref_key_drift_correction"
android:title="@string/pref_title_drift_correction"
android:summary="@string/pref_summary_drift_correction"
android:defaultValue="@string/pref_default_drift_correction"/>
<SwitchPreference
android:key="@string/pref_key_auto_exposure"
android:title="@string/pref_title_auto_exposure"
android:summary="@string/pref_summary_auto_exposure"
android:defaultValue="@string/pref_default_auto_exposure"/>
<SwitchPreference
android:key="@string/pref_key_resolution"
android:title="@string/pref_title_resolution"
android:summary="@string/pref_summary_resolution"
android:defaultValue="@string/pref_default_resolution"/>
<ListPreference
android:key="@string/pref_key_update_rate"
android:title="@string/pref_title_update_rate"
android:summary="@string/pref_summary_update_rate"
android:entries="@array/pref_update_rate_keys"
android:entryValues="@array/pref_update_rate_values"
android:defaultValue="@string/pref_default_update_rate"/>
<ListPreference
android:key="@string/pref_key_time_thr"
android:title="@string/pref_title_time_thr"
android:summary="@string/pref_summary_time_thr"
android:entries="@array/pref_time_thr_keys"
android:entryValues="@array/pref_time_thr_values"
android:defaultValue="@string/pref_default_time_thr"/>
<ListPreference
android:key="@string/pref_key_loop_thr"
android:title="@string/pref_title_loop_thr"
android:summary="@string/pref_summary_loop_thr"
android:entries="@array/pref_loop_thr_keys"
android:entryValues="@array/pref_loop_thr_values"
android:defaultValue="@string/pref_default_loop_thr"/>
<ListPreference
android:key="@string/pref_key_opt_error"
android:title="@string/pref_title_opt_error"
android:summary="@string/pref_summary_opt_error"
android:entries="@array/pref_opt_error_keys"
android:entryValues="@array/pref_opt_error_values"
android:defaultValue="@string/pref_default_opt_error"/>
<ListPreference
android:key="@string/pref_key_features"
android:title="@string/pref_title_features"
android:summary="@string/pref_summary_features"
android:entries="@array/pref_features_keys"
android:entryValues="@array/pref_features_values"
android:defaultValue="@string/pref_default_features"/>
<ListPreference
android:key="@string/pref_key_features_type"
android:title="@string/pref_title_features_type"
android:summary="@string/pref_summary_features_type"
android:entries="@array/pref_features_type_keys"
android:entryValues="@array/pref_features_type_values"
android:defaultValue="@string/pref_default_features_type"/>
</PreferenceScreen>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/pref_title_export">
<PreferenceScreen
android:key="pref_button_export"
android:title="@string/pref_title_export"
android:summary="@string/pref_summary_export"
android:persistent="false">
<ListPreference
android:key="@string/pref_key_cloud_voxel"
android:title="@string/pref_title_cloud_voxel"
android:summary="@string/pref_summary_cloud_voxel"
android:entries="@array/pref_cloud_voxel_keys"
android:entryValues="@array/pref_cloud_voxel_values"
android:defaultValue="@string/pref_default_cloud_voxel"/>
<ListPreference
android:key="@string/pref_key_texture_size"
android:title="@string/pref_title_texture_size"
android:summary="@string/pref_summary_texture_size"
android:entries="@array/pref_texture_size_keys"
android:entryValues="@array/pref_texture_size_values"
android:defaultValue="@string/pref_default_texture_size"/>
<ListPreference
android:key="@string/pref_key_normal_k"
android:title="@string/pref_title_normal_k"
android:summary="@string/pref_summary_normal_k"
android:entries="@array/pref_normal_k_values"
android:entryValues="@array/pref_normal_k_values"
android:defaultValue="@string/pref_default_normal_k"/>
<SwitchPreference
android:key="@string/pref_key_block_render"
android:title="@string/pref_title_block_render"
android:summary="@string/pref_summary_block_render"
android:defaultValue="@string/pref_default_block_render"/>
<PreferenceCategory
android:title="@string/pref_title_optimized">
<ListPreference
android:key="@string/pref_key_opt_depth"
android:title="@string/pref_title_opt_depth"
android:summary="@string/pref_summary_opt_depth"
android:entries="@array/pref_opt_depth_values"
android:entryValues="@array/pref_opt_depth_values"
android:defaultValue="@string/pref_default_opt_depth"/>
<ListPreference
android:key="@string/pref_key_opt_decimation_factor"
android:title="@string/pref_title_opt_decimation_factor"
android:summary="@string/pref_summary_opt_decimation_factor"
android:entries="@array/pref_opt_decimation_factor_keys"
android:entryValues="@array/pref_opt_decimation_factor_values"
android:defaultValue="@string/pref_default_opt_decimation_factor"/>
<ListPreference
android:key="@string/pref_key_opt_color_radius"
android:title="@string/pref_title_opt_color_radius"
android:summary="@string/pref_summary_opt_color_radius"
android:entries="@array/pref_opt_color_radius_keys"
android:entryValues="@array/pref_opt_color_radius_values"
android:defaultValue="@string/pref_default_opt_color_radius"/>
<SwitchPreference
android:key="@string/pref_key_opt_clean_white"
android:title="@string/pref_title_opt_clean_white"
android:summary="@string/pref_summary_opt_clean_white"
android:defaultValue="@string/pref_default_opt_clean_white"/>
</PreferenceCategory>
</PreferenceScreen>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/pref_title_general">
<PreferenceScreen
android:key="pref_button_mapping"
android:title="@string/pref_title_mapping_sub"
android:summary="@string/pref_summary_mapping"
android:persistent="false">
<SwitchPreference
android:key="@string/pref_key_append"
android:title="@string/pref_title_append"
android:summary="@string/pref_summary_append"
android:defaultValue="@string/pref_default_append"/>
<SwitchPreference
android:key="@string/pref_key_auto_exposure"
android:title="@string/pref_title_auto_exposure"
android:summary="@string/pref_summary_auto_exposure"
android:defaultValue="@string/pref_default_auto_exposure"/>
<SwitchPreference
android:key="@string/pref_key_resolution"
android:title="@string/pref_title_resolution"
android:summary="@string/pref_summary_resolution"
android:defaultValue="@string/pref_default_resolution"/>
<PreferenceCategory
android:title="@string/pref_title_mapping_core">
<ListPreference
android:key="@string/pref_key_update_rate"
android:title="@string/pref_title_update_rate"
android:summary="@string/pref_summary_update_rate"
android:entries="@array/pref_update_rate_keys"
android:entryValues="@array/pref_update_rate_values"
android:defaultValue="@string/pref_default_update_rate"/>
<ListPreference
android:key="@string/pref_key_time_thr"
android:title="@string/pref_title_time_thr"
android:summary="@string/pref_summary_time_thr"
android:entries="@array/pref_time_thr_keys"
android:entryValues="@array/pref_time_thr_values"
android:defaultValue="@string/pref_default_time_thr"/>
<ListPreference
android:key="@string/pref_key_mem_thr"
android:title="@string/pref_title_mem_thr"
android:summary="@string/pref_summary_mem_thr"
android:entries="@array/pref_mem_thr_keys"
android:entryValues="@array/pref_mem_thr_values"
android:defaultValue="@string/pref_default_mem_thr"/>
<ListPreference
android:key="@string/pref_key_loop_thr"
android:title="@string/pref_title_loop_thr"
android:summary="@string/pref_summary_loop_thr"
android:entries="@array/pref_loop_thr_keys"
android:entryValues="@array/pref_loop_thr_values"
android:defaultValue="@string/pref_default_loop_thr"/>
<ListPreference
android:key="@string/pref_key_sim_thr"
android:title="@string/pref_title_sim_thr"
android:summary="@string/pref_summary_sim_thr"
android:entries="@array/pref_sim_thr_keys"
android:entryValues="@array/pref_sim_thr_values"
android:defaultValue="@string/pref_default_sim_thr"/>
<ListPreference
android:key="@string/pref_key_opt_error"
android:title="@string/pref_title_opt_error"
android:summary="@string/pref_summary_opt_error"
android:entries="@array/pref_opt_error_keys"
android:entryValues="@array/pref_opt_error_values"
android:defaultValue="@string/pref_default_opt_error"/>
<ListPreference
android:key="@string/pref_key_features_voc"
android:title="@string/pref_title_features_voc"
android:summary="@string/pref_summary_features_voc"
android:entries="@array/pref_features_voc_keys"
android:entryValues="@array/pref_features_voc_values"
android:defaultValue="@string/pref_default_features_voc"/>
<ListPreference
android:key="@string/pref_key_features"
android:title="@string/pref_title_features"
android:summary="@string/pref_summary_features"
android:entries="@array/pref_features_keys"
android:entryValues="@array/pref_features_values"
android:defaultValue="@string/pref_default_features"/>
<ListPreference
android:key="@string/pref_key_features_type"
android:title="@string/pref_title_features_type"
android:summary="@string/pref_summary_features_type"
android:entries="@array/pref_features_type_keys"
android:entryValues="@array/pref_features_type_values"
android:defaultValue="@string/pref_default_features_type"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/pref_title_mapping_database">
<SwitchPreference
android:key="@string/pref_key_keep_all_db"
android:title="@string/pref_title_keep_all_db"
android:summary="@string/pref_summary_keep_all_db"
android:defaultValue="@string/pref_default_keep_all_db"/>
<SwitchPreference
android:key="@string/pref_key_raw_scan_saved"
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_db_in_memory"
android:title="@string/pref_title_db_in_memory"
android:summary="@string/pref_summary_db_in_memory"
android:defaultValue="@string/pref_default_db_in_memory"/>
</PreferenceCategory>
</PreferenceScreen>
<PreferenceScreen
android:key="pref_button_export"
android:title="@string/pref_title_export_sub"
android:summary="@string/pref_summary_export"
android:persistent="false">
<ListPreference
android:key="@string/pref_key_cloud_voxel"
android:title="@string/pref_title_cloud_voxel"
android:summary="@string/pref_summary_cloud_voxel"
android:entries="@array/pref_cloud_voxel_keys"
android:entryValues="@array/pref_cloud_voxel_values"
android:defaultValue="@string/pref_default_cloud_voxel"/>
<ListPreference
android:key="@string/pref_key_texture_size"
android:title="@string/pref_title_texture_size"
android:summary="@string/pref_summary_texture_size"
android:entries="@array/pref_texture_size_keys"
android:entryValues="@array/pref_texture_size_values"
android:defaultValue="@string/pref_default_texture_size"/>
<ListPreference
android:key="@string/pref_key_normal_k"
android:title="@string/pref_title_normal_k"
android:summary="@string/pref_summary_normal_k"
android:entries="@array/pref_normal_k_values"
android:entryValues="@array/pref_normal_k_values"
android:defaultValue="@string/pref_default_normal_k"/>
<ListPreference
android:key="@string/pref_key_max_texture_distance"
android:title="@string/pref_title_max_texture_distance"
android:summary="@string/pref_summary_max_texture_distance"
android:entries="@array/pref_max_texture_distance_keys"
android:entryValues="@array/pref_max_texture_distance_values"
android:defaultValue="@string/pref_default_max_texture_distance"/>
<SwitchPreference
android:key="@string/pref_key_block_render"
android:title="@string/pref_title_block_render"
android:summary="@string/pref_summary_block_render"
android:defaultValue="@string/pref_default_block_render"/>
<PreferenceCategory
android:title="@string/pref_title_optimized">
<ListPreference
android:key="@string/pref_key_opt_depth"
android:title="@string/pref_title_opt_depth"
android:summary="@string/pref_summary_opt_depth"
android:entries="@array/pref_opt_depth_values"
android:entryValues="@array/pref_opt_depth_values"
android:defaultValue="@string/pref_default_opt_depth"/>
<ListPreference
android:key="@string/pref_key_opt_decimation_factor"
android:title="@string/pref_title_opt_decimation_factor"
android:summary="@string/pref_summary_opt_decimation_factor"
android:entries="@array/pref_opt_decimation_factor_keys"
android:entryValues="@array/pref_opt_decimation_factor_values"
android:defaultValue="@string/pref_default_opt_decimation_factor"/>
<ListPreference
android:key="@string/pref_key_opt_color_radius"
android:title="@string/pref_title_opt_color_radius"
android:summary="@string/pref_summary_opt_color_radius"
android:entries="@array/pref_opt_color_radius_keys"
android:entryValues="@array/pref_opt_color_radius_values"
android:defaultValue="@string/pref_default_opt_color_radius"/>
<SwitchPreference
android:key="@string/pref_key_opt_clean_white"
android:title="@string/pref_title_opt_clean_white"
android:summary="@string/pref_summary_opt_clean_white"
android:defaultValue="@string/pref_default_opt_clean_white"/>
</PreferenceCategory>
</PreferenceScreen>
<ListPreference
android:key="@string/pref_key_gain_max_radius"
android:title="@string/pref_title_gain_max_radius"

View File

@@ -8,6 +8,7 @@
<item android:id="@+id/texture_mesh" android:checked="true" android:title="Texture Mesh" />
</group>
<item android:id="@+id/save" android:title="Save" android:showAsAction="ifRoom"/>
<item android:id="@+id/post_processing" android:title="Optimize" android:showAsAction="ifRoom">
<menu>
<item android:id="@+id/post_processing_standard" android:title="Standard Optimization" />
@@ -15,7 +16,6 @@
<menu>
<item android:id="@+id/global_graph_optimization" android:title="Global Graph Optimization" />
<item android:id="@+id/detect_more_loop_closures" android:title="Detect More Loop Closures" />
<item android:id="@+id/icp_refining" android:title="ICP Refining" />
<item android:id="@+id/gain_compensation_fast" android:title="Adjust Colors (Fast)" />
<item android:id="@+id/gain_compensation_full" android:title="Adjust Colors (Full)" />
<item android:id="@+id/bilateral_filtering" android:title="Mesh Smoothing" />
@@ -25,6 +25,7 @@
</item>
</menu>
</item>
<item android:id="@+id/export" android:showAsAction="ifRoom" android:title="Export">
<menu>
<item android:id="@+id/export_point_cloud" android:title="Point Cloud (*.ply)" />

View File

@@ -2,7 +2,7 @@
<resources>
<string name="app_name">RTAB-Map</string>
<string name="sys_name">RTAB-Map</string>
<string name="menu_name">Real-Time Appearance-Based Mapping</string>
<string name="menu_name">RTAB-Map</string>
<string name="settings">Settings</string>
<string name="dropbox">Dropbox</string>
<string name="status">"Status: "</string>
@@ -20,12 +20,14 @@
<string name="points">"Number of points: "</string>
<string name="update_time">"Update time (ms): "</string>
<string name="loop_closure">"Loop closure ID: "</string>
<string name="db_size">"Database (MB): "</string>
<string name="free_memory">"Free Memory (MB): "</string>
<string name="database_size">"Database (MB): "</string>
<string name="total_loop">"Loop closures: "</string>
<string name="inliers">"Inliers: "</string>
<string name="features">"Features: "</string>
<string name="rehearsal">"Rehearsal: "</string>
<string name="polygons">"Polygons: "</string>
<string name="memory">"Memory (MB): "</string>
<string name="memory">"Used Memory (MB): "</string>
<string name="hypothesis">"Hypothesis: "</string>
<string name="fps">"FPS (rendering): "</string>
@@ -33,7 +35,7 @@
<string name="pref_key_rendering">pref_key_rendering</string><string name="pref_default_rendering">2</string>
<string name="pref_key_reset_button">pref_key_reset_button</string>
<string name="pref_key_decimation">pref_key_decimation</string> <string name="pref_default_decimation">0</string>
<string name="pref_key_density">pref_key_density</string> <string name="pref_default_density">1</string>
<string name="pref_key_depth">pref_key_depth</string> <string name="pref_default_depth">0</string>
<string name="pref_key_point_size">pref_key_point_size</string> <string name="pref_default_point_size">5</string>
<string name="pref_key_angle">pref_key_angle</string> <string name="pref_default_angle">15</string>
@@ -41,23 +43,29 @@
<string name="pref_key_nodes_filtering">pref_key_nodes_filtering</string> <string name="pref_default_nodes_filtering">false</string>
<string name="pref_key_append">pref_key_append</string> <string name="pref_default_append">true</string>
<string name="pref_key_drift_correction">pref_key_drift_correction</string> <string name="pref_default_drift_correction">false</string>
<string name="pref_key_auto_exposure">pref_key_auto_exposure</string> <string name="pref_default_auto_exposure">true</string>
<string name="pref_key_resolution">pref_key_resolution</string> <string name="pref_default_resolution">false</string>
<string name="pref_key_update_rate">pref_key_update_rate</string> <string name="pref_default_update_rate">1</string>
<string name="pref_key_time_thr">pref_key_time_thr</string> <string name="pref_default_time_thr">800</string>
<string name="pref_key_time_thr">pref_key_time_thr</string> <string name="pref_default_time_thr">1000</string>
<string name="pref_key_mem_thr">pref_key_mem_thr</string> <string name="pref_default_mem_thr">0</string>
<string name="pref_key_loop_thr">pref_key_loop_thr</string> <string name="pref_default_loop_thr">0.11</string>
<string name="pref_key_sim_thr">pref_key_sim_thr</string> <string name="pref_default_sim_thr">0.3</string>
<string name="pref_key_opt_error">pref_key_opt_error</string> <string name="pref_default_opt_error">0.1</string>
<string name="pref_key_features_voc">pref_key_features_voc</string> <string name="pref_default_features_voc">200</string>
<string name="pref_key_features">pref_key_features</string> <string name="pref_default_features">400</string>
<string name="pref_key_features_type">pref_key_features_type</string> <string name="pref_default_features_type">6</string>
<string name="pref_key_keep_all_db">pref_key_keep_all_db</string> <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_db_in_memory">pref_key_db_in_memory</string> <string name="pref_default_db_in_memory">true</string>
<string name="pref_key_cloud_voxel">pref_key_cloud_voxel</string> <string name="pref_default_cloud_voxel">0</string>
<string name="pref_key_cloud_voxel">pref_key_cloud_voxel</string> <string name="pref_default_cloud_voxel">0.01</string>
<string name="pref_key_texture_size">pref_key_texture_size</string> <string name="pref_default_texture_size">4096</string>
<string name="pref_key_normal_k">pref_key_normal_k</string> <string name="pref_default_normal_k">6</string>
<string name="pref_key_max_texture_distance">pref_key_max_texture_distance</string> <string name="pref_default_max_texture_distance">0</string>
<string name="pref_key_block_render">pref_key_block_render</string> <string name="pref_default_block_render">false</string>
<string name="pref_key_opt_depth">pref_key_opt_depth</string> <string name="pref_default_opt_depth">8</string>
<string name="pref_key_opt_depth">pref_key_opt_depth</string> <string name="pref_default_opt_depth">9</string>
<string name="pref_key_opt_decimation_factor">pref_key_opt_decimation_factor</string><string name="pref_default_opt_decimation_factor">80</string>
<string name="pref_key_opt_color_radius">pref_key_opt_color_radius</string> <string name="pref_default_opt_color_radius">0.0</string>
<string name="pref_key_opt_color_radius">pref_key_opt_color_radius</string> <string name="pref_default_opt_color_radius">0</string>
<string name="pref_key_opt_clean_white">pref_key_opt_clean_white</string> <string name="pref_default_opt_clean_white">true</string>
<string name="pref_key_gain_max_radius">pref_key_gain_max_radius</string> <string name="pref_default_gain_max_radius">0.02</string>
@@ -66,8 +74,8 @@
<string name="pref_title_rendering">Rendering</string>
<string name="pref_title_decimation">Mesh Decimation</string>
<string name="pref_summary_decimation">Decimate the cloud size to reduce rendering time and memory.</string>
<string name="pref_title_density">Point Cloud Density</string>
<string name="pref_summary_density">Decrease density to reduce rendering time and memory. Tip: To apply a different density to current map: save the map, change density and re-open the same map to regenerate the point clouds at this density.</string>
<string name="pref_title_angle">Mesh Angle Tolerance</string>
<string name="pref_summary_angle">Minimum polygon angle.</string>
<string name="pref_title_triangle">Mesh Triangle Size</string>
@@ -77,17 +85,19 @@
<string name="pref_title_point_size">Point Size</string>
<string name="pref_summary_point_size">Size of the points when rendering only the point cloud.</string>
<string name="pref_title_nodes_filtering">Nodes Filtering</string>
<string name="pref_summary_nodes_filtering">Hide close point clouds from rendering.</string>
<string name="pref_summary_nodes_filtering">Render only the newest point cloud of a loop closure.</string>
<string-array name="pref_decimation_keys">
<string-array name="pref_density_keys">
<item>"Maximum"</item>
<item>"High"</item>
<item>"Medium"</item>
<item>"Disabled"</item>
<item>"Low"</item>
<item>"Very Low"</item>
</string-array>
<string-array name="pref_decimation_values">
<item>"2"</item>
<item>"1"</item>
<string-array name="pref_density_values">
<item>"0"</item>
<item>"1"</item>
<item>"2"</item>
<item>"3"</item>
</string-array>
<string-array name="pref_depth_keys">
@@ -148,13 +158,14 @@
<item>"2"</item>
</string-array>
<string name="pref_title_mapping_sub">Mapping...</string>
<string name="pref_title_mapping">Mapping</string>
<string name="pref_summary_mapping">Advanced mapping parameters for fine tuning.</string>
<string name="pref_title_mapping_core">Core</string>
<string name="pref_title_mapping_database">Database</string>
<string name="pref_title_append">Append Mode</string>
<string name="pref_summary_append">When resuming mapping, wait for a relocalization on the current map before starting a new map.</string>
<string name="pref_title_drift_correction">Drift Correction</string>
<string name="pref_summary_drift_correction">Iterative-closest-point (ICP) is done to refine geometrically the links in the map. Use only when environment is highly geometric. Camera should move slowly.</string>
<string name="pref_title_auto_exposure">Auto Exposure</string>
<string name="pref_summary_auto_exposure">Adjust camera exposure depending on the lighting to get always maximum contrast. This may change texture color between scanned images. Color correction option in Post-Processing can help to uniformize colors. May not work on some devices.</string>
<string name="pref_title_resolution">HD Mode</string>
@@ -164,14 +175,26 @@
<string name="pref_summary_update_rate">Rate at which a new node is added to map.</string>
<string name="pref_title_time_thr">Time Limit</string>
<string name="pref_summary_time_thr">Maximum time allowed for map updates. If time to add a new node is above this theshold, some old parts of the map are temporarly forgotten to reduce time of next updates.</string>
<string name="pref_title_mem_thr">Memory Limit</string>
<string name="pref_summary_mem_thr">Maximum nodes kept in working memory.</string>
<string name="pref_title_loop_thr">Loop Closure Threshold</string>
<string name="pref_summary_loop_thr">Threshold at which loop closure hypotheses are accepted. Higher means more robust to false loop closures while rejecting more good loop closures.</string>
<string name="pref_title_sim_thr">Similarity Threshold</string>
<string name="pref_summary_sim_thr">Threshold at which consecutive images are considered the same, so the corresponding node\'s weight is increased. The background turns dark blue when this happens.</string>
<string name="pref_title_opt_error">Max Optimization Error</string>
<string name="pref_summary_opt_error">Reject any loop closures causing error corrections in the map higher than this threshold.</string>
<string name="pref_title_features">Max Features Extracted</string>
<string name="pref_summary_features">Extracting more features per image would result in better loop closure detection but more processing time required.</string>
<string name="pref_title_features_voc">Max Features Extracted (Vocabulary)</string>
<string name="pref_summary_features_voc">Extracting more features per image would result in better loop closure hypotheses but more processing time is required.</string>
<string name="pref_title_features">Max Features Extracted (Loop Closure)</string>
<string name="pref_summary_features">Extracting more features per image would result in better loop closure transforms but more processing time is required.</string>
<string name="pref_title_features_type">Feature Type</string>
<string name="pref_summary_features_type">BRIEF features are fast to compute but are not rotation invariant like FREAK. Warning: Changing feature type will automatically reset the map!</string>
<string name="pref_title_keep_all_db">Save All Frames in Database</string>
<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_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>
<string-array name="pref_update_rate_keys">
<item>"Max"</item>
@@ -223,6 +246,25 @@
<item>"400"</item>
</string-array>
<string-array name="pref_mem_thr_keys">
<item>"No Limit"</item>
<item>"500 nodes"</item>
<item>"400 nodes"</item>
<item>"300 nodes"</item>
<item>"200 nodes"</item>
<item>"100 nodes"</item>
<item>"50 nodes"</item>
</string-array>
<string-array name="pref_mem_thr_values">
<item>"0"</item>
<item>"500"</item>
<item>"400"</item>
<item>"300"</item>
<item>"200"</item>
<item>"100"</item>
<item>"50"</item>
</string-array>
<string-array name="pref_loop_thr_keys">
<item>"0.90"</item>
<item>"0.80"</item>
@@ -232,7 +274,9 @@
<item>"0.40"</item>
<item>"0.30"</item>
<item>"0.20"</item>
<item>"0.15"</item>
<item>"0.11"</item>
<item>"0.10"</item>
</string-array>
<string-array name="pref_loop_thr_values">
<item>"0.90"</item>
@@ -243,7 +287,28 @@
<item>"0.40"</item>
<item>"0.30"</item>
<item>"0.20"</item>
<item>"0.15"</item>
<item>"0.11"</item>
<item>"0.10"</item>
</string-array>
<string-array name="pref_sim_thr_keys">
<item>"Disabled"</item>
<item>"0.60"</item>
<item>"0.50"</item>
<item>"0.40"</item>
<item>"0.30"</item>
<item>"0.20"</item>
<item>"0.10"</item>
</string-array>
<string-array name="pref_sim_thr_values">
<item>"0"</item>
<item>"0.6"</item>
<item>"0.5"</item>
<item>"0.4"</item>
<item>"0.3"</item>
<item>"0.2"</item>
<item>"0.1"</item>
</string-array>
<string-array name="pref_opt_error_keys">
@@ -269,7 +334,7 @@
<item>"0"</item>
</string-array>
<string-array name="pref_features_keys">
<string-array name="pref_features_voc_keys">
<item>"No Limit"</item>
<item>"1000"</item>
<item>"900"</item>
@@ -283,7 +348,7 @@
<item>"100"</item>
<item>"Disabled"</item>
</string-array>
<string-array name="pref_features_values">
<string-array name="pref_features_voc_values">
<item>"0"</item>
<item>"1000"</item>
<item>"900"</item>
@@ -298,6 +363,33 @@
<item>"-1"</item>
</string-array>
<string-array name="pref_features_keys">
<item>"No Limit"</item>
<item>"1000"</item>
<item>"900"</item>
<item>"800"</item>
<item>"700"</item>
<item>"600"</item>
<item>"500"</item>
<item>"400"</item>
<item>"300"</item>
<item>"200"</item>
<item>"100"</item>
</string-array>
<string-array name="pref_features_values">
<item>"0"</item>
<item>"1000"</item>
<item>"900"</item>
<item>"800"</item>
<item>"700"</item>
<item>"600"</item>
<item>"500"</item>
<item>"400"</item>
<item>"300"</item>
<item>"200"</item>
<item>"100"</item>
</string-array>
<string-array name="pref_features_type_keys">
<item>"BRIEF"</item>
<item>"FREAK"</item>
@@ -307,6 +399,7 @@
<item>"5"</item>
</string-array>
<string name="pref_title_export_sub">Exporting...</string>
<string name="pref_title_export">Exporting</string>
<string name="pref_summary_export">Advanced parameters used when exporting the map.</string>
@@ -316,8 +409,10 @@
<string name="pref_summary_texture_size">If the map is large, you may want to increase this to maximize the texture resolution.</string>
<string name="pref_title_normal_k">Normal K</string>
<string name="pref_summary_normal_k">K-nearest neighbors used for normal computation when a mesh is created.</string>
<string name="pref_title_max_texture_distance">Max Texture Distance</string>
<string name="pref_summary_max_texture_distance">Maximum distance from a camera for polygons to be textured by this camera.</string>
<string name="pref_title_block_render">Block Rendering Thread While Exporting</string>
<string name="pref_summary_block_render">This decreases exporting time, but freezes rendering while exporting.</string>
<string name="pref_summary_block_render">This decreases exporting time, but freezes rendering while exporting. This also clears temporary the rendered clouds/meshes from memory during exporting, this can be useful to avoid out of memory errors.</string>
<string-array name="pref_cloud_voxel_keys">
<item>"0.2 m"</item>
@@ -325,6 +420,7 @@
<item>"0.05 m"</item>
<item>"0.02 m"</item>
<item>"0.01 m"</item>
<item>"0.005 m"</item>
<item>"Disabled"</item>
</string-array>
<string-array name="pref_cloud_voxel_values">
@@ -333,6 +429,7 @@
<item>"0.05"</item>
<item>"0.02"</item>
<item>"0.01"</item>
<item>"0.005"</item>
<item>"0"</item>
</string-array>
@@ -358,6 +455,27 @@
<item>"12"</item>
<item>"6"</item>
</string-array>
<string-array name="pref_max_texture_distance_keys">
<item>"No Limit"</item>
<item>"5 m"</item>
<item>"4.5 m"</item>
<item>"4 m"</item>
<item>"3.5 m"</item>
<item>"3 m"</item>
<item>"2.5 m"</item>
<item>"2 m"</item>
</string-array>
<string-array name="pref_max_texture_distance_values">
<item>"0"</item>
<item>"5"</item>
<item>"4.5"</item>
<item>"4"</item>
<item>"3.5"</item>
<item>"3"</item>
<item>"2.5"</item>
<item>"2"</item>
</string-array>
<string name="pref_title_optimized">Optimized</string>
@@ -431,7 +549,7 @@
<string name="pref_title_general">General</string>
<string name="pref_title_gain_max_radius">Color Correction Radius</string>
<string name="pref_summary_gain_max_radius">Radius used to find pixel correspondences for color correction.</string>
<string name="pref_summary_gain_max_radius">Radius used to find pixel correspondences for Adjust Colors optimization.</string>
<string name="pref_title_min_cluster_size">Min Cluster Size</string>
<string name="pref_summary_min_cluster_size">Minimum number of polygons for a cluster to be kept after Noise Filtering optimization.</string>

View File

@@ -7,6 +7,8 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
@@ -15,6 +17,8 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Notification;
@@ -30,8 +34,13 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.opengl.GLSurfaceView;
import android.os.AsyncTask;
@@ -49,6 +58,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
@@ -80,6 +90,8 @@ public class RTABMapActivity extends Activity implements OnClickListener {
public static final String EXTRA_VALUE_ADF = "ADF_LOAD_SAVE_PERMISSION";
public static final int ZIP_BUFFER_SIZE = 1<<20; // 1MB
public static final String RTABMAP_TMP_DB = "rtabmap.tmp.db";
private static final String AUTHORIZE_PATH = "https://sketchfab.com/oauth2/authorize";
private static final String CLIENT_ID = "RXrIJYAwlTELpySsyM8TrK9r3kOGQ5Qjj9VVDIfV";
@@ -105,6 +117,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
// Screen size for normalizing the touch input for orbiting the render camera.
private Point mScreenSize = new Point();
private long mOnPauseStamp = 0;
private boolean mOnPause = false;
private MenuItem mItemSave;
@@ -145,19 +158,28 @@ public class RTABMapActivity extends Activity implements OnClickListener {
//Tango Service connection.
ServiceConnection mTangoServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
if(!RTABMapLib.onTangoServiceConnected(service))
{
mToast.makeText(getApplicationContext(),
String.format("Failed to intialize Tango!"), mToast.LENGTH_SHORT).show();
}
public void onServiceConnected(ComponentName name, final IBinder service) {
Thread bindThread = new Thread(new Runnable() {
public void run() {
if(!RTABMapLib.onTangoServiceConnected(service))
{
runOnUiThread(new Runnable() {
public void run() {
mToast.makeText(getApplicationContext(),
String.format("Failed to intialize Tango!"), mToast.LENGTH_LONG).show();
}
});
}
}
});
bindThread.start();
}
public void onServiceDisconnected(ComponentName name) {
// Handle this if you need to gracefully shutdown/retry
// in the event that Tango itself crashes/gets upgraded while running.
mToast.makeText(getApplicationContext(),
String.format("Tango disconnected!"), mToast.LENGTH_SHORT).show();
String.format("Tango disconnected!"), mToast.LENGTH_LONG).show();
}
};
@@ -206,7 +228,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
mGLView.setEGLContextClientVersion(2);
// Configure the OpenGL renderer.
mRenderer = new Renderer();
mRenderer = new Renderer(this);
mGLView.setRenderer(mRenderer);
mLayoutDebug = (LinearLayout) findViewById(R.id.debug_layout);
@@ -243,7 +265,31 @@ public class RTABMapActivity extends Activity implements OnClickListener {
}
RTABMapLib.onCreate(this);
RTABMapLib.openEmptyDatabase();
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(tmpDatabase, databaseInMemory, false);
DisplayManager displayManager = (DisplayManager) getSystemService(DISPLAY_SERVICE);
if (displayManager != null) {
displayManager.registerDisplayListener(new DisplayManager.DisplayListener() {
@Override
public void onDisplayAdded(int displayId) {
}
@Override
public void onDisplayChanged(int displayId) {
synchronized (this) {
setAndroidOrientation();
}
}
@Override
public void onDisplayRemoved(int displayId) {}
}, null);
}
}
@Override
@@ -258,78 +304,126 @@ public class RTABMapActivity extends Activity implements OnClickListener {
}
}
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause()");
mOnPause = true;
// This deletes OpenGL context!
mGLView.onPause();
RTABMapLib.onPause();
unbindService(mTangoServiceConnection);
if(!mButtonPause.isChecked())
{
mButtonPause.setChecked(true);
pauseMapping();
}
mOnPauseStamp = System.currentTimeMillis()/1000;
}
@Override
protected void onResume() {
super.onResume();
// update preferences
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
mUpdateRate = sharedPref.getString(getString(R.string.pref_key_update_rate), getString(R.string.pref_default_update_rate));
mTimeThr = sharedPref.getString(getString(R.string.pref_key_time_thr), getString(R.string.pref_default_time_thr));
mLoopThr = sharedPref.getString(getString(R.string.pref_key_loop_thr), getString(R.string.pref_default_loop_thr));
String optError = sharedPref.getString(getString(R.string.pref_key_opt_error), getString(R.string.pref_default_opt_error));
mMaxFeatures = sharedPref.getString(getString(R.string.pref_key_features), getString(R.string.pref_default_features));
String featureType = sharedPref.getString(getString(R.string.pref_key_features_type), getString(R.string.pref_default_features_type));
RTABMapLib.setNodesFiltering(sharedPref.getBoolean(getString(R.string.pref_key_nodes_filtering), Boolean.parseBoolean(getString(R.string.pref_default_nodes_filtering))));
RTABMapLib.setDriftCorrection(sharedPref.getBoolean(getString(R.string.pref_key_drift_correction), Boolean.parseBoolean(getString(R.string.pref_default_drift_correction))));
RTABMapLib.setAutoExposure(sharedPref.getBoolean(getString(R.string.pref_key_auto_exposure), Boolean.parseBoolean(getString(R.string.pref_default_auto_exposure))));
RTABMapLib.setFullResolution(sharedPref.getBoolean(getString(R.string.pref_key_resolution), Boolean.parseBoolean(getString(R.string.pref_default_resolution))));
RTABMapLib.setAppendMode(sharedPref.getBoolean(getString(R.string.pref_key_append), Boolean.parseBoolean(getString(R.string.pref_default_append))));
RTABMapLib.setMappingParameter("Rtabmap/DetectionRate", mUpdateRate.compareTo("Max")==0?"0":mUpdateRate);
RTABMapLib.setMappingParameter("Rtabmap/TimeThr", mTimeThr.compareTo("No Limit") == 0?"0":mTimeThr);
RTABMapLib.setMappingParameter("Kp/MaxFeatures", mMaxFeatures.compareTo("Disabled")==0?"-1":mMaxFeatures.compareTo("No Limit")==0?"0":mMaxFeatures);
RTABMapLib.setMappingParameter("Rtabmap/LoopThr", mLoopThr.compareTo("Disabled")==0?"1":mLoopThr);
RTABMapLib.setMappingParameter("RGBD/OptimizeMaxError", optError.compareTo("Disabled")==0?"0":optError);
RTABMapLib.setMappingParameter("Kp/DetectorStrategy", featureType);
RTABMapLib.setMeshDecimation(Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_decimation), getString(R.string.pref_default_decimation))));
RTABMapLib.setMaxCloudDepth(Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_depth), getString(R.string.pref_default_depth))));
RTABMapLib.setPointSize(Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_point_size), getString(R.string.pref_default_point_size))));
RTABMapLib.setMeshAngleTolerance(Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_angle), getString(R.string.pref_default_angle))));
RTABMapLib.setMeshTriangleSize(Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_triangle), getString(R.string.pref_default_triangle))));
RTABMapLib.setMinClusterSize(Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_min_cluster_size), getString(R.string.pref_default_min_cluster_size))));
RTABMapLib.setMaxGainRadius(Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_gain_max_radius), getString(R.string.pref_default_gain_max_radius))));
if(mItemRenderingPointCloud != null)
mProgressDialog.setTitle("");
if(mOnPause)
{
int renderingType = sharedPref.getInt(getString(R.string.pref_key_rendering), Integer.parseInt(getString(R.string.pref_default_rendering)));
if(renderingType == 0)
if(System.currentTimeMillis()/1000 - mOnPauseStamp < 1)
{
mItemRenderingPointCloud.setChecked(true);
}
else if(renderingType == 1)
{
mItemRenderingMesh.setChecked(true);
mProgressDialog.setMessage(String.format("RTAB-Map has been interrupted by another application, Tango should be re-initialized! Set your phone/tablet in Airplane mode if this happens often."));
}
else
{
mItemRenderingTextureMesh.setChecked(true);
mProgressDialog.setMessage(String.format("Hold Tight! Initializing Tango Service..."));
}
RTABMapLib.setMeshRendering(
mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked(),
mItemRenderingTextureMesh.isChecked());
}
mProgressDialog.setTitle("");
mProgressDialog.setMessage(String.format("Hold Tight! Initializing Tango Service..."));
mProgressDialog.show();
if(mOnPause)
{
mToast.makeText(this, "Mapping is paused!", mToast.LENGTH_LONG).show();
}
else
{
mToast.makeText(this, "Tip: If the camera is still drifting just after the mapping has started, do \"Reset\".", mToast.LENGTH_LONG).show();
mProgressDialog.setMessage(String.format("Hold Tight! Initializing Tango Service...\nTip: If the camera is still drifting just after the mapping has started, do \"Reset\"."));
}
mProgressDialog.show();
mOnPause = false;
setAndroidOrientation();
TangoInitializationHelper.bindTangoService(this, mTangoServiceConnection);
// update preferences
try
{
Log.d(TAG, "update preferences...");
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
mUpdateRate = sharedPref.getString(getString(R.string.pref_key_update_rate), getString(R.string.pref_default_update_rate));
mTimeThr = sharedPref.getString(getString(R.string.pref_key_time_thr), getString(R.string.pref_default_time_thr));
String memThr = sharedPref.getString(getString(R.string.pref_key_mem_thr), getString(R.string.pref_default_mem_thr));
mLoopThr = sharedPref.getString(getString(R.string.pref_key_loop_thr), getString(R.string.pref_default_loop_thr));
String simThr = sharedPref.getString(getString(R.string.pref_key_sim_thr), getString(R.string.pref_default_sim_thr));
String optError = sharedPref.getString(getString(R.string.pref_key_opt_error), getString(R.string.pref_default_opt_error));
mMaxFeatures = sharedPref.getString(getString(R.string.pref_key_features_voc), getString(R.string.pref_default_features_voc));
String maxFeaturesLoop = sharedPref.getString(getString(R.string.pref_key_features), getString(R.string.pref_default_features));
String featureType = sharedPref.getString(getString(R.string.pref_key_features_type), getString(R.string.pref_default_features_type));
boolean keepAllDb = sharedPref.getBoolean(getString(R.string.pref_key_keep_all_db), Boolean.parseBoolean(getString(R.string.pref_default_keep_all_db)));
Log.d(TAG, "set mapping parameters");
RTABMapLib.setNodesFiltering(sharedPref.getBoolean(getString(R.string.pref_key_nodes_filtering), Boolean.parseBoolean(getString(R.string.pref_default_nodes_filtering))));
RTABMapLib.setAutoExposure(sharedPref.getBoolean(getString(R.string.pref_key_auto_exposure), Boolean.parseBoolean(getString(R.string.pref_default_auto_exposure))));
RTABMapLib.setRawScanSaved(sharedPref.getBoolean(getString(R.string.pref_key_raw_scan_saved), Boolean.parseBoolean(getString(R.string.pref_default_raw_scan_saved))));
RTABMapLib.setFullResolution(sharedPref.getBoolean(getString(R.string.pref_key_resolution), Boolean.parseBoolean(getString(R.string.pref_default_resolution))));
RTABMapLib.setAppendMode(sharedPref.getBoolean(getString(R.string.pref_key_append), Boolean.parseBoolean(getString(R.string.pref_default_append))));
RTABMapLib.setMappingParameter("Rtabmap/DetectionRate", mUpdateRate);
RTABMapLib.setMappingParameter("Rtabmap/TimeThr", mTimeThr);
RTABMapLib.setMappingParameter("Rtabmap/MemoryThr", memThr);
RTABMapLib.setMappingParameter("Mem/RehearsalSimilarity", simThr);
RTABMapLib.setMappingParameter("Kp/MaxFeatures", mMaxFeatures);
RTABMapLib.setMappingParameter("Vis/MaxFeatures", maxFeaturesLoop);
RTABMapLib.setMappingParameter("Rtabmap/LoopThr", mLoopThr);
RTABMapLib.setMappingParameter("RGBD/OptimizeMaxError", optError);
RTABMapLib.setMappingParameter("Kp/DetectorStrategy", featureType);
RTABMapLib.setMappingParameter("Vis/FeatureType", featureType);
RTABMapLib.setMappingParameter("Mem/NotLinkedNodesKept", String.valueOf(keepAllDb));
Log.d(TAG, "set exporting parameters...");
RTABMapLib.setMeshDecimation(Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_density), getString(R.string.pref_default_density))));
RTABMapLib.setMaxCloudDepth(Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_depth), getString(R.string.pref_default_depth))));
RTABMapLib.setPointSize(Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_point_size), getString(R.string.pref_default_point_size))));
RTABMapLib.setMeshAngleTolerance(Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_angle), getString(R.string.pref_default_angle))));
RTABMapLib.setMeshTriangleSize(Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_triangle), getString(R.string.pref_default_triangle))));
Log.d(TAG, "set rendering parameters...");
RTABMapLib.setMinClusterSize(Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_min_cluster_size), getString(R.string.pref_default_min_cluster_size))));
RTABMapLib.setMaxGainRadius(Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_gain_max_radius), getString(R.string.pref_default_gain_max_radius))));
if(mItemRenderingPointCloud != null)
{
int renderingType = sharedPref.getInt(getString(R.string.pref_key_rendering), Integer.parseInt(getString(R.string.pref_default_rendering)));
if(renderingType == 0)
{
mItemRenderingPointCloud.setChecked(true);
}
else if(renderingType == 1)
{
mItemRenderingMesh.setChecked(true);
}
else
{
mItemRenderingTextureMesh.setChecked(true);
}
RTABMapLib.setMeshRendering(
mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked(),
mItemRenderingTextureMesh.isChecked());
}
}
catch(Exception e)
{
Log.e(TAG, "Error parsing preferences: " + e.getMessage());
mToast.makeText(this, String.format("Error parsing preferences: "+e.getMessage()), mToast.LENGTH_LONG).show();
}
Log.i(TAG, String.format("onResume()"));
@@ -343,28 +437,10 @@ public class RTABMapActivity extends Activity implements OnClickListener {
Tango.getRequestPermissionIntent(Tango.PERMISSIONTYPE_MOTION_TRACKING),
Tango.TANGO_INTENT_ACTIVITYCODE);
}
TangoInitializationHelper.bindTangoService(getActivity(), mTangoServiceConnection);
}
@Override
protected void onPause() {
super.onPause();
// This deletes OpenGL context!
mGLView.onPause();
mOnPause = true;
RTABMapLib.onPause();
unbindService(mTangoServiceConnection);
if(!mButtonPause.isChecked())
{
mButtonPause.setChecked(true);
pauseMapping();
}
}
private void setCamera(int type)
{
RTABMapLib.setCamera(type);
@@ -400,6 +476,13 @@ public class RTABMapActivity extends Activity implements OnClickListener {
return;
}
}
private void setAndroidOrientation() {
Display display = getWindowManager().getDefaultDisplay();
Camera.CameraInfo colorCameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(0, colorCameraInfo);
RTABMapLib.setScreenRotation(display.getRotation(), colorCameraInfo.orientation);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
@@ -438,6 +521,9 @@ public class RTABMapActivity extends Activity implements OnClickListener {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.optionmenu, menu);
getActionBar().setDisplayShowHomeEnabled(true);
getActionBar().setIcon(R.drawable.ic_launcher);
mItemSave = menu.findItem(R.id.save);
mItemOpen = menu.findItem(R.id.open);
@@ -458,28 +544,44 @@ public class RTABMapActivity extends Activity implements OnClickListener {
mItemPostProcessing.setEnabled(false);
mItemDataRecorderMode.setEnabled(false);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
int renderingType = sharedPref.getInt(getString(R.string.pref_key_rendering), Integer.parseInt(getString(R.string.pref_default_rendering)));
if(renderingType == 0)
try
{
mItemRenderingPointCloud.setChecked(true);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
int renderingType = sharedPref.getInt(getString(R.string.pref_key_rendering), Integer.parseInt(getString(R.string.pref_default_rendering)));
if(renderingType == 0)
{
mItemRenderingPointCloud.setChecked(true);
}
else if(renderingType == 1)
{
mItemRenderingMesh.setChecked(true);
}
else
{
mItemRenderingTextureMesh.setChecked(true);
}
RTABMapLib.setMeshRendering(
mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked(),
mItemRenderingTextureMesh.isChecked());
}
else if(renderingType == 1)
catch(Exception e)
{
mItemRenderingMesh.setChecked(true);
Log.e(TAG, "Error parsing rendering preferences: " + e.getMessage());
mToast.makeText(this, String.format("Error parsing rendering preferences: "+e.getMessage()), mToast.LENGTH_LONG).show();
}
else
{
mItemRenderingTextureMesh.setChecked(true);
}
RTABMapLib.setMeshRendering(
mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked(),
mItemRenderingTextureMesh.isChecked());
updateState(mState);
return true;
}
private long getFreeMemory()
{
MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
return mi.availMem / 0x100000L; // MB
}
private void updateStatsUI(
int nodes,
@@ -495,7 +597,8 @@ public class RTABMapActivity extends Activity implements OnClickListener {
float hypothesis,
int nodesDrawn,
float fps,
int rejected)
int rejected,
float rehearsalValue)
{
if(mButtonPause!=null)
{
@@ -505,7 +608,8 @@ public class RTABMapActivity extends Activity implements OnClickListener {
}
else
{
((TextView)findViewById(R.id.status)).setText(mItemLocalizationMode.isChecked()?String.format("Localization (%s Hz)", mUpdateRate):mItemDataRecorderMode.isChecked()?String.format("Recording (%s Hz)", mUpdateRate):String.format("Mapping (%s Hz)", mUpdateRate));
String updateValue = mUpdateRate.compareTo("0")==0?"Max":mUpdateRate;
((TextView)findViewById(R.id.status)).setText(mItemLocalizationMode.isChecked()?String.format("Localization (%s Hz)", updateValue):mItemDataRecorderMode.isChecked()?String.format("Recording (%s Hz)", updateValue):String.format("Mapping (%s Hz)", updateValue));
}
}
@@ -514,10 +618,12 @@ public class RTABMapActivity extends Activity implements OnClickListener {
((TextView)findViewById(R.id.nodes)).setText(String.format("%d (%d shown)", nodes, nodesDrawn));
((TextView)findViewById(R.id.words)).setText(String.valueOf(words));
((TextView)findViewById(R.id.memory)).setText(String.valueOf(Debug.getNativeHeapAllocatedSize()/(1024*1024)));
((TextView)findViewById(R.id.db_size)).setText(String.valueOf(databaseMemoryUsed));
((TextView)findViewById(R.id.free_memory)).setText(String.valueOf(getFreeMemory()));
((TextView)findViewById(R.id.database_size)).setText(String.valueOf(databaseMemoryUsed));
((TextView)findViewById(R.id.inliers)).setText(String.valueOf(inliers));
((TextView)findViewById(R.id.features)).setText(String.format("%d / %s", featuresExtracted, mMaxFeatures));
((TextView)findViewById(R.id.update_time)).setText(String.format("%.3f / %s", updateTime, mTimeThr));
((TextView)findViewById(R.id.features)).setText(String.format("%d / %s", featuresExtracted, mMaxFeatures.compareTo("0")==0?"No Limit":mMaxFeatures.compareTo("-1")==0?"Disabled":mMaxFeatures));
((TextView)findViewById(R.id.rehearsal)).setText(String.format("%.3f", rehearsalValue));
((TextView)findViewById(R.id.update_time)).setText(String.format("%.3f / %s", updateTime, mTimeThr.compareTo("0")==0?"No Limit":mTimeThr));
((TextView)findViewById(R.id.hypothesis)).setText(String.format("%.3f / %s (%d)", hypothesis, mLoopThr, loopClosureId>0?loopClosureId:highestHypId));
((TextView)findViewById(R.id.fps)).setText(String.format("%.3f Hz", fps));
if(mButtonPause!=null && !mButtonPause.isChecked())
@@ -553,13 +659,14 @@ public class RTABMapActivity extends Activity implements OnClickListener {
final float hypothesis,
final int nodesDrawn,
final float fps,
final int rejected)
final int rejected,
final float rehearsalValue)
{
Log.i(TAG, String.format("updateStatsCallback()"));
runOnUiThread(new Runnable() {
public void run() {
updateStatsUI(nodes, words, points, polygons, updateTime, loopClosureId, highestHypId, databaseMemoryUsed, inliers, features, hypothesis, nodesDrawn, fps, rejected);
updateStatsUI(nodes, words, points, polygons, updateTime, loopClosureId, highestHypId, databaseMemoryUsed, inliers, features, hypothesis, nodesDrawn, fps, rejected, rehearsalValue);
}
});
}
@@ -692,7 +799,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
@Override
public boolean accept(File dir, String filename) {
File sel = new File(dir, filename);
return filename.endsWith(".db");
return filename.compareTo(RTABMAP_TMP_DB) != 0 && filename.endsWith(".db");
}
};
@@ -859,33 +966,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
});
workingThread.start();
}
else if (itemId == R.id.icp_refining)
{
mProgressDialog.setTitle("Post-Processing");
mProgressDialog.setMessage(String.format("Please wait while refining links..."));
mProgressDialog.show();
updateState(State.STATE_PROCESSING);
Thread workingThread = new Thread(new Runnable() {
public void run() {
final int linksRefined = RTABMapLib.postProcessing(3);
runOnUiThread(new Runnable() {
public void run() {
mProgressDialog.dismiss();
if(linksRefined >= 0)
{
mToast.makeText(getActivity(), String.format("Refining done! %d link(s) refined.", linksRefined), mToast.LENGTH_SHORT).show();
}
else if(linksRefined < 0)
{
mToast.makeText(getActivity(), String.format("Refining failed!"), mToast.LENGTH_SHORT).show();
}
updateState(State.STATE_IDLE);
}
});
}
});
workingThread.start();
}
else if (itemId == R.id.global_graph_optimization)
{
mProgressDialog.setTitle("Post-Processing");
@@ -1201,7 +1281,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
((TextView)findViewById(R.id.nodes)).setText(String.valueOf(0));
((TextView)findViewById(R.id.words)).setText(String.valueOf(0));
((TextView)findViewById(R.id.memory)).setText(String.valueOf(Debug.getNativeHeapAllocatedSize()/(1024*1024)));
((TextView)findViewById(R.id.db_size)).setText(String.valueOf(0));
((TextView)findViewById(R.id.free_memory)).setText(String.valueOf(getFreeMemory()));
((TextView)findViewById(R.id.inliers)).setText(String.valueOf(0));
((TextView)findViewById(R.id.features)).setText(String.valueOf(0));
((TextView)findViewById(R.id.update_time)).setText(String.valueOf(0));
@@ -1210,19 +1290,18 @@ public class RTABMapActivity extends Activity implements OnClickListener {
mTotalLoopClosures = 0;
((TextView)findViewById(R.id.total_loop)).setText(String.valueOf(mTotalLoopClosures));
if(mOpenedDatabasePath.isEmpty())
{
RTABMapLib.resetMapping();
}
else
{
mOpenedDatabasePath = "";
RTABMapLib.openEmptyDatabase();
}
mOpenedDatabasePath = "";
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)));
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
(new File(tmpDatabase)).delete();
RTABMapLib.openDatabase(tmpDatabase, databaseInMemory, false);
mMapIsEmpty = true;
mItemSave.setEnabled(false);
mItemExport.setEnabled(false);
mItemPostProcessing.setEnabled(false);
updateState(State.STATE_IDLE);
}
else if(itemId == R.id.data_recorder)
{
@@ -1238,7 +1317,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
((TextView)findViewById(R.id.nodes)).setText(String.valueOf(0));
((TextView)findViewById(R.id.words)).setText(String.valueOf(0));
((TextView)findViewById(R.id.memory)).setText(String.valueOf(Debug.getNativeHeapAllocatedSize()/(1024*1024)));
((TextView)findViewById(R.id.db_size)).setText(String.valueOf(0));
((TextView)findViewById(R.id.free_memory)).setText(String.valueOf(getFreeMemory()));
((TextView)findViewById(R.id.inliers)).setText(String.valueOf(0));
((TextView)findViewById(R.id.features)).setText(String.valueOf(0));
((TextView)findViewById(R.id.update_time)).setText(String.valueOf(0));
@@ -1251,7 +1330,11 @@ public class RTABMapActivity extends Activity implements OnClickListener {
RTABMapLib.setDataRecorderMode(mItemDataRecorderMode.isChecked());
mOpenedDatabasePath = "";
RTABMapLib.openEmptyDatabase();
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)));
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
(new File(tmpDatabase)).delete();
RTABMapLib.openDatabase(tmpDatabase, databaseInMemory, false);
mItemOpen.setEnabled(!mItemDataRecorderMode.isChecked() && mButtonPause.isChecked());
mItemPostProcessing.setEnabled(!mItemDataRecorderMode.isChecked() && mButtonPause.isChecked());
@@ -1295,6 +1378,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
final float cloudVoxelSize = Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_cloud_voxel), getString(R.string.pref_default_cloud_voxel)));
final int textureSize = isOBJ?Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_texture_size), getString(R.string.pref_default_texture_size))):0;
final int normalK = Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_normal_k), getString(R.string.pref_default_normal_k)));
final float maxTextureDistance = Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_max_texture_distance), getString(R.string.pref_default_max_texture_distance)));
final float optimizedVoxelSize = cloudVoxelSize;
final int optimizedDepth = Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_opt_depth), getString(R.string.pref_default_opt_depth)));
final float optimizedDecimationFactor = Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_opt_decimation_factor), getString(R.string.pref_default_opt_decimation_factor)))/100.0f;
@@ -1353,6 +1437,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
meshing,
textureSize,
normalK,
maxTextureDistance,
optimized,
optimizedVoxelSize,
optimizedDepth,
@@ -1454,6 +1539,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
meshing,
textureSize,
normalK,
maxTextureDistance,
optimized,
optimizedVoxelSize,
optimizedDepth,
@@ -1553,18 +1639,24 @@ public class RTABMapActivity extends Activity implements OnClickListener {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose Your File (*.db)");
builder.setItems(filesWithSize, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mOpenedDatabasePath = mWorkingDirectory + files[which];
if(!mItemTrajectoryMode.isChecked())
{
mProgressDialog.setTitle("Loading");
mProgressDialog.setMessage(String.format("Database \"%s\" loaded. Please wait while creating point clouds and meshes...", files[which]));
mProgressDialog.show();
}
RTABMapLib.openDatabase(mOpenedDatabasePath);
setCamera(1);
public void onClick(DialogInterface dialog, final int which) {
// Smooth and adjust color now?
new AlertDialog.Builder(getActivity())
.setTitle("Opening database...")
.setMessage("Do you want to smooth and 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();
@@ -1584,6 +1676,56 @@ public class RTABMapActivity extends Activity implements OnClickListener {
return true;
}
private void openDatabase(String fileName, boolean optimize)
{
mOpenedDatabasePath = mWorkingDirectory + fileName;
if(!mItemTrajectoryMode.isChecked())
{
mProgressDialog.setTitle("Loading");
mProgressDialog.setMessage(String.format("Database \"%s\" loaded. Please wait while creating point clouds and meshes...", fileName));
mProgressDialog.show();
updateState(State.STATE_PROCESSING);
}
String tmpDatabase = mWorkingDirectory+RTABMAP_TMP_DB;
(new File(tmpDatabase)).delete();
try{
copy(new File(mOpenedDatabasePath), new File(tmpDatabase));
}
catch(IOException e)
{
mToast.makeText(getActivity(), String.format("Failed to create temp database from %s!", mOpenedDatabasePath), mToast.LENGTH_LONG).show();
}
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)));
RTABMapLib.openDatabase(tmpDatabase, databaseInMemory, optimize);
setCamera(1);
updateState(State.STATE_IDLE);
}
public void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
public static void zip(String file, String zipFile) throws IOException {
Log.i(TAG, "Zipping " + file +" to " + zipFile);
@@ -1662,54 +1804,78 @@ public class RTABMapActivity extends Activity implements OnClickListener {
if(files.length > 0)
{
final String[] filesToZip = files;
// get token the first time
if(mAuthToken == null)
{
Log.i(TAG,"We don't have the token, get it!");
authorizeAndPublish(filesToZip, fileName);
}
}
private void authorizeAndPublish(final String[] filesToZip, final String fileName)
{
if(!isNetworkAvailable())
{
// Visualize the result?
new AlertDialog.Builder(getActivity())
.setTitle("Sharing to Sketchfab...")
.setMessage("Network is not available. Make sure you have internet before continuing.")
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
authorizeAndPublish(filesToZip, fileName);
}
})
.setNeutralButton("Abort", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
return;
}
WebView web;
mAuthDialog = new Dialog(this);
mAuthDialog.setContentView(R.layout.auth_dialog);
web = (WebView)mAuthDialog.findViewById(R.id.webv);
web.getSettings().setJavaScriptEnabled(true);
String auth_url = AUTHORIZE_PATH+"?redirect_uri="+REDIRECT_URI+"&response_type=token&client_id="+CLIENT_ID;
Log.i(TAG, "Auhorize url="+auth_url);
web.setWebViewClient(new WebViewClient() {
// get token the first time
if(mAuthToken == null)
{
Log.i(TAG,"We don't have the token, get it!");
boolean authComplete = false;
WebView web;
mAuthDialog = new Dialog(this);
mAuthDialog.setContentView(R.layout.auth_dialog);
web = (WebView)mAuthDialog.findViewById(R.id.webv);
web.getSettings().setJavaScriptEnabled(true);
String auth_url = AUTHORIZE_PATH+"?redirect_uri="+REDIRECT_URI+"&response_type=token&client_id="+CLIENT_ID;
Log.i(TAG, "Auhorize url="+auth_url);
web.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
boolean authComplete = false;
//Log.i(TAG,"onPageFinished url="+url);
if(url.contains("error=access_denied")){
Log.e(TAG, "ACCESS_DENIED_HERE");
authComplete = true;
Toast.makeText(getApplicationContext(), "Error Occured", Toast.LENGTH_SHORT).show();
mAuthDialog.dismiss();
}
else if (url.startsWith(REDIRECT_URI) && url.contains("access_token") && authComplete != true) {
//Log.i(TAG,"onPageFinished received token="+url);
String[] sArray = url.split("access_token=");
mAuthToken = (sArray[1].split("&token_type=Bearer"))[0];
authComplete = true;
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
mAuthDialog.dismiss();
zipAndPublish(filesToZip, fileName);
}
//Log.i(TAG,"onPageFinished url="+url);
if(url.contains("error=access_denied")){
Log.e(TAG, "ACCESS_DENIED_HERE");
authComplete = true;
Toast.makeText(getApplicationContext(), "Error Occured", Toast.LENGTH_SHORT).show();
mAuthDialog.dismiss();
}
});
mAuthDialog.show();
mAuthDialog.setTitle("Authorize RTAB-Map");
mAuthDialog.setCancelable(true);
web.loadUrl(auth_url);
}
else
{
zipAndPublish(filesToZip, fileName);
}
else if (url.startsWith(REDIRECT_URI) && url.contains("access_token") && authComplete != true) {
//Log.i(TAG,"onPageFinished received token="+url);
String[] sArray = url.split("access_token=");
mAuthToken = (sArray[1].split("&token_type=Bearer"))[0];
authComplete = true;
mAuthDialog.dismiss();
zipAndPublish(filesToZip, fileName);
}
}
});
mAuthDialog.show();
mAuthDialog.setTitle("Authorize RTAB-Map");
mAuthDialog.setCancelable(true);
web.loadUrl(auth_url);
}
else
{
zipAndPublish(filesToZip, fileName);
}
}

View File

@@ -25,8 +25,9 @@ public class RTABMapLib
// The activity object is used for checking if the API version is outdated.
public static native void onCreate(RTABMapActivity activity);
public static native void openEmptyDatabase();
public static native void openDatabase(String databasePath);
public static native void setScreenRotation(int displayRotation, int cameraRotation);
public static native void openDatabase(String databasePath, boolean databaseInMemory, boolean optimize);
/*
* Called when the Tango service is connected.
@@ -64,10 +65,10 @@ public class RTABMapLib
public static native void setTrajectoryMode(boolean enabled);
public static native void setGraphOptimization(boolean enabled);
public static native void setNodesFiltering(boolean enabled);
public static native void setDriftCorrection(boolean enabled);
public static native void setGraphVisible(boolean visible);
public static native void setGridVisible(boolean visible);
public static native void setAutoExposure(boolean enabled);
public static native void setRawScanSaved(boolean enabled);
public static native void setFullResolution(boolean enabled);
public static native void setAppendMode(boolean enabled);
public static native void setDataRecorderMode(boolean enabled);
@@ -89,6 +90,7 @@ public class RTABMapLib
boolean meshing,
int textureSize,
int normalK,
float maxTextureDistance,
boolean optimized,
float optimizedVoxelSize,
int optimizedDepth,

View File

@@ -16,8 +16,12 @@
package com.introlab.rtabmap;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.widget.Toast;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
@@ -27,6 +31,11 @@ import javax.microedition.khronos.opengles.GL10;
// device's pose.
public class Renderer implements GLSurfaceView.Renderer {
private static Activity mActivity;
public Renderer(Activity c) {
mActivity = c;
}
private ProgressDialog mProgressDialog;
public void setProgressDialog(ProgressDialog progressDialog)
@@ -34,14 +43,35 @@ public class Renderer implements GLSurfaceView.Renderer {
mProgressDialog = progressDialog;
}
// Render loop of the Gl context.
public void onDrawFrame(GL10 gl) {
int value = RTABMapLib.render();
if(value == 1 && mProgressDialog != null)
{
mProgressDialog.dismiss();
}
}
// Render loop of the Gl context.
public void onDrawFrame(GL10 gl) {
try
{
final int value = RTABMapLib.render();
mActivity.runOnUiThread(new Runnable() {
public void run() {
if(value != 0 && mProgressDialog != null && mProgressDialog.isShowing())
{
Log.i("RTABMapActivity", "Renderer: dismiss dialog, value received=" + String.valueOf(value));
mProgressDialog.dismiss();
}
if(value==-1)
{
Toast.makeText(mActivity, String.format("Out of Memory!"), Toast.LENGTH_LONG).show();
}
}
});
}
catch(final Exception e)
{
mActivity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(mActivity, String.format("Rendering error! %s", e.getMessage()), Toast.LENGTH_LONG).show();
}
});
}
}
// Called when the surface size changes.
public void onSurfaceChanged(GL10 gl, int width, int height) {

View File

@@ -28,7 +28,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
}
});
((Preference)findPreference(getString(R.string.pref_key_decimation))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_decimation))).getEntry() + ") "+getString(R.string.pref_summary_decimation));
((Preference)findPreference(getString(R.string.pref_key_density))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_density))).getEntry() + ") "+getString(R.string.pref_summary_density));
((Preference)findPreference(getString(R.string.pref_key_depth))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_depth))).getEntry() + ") "+getString(R.string.pref_summary_depth));
((Preference)findPreference(getString(R.string.pref_key_point_size))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_point_size))).getEntry() + ") "+getString(R.string.pref_summary_point_size));
((Preference)findPreference(getString(R.string.pref_key_angle))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_angle))).getEntry() + ") "+getString(R.string.pref_summary_angle));
@@ -36,14 +36,18 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
((Preference)findPreference(getString(R.string.pref_key_update_rate))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_update_rate))).getEntry() + ") "+getString(R.string.pref_summary_update_rate));
((Preference)findPreference(getString(R.string.pref_key_time_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_time_thr))).getEntry() + ") "+getString(R.string.pref_summary_time_thr));
((Preference)findPreference(getString(R.string.pref_key_mem_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_mem_thr))).getEntry() + ") "+getString(R.string.pref_summary_mem_thr));
((Preference)findPreference(getString(R.string.pref_key_loop_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_loop_thr))).getEntry() + ") "+getString(R.string.pref_summary_loop_thr));
((Preference)findPreference(getString(R.string.pref_key_sim_thr))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_sim_thr))).getEntry() + ") "+getString(R.string.pref_summary_sim_thr));
((Preference)findPreference(getString(R.string.pref_key_opt_error))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_error))).getEntry() + ") "+getString(R.string.pref_summary_opt_error));
((Preference)findPreference(getString(R.string.pref_key_features_voc))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_features_voc))).getEntry() + ") "+getString(R.string.pref_summary_features_voc));
((Preference)findPreference(getString(R.string.pref_key_features))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_features))).getEntry() + ") "+getString(R.string.pref_summary_features));
((Preference)findPreference(getString(R.string.pref_key_features_type))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_features_type))).getEntry() + ") "+getString(R.string.pref_summary_features_type));
((Preference)findPreference(getString(R.string.pref_key_cloud_voxel))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_cloud_voxel))).getEntry() + ") "+getString(R.string.pref_summary_cloud_voxel));
((Preference)findPreference(getString(R.string.pref_key_texture_size))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_texture_size))).getEntry() + ") "+getString(R.string.pref_summary_texture_size));
((Preference)findPreference(getString(R.string.pref_key_normal_k))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_normal_k))).getEntry() + ") "+getString(R.string.pref_summary_normal_k));
((Preference)findPreference(getString(R.string.pref_key_max_texture_distance))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_max_texture_distance))).getEntry() + ") "+getString(R.string.pref_summary_max_texture_distance));
((Preference)findPreference(getString(R.string.pref_key_opt_depth))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_depth))).getEntry() + ") "+getString(R.string.pref_summary_opt_depth));
((Preference)findPreference(getString(R.string.pref_key_opt_decimation_factor))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_decimation_factor))).getValue() + "%%) "+getString(R.string.pref_summary_opt_decimation_factor));
@@ -57,7 +61,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
Preference pref = findPreference(key);
if (pref instanceof ListPreference) {
if(key.compareTo(getString(R.string.pref_key_decimation))==0) pref.setSummary("("+ ((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_decimation));
if(key.compareTo(getString(R.string.pref_key_density))==0) pref.setSummary("("+ ((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_density));
if(key.compareTo(getString(R.string.pref_key_depth))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_depth));
if(key.compareTo(getString(R.string.pref_key_point_size))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_point_size));
if(key.compareTo(getString(R.string.pref_key_angle))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_angle));
@@ -65,14 +69,18 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
if(key.compareTo(getString(R.string.pref_key_update_rate))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_update_rate));
if(key.compareTo(getString(R.string.pref_key_time_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_time_thr));
if(key.compareTo(getString(R.string.pref_key_mem_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_mem_thr));
if(key.compareTo(getString(R.string.pref_key_loop_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_loop_thr));
if(key.compareTo(getString(R.string.pref_key_sim_thr))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_sim_thr));
if(key.compareTo(getString(R.string.pref_key_opt_error))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_error));
if(key.compareTo(getString(R.string.pref_key_features_voc))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_features_voc));
if(key.compareTo(getString(R.string.pref_key_features))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_features));
if(key.compareTo(getString(R.string.pref_key_features_type))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_features_type));
if(key.compareTo(getString(R.string.pref_key_cloud_voxel))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_cloud_voxel));
if(key.compareTo(getString(R.string.pref_key_texture_size))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_texture_size));
if(key.compareTo(getString(R.string.pref_key_normal_k))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_normal_k));
if(key.compareTo(getString(R.string.pref_key_max_texture_distance))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_max_texture_distance));
if(key.compareTo(getString(R.string.pref_key_opt_depth))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_depth));
if(key.compareTo(getString(R.string.pref_key_opt_decimation_factor))==0) pref.setSummary("("+((ListPreference)pref).getValue() + "%%) "+getString(R.string.pref_summary_opt_decimation_factor));