mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-13 23:10:20 +08:00
Compare commits
42
Commits
0.13.0
...
0.13.2-lunar
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75854fc026 | ||
|
|
d8a6ed4ba6 | ||
|
|
459bbda60c | ||
|
|
2a9508b4e3 | ||
|
|
c0c288e0d9 | ||
|
|
82fd5b36a8 | ||
|
|
dd3c7d8fa4 | ||
|
|
b63f073d90 | ||
|
|
0491125e92 | ||
|
|
3443c3b8ea | ||
|
|
be720be74a | ||
|
|
f3e491f15b | ||
|
|
5855198b5f | ||
|
|
62de6fcdae | ||
|
|
57dc0cd53e | ||
|
|
0a1694dd78 | ||
|
|
edc690973a | ||
|
|
48148a9e26 | ||
|
|
62b9911176 | ||
|
|
fb69a37445 | ||
|
|
81ae1eae51 | ||
|
|
517c70d855 | ||
|
|
85f7c1e73c | ||
|
|
b4cfa0e844 | ||
|
|
3c758ab2f6 | ||
|
|
1ed01b8d3d | ||
|
|
19abbe0dbd | ||
|
|
c833af1ae6 | ||
|
|
78bdd4a087 | ||
|
|
dc77bb4332 | ||
|
|
9e011d6ad9 | ||
|
|
f9ed36ed54 | ||
|
|
495681770e | ||
|
|
eb1f0e0a8a | ||
|
|
23ae5caa3c | ||
|
|
4b7d558026 | ||
|
|
44969a7fdf | ||
|
|
5f5c74f260 | ||
|
|
5646751f88 | ||
|
|
b6d3e785df | ||
|
|
ebada30984 | ||
|
|
64fc9f203e |
@@ -1,6 +1,7 @@
|
|||||||
sudo: true
|
sudo: true
|
||||||
dist: trusty
|
dist: trusty
|
||||||
language: cpp
|
language: cpp
|
||||||
|
group: deprecated-2017Q3
|
||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
|
|||||||
+18
-13
@@ -21,7 +21,7 @@ SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_modules")
|
|||||||
#######################
|
#######################
|
||||||
SET(RTABMAP_MAJOR_VERSION 0)
|
SET(RTABMAP_MAJOR_VERSION 0)
|
||||||
SET(RTABMAP_MINOR_VERSION 13)
|
SET(RTABMAP_MINOR_VERSION 13)
|
||||||
SET(RTABMAP_PATCH_VERSION 0)
|
SET(RTABMAP_PATCH_VERSION 2)
|
||||||
SET(RTABMAP_VERSION
|
SET(RTABMAP_VERSION
|
||||||
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
${RTABMAP_MAJOR_VERSION}.${RTABMAP_MINOR_VERSION}.${RTABMAP_PATCH_VERSION})
|
||||||
|
|
||||||
@@ -124,6 +124,15 @@ set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH
|
|||||||
"Installation directory for CMake files")
|
"Installation directory for CMake files")
|
||||||
|
|
||||||
####### BUILD OPTIONS #######
|
####### BUILD OPTIONS #######
|
||||||
|
|
||||||
|
# ANDROID_PREBUILD (early exit if true)
|
||||||
|
OPTION( ANDROID_PREBUILD "Set to ON to build rtabmap resource build tool (required for android build)" OFF )
|
||||||
|
IF(ANDROID_PREBUILD)
|
||||||
|
MESSAGE("Option ANDROID_PREBUILD is set, only rtabmap resource tool will be built. You can use android toolchain after that.")
|
||||||
|
ADD_SUBDIRECTORY( utilite )
|
||||||
|
return()
|
||||||
|
ENDIF(ANDROID_PREBUILD)
|
||||||
|
|
||||||
IF(APPLE)
|
IF(APPLE)
|
||||||
OPTION(BUILD_AS_BUNDLE "Set to ON to build as bundle (DragNDrop)" OFF)
|
OPTION(BUILD_AS_BUNDLE "Set to ON to build as bundle (DragNDrop)" OFF)
|
||||||
ENDIF(APPLE)
|
ENDIF(APPLE)
|
||||||
@@ -162,9 +171,11 @@ FIND_PACKAGE(OpenCV REQUIRED QUIET)
|
|||||||
FIND_PACKAGE(PCL 1.7 REQUIRED QUIET)
|
FIND_PACKAGE(PCL 1.7 REQUIRED QUIET)
|
||||||
FIND_PACKAGE(ZLIB REQUIRED QUIET)
|
FIND_PACKAGE(ZLIB REQUIRED QUIET)
|
||||||
|
|
||||||
# fix libproj.so not found on Xenial
|
|
||||||
if(NOT "${PCL_LIBRARIES}" STREQUAL "")
|
if(NOT "${PCL_LIBRARIES}" STREQUAL "")
|
||||||
|
# fix libproj.so not found on Xenial
|
||||||
list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4")
|
list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4")
|
||||||
|
# fix libmpi.so not found on Zesty
|
||||||
|
list(REMOVE_ITEM PCL_LIBRARIES "/usr/lib/libmpi.so")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# OpenMP ("-fopenmp" should be added for flann included in PCL)
|
# OpenMP ("-fopenmp" should be added for flann included in PCL)
|
||||||
@@ -205,12 +216,12 @@ IF(WITH_QT)
|
|||||||
IF("${VTK_MAJOR_VERSION}" GREATER 5)
|
IF("${VTK_MAJOR_VERSION}" GREATER 5)
|
||||||
FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui QUIET)
|
FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui QUIET)
|
||||||
IF(Qt5_FOUND)
|
IF(Qt5_FOUND)
|
||||||
FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui Svg)
|
FIND_PACKAGE(Qt5 COMPONENTS Widgets Core Gui OPTIONAL_COMPONENTS Svg)
|
||||||
ENDIF(Qt5_FOUND)
|
ENDIF(Qt5_FOUND)
|
||||||
ENDIF("${VTK_MAJOR_VERSION}" GREATER 5)
|
ENDIF("${VTK_MAJOR_VERSION}" GREATER 5)
|
||||||
|
|
||||||
IF(NOT Qt5_FOUND)
|
IF(NOT Qt5_FOUND)
|
||||||
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtSvg)
|
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui OPTIONAL_COMPONENTS QtSvg)
|
||||||
ENDIF(NOT Qt5_FOUND)
|
ENDIF(NOT Qt5_FOUND)
|
||||||
|
|
||||||
IF(QT4_FOUND OR Qt5_FOUND)
|
IF(QT4_FOUND OR Qt5_FOUND)
|
||||||
@@ -369,7 +380,7 @@ IF(WITH_DVO)
|
|||||||
ENDIF(dvo_core_FOUND)
|
ENDIF(dvo_core_FOUND)
|
||||||
ENDIF(WITH_DVO)
|
ENDIF(WITH_DVO)
|
||||||
|
|
||||||
IF(WITH_ORB_SLAM2 AND NOT G2O_FOUND AND NOT RealSense_FOUND)
|
IF(WITH_ORB_SLAM2 AND NOT G2O_FOUND)
|
||||||
FIND_PACKAGE(ORB_SLAM2 QUIET)
|
FIND_PACKAGE(ORB_SLAM2 QUIET)
|
||||||
IF(ORB_SLAM2_FOUND)
|
IF(ORB_SLAM2_FOUND)
|
||||||
MESSAGE(STATUS "Found ORB_SLAM2: ${ORB_SLAM2_INCLUDE_DIRS}")
|
MESSAGE(STATUS "Found ORB_SLAM2: ${ORB_SLAM2_INCLUDE_DIRS}")
|
||||||
@@ -381,12 +392,10 @@ IF(WITH_ORB_SLAM2 AND NOT G2O_FOUND AND NOT RealSense_FOUND)
|
|||||||
MESSAGE(STATUS "Found Pangolin: ${Pangolin_INCLUDE_DIRS}")
|
MESSAGE(STATUS "Found Pangolin: ${Pangolin_INCLUDE_DIRS}")
|
||||||
SET(ORB_SLAM2_INCLUDE_DIRS ${ORB_SLAM2_INCLUDE_DIRS} ${Pangolin_INCLUDE_DIRS})
|
SET(ORB_SLAM2_INCLUDE_DIRS ${ORB_SLAM2_INCLUDE_DIRS} ${Pangolin_INCLUDE_DIRS})
|
||||||
SET(ORB_SLAM2_LIBRARIES ${ORB_SLAM2_LIBRARIES} ${Pangolin_LIBRARIES})
|
SET(ORB_SLAM2_LIBRARIES ${ORB_SLAM2_LIBRARIES} ${Pangolin_LIBRARIES})
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")
|
MESSAGE(WARNING "Don't forget to build ORB_SLAM2 (and included g2o) without \"-march=native\" to avoid crash when ORB_SLAM2 starts.")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
|
|
||||||
# There could be crash issues if built with RealSense
|
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF(ORB_SLAM2_FOUND)
|
ENDIF(ORB_SLAM2_FOUND)
|
||||||
ENDIF(WITH_ORB_SLAM2 AND NOT G2O_FOUND AND NOT RealSense_FOUND)
|
ENDIF(WITH_ORB_SLAM2 AND NOT G2O_FOUND)
|
||||||
|
|
||||||
IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND OR ANDROID OR RealSense_FOUND OR ORB_SLAM2_FOUND)
|
IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND OR ANDROID OR RealSense_FOUND OR ORB_SLAM2_FOUND)
|
||||||
#Newest versions require std11
|
#Newest versions require std11
|
||||||
@@ -885,12 +894,8 @@ IF(ORB_SLAM2_FOUND)
|
|||||||
MESSAGE(STATUS " With ORB_SLAM2 = YES (License: GPLv3)")
|
MESSAGE(STATUS " With ORB_SLAM2 = YES (License: GPLv3)")
|
||||||
ELSEIF(NOT WITH_ORB_SLAM2)
|
ELSEIF(NOT WITH_ORB_SLAM2)
|
||||||
MESSAGE(STATUS " With ORB_SLAM2 = NO (WITH_ORB_SLAM2=OFF)")
|
MESSAGE(STATUS " With ORB_SLAM2 = NO (WITH_ORB_SLAM2=OFF)")
|
||||||
ELSEIF(G2O_FOUND AND RealSense_FOUND)
|
|
||||||
MESSAGE(STATUS " With ORB_SLAM2 = NO (WITH_G2O should be OFF as ORB_SLAM2 uses its own g2o version, WITH_REALSENSE should also be off to avoid eigen errors)")
|
|
||||||
ELSEIF(G2O_FOUND)
|
ELSEIF(G2O_FOUND)
|
||||||
MESSAGE(STATUS " With ORB_SLAM2 = NO (WITH_G2O should be OFF as ORB_SLAM2 uses its own g2o version)")
|
MESSAGE(STATUS " With ORB_SLAM2 = NO (WITH_G2O should be OFF as ORB_SLAM2 uses its own g2o version)")
|
||||||
ELSEIF(RealSense_FOUND)
|
|
||||||
MESSAGE(STATUS " With ORB_SLAM2 = NO (WITH_REALSENSE should be off to avoid eigen errors)")
|
|
||||||
ELSE()
|
ELSE()
|
||||||
MESSAGE(STATUS " With ORB_SLAM2 = NO (ORB_SLAM2 not found, make sure environment variable ORB_SLAM2_ROOT_DIR is set)")
|
MESSAGE(STATUS " With ORB_SLAM2 = NO (ORB_SLAM2 not found, make sure environment variable ORB_SLAM2_ROOT_DIR is set)")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|||||||
@@ -47,11 +47,11 @@ ENDIF()
|
|||||||
set(RTABMap_LIBRARIES ${RTABMap_CORE} ${RTABMap_UTILITE})
|
set(RTABMap_LIBRARIES ${RTABMap_CORE} ${RTABMap_UTILITE})
|
||||||
|
|
||||||
list(LENGTH RTABMap_FIND_COMPONENTS RTABMap_FIND_COMPONENTS_LENGTH)
|
list(LENGTH RTABMap_FIND_COMPONENTS RTABMap_FIND_COMPONENTS_LENGTH)
|
||||||
set(WITH_GUI OFF)
|
set(WITH_GUI ON)
|
||||||
if(${RTABMap_FIND_COMPONENTS_LENGTH} GREATER 0)
|
if(${RTABMap_FIND_COMPONENTS_LENGTH} GREATER 0)
|
||||||
list (FIND RTABMap_FIND_COMPONENTS "gui" _index)
|
list (FIND RTABMap_FIND_COMPONENTS "gui" _index)
|
||||||
if (${_index} GREATER -1)
|
if (${_index} EQUAL -1)
|
||||||
set(WITH_GUI ON)
|
set(WITH_GUI OFF)
|
||||||
endif()
|
endif()
|
||||||
endif(${RTABMap_FIND_COMPONENTS_LENGTH} GREATER 0)
|
endif(${RTABMap_FIND_COMPONENTS_LENGTH} GREATER 0)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<!-- BEGIN_INCLUDE(manifest) -->
|
<!-- BEGIN_INCLUDE(manifest) -->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.introlab.rtabmap"
|
package="com.introlab.rtabmap"
|
||||||
android:versionCode="51"
|
android:versionCode="55"
|
||||||
android:versionName="@RTABMAP_VERSION@">
|
android:versionName="@RTABMAP_VERSION@">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
@@ -31,7 +31,8 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:screenOrientation="fullSensor"
|
android:screenOrientation="fullSensor"
|
||||||
android:configChanges="orientation|screenSize|keyboardHidden">
|
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||||
|
android:theme="@style/ThemeApp">
|
||||||
<!-- Tell NativeActivity the name of our .so -->
|
<!-- Tell NativeActivity the name of our .so -->
|
||||||
<meta-data android:name="android.app.lib_name"
|
<meta-data android:name="android.app.lib_name"
|
||||||
android:value="NativeRTABMap" />
|
android:value="NativeRTABMap" />
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<h3>Real-Time Appearance-Based Mapping</h3>
|
<h3>Real-Time Appearance-Based Mapping</h3>
|
||||||
Version @RTABMAP_VERSION@<br>
|
Version @RTABMAP_VERSION@<br>
|
||||||
Author: Mathieu Labbé<br>
|
Author: Mathieu Labbé<br>
|
||||||
Copyright 2016<br>
|
Copyright 2016-2017<br>
|
||||||
IntRoLab - Université de Sherbrooke<br>
|
IntRoLab - Université de Sherbrooke<br>
|
||||||
<b>http://introlab.github.io/rtabmap</b><br><br>
|
<b>http://introlab.github.io/rtabmap</b><br><br>
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ bool CameraTango::init(const std::string & calibrationFolder, const std::string
|
|||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
|
|
||||||
TangoSupport_initializeLibrary();
|
TangoSupport_initialize(TangoService_getPoseAtTime, TangoService_getCameraIntrinsics);
|
||||||
|
|
||||||
// Connect to Tango
|
// Connect to Tango
|
||||||
LOGI("NativeRTABMap: Setup tango config");
|
LOGI("NativeRTABMap: Setup tango config");
|
||||||
|
|||||||
@@ -298,7 +298,11 @@ int RTABMapApp::openDatabase(const std::string & databasePath, bool databaseInMe
|
|||||||
optTexture_ = cv::Mat();
|
optTexture_ = cv::Mat();
|
||||||
cv::Mat cloudMat;
|
cv::Mat cloudMat;
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > polygons;
|
std::vector<std::vector<std::vector<unsigned int> > > polygons;
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > texCoords;
|
std::vector<std::vector<Eigen::Vector2f> > texCoords;
|
||||||
|
#endif
|
||||||
cv::Mat textures;
|
cv::Mat textures;
|
||||||
std::map<int, rtabmap::Transform> optPoses;
|
std::map<int, rtabmap::Transform> optPoses;
|
||||||
if(!databaseSource.empty())
|
if(!databaseSource.empty())
|
||||||
@@ -1051,6 +1055,7 @@ int RTABMapApp::Render()
|
|||||||
pcl::fromPCLPointCloud2(optMesh_->cloud, *mesh.cloud);
|
pcl::fromPCLPointCloud2(optMesh_->cloud, *mesh.cloud);
|
||||||
pcl::fromPCLPointCloud2(optMesh_->cloud, *mesh.normals);
|
pcl::fromPCLPointCloud2(optMesh_->cloud, *mesh.normals);
|
||||||
mesh.polygons = optMesh_->tex_polygons[0];
|
mesh.polygons = optMesh_->tex_polygons[0];
|
||||||
|
mesh.pose.setIdentity();
|
||||||
if(optMesh_->tex_coordinates.size())
|
if(optMesh_->tex_coordinates.size())
|
||||||
{
|
{
|
||||||
mesh.texCoords = optMesh_->tex_coordinates[0];
|
mesh.texCoords = optMesh_->tex_coordinates[0];
|
||||||
@@ -1568,7 +1573,7 @@ int RTABMapApp::Render()
|
|||||||
if(rtabmapEvents.size())
|
if(rtabmapEvents.size())
|
||||||
{
|
{
|
||||||
// send statistics to GUI
|
// send statistics to GUI
|
||||||
LOGW("Posting PostRenderEvent! %fs", renderingTime_);
|
LOGI("New data added to map, rendering time: %fs", renderingTime_);
|
||||||
UEventsManager::post(new PostRenderEvent(rtabmapEvents.back()));
|
UEventsManager::post(new PostRenderEvent(rtabmapEvents.back()));
|
||||||
rtabmapEvents.pop_back();
|
rtabmapEvents.pop_back();
|
||||||
|
|
||||||
@@ -1740,6 +1745,10 @@ void RTABMapApp::setOrthoCropFactor(float value)
|
|||||||
{
|
{
|
||||||
main_scene_.setOrthoCropFactor(value);
|
main_scene_.setOrthoCropFactor(value);
|
||||||
}
|
}
|
||||||
|
void RTABMapApp::setGridRotation(float value)
|
||||||
|
{
|
||||||
|
main_scene_.setGridRotation(value);
|
||||||
|
}
|
||||||
void RTABMapApp::setLighting(bool enabled)
|
void RTABMapApp::setLighting(bool enabled)
|
||||||
{
|
{
|
||||||
main_scene_.setLighting(enabled);
|
main_scene_.setLighting(enabled);
|
||||||
@@ -2011,8 +2020,10 @@ void RTABMapApp::save(const std::string & databasePath)
|
|||||||
dataRecorderMode_ = dataRecorderModeBackup;
|
dataRecorderMode_ = dataRecorderModeBackup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<int, rtabmap::Transform> poses = rtabmap_->getLocalOptimizedPoses();
|
||||||
rtabmap_->close(true, databasePath);
|
rtabmap_->close(true, databasePath);
|
||||||
rtabmap_->init(getRtabmapParameters(), dataRecorderMode_?"":databasePath);
|
rtabmap_->init(getRtabmapParameters(), dataRecorderMode_?"":databasePath);
|
||||||
|
rtabmap_->setOptimizedPoses(poses);
|
||||||
if(dataRecorderMode_)
|
if(dataRecorderMode_)
|
||||||
{
|
{
|
||||||
clearSceneOnNextRender_ = true;
|
clearSceneOnNextRender_ = true;
|
||||||
@@ -2040,7 +2051,7 @@ bool RTABMapApp::exportMesh(
|
|||||||
int optimizedMaxPolygons,
|
int optimizedMaxPolygons,
|
||||||
float optimizedColorRadius,
|
float optimizedColorRadius,
|
||||||
bool optimizedCleanWhitePolygons,
|
bool optimizedCleanWhitePolygons,
|
||||||
bool optimizedColorWhitePolygons, // not yet used
|
int optimizedMinClusterSize,
|
||||||
float optimizedMaxTextureDistance,
|
float optimizedMaxTextureDistance,
|
||||||
int optimizedMinTextureClusterSize,
|
int optimizedMinTextureClusterSize,
|
||||||
bool blockRendering)
|
bool blockRendering)
|
||||||
@@ -2048,6 +2059,24 @@ bool RTABMapApp::exportMesh(
|
|||||||
// make sure createdMeshes_ is not modified while exporting! We don't
|
// make sure createdMeshes_ is not modified while exporting! We don't
|
||||||
// lock the meshesMutex_ because we want to continue rendering.
|
// lock the meshesMutex_ because we want to continue rendering.
|
||||||
|
|
||||||
|
std::map<int, rtabmap::Transform> poses = rtabmap_->getLocalOptimizedPoses();
|
||||||
|
if(poses.empty())
|
||||||
|
{
|
||||||
|
// look if we just triggered new map without localizing afterward (pause/resume in append Mode)
|
||||||
|
std::multimap<int, rtabmap::Link> links;
|
||||||
|
rtabmap_->getGraph(
|
||||||
|
poses,
|
||||||
|
links,
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
if(poses.empty())
|
||||||
|
{
|
||||||
|
UERROR("Empty optimized poses!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
rtabmap_->setOptimizedPoses(poses);
|
||||||
|
}
|
||||||
|
|
||||||
if(blockRendering)
|
if(blockRendering)
|
||||||
{
|
{
|
||||||
renderingMutex_.lock();
|
renderingMutex_.lock();
|
||||||
@@ -2060,8 +2089,6 @@ bool RTABMapApp::exportMesh(
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
std::map<int, rtabmap::Transform> poses = rtabmap_->getLocalOptimizedPoses();
|
|
||||||
|
|
||||||
int totalSteps = 0;
|
int totalSteps = 0;
|
||||||
totalSteps+=poses.size(); // assemble
|
totalSteps+=poses.size(); // assemble
|
||||||
if(meshing)
|
if(meshing)
|
||||||
@@ -2314,7 +2341,7 @@ bool RTABMapApp::exportMesh(
|
|||||||
optimizedColorRadius,
|
optimizedColorRadius,
|
||||||
textureSize == 0,
|
textureSize == 0,
|
||||||
optimizedCleanWhitePolygons,
|
optimizedCleanWhitePolygons,
|
||||||
0);
|
optimizedMinClusterSize);
|
||||||
|
|
||||||
if(textureSize>0)
|
if(textureSize>0)
|
||||||
{
|
{
|
||||||
@@ -2364,6 +2391,10 @@ bool RTABMapApp::exportMesh(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UERROR("Merged cloud too small (%d points) to create polygons!", (int)mergedClouds->size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // organized meshes
|
else // organized meshes
|
||||||
{
|
{
|
||||||
@@ -2727,6 +2758,10 @@ bool RTABMapApp::exportMesh(
|
|||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UERROR("Merged cloud is empty!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progressionStatus_.finish();
|
progressionStatus_.finish();
|
||||||
@@ -2764,7 +2799,11 @@ bool RTABMapApp::postExportation(bool visualize)
|
|||||||
{
|
{
|
||||||
cv::Mat cloudMat;
|
cv::Mat cloudMat;
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > polygons;
|
std::vector<std::vector<std::vector<unsigned int> > > polygons;
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > texCoords;
|
std::vector<std::vector<Eigen::Vector2f> > texCoords;
|
||||||
|
#endif
|
||||||
cv::Mat textures;
|
cv::Mat textures;
|
||||||
std::map<int, rtabmap::Transform> optPoses;
|
std::map<int, rtabmap::Transform> optPoses;
|
||||||
if(rtabmap_ && rtabmap_->getMemory())
|
if(rtabmap_ && rtabmap_->getMemory())
|
||||||
@@ -2801,7 +2840,11 @@ bool RTABMapApp::writeExportedMesh(const std::string & directory, const std::str
|
|||||||
pcl::TextureMesh::Ptr textureMesh(new pcl::TextureMesh);
|
pcl::TextureMesh::Ptr textureMesh(new pcl::TextureMesh);
|
||||||
cv::Mat cloudMat;
|
cv::Mat cloudMat;
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > polygons;
|
std::vector<std::vector<std::vector<unsigned int> > > polygons;
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > texCoords;
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > texCoords;
|
std::vector<std::vector<Eigen::Vector2f> > texCoords;
|
||||||
|
#endif
|
||||||
cv::Mat textures;
|
cv::Mat textures;
|
||||||
std::map<int, rtabmap::Transform> optPoses;
|
std::map<int, rtabmap::Transform> optPoses;
|
||||||
if(rtabmap_ && rtabmap_->getMemory())
|
if(rtabmap_ && rtabmap_->getMemory())
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
void setPointSize(float value);
|
void setPointSize(float value);
|
||||||
void setFOV(float angle);
|
void setFOV(float angle);
|
||||||
void setOrthoCropFactor(float value);
|
void setOrthoCropFactor(float value);
|
||||||
|
void setGridRotation(float value);
|
||||||
void setLighting(bool enabled);
|
void setLighting(bool enabled);
|
||||||
void setBackfaceCulling(bool enabled);
|
void setBackfaceCulling(bool enabled);
|
||||||
void setWireframe(bool enabled);
|
void setWireframe(bool enabled);
|
||||||
@@ -163,7 +164,7 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
int optimizedMaxPolygons,
|
int optimizedMaxPolygons,
|
||||||
float optimizedColorRadius,
|
float optimizedColorRadius,
|
||||||
bool optimizedCleanWhitePolygons,
|
bool optimizedCleanWhitePolygons,
|
||||||
bool optimizedColorWhitePolygons,
|
int optimizedMinClusterSize,
|
||||||
float optimizedMaxTextureDistance,
|
float optimizedMaxTextureDistance,
|
||||||
int optimizedMinTextureClusterSize,
|
int optimizedMinTextureClusterSize,
|
||||||
bool blockRendering);
|
bool blockRendering);
|
||||||
|
|||||||
@@ -180,6 +180,12 @@ Java_com_introlab_rtabmap_RTABMapLib_setOrthoCropFactor(
|
|||||||
return app.setOrthoCropFactor(value);
|
return app.setOrthoCropFactor(value);
|
||||||
}
|
}
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
|
Java_com_introlab_rtabmap_RTABMapLib_setGridRotation(
|
||||||
|
JNIEnv*, jobject, float value)
|
||||||
|
{
|
||||||
|
return app.setGridRotation(value);
|
||||||
|
}
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
Java_com_introlab_rtabmap_RTABMapLib_setLighting(
|
Java_com_introlab_rtabmap_RTABMapLib_setLighting(
|
||||||
JNIEnv*, jobject, bool enabled)
|
JNIEnv*, jobject, bool enabled)
|
||||||
{
|
{
|
||||||
@@ -371,7 +377,7 @@ Java_com_introlab_rtabmap_RTABMapLib_exportMesh(
|
|||||||
int optimizedMaxPolygons,
|
int optimizedMaxPolygons,
|
||||||
float optimizedColorRadius,
|
float optimizedColorRadius,
|
||||||
bool optimizedCleanWhitePolygons,
|
bool optimizedCleanWhitePolygons,
|
||||||
bool optimizedColorWhitePolygons,
|
int optimizedMinClusterSize,
|
||||||
float optimizedMaxTextureDistance,
|
float optimizedMaxTextureDistance,
|
||||||
int optimizedMinTextureClusterSize,
|
int optimizedMinTextureClusterSize,
|
||||||
bool blockRendering)
|
bool blockRendering)
|
||||||
@@ -389,7 +395,7 @@ Java_com_introlab_rtabmap_RTABMapLib_exportMesh(
|
|||||||
optimizedMaxPolygons,
|
optimizedMaxPolygons,
|
||||||
optimizedColorRadius,
|
optimizedColorRadius,
|
||||||
optimizedCleanWhitePolygons,
|
optimizedCleanWhitePolygons,
|
||||||
optimizedColorWhitePolygons,
|
optimizedMinClusterSize,
|
||||||
optimizedMaxTextureDistance,
|
optimizedMaxTextureDistance,
|
||||||
optimizedMinTextureClusterSize,
|
optimizedMinTextureClusterSize,
|
||||||
blockRendering);
|
blockRendering);
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ private:
|
|||||||
bool isVisible() const {return visible_;}
|
bool isVisible() const {return visible_;}
|
||||||
bool hasMesh() const {return polygons_.size()!=0;}
|
bool hasMesh() const {return polygons_.size()!=0;}
|
||||||
bool hasTexture() const {return textures_ != 0;}
|
bool hasTexture() const {return textures_ != 0;}
|
||||||
|
float getMinHeight() const {return minHeight_;}
|
||||||
const pcl::PointXYZ & aabbMinModel() const {return aabbMinModel_;}
|
const pcl::PointXYZ & aabbMinModel() const {return aabbMinModel_;}
|
||||||
const pcl::PointXYZ & aabbMaxModel() const {return aabbMaxModel_;}
|
const pcl::PointXYZ & aabbMaxModel() const {return aabbMaxModel_;}
|
||||||
const pcl::PointXYZ & aabbMinWorld() const {return aabbMinWorld_;}
|
const pcl::PointXYZ & aabbMinWorld() const {return aabbMinWorld_;}
|
||||||
@@ -126,6 +127,7 @@ private:
|
|||||||
bool visible_;
|
bool visible_;
|
||||||
bool hasNormals_;
|
bool hasNormals_;
|
||||||
std::vector<unsigned int> organizedToDenseIndices_;
|
std::vector<unsigned int> organizedToDenseIndices_;
|
||||||
|
float minHeight_; // odom frame
|
||||||
|
|
||||||
float gainR_;
|
float gainR_;
|
||||||
float gainG_;
|
float gainG_;
|
||||||
|
|||||||
@@ -16,12 +16,16 @@
|
|||||||
|
|
||||||
#include <tango-gl/conversions.h>
|
#include <tango-gl/conversions.h>
|
||||||
#include <tango-gl/gesture_camera.h>
|
#include <tango-gl/gesture_camera.h>
|
||||||
|
#include <tango-gl/util.h>
|
||||||
|
|
||||||
#include <rtabmap/utilite/ULogger.h>
|
#include <rtabmap/utilite/ULogger.h>
|
||||||
#include <rtabmap/utilite/UStl.h>
|
#include <rtabmap/utilite/UStl.h>
|
||||||
#include <rtabmap/utilite/UTimer.h>
|
#include <rtabmap/utilite/UTimer.h>
|
||||||
#include <rtabmap/core/util3d_filtering.h>
|
#include <rtabmap/core/util3d_filtering.h>
|
||||||
|
#include <rtabmap/core/util3d_transforms.h>
|
||||||
|
#include <rtabmap/core/util3d_surface.h>
|
||||||
#include <pcl/common/transforms.h>
|
#include <pcl/common/transforms.h>
|
||||||
|
#include <pcl/common/common.h>
|
||||||
|
|
||||||
#include <glm/gtx/transform.hpp>
|
#include <glm/gtx/transform.hpp>
|
||||||
|
|
||||||
@@ -32,7 +36,7 @@
|
|||||||
// add an offset in z to our origin. We'll set this offset to 1.3 meters based
|
// add an offset in z to our origin. We'll set this offset to 1.3 meters based
|
||||||
// on the average height of a human standing with a Tango device. This allows us
|
// on the average height of a human standing with a Tango device. This allows us
|
||||||
// to place a grid roughly on the ground for most users.
|
// to place a grid roughly on the ground for most users.
|
||||||
const glm::vec3 kHeightOffset = glm::vec3(0.0f, 1.3f, 0.0f);
|
const glm::vec3 kHeightOffset = glm::vec3(0.0f, -1.3f, 0.0f);
|
||||||
|
|
||||||
// Color of the motion tracking trajectory.
|
// Color of the motion tracking trajectory.
|
||||||
const tango_gl::Color kTraceColor(0.66f, 0.66f, 0.66f);
|
const tango_gl::Color kTraceColor(0.66f, 0.66f, 0.66f);
|
||||||
@@ -130,7 +134,7 @@ void Scene::InitGLContent()
|
|||||||
trace_->ClearVertexArray();
|
trace_->ClearVertexArray();
|
||||||
trace_->SetColor(kTraceColor);
|
trace_->SetColor(kTraceColor);
|
||||||
grid_->SetColor(kGridColor);
|
grid_->SetColor(kGridColor);
|
||||||
grid_->SetPosition(-kHeightOffset);
|
grid_->SetPosition(kHeightOffset);
|
||||||
box_->SetShader();
|
box_->SetShader();
|
||||||
box_->SetColor(1,0,0);
|
box_->SetColor(1,0,0);
|
||||||
|
|
||||||
@@ -194,6 +198,10 @@ void Scene::clear()
|
|||||||
graph_ = 0;
|
graph_ = 0;
|
||||||
}
|
}
|
||||||
pointClouds_.clear();
|
pointClouds_.clear();
|
||||||
|
if(grid_)
|
||||||
|
{
|
||||||
|
grid_->SetPosition(kHeightOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Should only be called in OpenGL thread!
|
//Should only be called in OpenGL thread!
|
||||||
@@ -565,6 +573,15 @@ void Scene::setOrthoCropFactor(float value)
|
|||||||
{
|
{
|
||||||
gesture_camera_->SetOrthoCropFactor(value);
|
gesture_camera_->SetOrthoCropFactor(value);
|
||||||
}
|
}
|
||||||
|
void Scene::setGridRotation(float angleDeg)
|
||||||
|
{
|
||||||
|
float angleRad = angleDeg * DEGREE_2_RADIANS;
|
||||||
|
if(grid_)
|
||||||
|
{
|
||||||
|
glm::quat rot = glm::rotate(glm::quat(1,0,0,0), angleRad, glm::vec3(0, 1, 0));
|
||||||
|
grid_->SetRotation(rot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rtabmap::Transform Scene::GetOpenGLCameraPose(float * fov) const
|
rtabmap::Transform Scene::GetOpenGLCameraPose(float * fov) const
|
||||||
{
|
{
|
||||||
@@ -669,6 +686,58 @@ void Scene::addMesh(
|
|||||||
PointCloudDrawable * drawable = new PointCloudDrawable(mesh, createWireframe);
|
PointCloudDrawable * drawable = new PointCloudDrawable(mesh, createWireframe);
|
||||||
drawable->setPose(pose);
|
drawable->setPose(pose);
|
||||||
pointClouds_.insert(std::make_pair(id, drawable));
|
pointClouds_.insert(std::make_pair(id, drawable));
|
||||||
|
|
||||||
|
if(!mesh.pose.isNull() && mesh.cloud->size() && (!mesh.cloud->isOrganized() || mesh.indices->size()))
|
||||||
|
{
|
||||||
|
UTimer time;
|
||||||
|
float height = 0.0f;
|
||||||
|
Eigen::Affine3f affinePose = mesh.pose.toEigen3f();
|
||||||
|
if(mesh.polygons.size())
|
||||||
|
{
|
||||||
|
for(unsigned int i=0; i<mesh.polygons.size(); ++i)
|
||||||
|
{
|
||||||
|
for(unsigned int j=0; j<mesh.polygons[i].vertices.size(); ++j)
|
||||||
|
{
|
||||||
|
pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(mesh.polygons[i].vertices[j]), affinePose);
|
||||||
|
if(pt.z < height)
|
||||||
|
{
|
||||||
|
height = pt.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(mesh.cloud->isOrganized())
|
||||||
|
{
|
||||||
|
for(unsigned int i=0; i<mesh.indices->size(); ++i)
|
||||||
|
{
|
||||||
|
pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(mesh.indices->at(i)), affinePose);
|
||||||
|
if(pt.z < height)
|
||||||
|
{
|
||||||
|
height = pt.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(unsigned int i=0; i<mesh.cloud->size(); ++i)
|
||||||
|
{
|
||||||
|
pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(i), affinePose);
|
||||||
|
if(pt.z < height)
|
||||||
|
{
|
||||||
|
height = pt.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(grid_->GetPosition().y == kHeightOffset.y || grid_->GetPosition().y > height)
|
||||||
|
{
|
||||||
|
grid_->SetPosition(glm::vec3(0,height,0));
|
||||||
|
}
|
||||||
|
LOGD("compute min height %f s", time.ticks());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ class Scene {
|
|||||||
void setPointSize(float size) {pointSize_ = size;}
|
void setPointSize(float size) {pointSize_ = size;}
|
||||||
void setFOV(float angle);
|
void setFOV(float angle);
|
||||||
void setOrthoCropFactor(float value);
|
void setOrthoCropFactor(float value);
|
||||||
|
void setGridRotation(float angleDeg);
|
||||||
void setLighting(bool enabled) {lighting_ = enabled;}
|
void setLighting(bool enabled) {lighting_ = enabled;}
|
||||||
void setBackfaceCulling(bool enabled) {backfaceCulling_ = enabled;}
|
void setBackfaceCulling(bool enabled) {backfaceCulling_ = enabled;}
|
||||||
void setWireframe(bool enabled) {wireFrame_ = enabled;}
|
void setWireframe(bool enabled) {wireFrame_ = enabled;}
|
||||||
|
|||||||
@@ -63,11 +63,8 @@ GestureCamera::~GestureCamera() { delete cam_parent_transform_; }
|
|||||||
|
|
||||||
void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
|
void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
|
||||||
float y0, float x1, float y1) {
|
float y0, float x1, float y1) {
|
||||||
if (camera_type_ == kFirstPerson) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (touch_count == 1) {
|
if (camera_type_!=kFirstPerson && touch_count == 1) {
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case kTouch0Down: {
|
case kTouch0Down: {
|
||||||
cam_start_angle_ = cam_cur_angle_;
|
cam_start_angle_ = cam_cur_angle_;
|
||||||
@@ -100,6 +97,7 @@ void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
|
|||||||
float abs_y = y0 - y1;
|
float abs_y = y0 - y1;
|
||||||
start_touch_dist_ = std::sqrt(abs_x * abs_x + abs_y * abs_y);
|
start_touch_dist_ = std::sqrt(abs_x * abs_x + abs_y * abs_y);
|
||||||
cam_start_dist_ = GetPosition().z;
|
cam_start_dist_ = GetPosition().z;
|
||||||
|
cam_start_fov_ = this->getFOV();
|
||||||
|
|
||||||
// center touch
|
// center touch
|
||||||
touch0_start_position_.x = (x0+x1)/2.0f;
|
touch0_start_position_.x = (x0+x1)/2.0f;
|
||||||
@@ -111,25 +109,31 @@ void GestureCamera::OnTouchEvent(int touch_count, TouchEvent event, float x0,
|
|||||||
float abs_y = y0 - y1;
|
float abs_y = y0 - y1;
|
||||||
float dist = start_touch_dist_ - std::sqrt(abs_x * abs_x + abs_y * abs_y);
|
float dist = start_touch_dist_ - std::sqrt(abs_x * abs_x + abs_y * abs_y);
|
||||||
|
|
||||||
cam_cur_dist_ = tango_gl::util::Clamp(cam_start_dist_ + dist * kZoomSpeed,
|
if(camera_type_ == kFirstPerson)
|
||||||
kCamViewMinDist, kCamViewMaxDist);
|
|
||||||
|
|
||||||
this->SetOrthoMode(camera_type_ == kTopOrtho);
|
|
||||||
if(camera_type_ == kTopOrtho)
|
|
||||||
{
|
{
|
||||||
this->SetOrthoScale(cam_cur_dist_);
|
this->SetFieldOfView(tango_gl::util::Clamp(cam_start_fov_ + dist * kZoomSpeed*10.0f, 45, 90));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cam_cur_dist_ = tango_gl::util::Clamp(cam_start_dist_ + dist * kZoomSpeed,
|
||||||
|
kCamViewMinDist, kCamViewMaxDist);
|
||||||
|
|
||||||
glm::vec2 touch_center_position((x0+x1)/2.0f, (y0+y1)/2.0f);
|
this->SetOrthoMode(camera_type_ == kTopOrtho);
|
||||||
glm::vec2 offset;
|
if(camera_type_ == kTopOrtho)
|
||||||
offset.x = (touch_center_position.x - touch0_start_position_.x) * kMoveSpeed;
|
{
|
||||||
offset.y = (touch_center_position.y - touch0_start_position_.y) * kMoveSpeed;
|
this->SetOrthoScale(cam_cur_dist_);
|
||||||
touch0_start_position_ = touch_center_position;
|
}
|
||||||
|
|
||||||
StartCameraToCurrentTransform();
|
glm::vec2 touch_center_position((x0+x1)/2.0f, (y0+y1)/2.0f);
|
||||||
|
glm::vec2 offset;
|
||||||
|
offset.x = (touch_center_position.x - touch0_start_position_.x) * kMoveSpeed;
|
||||||
|
offset.y = (touch_center_position.y - touch0_start_position_.y) * kMoveSpeed;
|
||||||
|
touch0_start_position_ = touch_center_position;
|
||||||
|
|
||||||
anchor_offset_ += glm::rotate(cam_parent_transform_->GetRotation(), glm::vec3(-offset.x, offset.y, 0));
|
StartCameraToCurrentTransform();
|
||||||
|
|
||||||
|
anchor_offset_ += glm::rotate(cam_parent_transform_->GetRotation(), glm::vec3(-offset.x, offset.y, 0));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { break; }
|
default: { break; }
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ class GestureCamera : public Camera {
|
|||||||
glm::quat cam_cur_target_rot_;
|
glm::quat cam_cur_target_rot_;
|
||||||
|
|
||||||
float cam_start_dist_;
|
float cam_start_dist_;
|
||||||
|
float cam_start_fov_;
|
||||||
float cam_cur_dist_;
|
float cam_cur_dist_;
|
||||||
glm::vec3 anchor_offset_;
|
glm::vec3 anchor_offset_;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<gradient
|
||||||
|
android:endColor="#00ffffff"
|
||||||
|
android:startColor="#ff686868"
|
||||||
|
android:useLevel="false" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</layer-list>
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
android:layout_above="@+id/light_button"
|
android:layout_above="@+id/light_button"
|
||||||
android:layout_alignLeft="@+id/light_button"
|
android:layout_alignLeft="@+id/light_button"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_marginBottom="15dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:layout_marginRight="5dp"
|
android:layout_marginRight="5dp"
|
||||||
android:paddingRight="5dp"
|
android:paddingRight="5dp"
|
||||||
android:textOff="@string/wireframe"
|
android:textOff="@string/wireframe"
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
android:layout_above="@+id/backface_button"
|
android:layout_above="@+id/backface_button"
|
||||||
android:layout_alignLeft="@+id/backface_button"
|
android:layout_alignLeft="@+id/backface_button"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_marginBottom="15dp"
|
android:layout_marginBottom="5dp"
|
||||||
android:layout_marginRight="5dp"
|
android:layout_marginRight="5dp"
|
||||||
android:paddingRight="5dp"
|
android:paddingRight="5dp"
|
||||||
android:textOff="@string/light_off"
|
android:textOff="@string/light_off"
|
||||||
@@ -58,60 +58,36 @@
|
|||||||
android:id="@+id/backface_button"
|
android:id="@+id/backface_button"
|
||||||
android:layout_width="100dp"
|
android:layout_width="100dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_above="@+id/first_person_button"
|
android:layout_above="@+id/camera_button"
|
||||||
android:layout_alignLeft="@+id/first_person_button"
|
android:layout_alignRight="@+id/camera_button"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_marginBottom="5dp"
|
android:layout_marginBottom="15dp"
|
||||||
android:layout_marginRight="5dp"
|
android:layout_marginRight="5dp"
|
||||||
android:paddingRight="5dp"
|
android:paddingRight="5dp"
|
||||||
android:textOff="@string/backface_off"
|
android:textOff="@string/backface_off"
|
||||||
android:textOn="@string/backface_on" />
|
android:textOn="@string/backface_on" />
|
||||||
|
|
||||||
<ToggleButton
|
<com.introlab.rtabmap.NDSpinner
|
||||||
android:id="@+id/first_person_button"
|
android:id="@+id/camera_button"
|
||||||
android:layout_width="100dp"
|
android:layout_width="140dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="40dp"
|
||||||
android:layout_above="@+id/third_person_button"
|
|
||||||
android:layout_alignLeft="@+id/third_person_button"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:layout_marginRight="5dp"
|
|
||||||
android:paddingRight="5dp"
|
|
||||||
android:textOff="@string/first_person"
|
|
||||||
android:textOn="@string/first_person" />
|
|
||||||
|
|
||||||
<ToggleButton
|
|
||||||
android:id="@+id/third_person_button"
|
|
||||||
android:layout_width="100dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_above="@+id/top_down_button"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
android:layout_marginRight="5dp"
|
|
||||||
android:paddingRight="5dp"
|
|
||||||
android:textOff="@string/third_person"
|
|
||||||
android:textOn="@string/third_person" />
|
|
||||||
|
|
||||||
<ToggleButton
|
|
||||||
android:id="@+id/top_down_button"
|
|
||||||
android:layout_width="100dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:layout_marginRight="5dp"
|
android:layout_marginRight="5dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
android:paddingRight="5dp"
|
android:paddingRight="5dp"
|
||||||
android:textOff="@string/top_down"
|
android:paddingBottom="10dp"
|
||||||
android:textOn="@string/top_down" />
|
android:text="@string/camera_button"
|
||||||
|
android:spinnerMode="dropdown"/>
|
||||||
|
|
||||||
<ToggleButton
|
<ToggleButton
|
||||||
android:id="@+id/pause_button"
|
android:id="@+id/pause_button"
|
||||||
android:layout_width="100dp"
|
android:layout_width="100dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignLeft="@+id/first_person_button"
|
android:layout_marginRight="5dp"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_marginTop="61dp"
|
android:layout_marginTop="10dp"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_alignParentRight="true"
|
||||||
android:paddingRight="5dp"
|
|
||||||
android:textOff="@string/pause"
|
android:textOff="@string/pause"
|
||||||
android:textOn="@string/resume" />
|
android:textOn="@string/resume" />
|
||||||
|
|
||||||
@@ -119,37 +95,50 @@
|
|||||||
android:id="@+id/button_shareToSketchfab"
|
android:id="@+id/button_shareToSketchfab"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="5dp"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignRight="@+id/pause_button"
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
android:text="@string/share_to_sketchfab" />
|
android:text="@string/share_to_sketchfab" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button_saveOnDevice"
|
android:id="@+id/button_saveOnDevice"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignRight="@+id/button_shareToSketchfab"
|
||||||
android:layout_toLeftOf="@+id/button_shareToSketchfab"
|
android:layout_below="@+id/button_shareToSketchfab"
|
||||||
android:text="@string/save_to_file" />
|
android:text="@string/save_to_file" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/close_visualization_button"
|
android:id="@+id/close_visualization_button"
|
||||||
android:layout_width="200dp"
|
android:layout_width="200dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignBaseline="@+id/top_down_button"
|
android:layout_above="@+id/camera_button"
|
||||||
android:layout_alignBottom="@+id/top_down_button"
|
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:paddingLeft="5dp"
|
|
||||||
android:text="@string/close_visualization" />
|
android:text="@string/close_visualization" />
|
||||||
|
|
||||||
<SeekBar
|
<SeekBar
|
||||||
android:id="@+id/seekBar_fov"
|
android:id="@+id/seekBar_ortho_cut"
|
||||||
android:layout_width="200dp"
|
android:layout_width="200dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:rotation="270"
|
android:rotation="270"
|
||||||
|
android:layout_above="@+id/light_button"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_alignBaseline="@+id/first_person_button"
|
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginLeft="-50dp" />
|
android:layout_marginLeft="-50dp"
|
||||||
|
android:progressDrawable="@drawable/custom_seekbar" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekBar_grid"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignBottom="@+id/camera_button"
|
||||||
|
android:layout_marginLeft="35dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
|
android:progressDrawable="@drawable/custom_seekbar" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
@@ -292,6 +292,14 @@
|
|||||||
android:summary="@string/pref_summary_opt_clean_white"
|
android:summary="@string/pref_summary_opt_clean_white"
|
||||||
android:defaultValue="@string/pref_default_opt_clean_white"/>
|
android:defaultValue="@string/pref_default_opt_clean_white"/>
|
||||||
|
|
||||||
|
<ListPreference
|
||||||
|
android:key="@string/pref_key_opt_min_cluster_size"
|
||||||
|
android:title="@string/pref_title_opt_min_cluster_size"
|
||||||
|
android:summary="@string/pref_summary_opt_min_cluster_size"
|
||||||
|
android:entries="@array/pref_opt_min_cluster_size_keys"
|
||||||
|
android:entryValues="@array/pref_opt_min_cluster_size_values"
|
||||||
|
android:defaultValue="@string/pref_default_opt_min_cluster_size"/>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
<ListPreference
|
<ListPreference
|
||||||
@@ -308,6 +316,11 @@
|
|||||||
android:entries="@array/pref_cluster_ratio_keys"
|
android:entries="@array/pref_cluster_ratio_keys"
|
||||||
android:entryValues="@array/pref_cluster_ratio_values"
|
android:entryValues="@array/pref_cluster_ratio_values"
|
||||||
android:defaultValue="@string/pref_default_cluster_ratio"/>
|
android:defaultValue="@string/pref_default_cluster_ratio"/>
|
||||||
|
<SwitchPreference
|
||||||
|
android:key="@string/pref_key_notification_sound"
|
||||||
|
android:title="@string/pref_title_notification_sound"
|
||||||
|
android:summary="@string/pref_summary_notification_sound"
|
||||||
|
android:defaultValue="@string/pref_default_notification_sound"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="@string/pref_title_presets">
|
android:title="@string/pref_title_presets">
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
<resources>
|
||||||
|
<string-array name="camera_view_array">
|
||||||
|
<item>First View</item>
|
||||||
|
<item>Third-P. View</item>
|
||||||
|
<item>Top View</item>
|
||||||
|
<item>Ortho View</item>
|
||||||
|
</string-array>
|
||||||
|
</resources>
|
||||||
@@ -8,9 +8,7 @@
|
|||||||
<string name="sketchfab">Upload to Sketchfab…</string>
|
<string name="sketchfab">Upload to Sketchfab…</string>
|
||||||
<string name="status">"Status: "</string>
|
<string name="status">"Status: "</string>
|
||||||
<string name="words">"Words: "</string>
|
<string name="words">"Words: "</string>
|
||||||
<string name="first_person">First</string>
|
<string name="camera_button">First View</string>
|
||||||
<string name="third_person">Third</string>
|
|
||||||
<string name="top_down">Top</string>
|
|
||||||
<string name="pause">Pause</string>
|
<string name="pause">Pause</string>
|
||||||
<string name="resume">Resume</string>
|
<string name="resume">Resume</string>
|
||||||
<string name="backface_on">Backface</string>
|
<string name="backface_on">Backface</string>
|
||||||
@@ -126,10 +124,14 @@
|
|||||||
<string name="pref_default_opt_color_radius">0.05</string>
|
<string name="pref_default_opt_color_radius">0.05</string>
|
||||||
<string name="pref_key_opt_clean_white">pref_key_opt_clean_white</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_default_opt_clean_white">true</string>
|
||||||
|
<string name="pref_key_opt_min_cluster_size">pref_key_opt_min_cluster_size</string>
|
||||||
|
<string name="pref_default_opt_min_cluster_size">0</string>
|
||||||
<string name="pref_key_gain_max_radius">pref_key_gain_max_radius</string>
|
<string name="pref_key_gain_max_radius">pref_key_gain_max_radius</string>
|
||||||
<string name="pref_default_gain_max_radius">0.02</string>
|
<string name="pref_default_gain_max_radius">0.02</string>
|
||||||
<string name="pref_key_cluster_ratio">pref_key_cluster_ratio</string>
|
<string name="pref_key_cluster_ratio">pref_key_cluster_ratio</string>
|
||||||
<string name="pref_default_cluster_ratio">0.05</string>
|
<string name="pref_default_cluster_ratio">0.05</string>
|
||||||
|
<string name="pref_key_notification_sound">pref_key_notification_sound</string>
|
||||||
|
<string name="pref_default_notification_sound">true</string>
|
||||||
<!-- Preference keys: END -->
|
<!-- Preference keys: END -->
|
||||||
|
|
||||||
<string name="pref_title_rendering">Rendering</string>
|
<string name="pref_title_rendering">Rendering</string>
|
||||||
@@ -308,7 +310,7 @@
|
|||||||
<string name="pref_title_smoothing">Smoothing</string>
|
<string name="pref_title_smoothing">Smoothing</string>
|
||||||
<string name="pref_summary_smoothing">Smooth the point clouds.</string>
|
<string name="pref_summary_smoothing">Smooth the point clouds.</string>
|
||||||
<string name="pref_title_fisheye">Fish Eye Camera</string>
|
<string name="pref_title_fisheye">Fish Eye Camera</string>
|
||||||
<string name="pref_summary_fisheye">Use fish eye camera instead of the color camera. Cannot be used on Yellowstone tablet.</string>
|
<string name="pref_summary_fisheye">Use fish eye camera instead of the color camera. May not work on some devices.</string>
|
||||||
<string name="pref_title_update_rate">Update Rate</string>
|
<string name="pref_title_update_rate">Update Rate</string>
|
||||||
<string name="pref_summary_update_rate">Rate at which a new node is added to map.</string>
|
<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_title_time_thr">Time Limit</string>
|
||||||
@@ -659,22 +661,22 @@
|
|||||||
<item>"2"</item>
|
<item>"2"</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="pref_min_texture_cluster_size_keys">
|
<string-array name="pref_min_texture_cluster_size_keys">
|
||||||
<item>"Disabled"</item>
|
|
||||||
<item>"1000"</item>
|
<item>"1000"</item>
|
||||||
<item>"500"</item>
|
<item>"500"</item>
|
||||||
<item>"200"</item>
|
<item>"200"</item>
|
||||||
<item>"100"</item>
|
<item>"100"</item>
|
||||||
<item>"50"</item>
|
<item>"50"</item>
|
||||||
<item>"10"</item>
|
<item>"10"</item>
|
||||||
|
<item>"Disabled"</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="pref_min_texture_cluster_size_values">
|
<string-array name="pref_min_texture_cluster_size_values">
|
||||||
<item>"0"</item>
|
|
||||||
<item>"1000"</item>
|
<item>"1000"</item>
|
||||||
<item>"500"</item>
|
<item>"500"</item>
|
||||||
<item>"200"</item>
|
<item>"200"</item>
|
||||||
<item>"100"</item>
|
<item>"100"</item>
|
||||||
<item>"50"</item>
|
<item>"50"</item>
|
||||||
<item>"10"</item>
|
<item>"10"</item>
|
||||||
|
<item>"0"</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string name="pref_title_optimized">Optimized</string>
|
<string name="pref_title_optimized">Optimized</string>
|
||||||
@@ -686,6 +688,8 @@
|
|||||||
<string name="pref_summary_opt_color_radius">Radius used to transfer nearest color from the point cloud to reconstructed mesh. When exporting with texture, if Clean Mesh is also enabled, this will limit the number of polygons textured in holes.</string>
|
<string name="pref_summary_opt_color_radius">Radius used to transfer nearest color from the point cloud to reconstructed mesh. When exporting with texture, if Clean Mesh is also enabled, this will limit the number of polygons textured in holes.</string>
|
||||||
<string name="pref_title_opt_clean_white">Clean Mesh</string>
|
<string name="pref_title_opt_clean_white">Clean Mesh</string>
|
||||||
<string name="pref_summary_opt_clean_white">Clean mesh from textureless or colorless reconstructed polygons.</string>
|
<string name="pref_summary_opt_clean_white">Clean mesh from textureless or colorless reconstructed polygons.</string>
|
||||||
|
<string name="pref_summary_opt_min_cluster_size">This can be used to filter polygons before texturing.</string>
|
||||||
|
<string name="pref_title_opt_min_cluster_size">Polygon Filtering</string>
|
||||||
|
|
||||||
<string-array name="pref_opt_depth_keys">
|
<string-array name="pref_opt_depth_keys">
|
||||||
<item>"Auto"</item>
|
<item>"Auto"</item>
|
||||||
@@ -735,12 +739,22 @@
|
|||||||
<item>"0.01"</item>
|
<item>"0.01"</item>
|
||||||
<item>"-1"</item>
|
<item>"-1"</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string-array name="pref_opt_min_cluster_size_keys">
|
||||||
|
<item>"Only biggest cluster kept"</item>
|
||||||
|
<item>"Keep all polygons"</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="pref_opt_min_cluster_size_values">
|
||||||
|
<item>"-1"</item>
|
||||||
|
<item>"0"</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<string name="pref_title_general">General</string>
|
<string name="pref_title_general">General</string>
|
||||||
<string name="pref_title_gain_max_radius">Color Correction Radius</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 Adjust Colors optimization.</string>
|
<string name="pref_summary_gain_max_radius">Radius used to find pixel correspondences for Adjust Colors optimization.</string>
|
||||||
<string name="pref_title_cluster_ratio">Noise Filtering Ratio</string>
|
<string name="pref_title_cluster_ratio">Noise Filtering Ratio</string>
|
||||||
<string name="pref_summary_cluster_ratio">Polygon clusters with size smaller than this ratio of the largest cluster are removed by the Noise Filtering optimization.</string>
|
<string name="pref_summary_cluster_ratio">Polygon clusters with size smaller than this ratio of the largest cluster are removed by the Noise Filtering optimization.</string>
|
||||||
|
<string name="pref_title_notification_sound">Notification Sound</string>
|
||||||
|
<string name="pref_summary_notification_sound">After saving database or preparing data to export, a notification sound is played.</string>
|
||||||
|
|
||||||
<string-array name="pref_gain_max_radius_keys">
|
<string-array name="pref_gain_max_radius_keys">
|
||||||
<item>"0.3 m"</item>
|
<item>"0.3 m"</item>
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<resources>
|
||||||
|
<style name="ThemeActionBar" parent="@android:style/Widget.DeviceDefault.ActionBar.Solid">
|
||||||
|
<item name="android:background">#20000000</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="ThemeApp" parent="@android:style/Theme.DeviceDefault">
|
||||||
|
<item name="android:actionBarStyle">@style/ThemeActionBar</item>
|
||||||
|
<item name="android:windowActionBarOverlay">true</item>
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.introlab.rtabmap;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
|
||||||
|
|
||||||
|
/** Spinner extension that calls onItemSelected even when the selection is the same as its previous value
|
||||||
|
Author: Mattia Ruggiero
|
||||||
|
https://stackoverflow.com/questions/5335306/how-can-i-get-an-event-in-android-spinner-when-the-current-selected-item-is-sele
|
||||||
|
*/
|
||||||
|
public class NDSpinner extends Spinner {
|
||||||
|
|
||||||
|
public NDSpinner(Context context)
|
||||||
|
{ super(context); }
|
||||||
|
|
||||||
|
public NDSpinner(Context context, AttributeSet attrs)
|
||||||
|
{ super(context, attrs); }
|
||||||
|
|
||||||
|
public NDSpinner(Context context, AttributeSet attrs, int defStyle)
|
||||||
|
{ super(context, attrs, defStyle); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelection(int position, boolean animate) {
|
||||||
|
boolean sameSelected = position == getSelectedItemPosition();
|
||||||
|
super.setSelection(position, animate);
|
||||||
|
if (sameSelected) {
|
||||||
|
// Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
|
||||||
|
//getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSelection(int position) {
|
||||||
|
boolean sameSelected = position == getSelectedItemPosition();
|
||||||
|
super.setSelection(position);
|
||||||
|
if (sameSelected) {
|
||||||
|
// Spinner does not call the OnItemSelectedListener if the same item is selected, so do it manually now
|
||||||
|
getOnItemSelectedListener().onItemSelected(this, getSelectedView(), position, getSelectedItemId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -89,6 +89,9 @@ import android.view.WindowManager;
|
|||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.AdapterView.OnItemSelectedListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
@@ -96,6 +99,7 @@ import android.widget.NumberPicker;
|
|||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||||
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.ToggleButton;
|
import android.widget.ToggleButton;
|
||||||
@@ -104,7 +108,7 @@ import com.google.atap.tangoservice.Tango;
|
|||||||
|
|
||||||
// The main activity of the application. This activity shows debug information
|
// The main activity of the application. This activity shows debug information
|
||||||
// and a glSurfaceView that renders graphic content.
|
// and a glSurfaceView that renders graphic content.
|
||||||
public class RTABMapActivity extends Activity implements OnClickListener {
|
public class RTABMapActivity extends Activity implements OnClickListener, OnItemSelectedListener {
|
||||||
|
|
||||||
// Tag for debug logging.
|
// Tag for debug logging.
|
||||||
public static final String TAG = RTABMapActivity.class.getSimpleName();
|
public static final String TAG = RTABMapActivity.class.getSimpleName();
|
||||||
@@ -134,7 +138,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
public static final long NOTOUCH_TIMEOUT = 5000; // 5 sec
|
public static final long NOTOUCH_TIMEOUT = 5000; // 5 sec
|
||||||
private boolean mHudVisible = true;
|
private boolean mHudVisible = true;
|
||||||
private boolean mTipOrthoShown_ = false;
|
|
||||||
private int mSavedRenderingType = 0;
|
private int mSavedRenderingType = 0;
|
||||||
private boolean mMenuOpened = false;
|
private boolean mMenuOpened = false;
|
||||||
|
|
||||||
@@ -182,9 +185,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
private MenuItem mItemStatusVisibility;
|
private MenuItem mItemStatusVisibility;
|
||||||
private MenuItem mItemDebugVisibility;
|
private MenuItem mItemDebugVisibility;
|
||||||
|
|
||||||
private ToggleButton mButtonFirst;
|
private NDSpinner mButtonCameraView;
|
||||||
private ToggleButton mButtonThird;
|
|
||||||
private ToggleButton mButtonTop;
|
|
||||||
private ToggleButton mButtonPause;
|
private ToggleButton mButtonPause;
|
||||||
private ToggleButton mButtonLighting;
|
private ToggleButton mButtonLighting;
|
||||||
private ToggleButton mButtonWireframe;
|
private ToggleButton mButtonWireframe;
|
||||||
@@ -192,7 +193,8 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
private Button mButtonCloseVisualization;
|
private Button mButtonCloseVisualization;
|
||||||
private Button mButtonSaveOnDevice;
|
private Button mButtonSaveOnDevice;
|
||||||
private Button mButtonShareOnSketchfab;
|
private Button mButtonShareOnSketchfab;
|
||||||
private SeekBar mSeekBarFov;
|
private SeekBar mSeekBarOrthoCut;
|
||||||
|
private SeekBar mSeekBarGrid;
|
||||||
|
|
||||||
private String mOpenedDatabasePath = "";
|
private String mOpenedDatabasePath = "";
|
||||||
private String mWorkingDirectory = "";
|
private String mWorkingDirectory = "";
|
||||||
@@ -255,6 +257,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
display.getSize(mScreenSize);
|
display.getSize(mScreenSize);
|
||||||
|
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
|
||||||
|
|
||||||
// Setting content view of this activity.
|
// Setting content view of this activity.
|
||||||
setContentView(R.layout.activity_rtabmap);
|
setContentView(R.layout.activity_rtabmap);
|
||||||
@@ -267,9 +270,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mActionBarHeight = getActionBarHeight();
|
mActionBarHeight = getActionBarHeight();
|
||||||
|
|
||||||
// Buttons for selecting camera view and Set up button click listeners.
|
// Buttons for selecting camera view and Set up button click listeners.
|
||||||
mButtonFirst = (ToggleButton)findViewById(R.id.first_person_button);
|
mButtonCameraView = (NDSpinner)findViewById(R.id.camera_button);
|
||||||
mButtonThird = (ToggleButton)findViewById(R.id.third_person_button);
|
|
||||||
mButtonTop = (ToggleButton)findViewById(R.id.top_down_button);
|
|
||||||
mButtonPause = (ToggleButton)findViewById(R.id.pause_button);
|
mButtonPause = (ToggleButton)findViewById(R.id.pause_button);
|
||||||
mButtonLighting = (ToggleButton)findViewById(R.id.light_button);
|
mButtonLighting = (ToggleButton)findViewById(R.id.light_button);
|
||||||
mButtonWireframe = (ToggleButton)findViewById(R.id.wireframe_button);
|
mButtonWireframe = (ToggleButton)findViewById(R.id.wireframe_button);
|
||||||
@@ -277,9 +278,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mButtonCloseVisualization = (Button)findViewById(R.id.close_visualization_button);
|
mButtonCloseVisualization = (Button)findViewById(R.id.close_visualization_button);
|
||||||
mButtonSaveOnDevice = (Button)findViewById(R.id.button_saveOnDevice);
|
mButtonSaveOnDevice = (Button)findViewById(R.id.button_saveOnDevice);
|
||||||
mButtonShareOnSketchfab = (Button)findViewById(R.id.button_shareToSketchfab);
|
mButtonShareOnSketchfab = (Button)findViewById(R.id.button_shareToSketchfab);
|
||||||
mButtonFirst.setOnClickListener(this);
|
mButtonCameraView.setOnItemSelectedListener(this);
|
||||||
mButtonThird.setOnClickListener(this);
|
|
||||||
mButtonTop.setOnClickListener(this);
|
|
||||||
mButtonPause.setOnClickListener(this);
|
mButtonPause.setOnClickListener(this);
|
||||||
mButtonLighting.setOnClickListener(this);
|
mButtonLighting.setOnClickListener(this);
|
||||||
mButtonWireframe.setOnClickListener(this);
|
mButtonWireframe.setOnClickListener(this);
|
||||||
@@ -287,7 +286,6 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mButtonCloseVisualization.setOnClickListener(this);
|
mButtonCloseVisualization.setOnClickListener(this);
|
||||||
mButtonSaveOnDevice.setOnClickListener(this);
|
mButtonSaveOnDevice.setOnClickListener(this);
|
||||||
mButtonShareOnSketchfab.setOnClickListener(this);
|
mButtonShareOnSketchfab.setOnClickListener(this);
|
||||||
mButtonFirst.setChecked(true);
|
|
||||||
mButtonLighting.setChecked(false);
|
mButtonLighting.setChecked(false);
|
||||||
mButtonLighting.setVisibility(View.INVISIBLE);
|
mButtonLighting.setVisibility(View.INVISIBLE);
|
||||||
mButtonWireframe.setChecked(false);
|
mButtonWireframe.setChecked(false);
|
||||||
@@ -300,20 +298,43 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mButtonBackfaceShown.setVisibility(mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked()?View.VISIBLE:View.INVISIBLE);
|
mButtonBackfaceShown.setVisibility(mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked()?View.VISIBLE:View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
mSeekBarFov = (SeekBar)findViewById(R.id.seekBar_fov);
|
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.camera_view_array, android.R.layout.simple_spinner_item);
|
||||||
mSeekBarFov.setMax(45);
|
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
mSeekBarFov.setProgress(20);
|
mButtonCameraView.setAdapter(adapter);
|
||||||
mSeekBarFov.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
|
mButtonCameraView.setOnTouchListener(new OnTouchListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
resetNoTouchTimer();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mSeekBarOrthoCut = (SeekBar)findViewById(R.id.seekBar_ortho_cut);
|
||||||
|
mSeekBarOrthoCut.setMax(120);
|
||||||
|
mSeekBarOrthoCut.setProgress(80);
|
||||||
|
mSeekBarOrthoCut.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser) {
|
public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser) {
|
||||||
if(mButtonFirst.isChecked())
|
RTABMapLib.setOrthoCropFactor((float)(120-progressValue)/20.0f - 3.0f);
|
||||||
{
|
resetNoTouchTimer();
|
||||||
RTABMapLib.setFOV((float)progressValue+45.0f);
|
}
|
||||||
}
|
|
||||||
else if(mButtonTop.isChecked())
|
@Override
|
||||||
{
|
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||||
RTABMapLib.setOrthoCropFactor((float)(120-progressValue)/20.0f - 3.0f);
|
}
|
||||||
}
|
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mSeekBarGrid = (SeekBar)findViewById(R.id.seekBar_grid);
|
||||||
|
mSeekBarGrid.setMax(180);
|
||||||
|
mSeekBarGrid.setProgress(90);
|
||||||
|
mSeekBarGrid.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser) {
|
||||||
|
RTABMapLib.setGridRotation(((float)progressValue-90.0f)/2.0f);
|
||||||
resetNoTouchTimer();
|
resetNoTouchTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +361,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View v, MotionEvent event) {
|
public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
|
||||||
resetNoTouchTimer();
|
resetNoTouchTimer(getActionBar().isShowing() && mHudVisible == false);
|
||||||
|
|
||||||
mGesDetect.onTouchEvent(event);
|
mGesDetect.onTouchEvent(event);
|
||||||
|
|
||||||
@@ -701,7 +722,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TangoInitializationHelper.bindTangoService(getActivity(), mTangoServiceConnection);
|
TangoInitializationHelper.bindTangoService(getActivity(), mTangoServiceConnection);
|
||||||
resetNoTouchTimer();
|
resetNoTouchTimer(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCamera(int type)
|
private void setCamera(int type)
|
||||||
@@ -714,28 +735,13 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
updateStatusTexts();
|
updateStatusTexts();
|
||||||
|
|
||||||
RTABMapLib.setCamera(type);
|
RTABMapLib.setCamera(type);
|
||||||
mButtonFirst.setChecked(type==0);
|
mButtonCameraView.setSelection(type, true);
|
||||||
mButtonThird.setChecked(type==1);
|
mSeekBarOrthoCut.setVisibility(type!=3?View.INVISIBLE:View.VISIBLE);
|
||||||
mButtonTop.setChecked(type==2 || type==3);
|
mSeekBarGrid.setVisibility(mSeekBarGrid.isEnabled() && type==3?View.VISIBLE:View.INVISIBLE);
|
||||||
mButtonTop.setText(type==3?"Ortho":"Top");
|
|
||||||
mButtonTop.setTextOn(type==3?"Ortho":"Top");
|
|
||||||
mButtonTop.setTextOff(type==3?"Ortho":"Top");
|
|
||||||
mSeekBarFov.setVisibility(type!=0 && type!=3?View.INVISIBLE:View.VISIBLE);
|
|
||||||
if(type==0)
|
|
||||||
{
|
|
||||||
mSeekBarFov.setMax(45);
|
|
||||||
mSeekBarFov.setProgress(20);
|
|
||||||
}
|
|
||||||
if(type==3)
|
if(type==3)
|
||||||
{
|
{
|
||||||
mSeekBarFov.setMax(120);
|
mSeekBarOrthoCut.setMax(120);
|
||||||
mSeekBarFov.setProgress(80);
|
mSeekBarOrthoCut.setProgress(80);
|
||||||
}
|
|
||||||
|
|
||||||
if(type==2 && !mTipOrthoShown_)
|
|
||||||
{
|
|
||||||
mToast.makeText(this, "Tip: Click again on Top to set Ortho mode.", mToast.LENGTH_LONG).show();
|
|
||||||
mTipOrthoShown_ = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,15 +749,8 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
// Handle button clicks.
|
// Handle button clicks.
|
||||||
switch (v.getId()) {
|
switch (v.getId()) {
|
||||||
case R.id.first_person_button:
|
case R.id.gl_surface_view:
|
||||||
setCamera(0);
|
|
||||||
|
|
||||||
break;
|
|
||||||
case R.id.third_person_button:
|
|
||||||
setCamera(1);
|
|
||||||
break;
|
|
||||||
case R.id.top_down_button:
|
|
||||||
setCamera(mButtonFirst.isChecked() || mButtonThird.isChecked() || mButtonTop.getTextOn().equals("Ortho")?2:3);
|
|
||||||
break;
|
break;
|
||||||
case R.id.pause_button:
|
case R.id.pause_button:
|
||||||
pauseMapping();
|
pauseMapping();
|
||||||
@@ -793,6 +792,15 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
resetNoTouchTimer();
|
resetNoTouchTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
|
||||||
|
setCamera(pos);
|
||||||
|
resetNoTouchTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
resetNoTouchTimer();
|
||||||
|
}
|
||||||
|
|
||||||
private void setAndroidOrientation() {
|
private void setAndroidOrientation() {
|
||||||
Display display = getWindowManager().getDefaultDisplay();
|
Display display = getWindowManager().getDefaultDisplay();
|
||||||
Camera.CameraInfo colorCameraInfo = new Camera.CameraInfo();
|
Camera.CameraInfo colorCameraInfo = new Camera.CameraInfo();
|
||||||
@@ -806,11 +814,26 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDoubleTap(MotionEvent event) {
|
public boolean onDoubleTap(MotionEvent event) {
|
||||||
|
if(!DISABLE_LOG) Log.i(TAG, "onDoubleTap");
|
||||||
float normalizedX = event.getX(0) / mScreenSize.x;
|
float normalizedX = event.getX(0) / mScreenSize.x;
|
||||||
float normalizedY = event.getY(0) / mScreenSize.y;
|
float normalizedY = event.getY(0) / mScreenSize.y;
|
||||||
RTABMapLib.onTouchEvent(3, event.getActionMasked(), normalizedX, normalizedY, 0.0f, 0.0f);
|
RTABMapLib.onTouchEvent(3, event.getActionMasked(), normalizedX, normalizedY, 0.0f, 0.0f);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public boolean onSingleTapConfirmed(MotionEvent event) {
|
||||||
|
if(!DISABLE_LOG) Log.i(TAG, "onSingleTapConfirmed");
|
||||||
|
if(mHudVisible)
|
||||||
|
{
|
||||||
|
notouchHandler.removeCallbacks(notouchCallback);
|
||||||
|
notouchHandler.postDelayed(notouchCallback, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resetNoTouchTimer(true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1146,9 +1169,9 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateState(State.STATE_VISUALIZING_WHILE_LOADING);
|
updateState(State.STATE_VISUALIZING_WHILE_LOADING);
|
||||||
if(mButtonFirst.isChecked())
|
if(mButtonCameraView.getSelectedItemPosition() == 0)
|
||||||
{
|
{
|
||||||
setCamera(1);
|
setCamera(2);
|
||||||
}
|
}
|
||||||
mToast.makeText(getActivity(), String.format("Optimized mesh detected in the database, it is shown while the database is loading..."), mToast.LENGTH_LONG).show();
|
mToast.makeText(getActivity(), String.format("Optimized mesh detected in the database, it is shown while the database is loading..."), mToast.LENGTH_LONG).show();
|
||||||
mProgressDialog.dismiss();
|
mProgressDialog.dismiss();
|
||||||
@@ -1348,13 +1371,19 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public void resetNoTouchTimer(){
|
public void resetNoTouchTimer(){
|
||||||
if(!mHudVisible)
|
resetNoTouchTimer(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetNoTouchTimer(boolean showHud){
|
||||||
|
if(showHud)
|
||||||
{
|
{
|
||||||
setNavVisibility(true);
|
|
||||||
mHudVisible = true;
|
mHudVisible = true;
|
||||||
updateState(mState);
|
setNavVisibility(true);
|
||||||
|
if(mItemSave != null)
|
||||||
|
{
|
||||||
|
updateState(mState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mHudVisible = true;
|
|
||||||
|
|
||||||
notouchHandler.removeCallbacks(notouchCallback);
|
notouchHandler.removeCallbacks(notouchCallback);
|
||||||
notouchHandler.postDelayed(notouchCallback, NOTOUCH_TIMEOUT);
|
notouchHandler.postDelayed(notouchCallback, NOTOUCH_TIMEOUT);
|
||||||
@@ -1371,6 +1400,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mToast.makeText(getActivity(), String.format("Re-adding %d online clouds, this may take some time...", mMapNodes), mToast.LENGTH_LONG).show();
|
mToast.makeText(getActivity(), String.format("Re-adding %d online clouds, this may take some time...", mMapNodes), mToast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
mState = state;
|
mState = state;
|
||||||
|
if(!DISABLE_LOG) Log.i(TAG, String.format("updateState() state=%s hud=%d", state.toString(), mHudVisible?1:0));
|
||||||
switch(state)
|
switch(state)
|
||||||
{
|
{
|
||||||
case STATE_PROCESSING:
|
case STATE_PROCESSING:
|
||||||
@@ -1438,11 +1468,10 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mItemDataRecorderMode.setEnabled(mButtonPause.isChecked());
|
mItemDataRecorderMode.setEnabled(mButtonPause.isChecked());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mButtonFirst.setVisibility(mHudVisible?View.VISIBLE:View.INVISIBLE);
|
mButtonCameraView.setVisibility(mHudVisible?View.VISIBLE:View.INVISIBLE);
|
||||||
mButtonThird.setVisibility(mHudVisible?View.VISIBLE:View.INVISIBLE);
|
|
||||||
mButtonTop.setVisibility(mHudVisible?View.VISIBLE:View.INVISIBLE);
|
|
||||||
mButtonBackfaceShown.setVisibility(mHudVisible && (mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked())?View.VISIBLE:View.INVISIBLE);
|
mButtonBackfaceShown.setVisibility(mHudVisible && (mItemRenderingMesh.isChecked() || mItemRenderingTextureMesh.isChecked())?View.VISIBLE:View.INVISIBLE);
|
||||||
mSeekBarFov.setVisibility(mHudVisible && (mButtonFirst.isChecked() || (mButtonTop.isChecked() && mButtonTop.getTextOn().equals("Ortho")))?View.VISIBLE:View.INVISIBLE);
|
mSeekBarOrthoCut.setVisibility(mHudVisible && mButtonCameraView.getSelectedItemPosition() == 3?View.VISIBLE:View.INVISIBLE);
|
||||||
|
mSeekBarGrid.setVisibility(mHudVisible && mSeekBarGrid.isEnabled() && mButtonCameraView.getSelectedItemPosition() == 3?View.VISIBLE:View.INVISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pauseMapping() {
|
private void pauseMapping() {
|
||||||
@@ -1682,6 +1711,8 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
else if(itemId == R.id.grid_visible)
|
else if(itemId == R.id.grid_visible)
|
||||||
{
|
{
|
||||||
item.setChecked(!item.isChecked());
|
item.setChecked(!item.isChecked());
|
||||||
|
mSeekBarGrid.setEnabled(item.isChecked());
|
||||||
|
mSeekBarGrid.setVisibility(mHudVisible && mSeekBarGrid.isEnabled()&&mButtonCameraView.getSelectedItemPosition() == 3?View.VISIBLE:View.INVISIBLE);
|
||||||
RTABMapLib.setGridVisible(item.isChecked());
|
RTABMapLib.setGridVisible(item.isChecked());
|
||||||
}
|
}
|
||||||
else if (itemId == R.id.save)
|
else if (itemId == R.id.save)
|
||||||
@@ -1727,6 +1758,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
.setNegativeButton("No", new DialogInterface.OnClickListener() {
|
.setNegativeButton("No", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
|
resetNoTouchTimer(true);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.show();
|
.show();
|
||||||
@@ -1993,7 +2025,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
final int optimizedDepth = Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_opt_depth), getString(R.string.pref_default_opt_depth)));
|
final int optimizedDepth = Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_opt_depth), getString(R.string.pref_default_opt_depth)));
|
||||||
final float optimizedColorRadius = Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_opt_color_radius), getString(R.string.pref_default_opt_color_radius)));
|
final float optimizedColorRadius = Float.parseFloat(sharedPref.getString(getString(R.string.pref_key_opt_color_radius), getString(R.string.pref_default_opt_color_radius)));
|
||||||
final boolean optimizedCleanWhitePolygons = sharedPref.getBoolean(getString(R.string.pref_key_opt_clean_white), Boolean.parseBoolean(getString(R.string.pref_default_opt_clean_white)));
|
final boolean optimizedCleanWhitePolygons = sharedPref.getBoolean(getString(R.string.pref_key_opt_clean_white), Boolean.parseBoolean(getString(R.string.pref_default_opt_clean_white)));
|
||||||
final boolean optimizedColorWhitePolygons = false;//sharedPref.getBoolean("pref_key_opt_color_white", false); // not used
|
final int optimizedMinClusterSize = Integer.parseInt(sharedPref.getString(getString(R.string.pref_key_opt_min_cluster_size), getString(R.string.pref_default_opt_min_cluster_size)));
|
||||||
final boolean blockRendering = sharedPref.getBoolean(getString(R.string.pref_key_block_render), Boolean.parseBoolean(getString(R.string.pref_default_block_render)));
|
final boolean blockRendering = sharedPref.getBoolean(getString(R.string.pref_key_block_render), Boolean.parseBoolean(getString(R.string.pref_default_block_render)));
|
||||||
|
|
||||||
|
|
||||||
@@ -2024,7 +2056,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
optimizedMaxPolygons,
|
optimizedMaxPolygons,
|
||||||
optimizedColorRadius,
|
optimizedColorRadius,
|
||||||
optimizedCleanWhitePolygons,
|
optimizedCleanWhitePolygons,
|
||||||
optimizedColorWhitePolygons,
|
optimizedMinClusterSize,
|
||||||
maxTextureDistance,
|
maxTextureDistance,
|
||||||
minTextureClusterSize,
|
minTextureClusterSize,
|
||||||
blockRendering);
|
blockRendering);
|
||||||
@@ -2041,6 +2073,25 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
|
|
||||||
final long endTime = System.currentTimeMillis()/1000;
|
final long endTime = System.currentTimeMillis()/1000;
|
||||||
|
|
||||||
|
if(endTime-startTime > 10)
|
||||||
|
{
|
||||||
|
// build notification
|
||||||
|
// the addAction re-use the same intent to keep the example short
|
||||||
|
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||||
|
boolean notifySound = sharedPref.getBoolean(getString(R.string.pref_key_notification_sound), Boolean.parseBoolean(getString(R.string.pref_default_notification_sound)));
|
||||||
|
Notification n = new Notification.Builder(getActivity())
|
||||||
|
.setContentTitle(getString(R.string.app_name))
|
||||||
|
.setContentText("Data generated and ready to be exported!")
|
||||||
|
.setSmallIcon(R.drawable.ic_launcher)
|
||||||
|
.setDefaults(notifySound?Notification.DEFAULT_SOUND:0)
|
||||||
|
.setAutoCancel(true).build();
|
||||||
|
|
||||||
|
NotificationManager notificationManager =
|
||||||
|
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
notificationManager.notify(0, n);
|
||||||
|
}
|
||||||
|
|
||||||
// Visualize the result?
|
// Visualize the result?
|
||||||
AlertDialog d = new AlertDialog.Builder(getActivity())
|
AlertDialog d = new AlertDialog.Builder(getActivity())
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
@@ -2048,7 +2099,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
.setMessage(Html.fromHtml("Do you want visualize the result before saving to file or sharing to <a href=\"https://sketchfab.com/about\">Sketchfab</a>?"))
|
.setMessage(Html.fromHtml("Do you want visualize the result before saving to file or sharing to <a href=\"https://sketchfab.com/about\">Sketchfab</a>?"))
|
||||||
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
resetNoTouchTimer();
|
resetNoTouchTimer(true);
|
||||||
mSavedRenderingType = mItemRenderingPointCloud.isChecked()?0:mItemRenderingMesh.isChecked()?1:2;
|
mSavedRenderingType = mItemRenderingPointCloud.isChecked()?0:mItemRenderingMesh.isChecked()?1:2;
|
||||||
if(!meshing)
|
if(!meshing)
|
||||||
{
|
{
|
||||||
@@ -2069,7 +2120,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
updateState(State.STATE_VISUALIZING);
|
updateState(State.STATE_VISUALIZING);
|
||||||
RTABMapLib.postExportation(true);
|
RTABMapLib.postExportation(true);
|
||||||
if(mButtonFirst.isChecked())
|
if(mButtonCameraView.getSelectedItemPosition() == 0)
|
||||||
{
|
{
|
||||||
setCamera(2);
|
setCamera(2);
|
||||||
}
|
}
|
||||||
@@ -2096,6 +2147,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
})
|
})
|
||||||
.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
|
.setNeutralButton("Cancel", new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
resetNoTouchTimer(true);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.create();
|
.create();
|
||||||
@@ -2111,7 +2163,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updateState(State.STATE_IDLE);
|
updateState(previousState);
|
||||||
mToast.makeText(getActivity(), String.format("Exporting map failed!"), mToast.LENGTH_LONG).show();
|
mToast.makeText(getActivity(), String.format("Exporting map failed!"), mToast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
mExportProgressDialog.dismiss();
|
mExportProgressDialog.dismiss();
|
||||||
@@ -2142,45 +2194,51 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mProgressDialog.setMessage(String.format("Please wait while saving \"%s\"...", newDatabasePathHuman));
|
mProgressDialog.setMessage(String.format("Please wait while saving \"%s\"...", newDatabasePathHuman));
|
||||||
}
|
}
|
||||||
mProgressDialog.show();
|
mProgressDialog.show();
|
||||||
|
final State previousState = mState;
|
||||||
updateState(State.STATE_PROCESSING);
|
updateState(State.STATE_PROCESSING);
|
||||||
Thread saveThread = new Thread(new Runnable() {
|
Thread saveThread = new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
RTABMapLib.save(newDatabasePath); // save
|
RTABMapLib.save(newDatabasePath); // save
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
String msg;
|
||||||
if(mOpenedDatabasePath.equals(newDatabasePath))
|
if(mOpenedDatabasePath.equals(newDatabasePath))
|
||||||
{
|
{
|
||||||
mToast.makeText(getActivity(), String.format("Database \"%s\" updated.", newDatabasePathHuman), mToast.LENGTH_LONG).show();
|
msg = String.format("Database \"%s\" updated.", newDatabasePathHuman);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mToast.makeText(getActivity(), String.format("Database saved to \"%s\".", newDatabasePathHuman), mToast.LENGTH_LONG).show();
|
msg = String.format("Database saved to \"%s\".", newDatabasePathHuman);
|
||||||
|
|
||||||
Intent intent = new Intent(getActivity(), RTABMapActivity.class);
|
|
||||||
// use System.currentTimeMillis() to have a unique ID for the pending intent
|
|
||||||
PendingIntent pIntent = PendingIntent.getActivity(getActivity(), (int) System.currentTimeMillis(), intent, 0);
|
|
||||||
|
|
||||||
// build notification
|
|
||||||
// the addAction re-use the same intent to keep the example short
|
|
||||||
Notification n = new Notification.Builder(getActivity())
|
|
||||||
.setContentTitle(getString(R.string.app_name))
|
|
||||||
.setContentText(newDatabasePathHuman + " saved!")
|
|
||||||
.setSmallIcon(R.drawable.ic_launcher)
|
|
||||||
.setContentIntent(pIntent)
|
|
||||||
.setAutoCancel(true).build();
|
|
||||||
|
|
||||||
|
|
||||||
NotificationManager notificationManager =
|
|
||||||
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
|
||||||
|
|
||||||
notificationManager.notify(0, n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mToast.makeText(getActivity(), msg, mToast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
// build notification
|
||||||
|
Intent intent = new Intent(getActivity(), RTABMapActivity.class);
|
||||||
|
// use System.currentTimeMillis() to have a unique ID for the pending intent
|
||||||
|
PendingIntent pIntent = PendingIntent.getActivity(getActivity(), (int) System.currentTimeMillis(), intent, 0);
|
||||||
|
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||||
|
boolean notifySound = sharedPref.getBoolean(getString(R.string.pref_key_notification_sound), Boolean.parseBoolean(getString(R.string.pref_default_notification_sound)));
|
||||||
|
Notification n = new Notification.Builder(getActivity())
|
||||||
|
.setContentTitle(getString(R.string.app_name))
|
||||||
|
.setContentText(msg)
|
||||||
|
.setSmallIcon(R.drawable.ic_launcher)
|
||||||
|
.setContentIntent(pIntent)
|
||||||
|
.setDefaults(notifySound?Notification.DEFAULT_SOUND:0)
|
||||||
|
.setAutoCancel(true).build();
|
||||||
|
|
||||||
|
NotificationManager notificationManager =
|
||||||
|
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
|
notificationManager.notify(0, n);
|
||||||
|
|
||||||
|
resetNoTouchTimer(true);
|
||||||
if(!mItemDataRecorderMode.isChecked())
|
if(!mItemDataRecorderMode.isChecked())
|
||||||
{
|
{
|
||||||
mOpenedDatabasePath = newDatabasePath;
|
mOpenedDatabasePath = newDatabasePath;
|
||||||
}
|
}
|
||||||
mProgressDialog.dismiss();
|
mProgressDialog.dismiss();
|
||||||
updateState(State.STATE_IDLE);
|
updateState(previousState);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2215,6 +2273,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
public void onClick(DialogInterface dialog, int which)
|
public void onClick(DialogInterface dialog, int which)
|
||||||
{
|
{
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
|
resetNoTouchTimer(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
|
||||||
@@ -2339,11 +2398,12 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
.setContentIntent(pIntent)
|
.setContentIntent(pIntent)
|
||||||
.setAutoCancel(true).build();
|
.setAutoCancel(true).build();
|
||||||
|
|
||||||
|
|
||||||
NotificationManager notificationManager =
|
NotificationManager notificationManager =
|
||||||
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
|
||||||
notificationManager.notify(0, n);
|
notificationManager.notify(0, n);
|
||||||
|
|
||||||
|
resetNoTouchTimer(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2353,6 +2413,7 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
public void run() {
|
public void run() {
|
||||||
mProgressDialog.dismiss();
|
mProgressDialog.dismiss();
|
||||||
mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! No files found in tmp directory!? Last export may have failed or have been canceled.", pathHuman), mToast.LENGTH_LONG).show();
|
mToast.makeText(getActivity(), String.format("Exporting mesh \"%s\" failed! No files found in tmp directory!? Last export may have failed or have been canceled.", pathHuman), mToast.LENGTH_LONG).show();
|
||||||
|
resetNoTouchTimer(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2435,15 +2496,15 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
if(status >= 1 && status<=3)
|
if(status >= 1 && status<=3)
|
||||||
{
|
{
|
||||||
mProgressDialog.dismiss();
|
mProgressDialog.dismiss();
|
||||||
resetNoTouchTimer();
|
resetNoTouchTimer(true);
|
||||||
updateState(State.STATE_VISUALIZING);
|
updateState(State.STATE_VISUALIZING);
|
||||||
mToast.makeText(getActivity(), String.format("Database loaded!"), mToast.LENGTH_LONG).show();
|
mToast.makeText(getActivity(), String.format("Database loaded!"), mToast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
else if(!mItemTrajectoryMode.isChecked())
|
else if(!mItemTrajectoryMode.isChecked())
|
||||||
{
|
{
|
||||||
if(mButtonFirst.isChecked())
|
if(mButtonCameraView.getSelectedItemPosition() == 0)
|
||||||
{
|
{
|
||||||
setCamera(1);
|
setCamera(2);
|
||||||
}
|
}
|
||||||
// creating meshes...
|
// creating meshes...
|
||||||
updateState(State.STATE_IDLE);
|
updateState(State.STATE_IDLE);
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ public class RTABMapLib
|
|||||||
public static native void setPointSize(float value);
|
public static native void setPointSize(float value);
|
||||||
public static native void setFOV(float value);
|
public static native void setFOV(float value);
|
||||||
public static native void setOrthoCropFactor(float value);
|
public static native void setOrthoCropFactor(float value);
|
||||||
|
public static native void setGridRotation(float value);
|
||||||
public static native void setLighting(boolean enabled);
|
public static native void setLighting(boolean enabled);
|
||||||
public static native void setBackfaceCulling(boolean enabled);
|
public static native void setBackfaceCulling(boolean enabled);
|
||||||
public static native void setWireframe(boolean enabled);
|
public static native void setWireframe(boolean enabled);
|
||||||
@@ -108,7 +109,7 @@ public class RTABMapLib
|
|||||||
int optimizedMaxPolygons,
|
int optimizedMaxPolygons,
|
||||||
float optimizedColorRadius,
|
float optimizedColorRadius,
|
||||||
boolean optimizedCleanWhitePolygons,
|
boolean optimizedCleanWhitePolygons,
|
||||||
boolean optimizedColorWhitePolygons,
|
int optimizedMinClusterSize,
|
||||||
float optimizedMaxTextureDistance,
|
float optimizedMaxTextureDistance,
|
||||||
int optimizedMinTextureClusterSize,
|
int optimizedMinTextureClusterSize,
|
||||||
boolean blockRendering);
|
boolean blockRendering);
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
|
|||||||
|
|
||||||
((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_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_color_radius))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_color_radius))).getEntry() + ") "+getString(R.string.pref_summary_opt_color_radius));
|
((Preference)findPreference(getString(R.string.pref_key_opt_color_radius))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_color_radius))).getEntry() + ") "+getString(R.string.pref_summary_opt_color_radius));
|
||||||
|
((Preference)findPreference(getString(R.string.pref_key_opt_min_cluster_size))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_opt_min_cluster_size))).getEntry() + ") "+getString(R.string.pref_summary_opt_min_cluster_size));
|
||||||
|
|
||||||
((Preference)findPreference(getString(R.string.pref_key_cluster_ratio))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_cluster_ratio))).getEntry() + ") "+getString(R.string.pref_summary_cluster_ratio));
|
((Preference)findPreference(getString(R.string.pref_key_cluster_ratio))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_cluster_ratio))).getEntry() + ") "+getString(R.string.pref_summary_cluster_ratio));
|
||||||
((Preference)findPreference(getString(R.string.pref_key_gain_max_radius))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_gain_max_radius))).getEntry() + ") "+getString(R.string.pref_summary_gain_max_radius));
|
((Preference)findPreference(getString(R.string.pref_key_gain_max_radius))).setSummary("("+((ListPreference)findPreference(getString(R.string.pref_key_gain_max_radius))).getEntry() + ") "+getString(R.string.pref_summary_gain_max_radius));
|
||||||
@@ -272,6 +273,7 @@ public class SettingsActivity extends PreferenceActivity implements OnSharedPref
|
|||||||
|
|
||||||
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_depth))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_depth));
|
||||||
if(key.compareTo(getString(R.string.pref_key_opt_color_radius))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_color_radius));
|
if(key.compareTo(getString(R.string.pref_key_opt_color_radius))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_color_radius));
|
||||||
|
if(key.compareTo(getString(R.string.pref_key_opt_min_cluster_size))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_opt_min_cluster_size));
|
||||||
|
|
||||||
if(key.compareTo(getString(R.string.pref_key_cluster_ratio))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_cluster_ratio));
|
if(key.compareTo(getString(R.string.pref_key_cluster_ratio))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_cluster_ratio));
|
||||||
if(key.compareTo(getString(R.string.pref_key_gain_max_radius))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_gain_max_radius));
|
if(key.compareTo(getString(R.string.pref_key_gain_max_radius))==0) pref.setSummary("("+((ListPreference)pref).getEntry() + ") "+getString(R.string.pref_summary_gain_max_radius));
|
||||||
|
|||||||
@@ -74,7 +74,11 @@ ELSE()
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
TARGET_LINK_LIBRARIES(rtabmap rtabmap_core rtabmap_gui rtabmap_utilite ${LIBRARIES})
|
TARGET_LINK_LIBRARIES(rtabmap rtabmap_core rtabmap_gui rtabmap_utilite ${LIBRARIES})
|
||||||
IF(Qt5_FOUND)
|
IF(Qt5_FOUND)
|
||||||
QT5_USE_MODULES(rtabmap Widgets Core Gui Svg PrintSupport)
|
IF(Qt5Svg_FOUND)
|
||||||
|
QT5_USE_MODULES(rtabmap Widgets Core Gui Svg PrintSupport)
|
||||||
|
ELSE()
|
||||||
|
QT5_USE_MODULES(rtabmap Widgets Core Gui PrintSupport)
|
||||||
|
ENDIF()
|
||||||
ENDIF(Qt5_FOUND)
|
ENDIF(Qt5_FOUND)
|
||||||
|
|
||||||
IF(APPLE AND BUILD_AS_BUNDLE)
|
IF(APPLE AND BUILD_AS_BUNDLE)
|
||||||
|
|||||||
@@ -9,12 +9,13 @@
|
|||||||
|
|
||||||
find_path(ORB_SLAM2_INCLUDE_DIR NAMES System.h PATHS $ENV{ORB_SLAM2_ROOT_DIR}/include)
|
find_path(ORB_SLAM2_INCLUDE_DIR NAMES System.h PATHS $ENV{ORB_SLAM2_ROOT_DIR}/include)
|
||||||
find_library(ORB_SLAM2_LIBRARY NAMES ORB_SLAM2 PATHS $ENV{ORB_SLAM2_ROOT_DIR}/lib)
|
find_library(ORB_SLAM2_LIBRARY NAMES ORB_SLAM2 PATHS $ENV{ORB_SLAM2_ROOT_DIR}/lib)
|
||||||
|
find_library(g2o_LIBRARY NAMES g2o PATHS $ENV{ORB_SLAM2_ROOT_DIR}/Thirdparty/g2o/lib)
|
||||||
|
|
||||||
IF (ORB_SLAM2_INCLUDE_DIR AND ORB_SLAM2_LIBRARY)
|
IF (ORB_SLAM2_INCLUDE_DIR AND ORB_SLAM2_LIBRARY AND g2o_LIBRARY)
|
||||||
SET(ORB_SLAM2_FOUND TRUE)
|
SET(ORB_SLAM2_FOUND TRUE)
|
||||||
SET(ORB_SLAM2_INCLUDE_DIRS ${ORB_SLAM2_INCLUDE_DIR} $ENV{ORB_SLAM2_ROOT_DIR})
|
SET(ORB_SLAM2_INCLUDE_DIRS ${ORB_SLAM2_INCLUDE_DIR} $ENV{ORB_SLAM2_ROOT_DIR})
|
||||||
SET(ORB_SLAM2_LIBRARIES ${ORB_SLAM2_LIBRARY})
|
SET(ORB_SLAM2_LIBRARIES ${g2o_LIBRARY} ${ORB_SLAM2_LIBRARY})
|
||||||
ENDIF (ORB_SLAM2_INCLUDE_DIR AND ORB_SLAM2_LIBRARY)
|
ENDIF (ORB_SLAM2_INCLUDE_DIR AND ORB_SLAM2_LIBRARY AND g2o_LIBRARY)
|
||||||
|
|
||||||
IF (ORB_SLAM2_FOUND)
|
IF (ORB_SLAM2_FOUND)
|
||||||
# show which ORB_SLAM2 was found only if not quiet
|
# show which ORB_SLAM2 was found only if not quiet
|
||||||
|
|||||||
@@ -104,12 +104,20 @@ public:
|
|||||||
const cv::Mat & cloud,
|
const cv::Mat & cloud,
|
||||||
const std::map<int, Transform> & poses = std::map<int, Transform>(), // if we want to do localization afterward using optimized mesh
|
const std::map<int, Transform> & poses = std::map<int, Transform>(), // if we want to do localization afterward using optimized mesh
|
||||||
const std::vector<std::vector<std::vector<unsigned int> > > & polygons = std::vector<std::vector<std::vector<unsigned int> > >(), // Textures -> polygons -> vertices
|
const std::vector<std::vector<std::vector<unsigned int> > > & polygons = std::vector<std::vector<std::vector<unsigned int> > >(), // Textures -> polygons -> vertices
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
const std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > & texCoords = std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > >(), // Textures -> uv coords for each vertex of the polygons
|
||||||
|
#else
|
||||||
const std::vector<std::vector<Eigen::Vector2f> > & texCoords = std::vector<std::vector<Eigen::Vector2f> >(), // Textures -> uv coords for each vertex of the polygons
|
const std::vector<std::vector<Eigen::Vector2f> > & texCoords = std::vector<std::vector<Eigen::Vector2f> >(), // Textures -> uv coords for each vertex of the polygons
|
||||||
|
#endif
|
||||||
const cv::Mat & textures = cv::Mat()) const; // concatenated textures (assuming square textures with all same size);
|
const cv::Mat & textures = cv::Mat()) const; // concatenated textures (assuming square textures with all same size);
|
||||||
cv::Mat loadOptimizedMesh(
|
cv::Mat loadOptimizedMesh(
|
||||||
std::map<int, Transform> * poses = 0,
|
std::map<int, Transform> * poses = 0,
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > * polygons = 0,
|
std::vector<std::vector<std::vector<unsigned int> > > * polygons = 0,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > * texCoords = 0,
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > * texCoords = 0,
|
std::vector<std::vector<Eigen::Vector2f> > * texCoords = 0,
|
||||||
|
#endif
|
||||||
cv::Mat * textures = 0) const;
|
cv::Mat * textures = 0) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -219,12 +227,20 @@ private:
|
|||||||
const cv::Mat & cloud,
|
const cv::Mat & cloud,
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
const std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > & texCoords,
|
||||||
|
#else
|
||||||
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
||||||
|
#endif
|
||||||
const cv::Mat & textures) const = 0;
|
const cv::Mat & textures) const = 0;
|
||||||
virtual cv::Mat loadOptimizedMeshQuery(
|
virtual cv::Mat loadOptimizedMeshQuery(
|
||||||
std::map<int, Transform> * poses,
|
std::map<int, Transform> * poses,
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > * texCoords,
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
||||||
|
#endif
|
||||||
cv::Mat * textures) const = 0;
|
cv::Mat * textures) const = 0;
|
||||||
|
|
||||||
// Load objects
|
// Load objects
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public:
|
|||||||
kFeatureGfttBrief=6,
|
kFeatureGfttBrief=6,
|
||||||
kFeatureBrisk=7,
|
kFeatureBrisk=7,
|
||||||
kFeatureGfttOrb=8, //new 0.10.11
|
kFeatureGfttOrb=8, //new 0.10.11
|
||||||
kFeatureFreak=9}; //new 0.11.14
|
kFeatureKaze=9}; //new 0.13.2
|
||||||
|
|
||||||
static Feature2D * create(const ParametersMap & parameters = ParametersMap());
|
static Feature2D * create(const ParametersMap & parameters = ParametersMap());
|
||||||
static Feature2D * create(Feature2D::Type type, const ParametersMap & parameters = ParametersMap()); // for convenience
|
static Feature2D * create(Feature2D::Type type, const ParametersMap & parameters = ParametersMap()); // for convenience
|
||||||
@@ -433,27 +433,31 @@ private:
|
|||||||
cv::Ptr<CV_BRISK> brisk_;
|
cv::Ptr<CV_BRISK> brisk_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//FREAK
|
//KAZE
|
||||||
class RTABMAP_EXP FREAK : public Feature2D
|
class RTABMAP_EXP KAZE : public Feature2D
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FREAK(const ParametersMap & parameters = ParametersMap());
|
KAZE(const ParametersMap & parameters = ParametersMap());
|
||||||
virtual ~FREAK();
|
virtual ~KAZE();
|
||||||
|
|
||||||
virtual void parseParameters(const ParametersMap & parameters);
|
virtual void parseParameters(const ParametersMap & parameters);
|
||||||
virtual Feature2D::Type getType() const { return kFeatureFreak; }
|
virtual Feature2D::Type getType() const { return kFeatureKaze; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual std::vector<cv::KeyPoint> generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask = cv::Mat()) const;
|
virtual std::vector<cv::KeyPoint> generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask = cv::Mat()) const;
|
||||||
virtual cv::Mat generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const;
|
virtual cv::Mat generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool orientationNormalized_;
|
bool extended_;
|
||||||
bool scaleNormalized_;
|
bool upright_;
|
||||||
float patternScale_;
|
float threshold_;
|
||||||
int nOctaves_;
|
int nOctaves_;
|
||||||
|
int nOctaveLayers_;
|
||||||
|
int diffusivity_;
|
||||||
|
|
||||||
cv::Ptr<CV_FREAK> _freak;
|
#if CV_MAJOR_VERSION > 2
|
||||||
|
cv::Ptr<cv::KAZE> kaze_;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "rtabmap/utilite/UStl.h"
|
#include "rtabmap/utilite/UStl.h"
|
||||||
#include <opencv2/core/core.hpp>
|
#include <opencv2/core/core.hpp>
|
||||||
#include <opencv2/features2d/features2d.hpp>
|
#include <opencv2/features2d/features2d.hpp>
|
||||||
|
#include <pcl/pcl_config.h>
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
@@ -98,12 +99,20 @@ public:
|
|||||||
const cv::Mat & cloud,
|
const cv::Mat & cloud,
|
||||||
const std::map<int, Transform> & poses = std::map<int, Transform>(), // if we want to do localization afterward using optimized mesh
|
const std::map<int, Transform> & poses = std::map<int, Transform>(), // if we want to do localization afterward using optimized mesh
|
||||||
const std::vector<std::vector<std::vector<unsigned int> > > & polygons = std::vector<std::vector<std::vector<unsigned int> > >(), // Textures -> polygons -> vertices
|
const std::vector<std::vector<std::vector<unsigned int> > > & polygons = std::vector<std::vector<std::vector<unsigned int> > >(), // Textures -> polygons -> vertices
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
const std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > & texCoords = std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > >(), // Textures -> uv coords for each vertex of the polygons
|
||||||
|
#else
|
||||||
const std::vector<std::vector<Eigen::Vector2f> > & texCoords = std::vector<std::vector<Eigen::Vector2f> >(), // Textures -> uv coords for each vertex of the polygons
|
const std::vector<std::vector<Eigen::Vector2f> > & texCoords = std::vector<std::vector<Eigen::Vector2f> >(), // Textures -> uv coords for each vertex of the polygons
|
||||||
|
#endif
|
||||||
const cv::Mat & textures = cv::Mat()) const; // concatenated textures (assuming square textures with all same size)
|
const cv::Mat & textures = cv::Mat()) const; // concatenated textures (assuming square textures with all same size)
|
||||||
cv::Mat loadOptimizedMesh(
|
cv::Mat loadOptimizedMesh(
|
||||||
std::map<int, Transform> * poses = 0,
|
std::map<int, Transform> * poses = 0,
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > * polygons = 0,
|
std::vector<std::vector<std::vector<unsigned int> > > * polygons = 0,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > * texCoords = 0,
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > * texCoords = 0,
|
std::vector<std::vector<Eigen::Vector2f> > * texCoords = 0,
|
||||||
|
#endif
|
||||||
cv::Mat * textures = 0) const;
|
cv::Mat * textures = 0) const;
|
||||||
void emptyTrash();
|
void emptyTrash();
|
||||||
void joinTrashThread();
|
void joinTrashThread();
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ public:
|
|||||||
float getMinMapSize() const {return minMapSize_;}
|
float getMinMapSize() const {return minMapSize_;}
|
||||||
bool isGridFromDepth() const {return occupancyFromCloud_;}
|
bool isGridFromDepth() const {return occupancyFromCloud_;}
|
||||||
bool isFullUpdate() const {return fullUpdate_;}
|
bool isFullUpdate() const {return fullUpdate_;}
|
||||||
|
bool isMapFrameProjection() const {return projMapFrame_;}
|
||||||
const std::map<int, Transform> & addedNodes() const {return addedNodes_;}
|
const std::map<int, Transform> & addedNodes() const {return addedNodes_;}
|
||||||
int cacheSize() const {return (int)cache_.size();}
|
int cacheSize() const {return (int)cache_.size();}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ private:
|
|||||||
dvo::core::RgbdCameraPyramid * camera_;
|
dvo::core::RgbdCameraPyramid * camera_;
|
||||||
bool lost_;
|
bool lost_;
|
||||||
Transform motionFromKeyFrame_;
|
Transform motionFromKeyFrame_;
|
||||||
|
Transform previousLocalTransform_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -86,8 +86,6 @@ public:
|
|||||||
return std::vector<float>();
|
return std::vector<float>();
|
||||||
}
|
}
|
||||||
const OdometryInfo & info() const {return _info;}
|
const OdometryInfo & info() const {return _info;}
|
||||||
double rotVariance() const {return uMax3(_info.covariance.at<double>(3,3), _info.covariance.at<double>(4,4), _info.covariance.at<double>(5,5));}
|
|
||||||
double transVariance() const {return uMax3(_info.covariance.at<double>(0,0), _info.covariance.at<double>(1,1), _info.covariance.at<double>(2,2));}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SensorData _data;
|
SensorData _data;
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ private:
|
|||||||
fovis::StereoDepth * stereoDepth_;
|
fovis::StereoDepth * stereoDepth_;
|
||||||
ParametersMap fovisParameters_;
|
ParametersMap fovisParameters_;
|
||||||
bool lost_;
|
bool lost_;
|
||||||
|
Transform previousLocalTransform_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ private:
|
|||||||
ORBSLAM2System * orbslam2_;
|
ORBSLAM2System * orbslam2_;
|
||||||
ORB_SLAM2::System * system_;
|
ORB_SLAM2::System * system_;
|
||||||
bool firstFrame_;
|
bool firstFrame_;
|
||||||
|
Transform originLocalTransform_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ private:
|
|||||||
bool lost_;
|
bool lost_;
|
||||||
bool keep_reference_frame_;
|
bool keep_reference_frame_;
|
||||||
Transform reference_motion_;
|
Transform reference_motion_;
|
||||||
|
Transform previousLocalTransform_;
|
||||||
ParametersMap viso2Parameters_;
|
ParametersMap viso2Parameters_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,6 @@ typedef std::pair<std::string, std::string> ParametersPair;
|
|||||||
class RTABMAP_EXP Parameters
|
class RTABMAP_EXP Parameters
|
||||||
{
|
{
|
||||||
// Rtabmap parameters
|
// Rtabmap parameters
|
||||||
RTABMAP_PARAM(Rtabmap, VhStrategy, int, 0, "None 0, Similarity 1, Epipolar 2.");
|
|
||||||
RTABMAP_PARAM(Rtabmap, PublishStats, bool, true, "Publishing statistics.");
|
RTABMAP_PARAM(Rtabmap, PublishStats, bool, true, "Publishing statistics.");
|
||||||
RTABMAP_PARAM(Rtabmap, PublishLastSignature, bool, true, "Publishing last signature.");
|
RTABMAP_PARAM(Rtabmap, PublishLastSignature, bool, true, "Publishing last signature.");
|
||||||
RTABMAP_PARAM(Rtabmap, PublishPdf, bool, true, "Publishing pdf.");
|
RTABMAP_PARAM(Rtabmap, PublishPdf, bool, true, "Publishing pdf.");
|
||||||
@@ -225,9 +224,9 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Kp, BadSignRatio, float, 0.5, "Bad signature ratio (less than Ratio x AverageWordsPerImage = bad).");
|
RTABMAP_PARAM(Kp, BadSignRatio, float, 0.5, "Bad signature ratio (less than Ratio x AverageWordsPerImage = bad).");
|
||||||
RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)");
|
RTABMAP_PARAM(Kp, NndrRatio, float, 0.8, "NNDR ratio (A matching pair is detected, if its distance is closer than X times the distance of the second nearest neighbor.)");
|
||||||
#ifdef RTABMAP_NONFREE
|
#ifdef RTABMAP_NONFREE
|
||||||
RTABMAP_PARAM(Kp, DetectorStrategy, int, 0, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=FREAK.");
|
RTABMAP_PARAM(Kp, DetectorStrategy, int, 0, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE.");
|
||||||
#else
|
#else
|
||||||
RTABMAP_PARAM(Kp, DetectorStrategy, int, 2, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=FREAK.");
|
RTABMAP_PARAM(Kp, DetectorStrategy, int, 2, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE.");
|
||||||
#endif
|
#endif
|
||||||
RTABMAP_PARAM(Kp, TfIdfLikelihoodUsed, bool, true, "Use of the td-idf strategy to compute the likelihood.");
|
RTABMAP_PARAM(Kp, TfIdfLikelihoodUsed, bool, true, "Use of the td-idf strategy to compute the likelihood.");
|
||||||
RTABMAP_PARAM(Kp, Parallelized, bool, true, "If the dictionary update and signature creation were parallelized.");
|
RTABMAP_PARAM(Kp, Parallelized, bool, true, "If the dictionary update and signature creation were parallelized.");
|
||||||
@@ -295,22 +294,30 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(BRISK, Octaves, int, 3, "Detection octaves. Use 0 to do single scale.");
|
RTABMAP_PARAM(BRISK, Octaves, int, 3, "Detection octaves. Use 0 to do single scale.");
|
||||||
RTABMAP_PARAM(BRISK, PatternScale, float, 1,"Apply this scale to the pattern used for sampling the neighbourhood of a keypoint.");
|
RTABMAP_PARAM(BRISK, PatternScale, float, 1,"Apply this scale to the pattern used for sampling the neighbourhood of a keypoint.");
|
||||||
|
|
||||||
|
RTABMAP_PARAM(KAZE, Extended, bool, false, "Set to enable extraction of extended (128-byte) descriptor.");
|
||||||
|
RTABMAP_PARAM(KAZE, Upright, bool, false, "Set to enable use of upright descriptors (non rotation-invariant).");
|
||||||
|
RTABMAP_PARAM(KAZE, Threshold, float, 0.001, "Detector response threshold to accept point.");
|
||||||
|
RTABMAP_PARAM(KAZE, NOctaves, int, 4, "Maximum octave evolution of the image.");
|
||||||
|
RTABMAP_PARAM(KAZE, NOctaveLayers, int, 4, "Default number of sublevels per scale level.");
|
||||||
|
RTABMAP_PARAM(KAZE, Diffusivity, int, 1, "Diffusivity type: 0=DIFF_PM_G1, 1=DIFF_PM_G2, 2=DIFF_WEICKERT or 3=DIFF_CHARBONNIER.");
|
||||||
|
|
||||||
// BayesFilter
|
// BayesFilter
|
||||||
RTABMAP_PARAM(Bayes, VirtualPlacePriorThr, float, 0.9, "Virtual place prior");
|
RTABMAP_PARAM(Bayes, VirtualPlacePriorThr, float, 0.9, "Virtual place prior");
|
||||||
RTABMAP_PARAM_STR(Bayes, PredictionLC, "0.1 0.36 0.30 0.16 0.062 0.0151 0.00255 0.000324 2.5e-05 1.3e-06 4.8e-08 1.2e-09 1.9e-11 2.2e-13 1.7e-15 8.5e-18 2.9e-20 6.9e-23", "Prediction of loop closures (Gaussian-like, here with sigma=1.6) - Format: {VirtualPlaceProb, LoopClosureProb, NeighborLvl1, NeighborLvl2, ...}.");
|
RTABMAP_PARAM_STR(Bayes, PredictionLC, "0.1 0.36 0.30 0.16 0.062 0.0151 0.00255 0.000324 2.5e-05 1.3e-06 4.8e-08 1.2e-09 1.9e-11 2.2e-13 1.7e-15 8.5e-18 2.9e-20 6.9e-23", "Prediction of loop closures (Gaussian-like, here with sigma=1.6) - Format: {VirtualPlaceProb, LoopClosureProb, NeighborLvl1, NeighborLvl2, ...}.");
|
||||||
RTABMAP_PARAM(Bayes, FullPredictionUpdate, bool, false, "Regenerate all the prediction matrix on each iteration (otherwise only removed/added ids are updated).");
|
RTABMAP_PARAM(Bayes, FullPredictionUpdate, bool, false, "Regenerate all the prediction matrix on each iteration (otherwise only removed/added ids are updated).");
|
||||||
|
|
||||||
// Verify hypotheses
|
// Verify hypotheses
|
||||||
|
RTABMAP_PARAM(VhEp, Enabled, bool, false, uFormat("Verify visual loop closure hypothesis by computing a fundamental matrix. This is done prior to transformation computation when %s is enabled.", kRGBDEnabled().c_str()));
|
||||||
RTABMAP_PARAM(VhEp, MatchCountMin, int, 8, "Minimum of matching visual words pairs to accept the loop hypothesis.");
|
RTABMAP_PARAM(VhEp, MatchCountMin, int, 8, "Minimum of matching visual words pairs to accept the loop hypothesis.");
|
||||||
RTABMAP_PARAM(VhEp, RansacParam1, float, 3, "Fundamental matrix (see cvFindFundamentalMat()): Max distance (in pixels) from the epipolar line for a point to be inlier.");
|
RTABMAP_PARAM(VhEp, RansacParam1, float, 3, "Fundamental matrix (see cvFindFundamentalMat()): Max distance (in pixels) from the epipolar line for a point to be inlier.");
|
||||||
RTABMAP_PARAM(VhEp, RansacParam2, float, 0.99, "Fundamental matrix (see cvFindFundamentalMat()): Performance of the RANSAC.");
|
RTABMAP_PARAM(VhEp, RansacParam2, float, 0.99, "Fundamental matrix (see cvFindFundamentalMat()): Performance of RANSAC.");
|
||||||
|
|
||||||
// RGB-D SLAM
|
// RGB-D SLAM
|
||||||
RTABMAP_PARAM(RGBD, Enabled, bool, true, "");
|
RTABMAP_PARAM(RGBD, Enabled, bool, true, "");
|
||||||
RTABMAP_PARAM(RGBD, LinearUpdate, float, 0.1, "Minimum linear displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
RTABMAP_PARAM(RGBD, LinearUpdate, float, 0.1, "Minimum linear displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
||||||
RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.1, "Minimum angular displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
RTABMAP_PARAM(RGBD, AngularUpdate, float, 0.1, "Minimum angular displacement to update the map. Rehearsal is done prior to this, so weights are still updated.");
|
||||||
RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 0, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled).");
|
RTABMAP_PARAM(RGBD, NewMapOdomChangeDistance, float, 0, "A new map is created if a change of odometry translation greater than X m is detected (0 m = disabled).");
|
||||||
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest mode of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation).");
|
RTABMAP_PARAM(RGBD, OptimizeFromGraphEnd, bool, false, "Optimize graph from the newest node. If false, the graph is optimized from the oldest node of the current graph (this adds an overhead computation to detect to oldest node of the current graph, but it can be useful to preserve the map referential from the oldest node). Warning when set to false: when some nodes are transferred, the first referential of the local map may change, resulting in momentary changes in robot/map position (which are annoying in teleoperation).");
|
||||||
RTABMAP_PARAM(RGBD, OptimizeMaxError, float, 1, uFormat("Reject loop closures if optimization error is greater than this value (0=disabled). This will help to detect when a wrong loop closure is added to the graph. Not compatible with \"%s\" if enabled.", kOptimizerRobust().c_str()));
|
RTABMAP_PARAM(RGBD, OptimizeMaxError, float, 1, uFormat("Reject loop closures if optimization error is greater than this value (0=disabled). This will help to detect when a wrong loop closure is added to the graph. Not compatible with \"%s\" if enabled.", kOptimizerRobust().c_str()));
|
||||||
RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m).");
|
RTABMAP_PARAM(RGBD, GoalReachedRadius, float, 0.5, "Goal reached radius (m).");
|
||||||
RTABMAP_PARAM(RGBD, PlanStuckIterations, int, 0, "Mark the current goal node on the path as unreachable if it is not updated after X iterations (0=disabled). If all upcoming nodes on the path are unreachabled, the plan fails.");
|
RTABMAP_PARAM(RGBD, PlanStuckIterations, int, 0, "Mark the current goal node on the path as unreachable if it is not updated after X iterations (0=disabled). If all upcoming nodes on the path are unreachabled, the plan fails.");
|
||||||
@@ -469,12 +476,12 @@ class RTABMAP_EXP Parameters
|
|||||||
#ifndef RTABMAP_NONFREE
|
#ifndef RTABMAP_NONFREE
|
||||||
#ifdef RTABMAP_OPENCV3
|
#ifdef RTABMAP_OPENCV3
|
||||||
// OpenCV 3 without xFeatures2D module doesn't have BRIEF
|
// OpenCV 3 without xFeatures2D module doesn't have BRIEF
|
||||||
RTABMAP_PARAM(Vis, FeatureType, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=FREAK.");
|
RTABMAP_PARAM(Vis, FeatureType, int, 8, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE.");
|
||||||
#else
|
#else
|
||||||
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=FREAK.");
|
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE.");
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=FREAK.");
|
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=KAZE.");
|
||||||
#endif
|
#endif
|
||||||
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
|
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
|
||||||
RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
|
RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef REGISTRATION_H_
|
#ifndef RTABMAP_REGISTRATION_H_
|
||||||
#define REGISTRATION_H_
|
#define RTABMAP_REGISTRATION_H_
|
||||||
|
|
||||||
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
|
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ public:
|
|||||||
Transform computeTransformation(
|
Transform computeTransformation(
|
||||||
const SensorData & from,
|
const SensorData & from,
|
||||||
const SensorData & to,
|
const SensorData & to,
|
||||||
Transform SensorData = Transform::getIdentity(),
|
Transform guess = Transform::getIdentity(),
|
||||||
RegistrationInfo * info = 0) const;
|
RegistrationInfo * info = 0) const;
|
||||||
|
|
||||||
Transform computeTransformationMod(
|
Transform computeTransformationMod(
|
||||||
@@ -115,4 +115,4 @@ private:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* REGISTRATION_H_ */
|
#endif /* RTABMAP_REGISTRATION_H_ */
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ private:
|
|||||||
unsigned int _maxMemoryAllowed; // signatures count in WM
|
unsigned int _maxMemoryAllowed; // signatures count in WM
|
||||||
float _loopThr;
|
float _loopThr;
|
||||||
float _loopRatio;
|
float _loopRatio;
|
||||||
|
bool _verifyLoopClosureHypothesis;
|
||||||
unsigned int _maxRetrieved;
|
unsigned int _maxRetrieved;
|
||||||
unsigned int _maxLocalRetrieved;
|
unsigned int _maxLocalRetrieved;
|
||||||
bool _rawDataKept;
|
bool _rawDataKept;
|
||||||
|
|||||||
@@ -121,7 +121,9 @@ typename pcl::PointCloud<PointT>::Ptr OccupancyGrid::segmentCloud(
|
|||||||
{
|
{
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
// passthrough filter
|
// passthrough filter
|
||||||
groundIndices = rtabmap::util3d::passThrough(cloud, indices, "z", minGroundHeight_!=0.0f?minGroundHeight_:std::numeric_limits<int>::min(), maxGroundHeight_);
|
groundIndices = rtabmap::util3d::passThrough(cloud, indices, "z",
|
||||||
|
minGroundHeight_!=0.0f?minGroundHeight_:std::numeric_limits<int>::min(),
|
||||||
|
maxGroundHeight_!=0.0f?maxGroundHeight_:std::numeric_limits<int>::max());
|
||||||
|
|
||||||
pcl::IndicesPtr notObstacles = groundIndices;
|
pcl::IndicesPtr notObstacles = groundIndices;
|
||||||
if(indices->size())
|
if(indices->size())
|
||||||
|
|||||||
@@ -97,8 +97,7 @@ void denseMeshPostProcessing(
|
|||||||
|
|
||||||
if(cloud.get()!=0 &&
|
if(cloud.get()!=0 &&
|
||||||
!hasColors &&
|
!hasColors &&
|
||||||
transferColorRadius >= 0.0 &&
|
transferColorRadius >= 0.0)
|
||||||
coloredOutput)
|
|
||||||
{
|
{
|
||||||
if(progressState) progressState->callback(uFormat("Transferring color from point cloud to mesh..."));
|
if(progressState) progressState->callback(uFormat("Transferring color from point cloud to mesh..."));
|
||||||
|
|
||||||
@@ -179,63 +178,8 @@ void denseMeshPostProcessing(
|
|||||||
}
|
}
|
||||||
hasColors = true;
|
hasColors = true;
|
||||||
}
|
}
|
||||||
else if(cloud.get()!=0 &&
|
|
||||||
!hasColors &&
|
|
||||||
transferColorRadius > 0.0 &&
|
|
||||||
cleanMesh &&
|
|
||||||
!coloredOutput)
|
|
||||||
{
|
|
||||||
if(progressState) progressState->callback(uFormat("Removing polygons too far from the cloud..."));
|
|
||||||
|
|
||||||
// transfer color from point cloud to mesh
|
if(minClusterSize)
|
||||||
typename pcl::search::KdTree<pointRGBT>::Ptr tree (new pcl::search::KdTree<pointRGBT>(true));
|
|
||||||
tree->setInputCloud(cloud);
|
|
||||||
pcl::PointCloud<pcl::PointNormal>::Ptr optimizedCloud(new pcl::PointCloud<pcl::PointNormal>);
|
|
||||||
pcl::fromPCLPointCloud2(mesh->cloud, *optimizedCloud);
|
|
||||||
std::vector<bool> closePts(optimizedCloud->size());
|
|
||||||
for(unsigned int i=0; i<optimizedCloud->size(); ++i)
|
|
||||||
{
|
|
||||||
std::vector<int> kIndices;
|
|
||||||
std::vector<float> kDistances;
|
|
||||||
pointRGBT pt;
|
|
||||||
pt.x = optimizedCloud->at(i).x;
|
|
||||||
pt.y = optimizedCloud->at(i).y;
|
|
||||||
pt.z = optimizedCloud->at(i).z;
|
|
||||||
tree->radiusSearch(pt, transferColorRadius, kIndices, kDistances);
|
|
||||||
if(kIndices.size())
|
|
||||||
{
|
|
||||||
closePts.at(i) = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
closePts.at(i) = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove far polygons
|
|
||||||
std::vector<pcl::Vertices> filteredPolygons(mesh->polygons.size());
|
|
||||||
int oi=0;
|
|
||||||
for(unsigned int i=0; i<mesh->polygons.size(); ++i)
|
|
||||||
{
|
|
||||||
bool keepPolygon = true;
|
|
||||||
for(unsigned int j=0; j<mesh->polygons[i].vertices.size(); ++j)
|
|
||||||
{
|
|
||||||
if(!closePts.at(mesh->polygons[i].vertices[j]))
|
|
||||||
{
|
|
||||||
keepPolygon = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(keepPolygon)
|
|
||||||
{
|
|
||||||
filteredPolygons[oi++] = mesh->polygons[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
filteredPolygons.resize(oi);
|
|
||||||
mesh->polygons = filteredPolygons;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(minClusterSize && coloredOutput && !cleanMesh)
|
|
||||||
{
|
{
|
||||||
if(progressState) progressState->callback(uFormat("Filter small polygon clusters..."));
|
if(progressState) progressState->callback(uFormat("Filter small polygon clusters..."));
|
||||||
|
|
||||||
@@ -290,7 +234,7 @@ void denseMeshPostProcessing(
|
|||||||
int before = (int)mesh->polygons.size();
|
int before = (int)mesh->polygons.size();
|
||||||
mesh->polygons = filteredPolygons;
|
mesh->polygons = filteredPolygons;
|
||||||
|
|
||||||
if(progressState) progressState->callback(uFormat("Filtered %1 polygons.", before-(int)mesh->polygons.size()));
|
if(progressState) progressState->callback(uFormat("Filtered %d polygons.", before-(int)mesh->polygons.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute normals for the mesh if not already here, add also white color if colored output is required
|
// compute normals for the mesh if not already here, add also white color if colored output is required
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ void denseMeshPostProcessing(
|
|||||||
int maximumPolygons = 0, // 0=disabled
|
int maximumPolygons = 0, // 0=disabled
|
||||||
const typename pcl::PointCloud<pointRGBT>::Ptr & cloud = pcl::PointCloud<pointRGBT>::Ptr(), // A RGB point cloud used to transfer colors back to mesh (needed for parameters below)
|
const typename pcl::PointCloud<pointRGBT>::Ptr & cloud = pcl::PointCloud<pointRGBT>::Ptr(), // A RGB point cloud used to transfer colors back to mesh (needed for parameters below)
|
||||||
float transferColorRadius = 0.05f, // <0=disabled, 0=nearest color
|
float transferColorRadius = 0.05f, // <0=disabled, 0=nearest color
|
||||||
bool coloredOutput = true, // If output should be colored
|
bool coloredOutput = true, // Not used anymore, output is colored if transferColorRadius>=0
|
||||||
bool cleanMesh = true, // Remove polygons not colored (if coloredOutput is disabled, transferColorRadius is still used to clean the mesh)
|
bool cleanMesh = true, // Remove polygons not colored (if coloredOutput is disabled, transferColorRadius is still used to clean the mesh)
|
||||||
int minClusterSize = 50, // Remove small polygon clusters after the mesh has been cleaned (0=disabled)
|
int minClusterSize = 50, // Remove small polygon clusters after the mesh has been cleaned (0=disabled)
|
||||||
ProgressState * progressState = 0);
|
ProgressState * progressState = 0);
|
||||||
|
|||||||
@@ -344,7 +344,7 @@ SET(RESOURCES_HEADERS
|
|||||||
IF(ANDROID)
|
IF(ANDROID)
|
||||||
|
|
||||||
IF(NOT RTABMAP_RES_TOOL)
|
IF(NOT RTABMAP_RES_TOOL)
|
||||||
find_host_program(RTABMAP_RES_TOOL rtabmap-res_tool)
|
find_host_program(RTABMAP_RES_TOOL rtabmap-res_tool PATHS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||||
IF(NOT RTABMAP_RES_TOOL)
|
IF(NOT RTABMAP_RES_TOOL)
|
||||||
MESSAGE( FATAL_ERROR "RTABMAP_RES_TOOL is not defined (it is the path to \"rtabmap-res_tool\" application created by a non-Android build)." )
|
MESSAGE( FATAL_ERROR "RTABMAP_RES_TOOL is not defined (it is the path to \"rtabmap-res_tool\" application created by a non-Android build)." )
|
||||||
ENDIF(NOT RTABMAP_RES_TOOL)
|
ENDIF(NOT RTABMAP_RES_TOOL)
|
||||||
|
|||||||
@@ -860,18 +860,27 @@ bool CameraStereoZed::init(const std::string & calibrationFolder, const std::str
|
|||||||
param.depth_minimum_distance=-1;
|
param.depth_minimum_distance=-1;
|
||||||
param.camera_disable_self_calib=!selfCalibration_;
|
param.camera_disable_self_calib=!selfCalibration_;
|
||||||
|
|
||||||
|
sl::ERROR_CODE r = sl::ERROR_CODE::SUCCESS;
|
||||||
if(src_ == CameraVideo::kVideoFile)
|
if(src_ == CameraVideo::kVideoFile)
|
||||||
{
|
{
|
||||||
UINFO("svo file = %s", svoFilePath_.c_str());
|
UINFO("svo file = %s", svoFilePath_.c_str());
|
||||||
zed_ = new sl::Camera(); // Use in SVO playback mode
|
zed_ = new sl::Camera(); // Use in SVO playback mode
|
||||||
param.svo_input_filename=svoFilePath_.c_str();
|
param.svo_input_filename=svoFilePath_.c_str();
|
||||||
zed_->open(param);
|
r = zed_->open(param);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UINFO("Resolution=%d imagerate=%f device=%d", resolution_, getImageRate(), usbDevice_);
|
UINFO("Resolution=%d imagerate=%f device=%d", resolution_, getImageRate(), usbDevice_);
|
||||||
zed_ = new sl::Camera(); // Use in Live Mode
|
zed_ = new sl::Camera(); // Use in Live Mode
|
||||||
zed_->open(param);
|
r = zed_->open(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(r!=sl::ERROR_CODE::SUCCESS)
|
||||||
|
{
|
||||||
|
UERROR("Camera initialization failed: \"%s\"", errorCode2str(r).c_str());
|
||||||
|
delete zed_;
|
||||||
|
zed_ = 0;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -979,11 +988,7 @@ SensorData CameraStereoZed::captureImage(CameraInfo * info)
|
|||||||
{
|
{
|
||||||
SensorData data;
|
SensorData data;
|
||||||
#ifdef RTABMAP_ZED
|
#ifdef RTABMAP_ZED
|
||||||
sl::RuntimeParameters rparam;
|
sl::RuntimeParameters rparam((sl::SENSING_MODE)sensingMode_, quality_ > 0, quality_ > 0, sl::REFERENCE_FRAME_CAMERA);
|
||||||
rparam.sensing_mode=(sl::SENSING_MODE)sensingMode_;
|
|
||||||
rparam.enable_depth=quality_ > 0;
|
|
||||||
rparam.enable_point_cloud=quality_ > 0;
|
|
||||||
rparam.move_point_cloud_to_world_frame=false;
|
|
||||||
if(zed_)
|
if(zed_)
|
||||||
{
|
{
|
||||||
UTimer timer;
|
UTimer timer;
|
||||||
|
|||||||
@@ -1043,7 +1043,11 @@ void DBDriver::saveOptimizedMesh(
|
|||||||
const cv::Mat & cloud,
|
const cv::Mat & cloud,
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
const std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > & texCoords,
|
||||||
|
#else
|
||||||
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
||||||
|
#endif
|
||||||
const cv::Mat & textures) const
|
const cv::Mat & textures) const
|
||||||
{
|
{
|
||||||
_dbSafeAccessMutex.lock();
|
_dbSafeAccessMutex.lock();
|
||||||
@@ -1054,7 +1058,11 @@ void DBDriver::saveOptimizedMesh(
|
|||||||
cv::Mat DBDriver::loadOptimizedMesh(
|
cv::Mat DBDriver::loadOptimizedMesh(
|
||||||
std::map<int, Transform> * poses,
|
std::map<int, Transform> * poses,
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f>> > * texCoords,
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
||||||
|
#endif
|
||||||
cv::Mat * textures) const
|
cv::Mat * textures) const
|
||||||
{
|
{
|
||||||
_dbSafeAccessMutex.lock();
|
_dbSafeAccessMutex.lock();
|
||||||
|
|||||||
@@ -428,7 +428,7 @@ void DBDriverSqlite3::disconnectDatabaseQuery(bool save, const std::string & out
|
|||||||
}
|
}
|
||||||
if(outputFile.empty())
|
if(outputFile.empty())
|
||||||
{
|
{
|
||||||
UERROR("Database was initialized with an empty url (in memory). To save it "
|
UERROR("Database was initialized with an empty url (in memory). To save it, "
|
||||||
"the output url should not be empty. The database is thus closed without being saved!");
|
"the output url should not be empty. The database is thus closed without being saved!");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3833,7 +3833,11 @@ void DBDriverSqlite3::saveOptimizedMeshQuery(
|
|||||||
const cv::Mat & cloud,
|
const cv::Mat & cloud,
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
const std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > & texCoords,
|
||||||
|
#else
|
||||||
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
||||||
|
#endif
|
||||||
const cv::Mat & textures) const
|
const cv::Mat & textures) const
|
||||||
{
|
{
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
@@ -4049,7 +4053,11 @@ void DBDriverSqlite3::saveOptimizedMeshQuery(
|
|||||||
cv::Mat DBDriverSqlite3::loadOptimizedMeshQuery(
|
cv::Mat DBDriverSqlite3::loadOptimizedMeshQuery(
|
||||||
std::map<int, Transform> * poses,
|
std::map<int, Transform> * poses,
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > * texCoords,
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
||||||
|
#endif
|
||||||
cv::Mat * textures) const
|
cv::Mat * textures) const
|
||||||
{
|
{
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
@@ -4158,7 +4166,11 @@ cv::Mat DBDriverSqlite3::loadOptimizedMeshQuery(
|
|||||||
for(int t=0; t<serializedTexCoords.cols; ++t)
|
for(int t=0; t<serializedTexCoords.cols; ++t)
|
||||||
{
|
{
|
||||||
UASSERT(int(serializedTexCoords.at<float>(t)) > 0);
|
UASSERT(int(serializedTexCoords.at<float>(t)) > 0);
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > materialtexCoords(int(serializedTexCoords.at<float>(t)));
|
||||||
|
#else
|
||||||
std::vector<Eigen::Vector2f> materialtexCoords(int(serializedTexCoords.at<float>(t)));
|
std::vector<Eigen::Vector2f> materialtexCoords(int(serializedTexCoords.at<float>(t)));
|
||||||
|
#endif
|
||||||
++t;
|
++t;
|
||||||
UASSERT(t < serializedTexCoords.cols);
|
UASSERT(t < serializedTexCoords.cols);
|
||||||
UDEBUG("materialtexCoords=%d", (int)materialtexCoords.size());
|
UDEBUG("materialtexCoords=%d", (int)materialtexCoords.size());
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ private:
|
|||||||
const cv::Point3f & viewpoint) const;
|
const cv::Point3f & viewpoint) const;
|
||||||
|
|
||||||
virtual void updateDepthImageQuery(
|
virtual void updateDepthImageQuery(
|
||||||
int nodeId,
|
int nodeId,
|
||||||
const cv::Mat & image) const;
|
const cv::Mat & image) const;
|
||||||
|
|
||||||
virtual void addStatisticsQuery(const Statistics & statistics) const;
|
virtual void addStatisticsQuery(const Statistics & statistics) const;
|
||||||
virtual void savePreviewImageQuery(const cv::Mat & image) const;
|
virtual void savePreviewImageQuery(const cv::Mat & image) const;
|
||||||
@@ -101,12 +101,20 @@ private:
|
|||||||
const cv::Mat & cloud,
|
const cv::Mat & cloud,
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
const std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > & texCoords,
|
||||||
|
#else
|
||||||
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
||||||
|
#endif
|
||||||
const cv::Mat & textures) const;
|
const cv::Mat & textures) const;
|
||||||
virtual cv::Mat loadOptimizedMeshQuery(
|
virtual cv::Mat loadOptimizedMeshQuery(
|
||||||
std::map<int, Transform> * poses,
|
std::map<int, Transform> * poses,
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > * texCoords,
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
||||||
|
#endif
|
||||||
cv::Mat * textures) const;
|
cv::Mat * textures) const;
|
||||||
|
|
||||||
// Load objects
|
// Load objects
|
||||||
|
|||||||
+39
-37
@@ -414,8 +414,7 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
|
|||||||
if(type == Feature2D::kFeatureFastBrief ||
|
if(type == Feature2D::kFeatureFastBrief ||
|
||||||
type == Feature2D::kFeatureFastFreak ||
|
type == Feature2D::kFeatureFastFreak ||
|
||||||
type == Feature2D::kFeatureGfttBrief ||
|
type == Feature2D::kFeatureGfttBrief ||
|
||||||
type == Feature2D::kFeatureGfttFreak ||
|
type == Feature2D::kFeatureGfttFreak)
|
||||||
type == Feature2D::kFeatureFreak)
|
|
||||||
{
|
{
|
||||||
UWARN("BRIEF and FREAK features cannot be used because OpenCV was not built with xfeatures2d module. ORB is used instead.");
|
UWARN("BRIEF and FREAK features cannot be used because OpenCV was not built with xfeatures2d module. ORB is used instead.");
|
||||||
type = Feature2D::kFeatureOrb;
|
type = Feature2D::kFeatureOrb;
|
||||||
@@ -424,10 +423,15 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CV_MAJOR_VERSION < 3
|
#if CV_MAJOR_VERSION < 3
|
||||||
if(type == Feature2D::kFeatureFreak)
|
if(type == Feature2D::kFeatureKaze)
|
||||||
{
|
{
|
||||||
UWARN("FREAK detector/descriptor can be used only with OpenCV3. GFTT/FREAK is used instead.");
|
#ifdef RTABMAP_NONFREE
|
||||||
type = Feature2D::kFeatureGfttFreak;
|
UWARN("KAZE detector/descriptor can be used only with OpenCV3. SURF is used instead.");
|
||||||
|
type = Feature2D::kFeatureSurf;
|
||||||
|
#else
|
||||||
|
UWARN("KAZE detector/descriptor can be used only with OpenCV3. ORB is used instead.");
|
||||||
|
type = Feature2D::kFeatureOrb;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -461,6 +465,9 @@ Feature2D * Feature2D::create(Feature2D::Type type, const ParametersMap & parame
|
|||||||
case Feature2D::kFeatureBrisk:
|
case Feature2D::kFeatureBrisk:
|
||||||
feature2D = new BRISK(parameters);
|
feature2D = new BRISK(parameters);
|
||||||
break;
|
break;
|
||||||
|
case Feature2D::kFeatureKaze:
|
||||||
|
feature2D = new KAZE(parameters);
|
||||||
|
break;
|
||||||
#ifdef RTABMAP_NONFREE
|
#ifdef RTABMAP_NONFREE
|
||||||
default:
|
default:
|
||||||
feature2D = new SURF(parameters);
|
feature2D = new SURF(parameters);
|
||||||
@@ -1469,71 +1476,66 @@ cv::Mat BRISK::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::Ke
|
|||||||
return descriptors;
|
return descriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
//FREAK
|
//KAZE
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
FREAK::FREAK(const ParametersMap & parameters) :
|
KAZE::KAZE(const ParametersMap & parameters) :
|
||||||
orientationNormalized_(Parameters::defaultFREAKOrientationNormalized()),
|
extended_(Parameters::defaultKAZEExtended()),
|
||||||
scaleNormalized_(Parameters::defaultFREAKScaleNormalized()),
|
upright_(Parameters::defaultKAZEUpright()),
|
||||||
patternScale_(Parameters::defaultFREAKPatternScale()),
|
threshold_(Parameters::defaultKAZEThreshold()),
|
||||||
nOctaves_(Parameters::defaultFREAKNOctaves())
|
nOctaves_(Parameters::defaultKAZENOctaves()),
|
||||||
|
nOctaveLayers_(Parameters::defaultKAZENOctaveLayers()),
|
||||||
|
diffusivity_(Parameters::defaultKAZEDiffusivity())
|
||||||
{
|
{
|
||||||
parseParameters(parameters);
|
parseParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
FREAK::~FREAK()
|
KAZE::~KAZE()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void FREAK::parseParameters(const ParametersMap & parameters)
|
void KAZE::parseParameters(const ParametersMap & parameters)
|
||||||
{
|
{
|
||||||
Parameters::parse(parameters, Parameters::kFREAKOrientationNormalized(), orientationNormalized_);
|
Parameters::parse(parameters, Parameters::kKAZEExtended(), extended_);
|
||||||
Parameters::parse(parameters, Parameters::kFREAKScaleNormalized(), scaleNormalized_);
|
Parameters::parse(parameters, Parameters::kKAZEUpright(), upright_);
|
||||||
Parameters::parse(parameters, Parameters::kFREAKPatternScale(), patternScale_);
|
Parameters::parse(parameters, Parameters::kKAZEThreshold(), threshold_);
|
||||||
Parameters::parse(parameters, Parameters::kFREAKNOctaves(), nOctaves_);
|
Parameters::parse(parameters, Parameters::kKAZENOctaves(), nOctaves_);
|
||||||
|
Parameters::parse(parameters, Parameters::kKAZENOctaveLayers(), nOctaveLayers_);
|
||||||
|
Parameters::parse(parameters, Parameters::kKAZEDiffusivity(), diffusivity_);
|
||||||
|
|
||||||
#if CV_MAJOR_VERSION < 3
|
#if CV_MAJOR_VERSION > 2
|
||||||
_freak = cv::Ptr<CV_FREAK>(new CV_FREAK(orientationNormalized_, scaleNormalized_, patternScale_, nOctaves_));
|
kaze_ = cv::KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, diffusivity_);
|
||||||
#else
|
#else
|
||||||
#ifdef HAVE_OPENCV_XFEATURES2D
|
UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!");
|
||||||
_freak = CV_FREAK::create(orientationNormalized_, scaleNormalized_, patternScale_, nOctaves_);
|
|
||||||
#else
|
|
||||||
UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Freak cannot be used!");
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<cv::KeyPoint> FREAK::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
|
std::vector<cv::KeyPoint> KAZE::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
|
||||||
{
|
{
|
||||||
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
||||||
std::vector<cv::KeyPoint> keypoints;
|
std::vector<cv::KeyPoint> keypoints;
|
||||||
#ifdef HAVE_OPENCV_XFEATURES2D
|
#if CV_MAJOR_VERSION > 2
|
||||||
cv::Mat imgRoi(image, roi);
|
cv::Mat imgRoi(image, roi);
|
||||||
cv::Mat maskRoi;
|
cv::Mat maskRoi;
|
||||||
if (!mask.empty())
|
if (!mask.empty())
|
||||||
{
|
{
|
||||||
maskRoi = cv::Mat(mask, roi);
|
maskRoi = cv::Mat(mask, roi);
|
||||||
}
|
}
|
||||||
_freak->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints
|
kaze_->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints
|
||||||
#else
|
#else
|
||||||
UWARN("RTAB-Map is not built with OpenCV3 xfeatures2d module so Freak (for keypoint detection) cannot be used!");
|
UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!");
|
||||||
#endif
|
#endif
|
||||||
return keypoints;
|
return keypoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat FREAK::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
|
cv::Mat KAZE::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
|
||||||
{
|
{
|
||||||
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
|
||||||
cv::Mat descriptors;
|
cv::Mat descriptors;
|
||||||
#if CV_MAJOR_VERSION < 3
|
#if CV_MAJOR_VERSION > 2
|
||||||
_freak->compute(image, keypoints, descriptors);
|
kaze_->compute(image, keypoints, descriptors);
|
||||||
#else
|
#else
|
||||||
#ifdef HAVE_OPENCV_XFEATURES2D
|
UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!");
|
||||||
_freak->compute(image, keypoints, descriptors);
|
|
||||||
#else
|
|
||||||
UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Freak cannot be used!");
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
return descriptors;
|
return descriptors;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -718,7 +718,15 @@ void Memory::addSignatureToStm(Signature * signature, const cv::Mat & covariance
|
|||||||
if(!signature->getPose().isNull() &&
|
if(!signature->getPose().isNull() &&
|
||||||
!_signatures.at(*_stMem.rbegin())->getPose().isNull())
|
!_signatures.at(*_stMem.rbegin())->getPose().isNull())
|
||||||
{
|
{
|
||||||
|
UASSERT(covariance.cols == 6 && covariance.rows == 6 && covariance.type() == CV_64FC1);
|
||||||
cv::Mat infMatrix = covariance.inv();
|
cv::Mat infMatrix = covariance.inv();
|
||||||
|
if((uIsFinite(covariance.at<double>(0,0)) && covariance.at<double>(0,0)>0.0) &&
|
||||||
|
!(uIsFinite(infMatrix.at<double>(0,0)) && infMatrix.at<double>(0,0)>0.0))
|
||||||
|
{
|
||||||
|
UERROR("Failed to invert the covariance matrix! Covariance matrix should be invertible!");
|
||||||
|
std::cout << "Covariance: " << covariance << std::endl;
|
||||||
|
infMatrix = cv::Mat::eye(6,6,CV_64FC1);
|
||||||
|
}
|
||||||
motionEstimate = _signatures.at(*_stMem.rbegin())->getPose().inverse() * signature->getPose();
|
motionEstimate = _signatures.at(*_stMem.rbegin())->getPose().inverse() * signature->getPose();
|
||||||
_signatures.at(*_stMem.rbegin())->addLink(Link(*_stMem.rbegin(), signature->id(), Link::kNeighbor, motionEstimate, infMatrix));
|
_signatures.at(*_stMem.rbegin())->addLink(Link(*_stMem.rbegin(), signature->id(), Link::kNeighbor, motionEstimate, infMatrix));
|
||||||
signature->addLink(Link(signature->id(), *_stMem.rbegin(), Link::kNeighbor, motionEstimate.inverse(), infMatrix));
|
signature->addLink(Link(signature->id(), *_stMem.rbegin(), Link::kNeighbor, motionEstimate.inverse(), infMatrix));
|
||||||
@@ -1671,7 +1679,11 @@ void Memory::saveOptimizedMesh(
|
|||||||
const cv::Mat & cloud,
|
const cv::Mat & cloud,
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
const std::vector<std::vector<std::vector<unsigned int> > > & polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
const std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > > & texCoords,
|
||||||
|
#else
|
||||||
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
const std::vector<std::vector<Eigen::Vector2f> > & texCoords,
|
||||||
|
#endif
|
||||||
const cv::Mat & textures) const
|
const cv::Mat & textures) const
|
||||||
{
|
{
|
||||||
if(_dbDriver)
|
if(_dbDriver)
|
||||||
@@ -1683,7 +1695,11 @@ void Memory::saveOptimizedMesh(
|
|||||||
cv::Mat Memory::loadOptimizedMesh(
|
cv::Mat Memory::loadOptimizedMesh(
|
||||||
std::map<int, Transform> * poses,
|
std::map<int, Transform> * poses,
|
||||||
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
std::vector<std::vector<std::vector<unsigned int> > > * polygons,
|
||||||
|
#if PCL_VERSION_COMPARE(>=, 1, 8, 0)
|
||||||
|
std::vector<std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f>> > * texCoords,
|
||||||
|
#else
|
||||||
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
std::vector<std::vector<Eigen::Vector2f> > * texCoords,
|
||||||
|
#endif
|
||||||
cv::Mat * textures) const
|
cv::Mat * textures) const
|
||||||
{
|
{
|
||||||
if(_dbDriver)
|
if(_dbDriver)
|
||||||
|
|||||||
@@ -98,26 +98,6 @@ void OccupancyGrid::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::parse(parameters, Parameters::kGridMaxObstacleHeight(), maxObstacleHeight_);
|
Parameters::parse(parameters, Parameters::kGridMaxObstacleHeight(), maxObstacleHeight_);
|
||||||
Parameters::parse(parameters, Parameters::kGridMinGroundHeight(), minGroundHeight_);
|
Parameters::parse(parameters, Parameters::kGridMinGroundHeight(), minGroundHeight_);
|
||||||
Parameters::parse(parameters, Parameters::kGridMaxGroundHeight(), maxGroundHeight_);
|
Parameters::parse(parameters, Parameters::kGridMaxGroundHeight(), maxGroundHeight_);
|
||||||
if(maxGroundHeight_ != 0.0f &&
|
|
||||||
maxObstacleHeight_ != 0.0f &&
|
|
||||||
maxObstacleHeight_ < maxGroundHeight_)
|
|
||||||
{
|
|
||||||
UWARN("\"%s\" should be lower than \"%s\", setting \"%s\" to 0 (disabled).",
|
|
||||||
Parameters::kGridMaxGroundHeight().c_str(),
|
|
||||||
Parameters::kGridMaxObstacleHeight().c_str(),
|
|
||||||
Parameters::kGridMaxObstacleHeight().c_str());
|
|
||||||
maxObstacleHeight_ = 0;
|
|
||||||
}
|
|
||||||
if(maxGroundHeight_ != 0.0f &&
|
|
||||||
minGroundHeight_ != 0.0f &&
|
|
||||||
maxGroundHeight_ < minGroundHeight_)
|
|
||||||
{
|
|
||||||
UWARN("\"%s\" should be lower than \"%s\", setting \"%s\" to 0 (disabled).",
|
|
||||||
Parameters::kGridMinGroundHeight().c_str(),
|
|
||||||
Parameters::kGridMaxGroundHeight().c_str(),
|
|
||||||
Parameters::kGridMinGroundHeight().c_str());
|
|
||||||
minGroundHeight_ = 0;
|
|
||||||
}
|
|
||||||
Parameters::parse(parameters, Parameters::kGridNormalK(), normalKSearch_);
|
Parameters::parse(parameters, Parameters::kGridNormalK(), normalKSearch_);
|
||||||
if(Parameters::parse(parameters, Parameters::kGridMaxGroundAngle(), maxGroundAngle_))
|
if(Parameters::parse(parameters, Parameters::kGridMaxGroundAngle(), maxGroundAngle_))
|
||||||
{
|
{
|
||||||
@@ -182,6 +162,26 @@ void OccupancyGrid::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::kGridMaxGroundHeight().c_str(), cellSize_);
|
Parameters::kGridMaxGroundHeight().c_str(), cellSize_);
|
||||||
maxGroundHeight_ = cellSize_;
|
maxGroundHeight_ = cellSize_;
|
||||||
}
|
}
|
||||||
|
if(maxGroundHeight_ != 0.0f &&
|
||||||
|
maxObstacleHeight_ != 0.0f &&
|
||||||
|
maxObstacleHeight_ < maxGroundHeight_)
|
||||||
|
{
|
||||||
|
UWARN("\"%s\" should be lower than \"%s\", setting \"%s\" to 0 (disabled).",
|
||||||
|
Parameters::kGridMaxGroundHeight().c_str(),
|
||||||
|
Parameters::kGridMaxObstacleHeight().c_str(),
|
||||||
|
Parameters::kGridMaxObstacleHeight().c_str());
|
||||||
|
maxObstacleHeight_ = 0;
|
||||||
|
}
|
||||||
|
if(maxGroundHeight_ != 0.0f &&
|
||||||
|
minGroundHeight_ != 0.0f &&
|
||||||
|
maxGroundHeight_ < minGroundHeight_)
|
||||||
|
{
|
||||||
|
UWARN("\"%s\" should be lower than \"%s\", setting \"%s\" to 0 (disabled).",
|
||||||
|
Parameters::kGridMinGroundHeight().c_str(),
|
||||||
|
Parameters::kGridMaxGroundHeight().c_str(),
|
||||||
|
Parameters::kGridMinGroundHeight().c_str());
|
||||||
|
minGroundHeight_ = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OccupancyGrid::setCellSize(float cellSize)
|
void OccupancyGrid::setCellSize(float cellSize)
|
||||||
@@ -299,7 +299,8 @@ void OccupancyGrid::createLocalMap(
|
|||||||
viewPoint.z = viewpointRotated.z();
|
viewPoint.z = viewpointRotated.z();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cloud->size())
|
if((cloud->is_dense && cloud->size()) ||
|
||||||
|
(!cloud->is_dense && indices->size()))
|
||||||
{
|
{
|
||||||
pcl::IndicesPtr groundIndices(new std::vector<int>);
|
pcl::IndicesPtr groundIndices(new std::vector<int>);
|
||||||
pcl::IndicesPtr obstaclesIndices(new std::vector<int>);
|
pcl::IndicesPtr obstaclesIndices(new std::vector<int>);
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ void OdometryDVO::reset(const Transform & initialPose)
|
|||||||
}
|
}
|
||||||
lost_ = false;
|
lost_ = false;
|
||||||
motionFromKeyFrame_.setIdentity();
|
motionFromKeyFrame_.setIdentity();
|
||||||
|
previousLocalTransform_.setNull();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,6 +193,7 @@ Transform OdometryDVO::computeTransform(
|
|||||||
|
|
||||||
dvo::core::RgbdImagePyramid * current = new dvo::core::RgbdImagePyramid(*camera_, grey_s16, depth_float);
|
dvo::core::RgbdImagePyramid * current = new dvo::core::RgbdImagePyramid(*camera_, grey_s16, depth_float);
|
||||||
|
|
||||||
|
const Transform & localTransform = data.cameraModels()[0].localTransform();
|
||||||
cv::Mat covariance;
|
cv::Mat covariance;
|
||||||
if(reference_ == 0)
|
if(reference_ == 0)
|
||||||
{
|
{
|
||||||
@@ -245,16 +247,24 @@ Transform OdometryDVO::computeTransform(
|
|||||||
reference_ = 0; // this will make restart from the next frame
|
reference_ = 0; // this will make restart from the next frame
|
||||||
motionFromKeyFrame_.setIdentity();
|
motionFromKeyFrame_.setIdentity();
|
||||||
t.setNull();
|
t.setNull();
|
||||||
|
previousLocalTransform_.setNull();
|
||||||
covariance = cv::Mat::eye(6,6,CV_64FC1) * 9999.0;
|
covariance = cv::Mat::eye(6,6,CV_64FC1) * 9999.0;
|
||||||
UWARN("dvo failed to estimate motion, tracking will be reinitialized on next frame.");
|
UWARN("dvo failed to estimate motion, tracking will be reinitialized on next frame.");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const Transform & localTransform = data.cameraModels()[0].localTransform();
|
if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull())
|
||||||
if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull())
|
{
|
||||||
{
|
// from camera frame to base frame
|
||||||
// from camera frame to base frame
|
if(!previousLocalTransform_.isNull())
|
||||||
t = localTransform * t * localTransform.inverse();
|
{
|
||||||
|
t = previousLocalTransform_ * t * localTransform.inverse();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = localTransform * t * localTransform.inverse();
|
||||||
|
}
|
||||||
|
previousLocalTransform_ = localTransform;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(info)
|
if(info)
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ void OdometryFovis::reset(const Transform & initialPose)
|
|||||||
stereoDepth_ = 0;
|
stereoDepth_ = 0;
|
||||||
}
|
}
|
||||||
lost_ = false;
|
lost_ = false;
|
||||||
|
previousLocalTransform_.setNull();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,12 +342,14 @@ Transform OdometryFovis::computeTransform(
|
|||||||
t.setNull();
|
t.setNull();
|
||||||
lost_ = true;
|
lost_ = true;
|
||||||
covariance = cv::Mat::eye(6,6, CV_64FC1)*9999.0;
|
covariance = cv::Mat::eye(6,6, CV_64FC1)*9999.0;
|
||||||
|
previousLocalTransform_.setNull();
|
||||||
}
|
}
|
||||||
else if(lost_)
|
else if(lost_)
|
||||||
{
|
{
|
||||||
lost_ = false;
|
lost_ = false;
|
||||||
// we are not lost anymore but we don't know where we are now according to last valid pose
|
// we are not lost anymore but we don't know where we are now according to last valid pose
|
||||||
covariance = cv::Mat::eye(6,6, CV_64FC1)*9999.0;
|
covariance = cv::Mat::eye(6,6, CV_64FC1)*9999.0;
|
||||||
|
previousLocalTransform_.setNull();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -362,7 +365,15 @@ Transform OdometryFovis::computeTransform(
|
|||||||
if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull())
|
if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull())
|
||||||
{
|
{
|
||||||
// from camera frame to base frame
|
// from camera frame to base frame
|
||||||
t = localTransform * t * localTransform.inverse();
|
if(!previousLocalTransform_.isNull())
|
||||||
|
{
|
||||||
|
t = previousLocalTransform_ * t * localTransform.inverse();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = localTransform * t * localTransform.inverse();
|
||||||
|
}
|
||||||
|
previousLocalTransform_ = localTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(info)
|
if(info)
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "rtabmap/utilite/ULogger.h"
|
#include "rtabmap/utilite/ULogger.h"
|
||||||
#include "rtabmap/utilite/UTimer.h"
|
#include "rtabmap/utilite/UTimer.h"
|
||||||
#include "rtabmap/utilite/UStl.h"
|
#include "rtabmap/utilite/UStl.h"
|
||||||
|
#include "rtabmap/utilite/UDirectory.h"
|
||||||
|
|
||||||
#ifdef RTABMAP_ORB_SLAM2
|
#ifdef RTABMAP_ORB_SLAM2
|
||||||
#include <System.h>
|
#include <System.h>
|
||||||
@@ -495,6 +496,7 @@ public:
|
|||||||
if(!vocabularyPath.empty())
|
if(!vocabularyPath.empty())
|
||||||
{
|
{
|
||||||
//Load ORB Vocabulary
|
//Load ORB Vocabulary
|
||||||
|
vocabularyPath = uReplaceChar(vocabularyPath, '~', UDirectory::homeDir());
|
||||||
UWARN("Loading ORB Vocabulary: \"%s\". This could take a while...", vocabularyPath.c_str());
|
UWARN("Loading ORB Vocabulary: \"%s\". This could take a while...", vocabularyPath.c_str());
|
||||||
mpVocabulary = new ORB_SLAM2::ORBVocabulary();
|
mpVocabulary = new ORB_SLAM2::ORBVocabulary();
|
||||||
bool bVocLoad = mpVocabulary->loadFromTextFile(vocabularyPath);
|
bool bVocLoad = mpVocabulary->loadFromTextFile(vocabularyPath);
|
||||||
@@ -773,6 +775,7 @@ void OdometryORBSLAM2::reset(const Transform & initialPose)
|
|||||||
orbslam2_->shutdown();
|
orbslam2_->shutdown();
|
||||||
}
|
}
|
||||||
firstFrame_ = true;
|
firstFrame_ = true;
|
||||||
|
originLocalTransform_.setNull();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -845,14 +848,17 @@ Transform OdometryORBSLAM2::computeTransform(
|
|||||||
}
|
}
|
||||||
else if(Tcw.cols == 4 && Tcw.rows == 4)
|
else if(Tcw.cols == 4 && Tcw.rows == 4)
|
||||||
{
|
{
|
||||||
t = Transform(cv::Mat(Tcw, cv::Range(0,3), cv::Range(0,4)).clone());
|
t = Transform(cv::Mat(Tcw, cv::Range(0,3), cv::Range(0,4)));
|
||||||
|
|
||||||
if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull())
|
if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull())
|
||||||
{
|
{
|
||||||
// from camera frame to base frame
|
if(originLocalTransform_.isNull())
|
||||||
t = localTransform * t.inverse() * localTransform.inverse();
|
{
|
||||||
|
originLocalTransform_ = localTransform;
|
||||||
|
}
|
||||||
|
t = originLocalTransform_ * t.inverse() * localTransform.inverse();
|
||||||
|
t = this->getPose().inverse() * t;
|
||||||
}
|
}
|
||||||
t = this->getPose().inverse() * t;
|
|
||||||
|
|
||||||
if(firstFrame_)
|
if(firstFrame_)
|
||||||
{
|
{
|
||||||
@@ -916,12 +922,13 @@ Transform OdometryORBSLAM2::computeTransform(
|
|||||||
}
|
}
|
||||||
info->wordMatches.resize(oi);
|
info->wordMatches.resize(oi);
|
||||||
info->wordInliers.resize(oi);
|
info->wordInliers.resize(oi);
|
||||||
|
info->inliers = oi;
|
||||||
|
|
||||||
std::vector<ORB_SLAM2::MapPoint*> mapPoints = orbslam2_->mpMap->GetAllMapPoints();
|
std::vector<ORB_SLAM2::MapPoint*> mapPoints = orbslam2_->mpMap->GetAllMapPoints();
|
||||||
for (unsigned int i = 0; i < mapPoints.size(); ++i)
|
for (unsigned int i = 0; i < mapPoints.size(); ++i)
|
||||||
{
|
{
|
||||||
cv::Mat pt = mapPoints[i]->GetWorldPos();
|
cv::Mat pt = mapPoints[i]->GetWorldPos();
|
||||||
info->localMap.insert(std::make_pair(mapPoints[i]->mnId, util3d::transformPoint(cv::Point3f(pt), localTransform)));
|
info->localMap.insert(std::make_pair(mapPoints[i]->mnId, util3d::transformPoint(cv::Point3f(pt), originLocalTransform_)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ void OdometryViso2::reset(const Transform & initialPose)
|
|||||||
}
|
}
|
||||||
lost_ = false;
|
lost_ = false;
|
||||||
reference_motion_.setIdentity();
|
reference_motion_.setIdentity();
|
||||||
|
previousLocalTransform_.setNull();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,10 +254,19 @@ Transform OdometryViso2::computeTransform(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!t.isNull() && !t.isIdentity() && !data.stereoCameraModel().localTransform().isIdentity() && !data.stereoCameraModel().localTransform().isNull())
|
const Transform & localTransform = data.stereoCameraModel().localTransform();
|
||||||
|
if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull())
|
||||||
{
|
{
|
||||||
// from camera frame to base frame
|
// from camera frame to base frame
|
||||||
t = data.stereoCameraModel().localTransform() * t * data.stereoCameraModel().localTransform().inverse();
|
if(!previousLocalTransform_.isNull())
|
||||||
|
{
|
||||||
|
t = previousLocalTransform_ * t * localTransform.inverse();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = localTransform * t * localTransform.inverse();
|
||||||
|
}
|
||||||
|
previousLocalTransform_ = localTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(info)
|
if(info)
|
||||||
|
|||||||
@@ -156,7 +156,8 @@ bool Parameters::isFeatureParameter(const std::string & parameter)
|
|||||||
group.compare("FREAK") == 0 ||
|
group.compare("FREAK") == 0 ||
|
||||||
group.compare("BRIEF") == 0 ||
|
group.compare("BRIEF") == 0 ||
|
||||||
group.compare("GFTT") == 0 ||
|
group.compare("GFTT") == 0 ||
|
||||||
group.compare("BRISK") == 0;
|
group.compare("BRISK") == 0 ||
|
||||||
|
group.compare("KAZE") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtabmap::ParametersMap Parameters::getDefaultOdometryParameters(bool stereo, bool vis, bool icp)
|
rtabmap::ParametersMap Parameters::getDefaultOdometryParameters(bool stereo, bool vis, bool icp)
|
||||||
@@ -224,6 +225,9 @@ const std::map<std::string, std::pair<bool, std::string> > & Parameters::getRemo
|
|||||||
{
|
{
|
||||||
// removed parameters
|
// removed parameters
|
||||||
|
|
||||||
|
// 0.13.1
|
||||||
|
removedParameters_.insert(std::make_pair("Rtabmap/VhStrategy", std::make_pair(true, Parameters::kVhEpEnabled())));
|
||||||
|
|
||||||
// 0.12.5
|
// 0.12.5
|
||||||
removedParameters_.insert(std::make_pair("Grid/FullUpdate", std::make_pair(true, Parameters::kGridGlobalFullUpdate())));
|
removedParameters_.insert(std::make_pair("Grid/FullUpdate", std::make_pair(true, Parameters::kGridGlobalFullUpdate())));
|
||||||
|
|
||||||
@@ -807,7 +811,7 @@ void Parameters::readINI(const std::string & configFile, ParametersMap & paramet
|
|||||||
{
|
{
|
||||||
ULOGGER_WARN("Section \"Core\" in %s doesn't exist... "
|
ULOGGER_WARN("Section \"Core\" in %s doesn't exist... "
|
||||||
"Ignore this warning if the ini file does not exist yet. "
|
"Ignore this warning if the ini file does not exist yet. "
|
||||||
"The ini file will be automatically created when this node will close.", configFile.c_str());
|
"The ini file will be automatically created when rtabmap will close.", configFile.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -257,17 +257,17 @@ void Registration::normalizeCovariance(cv::Mat & covariance, const Transform & t
|
|||||||
}
|
}
|
||||||
|
|
||||||
double epsilon = 0.000001;
|
double epsilon = 0.000001;
|
||||||
if(covariance.at<double>(0,0)<=0.0)
|
if(covariance.at<double>(0,0)<=epsilon)
|
||||||
covariance.at<double>(0,0) = epsilon; // epsilon if exact transform
|
covariance.at<double>(0,0) = epsilon; // epsilon if exact transform
|
||||||
if(covariance.at<double>(1,1)<=0.0)
|
if(covariance.at<double>(1,1)<=epsilon)
|
||||||
covariance.at<double>(1,1) = epsilon; // epsilon if exact transform
|
covariance.at<double>(1,1) = epsilon; // epsilon if exact transform
|
||||||
if(covariance.at<double>(2,2)<=0.0)
|
if(covariance.at<double>(2,2)<=epsilon)
|
||||||
covariance.at<double>(2,2) = epsilon; // epsilon if exact transform
|
covariance.at<double>(2,2) = epsilon; // epsilon if exact transform
|
||||||
if(covariance.at<double>(3,3)<=0.0)
|
if(covariance.at<double>(3,3)<=epsilon)
|
||||||
covariance.at<double>(3,3) = epsilon; // epsilon if exact transform
|
covariance.at<double>(3,3) = epsilon; // epsilon if exact transform
|
||||||
if(covariance.at<double>(4,4)<=0.0)
|
if(covariance.at<double>(4,4)<=epsilon)
|
||||||
covariance.at<double>(4,4) = epsilon; // epsilon if exact transform
|
covariance.at<double>(4,4) = epsilon; // epsilon if exact transform
|
||||||
if(covariance.at<double>(5,5)<=0.0)
|
if(covariance.at<double>(5,5)<=epsilon)
|
||||||
covariance.at<double>(5,5) = epsilon; // epsilon if exact transform
|
covariance.at<double>(5,5) = epsilon; // epsilon if exact transform
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1234,6 +1234,20 @@ Transform RegistrationVis::computeTransformationImpl(
|
|||||||
UINFO(msg.c_str());
|
UINFO(msg.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double epsilon = 0.000001;
|
||||||
|
if(covariances[dir].at<double>(0,0)<=epsilon)
|
||||||
|
covariances[dir].at<double>(0,0) = epsilon; // epsilon if exact transform
|
||||||
|
if(covariances[dir].at<double>(1,1)<=epsilon)
|
||||||
|
covariances[dir].at<double>(1,1) = epsilon; // epsilon if exact transform
|
||||||
|
if(covariances[dir].at<double>(2,2)<=epsilon)
|
||||||
|
covariances[dir].at<double>(2,2) = epsilon; // epsilon if exact transform
|
||||||
|
if(covariances[dir].at<double>(3,3)<=epsilon)
|
||||||
|
covariances[dir].at<double>(3,3) = epsilon; // epsilon if exact transform
|
||||||
|
if(covariances[dir].at<double>(4,4)<=epsilon)
|
||||||
|
covariances[dir].at<double>(4,4) = epsilon; // epsilon if exact transform
|
||||||
|
if(covariances[dir].at<double>(5,5)<=epsilon)
|
||||||
|
covariances[dir].at<double>(5,5) = epsilon; // epsilon if exact transform
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_forwardEstimateOnly)
|
if(!_forwardEstimateOnly)
|
||||||
@@ -1292,13 +1306,13 @@ Transform RegistrationVis::computeTransformationImpl(
|
|||||||
poses.insert(std::make_pair(2, transforms[0]));
|
poses.insert(std::make_pair(2, transforms[0]));
|
||||||
|
|
||||||
cv::Mat cov = covariances[0].clone();
|
cv::Mat cov = covariances[0].clone();
|
||||||
normalizeCovariance(cov, transform);
|
normalizeCovariance(cov, transforms[0]);
|
||||||
|
|
||||||
links.insert(std::make_pair(1, Link(1, 2, Link::kNeighbor, transforms[0], cov.inv())));
|
links.insert(std::make_pair(1, Link(1, 2, Link::kNeighbor, transforms[0], cov.inv())));
|
||||||
if(!transforms[1].isNull() && inliers[1].size())
|
if(!transforms[1].isNull() && inliers[1].size())
|
||||||
{
|
{
|
||||||
cov = covariances[1].clone();
|
cov = covariances[1].clone();
|
||||||
normalizeCovariance(cov, transform);
|
normalizeCovariance(cov, transforms[1]);
|
||||||
links.insert(std::make_pair(2, Link(2, 1, Link::kNeighbor, transforms[1], cov.inv())));
|
links.insert(std::make_pair(2, Link(2, 1, Link::kNeighbor, transforms[1], cov.inv())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-14
@@ -83,6 +83,7 @@ Rtabmap::Rtabmap() :
|
|||||||
_maxMemoryAllowed(Parameters::defaultRtabmapMemoryThr()), // 0=inf
|
_maxMemoryAllowed(Parameters::defaultRtabmapMemoryThr()), // 0=inf
|
||||||
_loopThr(Parameters::defaultRtabmapLoopThr()),
|
_loopThr(Parameters::defaultRtabmapLoopThr()),
|
||||||
_loopRatio(Parameters::defaultRtabmapLoopRatio()),
|
_loopRatio(Parameters::defaultRtabmapLoopRatio()),
|
||||||
|
_verifyLoopClosureHypothesis(Parameters::defaultVhEpEnabled()),
|
||||||
_maxRetrieved(Parameters::defaultRtabmapMaxRetrieved()),
|
_maxRetrieved(Parameters::defaultRtabmapMaxRetrieved()),
|
||||||
_maxLocalRetrieved(Parameters::defaultRGBDMaxLocalRetrieved()),
|
_maxLocalRetrieved(Parameters::defaultRGBDMaxLocalRetrieved()),
|
||||||
_rawDataKept(Parameters::defaultMemImageKept()),
|
_rawDataKept(Parameters::defaultMemImageKept()),
|
||||||
@@ -401,6 +402,7 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::parse(parameters, Parameters::kRtabmapMemoryThr(), _maxMemoryAllowed);
|
Parameters::parse(parameters, Parameters::kRtabmapMemoryThr(), _maxMemoryAllowed);
|
||||||
Parameters::parse(parameters, Parameters::kRtabmapLoopThr(), _loopThr);
|
Parameters::parse(parameters, Parameters::kRtabmapLoopThr(), _loopThr);
|
||||||
Parameters::parse(parameters, Parameters::kRtabmapLoopRatio(), _loopRatio);
|
Parameters::parse(parameters, Parameters::kRtabmapLoopRatio(), _loopRatio);
|
||||||
|
Parameters::parse(parameters, Parameters::kVhEpEnabled(), _verifyLoopClosureHypothesis);
|
||||||
Parameters::parse(parameters, Parameters::kRtabmapMaxRetrieved(), _maxRetrieved);
|
Parameters::parse(parameters, Parameters::kRtabmapMaxRetrieved(), _maxRetrieved);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDMaxLocalRetrieved(), _maxLocalRetrieved);
|
Parameters::parse(parameters, Parameters::kRGBDMaxLocalRetrieved(), _maxLocalRetrieved);
|
||||||
Parameters::parse(parameters, Parameters::kMemImageKept(), _rawDataKept);
|
Parameters::parse(parameters, Parameters::kMemImageKept(), _rawDataKept);
|
||||||
@@ -470,22 +472,11 @@ void Rtabmap::parseParameters(const ParametersMap & parameters)
|
|||||||
_memory->parseParameters(parameters);
|
_memory->parseParameters(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
VhStrategy vhStrategy = kVhUndef;
|
if(!_epipolarGeometry)
|
||||||
// Verifying hypotheses strategy
|
|
||||||
if((iter=parameters.find(Parameters::kRtabmapVhStrategy())) != parameters.end())
|
|
||||||
{
|
|
||||||
vhStrategy = (VhStrategy)std::atoi((*iter).second.c_str());
|
|
||||||
}
|
|
||||||
if(!_epipolarGeometry && vhStrategy == kVhEpipolar)
|
|
||||||
{
|
{
|
||||||
_epipolarGeometry = new EpipolarGeometry(_parameters);
|
_epipolarGeometry = new EpipolarGeometry(_parameters);
|
||||||
}
|
}
|
||||||
else if(_epipolarGeometry && vhStrategy == kVhNone)
|
else
|
||||||
{
|
|
||||||
delete _epipolarGeometry;
|
|
||||||
_epipolarGeometry = 0;
|
|
||||||
}
|
|
||||||
else if(_epipolarGeometry)
|
|
||||||
{
|
{
|
||||||
_epipolarGeometry->parseParameters(parameters);
|
_epipolarGeometry->parseParameters(parameters);
|
||||||
}
|
}
|
||||||
@@ -1407,7 +1398,7 @@ bool Rtabmap::process(
|
|||||||
// Ignore loop closure if there is only one loop closure hypothesis
|
// Ignore loop closure if there is only one loop closure hypothesis
|
||||||
UDEBUG("rejected hypothesis: single hypothesis");
|
UDEBUG("rejected hypothesis: single hypothesis");
|
||||||
}
|
}
|
||||||
else if(_epipolarGeometry && !_epipolarGeometry->check(signature, _memory->getSignature(_highestHypothesis.first)))
|
else if(_verifyLoopClosureHypothesis && !_epipolarGeometry->check(signature, _memory->getSignature(_highestHypothesis.first)))
|
||||||
{
|
{
|
||||||
UWARN("rejected hypothesis: by epipolar geometry");
|
UWARN("rejected hypothesis: by epipolar geometry");
|
||||||
}
|
}
|
||||||
@@ -2550,6 +2541,7 @@ bool Rtabmap::process(
|
|||||||
id = _memory->getLastWorkingSignature()->id();
|
id = _memory->getLastWorkingSignature()->id();
|
||||||
UDEBUG("Refresh local map from %d", id);
|
UDEBUG("Refresh local map from %d", id);
|
||||||
}
|
}
|
||||||
|
UDEBUG("id=%d _optimizedPoses=%d", id, (int)_optimizedPoses.size());
|
||||||
if(id > 0)
|
if(id > 0)
|
||||||
{
|
{
|
||||||
if(_lastLocalizationNodeId != 0)
|
if(_lastLocalizationNodeId != 0)
|
||||||
|
|||||||
@@ -570,8 +570,7 @@ void RtabmapThread::addData(const OdometryEvent & odomEvent)
|
|||||||
}
|
}
|
||||||
if(!lastPose_.isIdentity() &&
|
if(!lastPose_.isIdentity() &&
|
||||||
(odomEvent.pose().isIdentity() ||
|
(odomEvent.pose().isIdentity() ||
|
||||||
odomEvent.rotVariance()>=9999 ||
|
odomEvent.info().covariance.at<double>(0,0)>=9999))
|
||||||
odomEvent.transVariance()>=9999))
|
|
||||||
{
|
{
|
||||||
if(odomEvent.pose().isIdentity())
|
if(odomEvent.pose().isIdentity())
|
||||||
{
|
{
|
||||||
@@ -579,21 +578,21 @@ void RtabmapThread::addData(const OdometryEvent & odomEvent)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UWARN("Odometry is reset (high variance (%f/%f >=9999 detected). Increment map id!", odomEvent.transVariance(), odomEvent.rotVariance());
|
UWARN("Odometry is reset (high variance (%f >=9999 detected). Increment map id!", odomEvent.info().covariance.at<double>(0,0));
|
||||||
}
|
}
|
||||||
pushNewState(kStateTriggeringMap);
|
pushNewState(kStateTriggeringMap);
|
||||||
covariance_ = cv::Mat();
|
covariance_ = cv::Mat();
|
||||||
}
|
}
|
||||||
|
|
||||||
double maxRotVar = odomEvent.rotVariance();
|
if(uIsFinite(odomEvent.info().covariance.at<double>(0,0)) &&
|
||||||
double maxTransVar = odomEvent.transVariance();
|
odomEvent.info().covariance.at<double>(0,0) != 1.0 &&
|
||||||
if(maxRotVar != 1.0f && maxTransVar != 1.0f && !covariance_.empty())
|
odomEvent.info().covariance.at<double>(0,0)>0.0)
|
||||||
{
|
{
|
||||||
covariance_ += odomEvent.covariance();
|
// Use largest covariance error (to be independent of the odometry frame rate)
|
||||||
}
|
if(covariance_.empty() || odomEvent.info().covariance.at<double>(0,0) > covariance_.at<double>(0,0))
|
||||||
else
|
{
|
||||||
{
|
covariance_ = odomEvent.info().covariance;
|
||||||
covariance_ = odomEvent.covariance();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ignoreFrame && !_createIntermediateNodes)
|
if(ignoreFrame && !_createIntermediateNodes)
|
||||||
|
|||||||
+69
-5
@@ -957,9 +957,40 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr RTABMAP_EXP cloudFromSensorData(
|
|||||||
leftMono = sensorData.imageRaw();
|
leftMono = sensorData.imageRaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Mat right(sensorData.rightRaw());
|
||||||
|
StereoCameraModel model = sensorData.stereoCameraModel();
|
||||||
|
if( roiRatios.size() == 4 &&
|
||||||
|
((roiRatios[0] > 0.0f && roiRatios[0] <= 1.0f) ||
|
||||||
|
(roiRatios[1] > 0.0f && roiRatios[1] <= 1.0f) ||
|
||||||
|
(roiRatios[2] > 0.0f && roiRatios[2] <= 1.0f) ||
|
||||||
|
(roiRatios[3] > 0.0f && roiRatios[3] <= 1.0f)))
|
||||||
|
{
|
||||||
|
cv::Rect roi = util2d::computeRoi(leftMono, roiRatios);
|
||||||
|
if( roi.width%decimation==0 &&
|
||||||
|
roi.height%decimation==0)
|
||||||
|
{
|
||||||
|
leftMono = cv::Mat(leftMono, roi);
|
||||||
|
right = cv::Mat(right, roi);
|
||||||
|
model.roi(roi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UERROR("Cannot apply ROI ratios [%f,%f,%f,%f] because resulting "
|
||||||
|
"dimension (left=%dx%d) cannot be divided exactly "
|
||||||
|
"by decimation parameter (%d). Ignoring ROI ratios...",
|
||||||
|
roiRatios[0],
|
||||||
|
roiRatios[1],
|
||||||
|
roiRatios[2],
|
||||||
|
roiRatios[3],
|
||||||
|
roi.width,
|
||||||
|
roi.height,
|
||||||
|
decimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cloud = cloudFromDisparity(
|
cloud = cloudFromDisparity(
|
||||||
util2d::disparityFromStereoImages(leftMono, sensorData.rightRaw(), stereoParameters),
|
util2d::disparityFromStereoImages(leftMono, right, stereoParameters),
|
||||||
sensorData.stereoCameraModel(),
|
model,
|
||||||
decimation,
|
decimation,
|
||||||
maxDepth,
|
maxDepth,
|
||||||
minDepth,
|
minDepth,
|
||||||
@@ -1091,10 +1122,43 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr RTABMAP_EXP cloudRGBFromSensorData(
|
|||||||
{
|
{
|
||||||
//stereo
|
//stereo
|
||||||
UDEBUG("");
|
UDEBUG("");
|
||||||
|
|
||||||
|
cv::Mat left(sensorData.imageRaw());
|
||||||
|
cv::Mat right(sensorData.rightRaw());
|
||||||
|
StereoCameraModel model = sensorData.stereoCameraModel();
|
||||||
|
if( roiRatios.size() == 4 &&
|
||||||
|
((roiRatios[0] > 0.0f && roiRatios[0] <= 1.0f) ||
|
||||||
|
(roiRatios[1] > 0.0f && roiRatios[1] <= 1.0f) ||
|
||||||
|
(roiRatios[2] > 0.0f && roiRatios[2] <= 1.0f) ||
|
||||||
|
(roiRatios[3] > 0.0f && roiRatios[3] <= 1.0f)))
|
||||||
|
{
|
||||||
|
cv::Rect roi = util2d::computeRoi(left, roiRatios);
|
||||||
|
if( roi.width%decimation==0 &&
|
||||||
|
roi.height%decimation==0)
|
||||||
|
{
|
||||||
|
left = cv::Mat(left, roi);
|
||||||
|
right = cv::Mat(right, roi);
|
||||||
|
model.roi(roi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UERROR("Cannot apply ROI ratios [%f,%f,%f,%f] because resulting "
|
||||||
|
"dimension (left=%dx%d) cannot be divided exactly "
|
||||||
|
"by decimation parameter (%d). Ignoring ROI ratios...",
|
||||||
|
roiRatios[0],
|
||||||
|
roiRatios[1],
|
||||||
|
roiRatios[2],
|
||||||
|
roiRatios[3],
|
||||||
|
roi.width,
|
||||||
|
roi.height,
|
||||||
|
decimation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cloud = cloudFromStereoImages(
|
cloud = cloudFromStereoImages(
|
||||||
sensorData.imageRaw(),
|
left,
|
||||||
sensorData.rightRaw(),
|
right,
|
||||||
sensorData.stereoCameraModel(),
|
model,
|
||||||
decimation,
|
decimation,
|
||||||
maxDepth,
|
maxDepth,
|
||||||
minDepth,
|
minDepth,
|
||||||
|
|||||||
@@ -142,6 +142,8 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr voxelize(
|
|||||||
float voxelSize)
|
float voxelSize)
|
||||||
{
|
{
|
||||||
UASSERT(voxelSize > 0.0f);
|
UASSERT(voxelSize > 0.0f);
|
||||||
|
UASSERT_MSG((cloud->is_dense && cloud->size()) || (!cloud->is_dense && indices->size()),
|
||||||
|
uFormat("Cloud size=%d indices=%d is_dense=%s", (int)cloud->size(), (int)indices->size(), cloud->is_dense?"true":"false").c_str());
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>);
|
pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>);
|
||||||
pcl::VoxelGrid<pcl::PointXYZ> filter;
|
pcl::VoxelGrid<pcl::PointXYZ> filter;
|
||||||
filter.setLeafSize(voxelSize, voxelSize, voxelSize);
|
filter.setLeafSize(voxelSize, voxelSize, voxelSize);
|
||||||
@@ -159,6 +161,8 @@ pcl::PointCloud<pcl::PointNormal>::Ptr voxelize(
|
|||||||
float voxelSize)
|
float voxelSize)
|
||||||
{
|
{
|
||||||
UASSERT(voxelSize > 0.0f);
|
UASSERT(voxelSize > 0.0f);
|
||||||
|
UASSERT_MSG((cloud->is_dense && cloud->size()) || (!cloud->is_dense && indices->size()),
|
||||||
|
uFormat("Cloud size=%d indices=%d is_dense=%s", (int)cloud->size(), (int)indices->size(), cloud->is_dense?"true":"false").c_str());
|
||||||
pcl::PointCloud<pcl::PointNormal>::Ptr output(new pcl::PointCloud<pcl::PointNormal>);
|
pcl::PointCloud<pcl::PointNormal>::Ptr output(new pcl::PointCloud<pcl::PointNormal>);
|
||||||
pcl::VoxelGrid<pcl::PointNormal> filter;
|
pcl::VoxelGrid<pcl::PointNormal> filter;
|
||||||
filter.setLeafSize(voxelSize, voxelSize, voxelSize);
|
filter.setLeafSize(voxelSize, voxelSize, voxelSize);
|
||||||
@@ -176,6 +180,8 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr voxelize(
|
|||||||
float voxelSize)
|
float voxelSize)
|
||||||
{
|
{
|
||||||
UASSERT(voxelSize > 0.0f);
|
UASSERT(voxelSize > 0.0f);
|
||||||
|
UASSERT_MSG((cloud->is_dense && cloud->size()) || (!cloud->is_dense && indices->size()),
|
||||||
|
uFormat("Cloud size=%d indices=%d is_dense=%s", (int)cloud->size(), (int)indices->size(), cloud->is_dense?"true":"false").c_str());
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||||
pcl::VoxelGrid<pcl::PointXYZRGB> filter;
|
pcl::VoxelGrid<pcl::PointXYZRGB> filter;
|
||||||
filter.setLeafSize(voxelSize, voxelSize, voxelSize);
|
filter.setLeafSize(voxelSize, voxelSize, voxelSize);
|
||||||
@@ -193,6 +199,8 @@ pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr voxelize(
|
|||||||
float voxelSize)
|
float voxelSize)
|
||||||
{
|
{
|
||||||
UASSERT(voxelSize > 0.0f);
|
UASSERT(voxelSize > 0.0f);
|
||||||
|
UASSERT_MSG((cloud->is_dense && cloud->size()) || (!cloud->is_dense && indices->size()),
|
||||||
|
uFormat("Cloud size=%d indices=%d is_dense=%s", (int)cloud->size(), (int)indices->size(), cloud->is_dense?"true":"false").c_str());
|
||||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
|
||||||
pcl::VoxelGrid<pcl::PointXYZRGBNormal> filter;
|
pcl::VoxelGrid<pcl::PointXYZRGBNormal> filter;
|
||||||
filter.setLeafSize(voxelSize, voxelSize, voxelSize);
|
filter.setLeafSize(voxelSize, voxelSize, voxelSize);
|
||||||
@@ -266,7 +274,7 @@ pcl::IndicesPtr passThrough(
|
|||||||
float max,
|
float max,
|
||||||
bool negative)
|
bool negative)
|
||||||
{
|
{
|
||||||
UASSERT(max > min);
|
UASSERT_MSG(max > min, uFormat("cloud=%d, max=%f min=%f axis=%s", (int)cloud->size(), max, min, axis.c_str()).c_str());
|
||||||
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
||||||
|
|
||||||
pcl::IndicesPtr output(new std::vector<int>);
|
pcl::IndicesPtr output(new std::vector<int>);
|
||||||
@@ -287,7 +295,7 @@ pcl::IndicesPtr passThrough(
|
|||||||
float max,
|
float max,
|
||||||
bool negative)
|
bool negative)
|
||||||
{
|
{
|
||||||
UASSERT(max > min);
|
UASSERT_MSG(max > min, uFormat("cloud=%d, max=%f min=%f axis=%s", (int)cloud->size(), max, min, axis.c_str()).c_str());
|
||||||
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
||||||
|
|
||||||
pcl::IndicesPtr output(new std::vector<int>);
|
pcl::IndicesPtr output(new std::vector<int>);
|
||||||
@@ -308,7 +316,7 @@ pcl::PointCloud<pcl::PointXYZ>::Ptr passThrough(
|
|||||||
float max,
|
float max,
|
||||||
bool negative)
|
bool negative)
|
||||||
{
|
{
|
||||||
UASSERT(max > min);
|
UASSERT_MSG(max > min, uFormat("cloud=%d, max=%f min=%f axis=%s", (int)cloud->size(), max, min, axis.c_str()).c_str());
|
||||||
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>);
|
pcl::PointCloud<pcl::PointXYZ>::Ptr output(new pcl::PointCloud<pcl::PointXYZ>);
|
||||||
@@ -328,7 +336,7 @@ pcl::PointCloud<pcl::PointXYZRGB>::Ptr passThrough(
|
|||||||
float max,
|
float max,
|
||||||
bool negative)
|
bool negative)
|
||||||
{
|
{
|
||||||
UASSERT(max > min);
|
UASSERT_MSG(max > min, uFormat("cloud=%d, max=%f min=%f axis=%s", (int)cloud->size(), max, min, axis.c_str()).c_str());
|
||||||
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||||
@@ -348,7 +356,7 @@ pcl::PointCloud<pcl::PointNormal>::Ptr passThrough(
|
|||||||
float max,
|
float max,
|
||||||
bool negative)
|
bool negative)
|
||||||
{
|
{
|
||||||
UASSERT(max > min);
|
UASSERT_MSG(max > min, uFormat("cloud=%d, max=%f min=%f axis=%s", (int)cloud->size(), max, min, axis.c_str()).c_str());
|
||||||
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
UASSERT(axis.compare("x") == 0 || axis.compare("y") == 0 || axis.compare("z") == 0);
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointNormal>::Ptr output(new pcl::PointCloud<pcl::PointNormal>);
|
pcl::PointCloud<pcl::PointNormal>::Ptr output(new pcl::PointCloud<pcl::PointNormal>);
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
# Image: introlab3it/rtabmap:android-deps
|
# Image: introlab3it/rtabmap:android-deps
|
||||||
|
|
||||||
FROM introlab3it/rtabmap
|
FROM ubuntu:16.04
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
git \
|
||||||
|
cmake \
|
||||||
|
g++ \
|
||||||
|
software-properties-common
|
||||||
|
|
||||||
ENV ANDROID_HOME=/opt/android-sdk
|
ENV ANDROID_HOME=/opt/android-sdk
|
||||||
ENV ANDROID_NATIVE_API_LEVEL=android-19
|
ENV ANDROID_NATIVE_API_LEVEL=android-19
|
||||||
@@ -15,4 +22,4 @@ RUN /bin/bash -c "./setup_android_env.bash"
|
|||||||
|
|
||||||
ADD install_deps.bash /root/install_deps.bash
|
ADD install_deps.bash /root/install_deps.bash
|
||||||
RUN chmod +x install_deps.bash
|
RUN chmod +x install_deps.bash
|
||||||
RUN /bin/bash -c "./install_deps.bash"
|
RUN /bin/bash -c "./install_deps.bash /opt/android"
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
echo "install_deps.bash android_install_prefix # Example: install_deps.bash /opt/android"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
prefix=$1
|
||||||
|
pwd=$(pwd)
|
||||||
|
wget -nv https://github.com/introlab/rtabmap/raw/master/cmake_modules/android.toolchain.cmake
|
||||||
|
|
||||||
|
# Install directory for all dependencies
|
||||||
|
mkdir -p $prefix/armeabi-v7a
|
||||||
|
mkdir -p $prefix/arm64-v8a
|
||||||
|
|
||||||
# Boost
|
# Boost
|
||||||
echo "wget boost..."
|
echo "wget boost..."
|
||||||
wget -nv https://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz
|
wget -nv https://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz
|
||||||
@@ -9,11 +22,11 @@ wget -nv https://gist.github.com/matlabbe/0bce8feeb73a499a76afbbcc5c687221/raw/4
|
|||||||
wget -nv https://gist.github.com/matlabbe/0bce8feeb73a499a76afbbcc5c687221/raw/e7fbf0e301cfea417a7aa69989a761a4de08b8c3/CMakeLists.txt
|
wget -nv https://gist.github.com/matlabbe/0bce8feeb73a499a76afbbcc5c687221/raw/e7fbf0e301cfea417a7aa69989a761a4de08b8c3/CMakeLists.txt
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
rm -r *
|
rm -r *
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
cd
|
cd
|
||||||
@@ -26,11 +39,11 @@ tar -xzf 3.2.7.tar.gz
|
|||||||
cd eigen-eigen-b30b87236a1b
|
cd eigen-eigen-b30b87236a1b
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
rm -r *
|
rm -r *
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
cd
|
cd
|
||||||
@@ -43,11 +56,11 @@ unzip -qq flann-1.8.4-src.zip
|
|||||||
cd flann-1.8.4-src
|
cd flann-1.8.4-src
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
rm -r *
|
rm -r *
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
cd
|
cd
|
||||||
@@ -62,11 +75,11 @@ wget -nv https://gist.github.com/matlabbe/726b490c658afd3293f4b3f2f501b863/raw/d
|
|||||||
git apply gtsam_GKlib_android_fix.patch
|
git apply gtsam_GKlib_android_fix.patch
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DMETIS_SHARED=OFF -DGTSAM_BUILD_STATIC_LIBRARY=ON -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DMETIS_SHARED=OFF -DGTSAM_BUILD_STATIC_LIBRARY=ON -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
rm -r *
|
rm -r *
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DMETIS_SHARED=OFF -DGTSAM_BUILD_STATIC_LIBRARY=ON -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DMETIS_SHARED=OFF -DGTSAM_BUILD_STATIC_LIBRARY=ON -DGTSAM_BUILD_TESTS=OFF -DGTSAM_BUILD_EXAMPLES_ALWAYS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
cd
|
cd
|
||||||
@@ -77,11 +90,11 @@ git clone https://github.com/RainerKuemmerle/g2o.git
|
|||||||
cd g2o
|
cd g2o
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_LGPL_SHARED_LIBS=OFF -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_LGPL_SHARED_LIBS=OFF -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
rm -r *
|
rm -r *
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_LGPL_SHARED_LIBS=OFF -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_LGPL_SHARED_LIBS=OFF -DG2O_BUILD_APPS=OFF -DG2O_BUILD_EXAMPLES=OFF -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
cd
|
cd
|
||||||
@@ -100,13 +113,13 @@ cd VTK
|
|||||||
git checkout tags/v7.1.1
|
git checkout tags/v7.1.1
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
~/cmake-3.7.2-Linux-x86_64/bin/cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_ANDROID_BUILD=ON -DANDROID_ARCH_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
~/cmake-3.7.2-Linux-x86_64/bin/cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_ANDROID_BUILD=ON -DANDROID_ARCH_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
make
|
make
|
||||||
cp -r CMakeExternals/Install/vtk-android/* /opt/android/armeabi-v7a/.
|
cp -r CMakeExternals/Install/vtk-android/* $prefix/armeabi-v7a/.
|
||||||
rm -r *
|
rm -r *
|
||||||
~/cmake-3.7.2-Linux-x86_64/bin/cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_ANDROID_BUILD=ON -DANDROID_ARCH_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
~/cmake-3.7.2-Linux-x86_64/bin/cmake -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF -DVTK_ANDROID_BUILD=ON -DANDROID_ARCH_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
make
|
make
|
||||||
cp -r CMakeExternals/Install/vtk-android/* /opt/android/arm64-v8a/.
|
cp -r CMakeExternals/Install/vtk-android/* $prefix/arm64-v8a/.
|
||||||
cd
|
cd
|
||||||
rm -r VTK cmake-3.7.2-Linux-x86_64
|
rm -r VTK cmake-3.7.2-Linux-x86_64
|
||||||
|
|
||||||
@@ -120,14 +133,14 @@ git apply pcl_1_8_0_vtk_android_support.patch
|
|||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
# do it 2 times because there is a cmake error on the first time and not the second time!?
|
# do it 2 times because there is a cmake error on the first time and not the second time!?
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
rm -r *
|
rm -r *
|
||||||
# do it 2 times because there is a cmake error on the first time and not the second time!?
|
# do it 2 times because there is a cmake error on the first time and not the second time!?
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_apps=OFF -DBUILD_examples=OFF -DBUILD_tools=OFF -DBUILD_visualization=OFF -DBUILD_tracking=OFF -DBUILD_people=OFF -DBUILD_global_tests=OFF -DWITH_QT=OFF -DWITH_OPENGL=OFF -DWITH_VTK=ON -DPCL_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
cd
|
cd
|
||||||
@@ -143,11 +156,11 @@ cd opencv
|
|||||||
git checkout tags/3.2.0
|
git checkout tags/3.2.0
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DOPENCV_EXTRA_MODULES_PATH=$pwd/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
rm -r *
|
rm -r *
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=/root/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ..
|
cmake -DCMAKE_TOOLCHAIN_FILE=$pwd/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DOPENCV_EXTRA_MODULES_PATH=$pwd/opencv_contrib/modules -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ..
|
||||||
make
|
make
|
||||||
make install
|
make install
|
||||||
cd
|
cd
|
||||||
|
|||||||
@@ -22,9 +22,4 @@ echo "wget android-ndk..."
|
|||||||
wget -nv https://dl.google.com/android/repository/android-ndk-r14-linux-x86_64.zip
|
wget -nv https://dl.google.com/android/repository/android-ndk-r14-linux-x86_64.zip
|
||||||
unzip -qq android-ndk-r14-linux-x86_64.zip
|
unzip -qq android-ndk-r14-linux-x86_64.zip
|
||||||
rm android-ndk-r14-linux-x86_64.zip
|
rm android-ndk-r14-linux-x86_64.zip
|
||||||
mv android-ndk-r14 /opt/.
|
mv android-ndk-r14 $ANDROID_NDK
|
||||||
|
|
||||||
# Install directory for all dependencies
|
|
||||||
mkdir -p /opt/android/armeabi-v7a
|
|
||||||
mkdir -p /opt/android/arm64-v8a
|
|
||||||
wget -nv https://github.com/introlab/rtabmap/raw/master/cmake_modules/android.toolchain.cmake
|
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ WORKDIR /root/
|
|||||||
|
|
||||||
ADD build.bash /root/build.bash
|
ADD build.bash /root/build.bash
|
||||||
RUN chmod +x build.bash
|
RUN chmod +x build.bash
|
||||||
RUN /bin/bash -c "./build.bash"
|
RUN /bin/bash -c "./build.bash /opt/android"
|
||||||
|
|
||||||
WORKDIR /root/
|
WORKDIR /root/
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
echo "build.bash android_install_prefix # Example: build.bash /opt/android"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
prefix=$1
|
||||||
|
|
||||||
# get rtabmap
|
# get rtabmap
|
||||||
git clone https://github.com/introlab/rtabmap.git rtabmap-tango
|
git clone https://github.com/introlab/rtabmap.git rtabmap-tango
|
||||||
|
|
||||||
@@ -7,33 +14,39 @@ git clone https://github.com/introlab/rtabmap.git rtabmap-tango
|
|||||||
wget https://developers.google.com/tango/downloads/TangoSDK_Ikariotikos_C.zip
|
wget https://developers.google.com/tango/downloads/TangoSDK_Ikariotikos_C.zip
|
||||||
unzip -qq TangoSDK_Ikariotikos_C.zip
|
unzip -qq TangoSDK_Ikariotikos_C.zip
|
||||||
rm TangoSDK_Ikariotikos_C.zip
|
rm TangoSDK_Ikariotikos_C.zip
|
||||||
cp -r lib_tango_client_api/include/* /opt/android/armeabi-v7a/include/.
|
cp -r lib_tango_client_api/include/* $prefix/armeabi-v7a/include/.
|
||||||
cp -r lib_tango_client_api/include/* /opt/android/arm64-v8a/include/.
|
cp -r lib_tango_client_api/include/* $prefix/arm64-v8a/include/.
|
||||||
cp -r lib_tango_client_api/lib/armeabi-v7a/* /opt/android/armeabi-v7a/lib/.
|
cp -r lib_tango_client_api/lib/armeabi-v7a/* $prefix/armeabi-v7a/lib/.
|
||||||
cp -r lib_tango_client_api/lib/arm64-v8a/* /opt/android/arm64-v8a/lib/.
|
cp -r lib_tango_client_api/lib/arm64-v8a/* $prefix/arm64-v8a/lib/.
|
||||||
rm -r lib_tango_client_api
|
rm -r lib_tango_client_api
|
||||||
wget https://developers.google.com/tango/downloads/TangoSupport_Ikariotikos_C.zip
|
wget https://developers.google.com/tango/downloads/TangoSupport_Ikariotikos_C.zip
|
||||||
unzip -qq TangoSupport_Ikariotikos_C.zip
|
unzip -qq TangoSupport_Ikariotikos_C.zip
|
||||||
rm TangoSupport_Ikariotikos_C.zip
|
rm TangoSupport_Ikariotikos_C.zip
|
||||||
cp -r lib_tango_support_api/include/* /opt/android/armeabi-v7a/include/.
|
cp -r lib_tango_support_api/include/* $prefix/armeabi-v7a/include/.
|
||||||
cp -r lib_tango_support_api/include/* /opt/android/arm64-v8a/include/.
|
cp -r lib_tango_support_api/include/* $prefix/arm64-v8a/include/.
|
||||||
cp -r lib_tango_support_api/lib/armeabi-v7a/* /opt/android/armeabi-v7a/lib/.
|
cp -r lib_tango_support_api/lib/armeabi-v7a/* $prefix/armeabi-v7a/lib/.
|
||||||
cp -r lib_tango_support_api/lib/arm64-v8a/* /opt/android/arm64-v8a/lib/.
|
cp -r lib_tango_support_api/lib/arm64-v8a/* $prefix/arm64-v8a/lib/.
|
||||||
cp -r lib_tango_support_api/lib/* rtabmap-tango/app/android/jni/third-party/lib/.
|
cp -r lib_tango_support_api/lib/* rtabmap-tango/app/android/jni/third-party/lib/.
|
||||||
rm -r lib_tango_support_api
|
rm -r lib_tango_support_api
|
||||||
wget https://developers.google.com/tango/downloads/TangoSDK_Ikariotikos_Java.jar
|
wget https://developers.google.com/tango/downloads/TangoSDK_Ikariotikos_Java.jar
|
||||||
mv TangoSDK_Ikariotikos_Java.jar rtabmap-tango/app/android/libs/.
|
mv TangoSDK_Ikariotikos_Java.jar rtabmap-tango/app/android/libs/.
|
||||||
|
|
||||||
|
# resource tool
|
||||||
|
cd rtabmap-tango/build
|
||||||
|
cmake -DANDROID_PREBUILD=ON ..
|
||||||
|
make
|
||||||
|
cd
|
||||||
|
|
||||||
# rtabmap
|
# rtabmap
|
||||||
mkdir rtabmap-tango/build/armeabi-v7a
|
mkdir rtabmap-tango/build/armeabi-v7a
|
||||||
cd rtabmap-tango/build/armeabi-v7a
|
cd rtabmap-tango/build/armeabi-v7a
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=../../cmake_modules/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TOOLS=OFF -DCMAKE_BUILD_TYPE=Release -DOpenCV_DIR=/opt/android/armeabi-v7a/sdk/native/jni -DCMAKE_INSTALL_PREFIX=/opt/android/armeabi-v7a ../..
|
cmake -DCMAKE_TOOLCHAIN_FILE=../../cmake_modules/android.toolchain.cmake -DANDROID_ABI=armeabi-v7a -DBUILD_SHARED_LIBS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TOOLS=OFF -DCMAKE_BUILD_TYPE=Release -DOpenCV_DIR=$prefix/armeabi-v7a/sdk/native/jni -DCMAKE_INSTALL_PREFIX=$prefix/armeabi-v7a ../..
|
||||||
make
|
make
|
||||||
|
|
||||||
cd
|
cd
|
||||||
mkdir rtabmap-tango/build/arm64-v8a
|
mkdir rtabmap-tango/build/arm64-v8a
|
||||||
cd rtabmap-tango/build/arm64-v8a
|
cd rtabmap-tango/build/arm64-v8a
|
||||||
cmake -DCMAKE_TOOLCHAIN_FILE=../../cmake_modules/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TOOLS=OFF -DCMAKE_BUILD_TYPE=Release -DOpenCV_DIR=/opt/android/arm64-v8a/sdk/native/jni -DCMAKE_INSTALL_PREFIX=/opt/android/arm64-v8a ../..
|
cmake -DCMAKE_TOOLCHAIN_FILE=../../cmake_modules/android.toolchain.cmake -DANDROID_ABI=arm64-v8a -DBUILD_SHARED_LIBS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TOOLS=OFF -DCMAKE_BUILD_TYPE=Release -DOpenCV_DIR=$prefix/arm64-v8a/sdk/native/jni -DCMAKE_INSTALL_PREFIX=$prefix/arm64-v8a ../..
|
||||||
make
|
make
|
||||||
|
|
||||||
# package with binaries of both architectures
|
# package with binaries of both architectures
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
# Image: introlab3it/rtabmap:zesty
|
||||||
|
|
||||||
|
FROM ubuntu:17.04
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
libsqlite3-dev \
|
||||||
|
libpcl-dev \
|
||||||
|
libopencv-dev \
|
||||||
|
git \
|
||||||
|
cmake \
|
||||||
|
libproj-dev \
|
||||||
|
libqt5svg5-dev \
|
||||||
|
software-properties-common
|
||||||
|
|
||||||
|
# Issue: http://www.pcl-users.org/Build-failure-on-Ubuntu-17-04-td4044552.html
|
||||||
|
RUN sed -i 's|/usr/lib/libmpi.so;||g' /usr/lib/x86_64-linux-gnu/cmake/pcl/PCLConfig.cmake
|
||||||
|
|
||||||
|
# Clone source code
|
||||||
|
WORKDIR /root/
|
||||||
|
RUN git clone https://github.com/introlab/rtabmap.git
|
||||||
|
|
||||||
|
# Build RTAB-Map project
|
||||||
|
RUN cd rtabmap/build && \
|
||||||
|
cmake .. && \
|
||||||
|
make -j$(nproc) && \
|
||||||
|
make install && \
|
||||||
|
cd ../.. && \
|
||||||
|
rm -rf rtabmap && \
|
||||||
|
ldconfig
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
@@ -29,6 +29,12 @@ else()
|
|||||||
IF(NOT Qt5_FOUND)
|
IF(NOT Qt5_FOUND)
|
||||||
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtSvg)
|
FIND_PACKAGE(Qt4 COMPONENTS QtCore QtGui QtSvg)
|
||||||
ENDIF(NOT Qt5_FOUND)
|
ENDIF(NOT Qt5_FOUND)
|
||||||
|
|
||||||
|
# fix libproj.so not found on Xenial
|
||||||
|
if(NOT "${PCL_LIBRARIES}" STREQUAL "")
|
||||||
|
list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4")
|
||||||
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(POLICY CMP0020)
|
if(POLICY CMP0020)
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <pcl/io/pcd_io.h>
|
#include <pcl/io/pcd_io.h>
|
||||||
#include <pcl/io/ply_io.h>
|
#include <pcl/io/ply_io.h>
|
||||||
|
#include <pcl/filters/filter.h>
|
||||||
|
|
||||||
#include "MapBuilder.h"
|
#include "MapBuilder.h"
|
||||||
|
|
||||||
@@ -216,8 +217,14 @@ int main(int argc, char * argv[])
|
|||||||
node.sensorData(),
|
node.sensorData(),
|
||||||
4, // image decimation before creating the clouds
|
4, // image decimation before creating the clouds
|
||||||
4.0f, // maximum depth of the cloud
|
4.0f, // maximum depth of the cloud
|
||||||
0.01f); // Voxel grid filtering
|
0.0f);
|
||||||
*cloud += *util3d::transformPointCloud(tmp, iter->second); // transform the point cloud to its pose
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr tmpNoNaN(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||||
|
std::vector<int> index;
|
||||||
|
pcl::removeNaNFromPointCloud(*tmp, *tmpNoNaN, index);
|
||||||
|
if(!tmpNoNaN->empty())
|
||||||
|
{
|
||||||
|
*cloud += *util3d::transformPointCloud(tmpNoNaN, iter->second); // transform the point cloud to its pose
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(cloud->size())
|
if(cloud->size())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void configChanged();
|
void configChanged();
|
||||||
|
void mapShownRequested();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void restoreDefaults();
|
void restoreDefaults();
|
||||||
|
|||||||
@@ -161,7 +161,11 @@ ADD_LIBRARY(rtabmap_gui ${SRC_FILES})
|
|||||||
|
|
||||||
TARGET_LINK_LIBRARIES(rtabmap_gui rtabmap_core rtabmap_utilite ${LIBRARIES})
|
TARGET_LINK_LIBRARIES(rtabmap_gui rtabmap_core rtabmap_utilite ${LIBRARIES})
|
||||||
IF(Qt5_FOUND)
|
IF(Qt5_FOUND)
|
||||||
QT5_USE_MODULES(rtabmap_gui Widgets Core Gui Svg PrintSupport)
|
IF(Qt5Svg_FOUND)
|
||||||
|
QT5_USE_MODULES(rtabmap_gui Widgets Core Gui Svg PrintSupport)
|
||||||
|
ELSE()
|
||||||
|
QT5_USE_MODULES(rtabmap_gui Widgets Core Gui PrintSupport)
|
||||||
|
ENDIF()
|
||||||
ENDIF(Qt5_FOUND)
|
ENDIF(Qt5_FOUND)
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES(
|
SET_TARGET_PROPERTIES(
|
||||||
|
|||||||
@@ -296,6 +296,7 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
|
|||||||
connect(ui_->horizontalSlider_iterations, SIGNAL(sliderMoved(int)), this, SLOT(sliderIterationsValueChanged(int)));
|
connect(ui_->horizontalSlider_iterations, SIGNAL(sliderMoved(int)), this, SLOT(sliderIterationsValueChanged(int)));
|
||||||
connect(ui_->spinBox_optimizationsFrom, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
|
connect(ui_->spinBox_optimizationsFrom, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
|
||||||
connect(ui_->checkBox_spanAllMaps, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
|
connect(ui_->checkBox_spanAllMaps, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
|
||||||
|
connect(ui_->graphViewer, SIGNAL(mapShownRequested()), this, SLOT(updateGraphView()));
|
||||||
connect(ui_->checkBox_ignorePoseCorrection, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
|
connect(ui_->checkBox_ignorePoseCorrection, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
|
||||||
connect(ui_->checkBox_ignorePoseCorrection, SIGNAL(stateChanged(int)), this, SLOT(updateConstraintView()));
|
connect(ui_->checkBox_ignorePoseCorrection, SIGNAL(stateChanged(int)), this, SLOT(updateConstraintView()));
|
||||||
connect(ui_->checkBox_ignoreGlobalLoop, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
|
connect(ui_->checkBox_ignoreGlobalLoop, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
|
||||||
@@ -2559,6 +2560,7 @@ void DatabaseViewer::update(int value,
|
|||||||
if(!data.imageRaw().empty())
|
if(!data.imageRaw().empty())
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
||||||
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
if(!data.depthRaw().empty() && data.cameraModels().size()==1)
|
if(!data.depthRaw().empty() && data.cameraModels().size()==1)
|
||||||
{
|
{
|
||||||
cv::Mat depth = data.depthRaw();
|
cv::Mat depth = data.depthRaw();
|
||||||
@@ -2569,8 +2571,9 @@ void DatabaseViewer::update(int value,
|
|||||||
cloud = util3d::cloudFromDepthRGB(
|
cloud = util3d::cloudFromDepthRGB(
|
||||||
data.imageRaw(),
|
data.imageRaw(),
|
||||||
depth,
|
depth,
|
||||||
data.cameraModels()[0]);
|
data.cameraModels()[0],
|
||||||
if(cloud->size())
|
1,0,0,indices.get());
|
||||||
|
if(indices->size())
|
||||||
{
|
{
|
||||||
cloud = util3d::transformPointCloud(cloud, data.cameraModels()[0].localTransform());
|
cloud = util3d::transformPointCloud(cloud, data.cameraModels()[0].localTransform());
|
||||||
}
|
}
|
||||||
@@ -2578,13 +2581,13 @@ void DatabaseViewer::update(int value,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cloud = util3d::cloudRGBFromSensorData(data, 1, 0, 0, 0, ui_->parameters_toolbox->getParameters());
|
cloud = util3d::cloudRGBFromSensorData(data, 1, 0, 0, indices.get(), ui_->parameters_toolbox->getParameters());
|
||||||
}
|
}
|
||||||
if(cloud->size())
|
if(indices->size())
|
||||||
{
|
{
|
||||||
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
{
|
{
|
||||||
cloud = util3d::voxelize(cloud, ui_->doubleSpinBox_voxelSize->value());
|
cloud = util3d::voxelize(cloud, indices, ui_->doubleSpinBox_voxelSize->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ui_->checkBox_showMesh->isChecked() && !cloud->is_dense)
|
if(ui_->checkBox_showMesh->isChecked() && !cloud->is_dense)
|
||||||
@@ -2645,12 +2648,13 @@ void DatabaseViewer::update(int value,
|
|||||||
else if(ui_->checkBox_showCloud->isChecked())
|
else if(ui_->checkBox_showCloud->isChecked())
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
|
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
|
||||||
cloud = util3d::cloudFromSensorData(data, 1, 0, 0, 0, ui_->parameters_toolbox->getParameters());
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
if(cloud->size())
|
cloud = util3d::cloudFromSensorData(data, 1, 0, 0, indices.get(), ui_->parameters_toolbox->getParameters());
|
||||||
|
if(indices->size())
|
||||||
{
|
{
|
||||||
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
{
|
{
|
||||||
cloud = util3d::voxelize(cloud, ui_->doubleSpinBox_voxelSize->value());
|
cloud = util3d::voxelize(cloud, indices, ui_->doubleSpinBox_voxelSize->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
cloudViewer_->addCloud("cloud", cloud, pose);
|
cloudViewer_->addCloud("cloud", cloud, pose);
|
||||||
@@ -3498,15 +3502,15 @@ void DatabaseViewer::updateConstraintView(
|
|||||||
cloudTo=util3d::cloudRGBFromSensorData(dataTo, 1, 0, 0, indicesTo.get(), ui_->parameters_toolbox->getParameters());
|
cloudTo=util3d::cloudRGBFromSensorData(dataTo, 1, 0, 0, indicesTo.get(), ui_->parameters_toolbox->getParameters());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cloudTo.get() && cloudTo->size())
|
if(cloudTo.get() && indicesTo->size())
|
||||||
{
|
{
|
||||||
cloudTo = rtabmap::util3d::transformPointCloud(cloudTo, t);
|
cloudTo = rtabmap::util3d::transformPointCloud(cloudTo, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gain compensation
|
// Gain compensation
|
||||||
if(ui_->doubleSpinBox_gainCompensationRadius->value()>0.0 &&
|
if(ui_->doubleSpinBox_gainCompensationRadius->value()>0.0 &&
|
||||||
cloudFrom.get() && cloudFrom->size() &&
|
cloudFrom.get() && indicesFrom->size() &&
|
||||||
cloudTo.get() && cloudTo->size())
|
cloudTo.get() && indicesTo->size())
|
||||||
{
|
{
|
||||||
UTimer t;
|
UTimer t;
|
||||||
GainCompensator compensator(ui_->doubleSpinBox_gainCompensationRadius->value());
|
GainCompensator compensator(ui_->doubleSpinBox_gainCompensationRadius->value());
|
||||||
@@ -3516,19 +3520,19 @@ void DatabaseViewer::updateConstraintView(
|
|||||||
UINFO("Gain compensation time = %fs", t.ticks());
|
UINFO("Gain compensation time = %fs", t.ticks());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(cloudFrom.get() && cloudFrom->size())
|
if(cloudFrom.get() && indicesFrom->size())
|
||||||
{
|
{
|
||||||
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
{
|
{
|
||||||
cloudFrom = util3d::voxelize(cloudFrom, ui_->doubleSpinBox_voxelSize->value());
|
cloudFrom = util3d::voxelize(cloudFrom, indicesFrom, ui_->doubleSpinBox_voxelSize->value());
|
||||||
}
|
}
|
||||||
constraintsViewer_->addCloud("cloud0", cloudFrom, pose, Qt::red);
|
constraintsViewer_->addCloud("cloud0", cloudFrom, pose, Qt::red);
|
||||||
}
|
}
|
||||||
if(cloudTo.get() && cloudTo->size())
|
if(cloudTo.get() && indicesTo->size())
|
||||||
{
|
{
|
||||||
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
{
|
{
|
||||||
cloudTo = util3d::voxelize(cloudTo, ui_->doubleSpinBox_voxelSize->value());
|
cloudTo = util3d::voxelize(cloudTo, indicesTo, ui_->doubleSpinBox_voxelSize->value());
|
||||||
}
|
}
|
||||||
constraintsViewer_->addCloud("cloud1", cloudTo, pose, Qt::cyan);
|
constraintsViewer_->addCloud("cloud1", cloudTo, pose, Qt::cyan);
|
||||||
}
|
}
|
||||||
@@ -3751,45 +3755,51 @@ void DatabaseViewer::updateConstraintView(
|
|||||||
// Added loop closure scans
|
// Added loop closure scans
|
||||||
constraintsViewer_->removeCloud("scan0");
|
constraintsViewer_->removeCloud("scan0");
|
||||||
constraintsViewer_->removeCloud("scan1");
|
constraintsViewer_->removeCloud("scan1");
|
||||||
if(dataFrom.laserScanRaw().channels() == 6)
|
if(!dataFrom.laserScanRaw().empty())
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::PointNormal>::Ptr scan;
|
if(dataFrom.laserScanRaw().channels() == 6)
|
||||||
scan = rtabmap::util3d::laserScanToPointCloudNormal(dataFrom.laserScanRaw(), dataFrom.laserScanInfo().localTransform());
|
|
||||||
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
|
||||||
{
|
{
|
||||||
scan = util3d::voxelize(scan, ui_->doubleSpinBox_voxelSize->value());
|
pcl::PointCloud<pcl::PointNormal>::Ptr scan;
|
||||||
|
scan = rtabmap::util3d::laserScanToPointCloudNormal(dataFrom.laserScanRaw(), dataFrom.laserScanInfo().localTransform());
|
||||||
|
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
|
{
|
||||||
|
scan = util3d::voxelize(scan, ui_->doubleSpinBox_voxelSize->value());
|
||||||
|
}
|
||||||
|
constraintsViewer_->addCloud("scan0", scan, pose, Qt::yellow);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pcl::PointCloud<pcl::PointXYZ>::Ptr scan;
|
||||||
|
scan = rtabmap::util3d::laserScanToPointCloud(dataFrom.laserScanRaw(), dataFrom.laserScanInfo().localTransform());
|
||||||
|
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
|
{
|
||||||
|
scan = util3d::voxelize(scan, ui_->doubleSpinBox_voxelSize->value());
|
||||||
|
}
|
||||||
|
constraintsViewer_->addCloud("scan0", scan, pose, Qt::yellow);
|
||||||
}
|
}
|
||||||
constraintsViewer_->addCloud("scan0", scan, pose, Qt::yellow);
|
|
||||||
}
|
}
|
||||||
else
|
if(!dataTo.laserScanRaw().empty())
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr scan;
|
if(dataTo.laserScanRaw().channels() == 6)
|
||||||
scan = rtabmap::util3d::laserScanToPointCloud(dataFrom.laserScanRaw(), dataFrom.laserScanInfo().localTransform());
|
|
||||||
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
|
||||||
{
|
{
|
||||||
scan = util3d::voxelize(scan, ui_->doubleSpinBox_voxelSize->value());
|
pcl::PointCloud<pcl::PointNormal>::Ptr scan;
|
||||||
|
scan = rtabmap::util3d::laserScanToPointCloudNormal(dataTo.laserScanRaw(), t*dataTo.laserScanInfo().localTransform());
|
||||||
|
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
|
{
|
||||||
|
scan = util3d::voxelize(scan, ui_->doubleSpinBox_voxelSize->value());
|
||||||
|
}
|
||||||
|
constraintsViewer_->addCloud("scan1", scan, pose, Qt::magenta);
|
||||||
}
|
}
|
||||||
constraintsViewer_->addCloud("scan0", scan, pose, Qt::yellow);
|
else
|
||||||
}
|
|
||||||
if(dataTo.laserScanRaw().channels() == 6)
|
|
||||||
{
|
|
||||||
pcl::PointCloud<pcl::PointNormal>::Ptr scan;
|
|
||||||
scan = rtabmap::util3d::laserScanToPointCloudNormal(dataTo.laserScanRaw(), t*dataTo.laserScanInfo().localTransform());
|
|
||||||
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
|
||||||
{
|
{
|
||||||
scan = util3d::voxelize(scan, ui_->doubleSpinBox_voxelSize->value());
|
pcl::PointCloud<pcl::PointXYZ>::Ptr scan;
|
||||||
|
scan = rtabmap::util3d::laserScanToPointCloud(dataTo.laserScanRaw(), t*dataTo.laserScanInfo().localTransform());
|
||||||
|
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
|
{
|
||||||
|
scan = util3d::voxelize(scan, ui_->doubleSpinBox_voxelSize->value());
|
||||||
|
}
|
||||||
|
constraintsViewer_->addCloud("scan1", scan, pose, Qt::magenta);
|
||||||
}
|
}
|
||||||
constraintsViewer_->addCloud("scan1", scan, pose, Qt::magenta);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr scan;
|
|
||||||
scan = rtabmap::util3d::laserScanToPointCloud(dataTo.laserScanRaw(), t*dataTo.laserScanInfo().localTransform());
|
|
||||||
if(ui_->doubleSpinBox_voxelSize->value() > 0.0)
|
|
||||||
{
|
|
||||||
scan = util3d::voxelize(scan, ui_->doubleSpinBox_voxelSize->value());
|
|
||||||
}
|
|
||||||
constraintsViewer_->addCloud("scan1", scan, pose, Qt::magenta);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4090,7 +4100,7 @@ void DatabaseViewer::sliderIterationsValueChanged(int value)
|
|||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UINFO("Update local maps list... done");
|
UINFO("Update local maps list... done (%d local maps, graph size=%d)", (int)localMaps.size(), (int)graph.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_->graphViewer->updateGTGraph(groundTruthPoses_);
|
ui_->graphViewer->updateGTGraph(groundTruthPoses_);
|
||||||
@@ -4835,6 +4845,15 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent)
|
|||||||
toS->sensorData().setFeatures(std::vector<cv::KeyPoint>(), std::vector<cv::Point3f>(), cv::Mat());
|
toS->sensorData().setFeatures(std::vector<cv::KeyPoint>(), std::vector<cv::Point3f>(), cv::Mat());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(!reextractVisualFeatures && fromS->getWords().empty() && toS->getWords().empty())
|
||||||
|
{
|
||||||
|
UWARN("\"%s\" is false and signatures (%d and %d) don't have words, "
|
||||||
|
"registration will not be possible. Set \"%s\" to true.",
|
||||||
|
Parameters::kRGBDLoopClosureReextractFeatures().c_str(),
|
||||||
|
fromS->id(),
|
||||||
|
toS->id(),
|
||||||
|
Parameters::kRGBDLoopClosureReextractFeatures().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
t = reg->computeTransformationMod(*fromS, *toS, Transform(), &info);
|
t = reg->computeTransformationMod(*fromS, *toS, Transform(), &info);
|
||||||
delete reg;
|
delete reg;
|
||||||
|
|||||||
@@ -227,25 +227,54 @@ void DepthCalibrationDialog::calibrate(
|
|||||||
_ui->label_width->setText("NA");
|
_ui->label_width->setText("NA");
|
||||||
_ui->label_height->setText("NA");
|
_ui->label_height->setText("NA");
|
||||||
_imageSize = cv::Size();
|
_imageSize = cv::Size();
|
||||||
|
CameraModel model;
|
||||||
if(cachedSignatures.size())
|
if(cachedSignatures.size())
|
||||||
{
|
{
|
||||||
const Signature & s = cachedSignatures.begin().value();
|
const Signature & s = cachedSignatures.begin().value();
|
||||||
const SensorData & data = s.sensorData();
|
const SensorData & data = s.sensorData();
|
||||||
if(data.cameraModels().size() == 1 && data.cameraModels()[0].isValidForReprojection())
|
cv::Mat depth;
|
||||||
|
data.uncompressDataConst(0, &depth);
|
||||||
|
if(data.cameraModels().size() == 1 && data.cameraModels()[0].isValidForProjection() && !depth.empty())
|
||||||
{
|
{
|
||||||
_imageSize = data.cameraModels()[0].imageSize();
|
// use depth image size
|
||||||
_ui->label_width->setNum(data.cameraModels()[0].imageWidth());
|
_imageSize = depth.size();
|
||||||
_ui->label_height->setNum(data.cameraModels()[0].imageHeight());
|
_ui->label_width->setNum(_imageSize.width);
|
||||||
|
_ui->label_height->setNum(_imageSize.height);
|
||||||
|
|
||||||
if(data.cameraModels()[0].imageWidth() % _ui->spinBox_bin_width->value() != 0 ||
|
if(_imageSize.width % _ui->spinBox_bin_width->value() != 0 ||
|
||||||
data.cameraModels()[0].imageHeight() % _ui->spinBox_bin_height->value() != 0)
|
_imageSize.height % _ui->spinBox_bin_height->value() != 0)
|
||||||
{
|
{
|
||||||
size_t bin_width, bin_height;
|
size_t bin_width, bin_height;
|
||||||
clams::DiscreteDepthDistortionModel::getBinSize(data.cameraModels()[0].imageWidth(), data.cameraModels()[0].imageHeight(), bin_width, bin_height);
|
clams::DiscreteDepthDistortionModel::getBinSize(_imageSize.width, _imageSize.height, bin_width, bin_height);
|
||||||
_ui->spinBox_bin_width->setValue(bin_width);
|
_ui->spinBox_bin_width->setValue(bin_width);
|
||||||
_ui->spinBox_bin_height->setValue(bin_height);
|
_ui->spinBox_bin_height->setValue(bin_height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(data.cameraModels().size() > 1)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Depth Calibration"),tr("Multi-camera not supported!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(data.cameraModels().size() != 1)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Depth Calibration"), tr("Camera model not found."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(data.cameraModels().size() == 1 && !data.cameraModels()[0].isValidForProjection())
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Depth Calibration"), tr("Camera model %1 not valid for projection.").arg(s.id()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Depth Calibration"), tr("Depth image cannot be found in the cache, make sure to update cache before doing calibration."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this, tr("Depth Calibration"), tr("No signatures detected! Map is empty!?"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this->exec() == QDialog::Accepted)
|
if(this->exec() == QDialog::Accepted)
|
||||||
@@ -285,65 +314,63 @@ void DepthCalibrationDialog::calibrate(
|
|||||||
{
|
{
|
||||||
const Signature & s = cachedSignatures.find(iter->first).value();
|
const Signature & s = cachedSignatures.find(iter->first).value();
|
||||||
SensorData data = s.sensorData();
|
SensorData data = s.sensorData();
|
||||||
if(data.cameraModels().size() == 1 && data.cameraModels()[0].isValidForReprojection())
|
|
||||||
|
cv::Mat depth, laserScan;
|
||||||
|
data.uncompressData(0, &depth, _ui->checkBox_laserScan->isChecked()?&laserScan:0);
|
||||||
|
if(data.cameraModels().size() == 1 && data.cameraModels()[0].isValidForProjection() && !depth.empty())
|
||||||
{
|
{
|
||||||
cv::Mat image, depth, laserScan;
|
UASSERT(iter->first == data.id());
|
||||||
data.uncompressData(&image, &depth, _ui->checkBox_laserScan->isChecked()?&laserScan:0);
|
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
|
||||||
if(!image.empty() && !depth.empty())
|
|
||||||
|
if(_ui->checkBox_laserScan->isChecked())
|
||||||
{
|
{
|
||||||
UASSERT(iter->first == data.id());
|
cloud = util3d::laserScanToPointCloud(laserScan);
|
||||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud;
|
indices->resize(cloud->size());
|
||||||
|
for(unsigned int i=0; i<indices->size(); ++i)
|
||||||
if(_ui->checkBox_laserScan->isChecked())
|
|
||||||
{
|
{
|
||||||
cloud = util3d::laserScanToPointCloud(laserScan);
|
indices->at(i) = i;
|
||||||
indices->resize(cloud->size());
|
|
||||||
for(unsigned int i=0; i<indices->size(); ++i)
|
|
||||||
{
|
|
||||||
indices->at(i) = i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cloud = util3d::cloudFromSensorData(
|
||||||
|
data,
|
||||||
|
_ui->spinBox_decimation->value(),
|
||||||
|
_ui->doubleSpinBox_maxDepth->value(),
|
||||||
|
_ui->doubleSpinBox_minDepth->value(),
|
||||||
|
indices.get(),
|
||||||
|
parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(indices->size())
|
||||||
|
{
|
||||||
|
if(_ui->doubleSpinBox_voxelSize->value() > 0.0)
|
||||||
{
|
{
|
||||||
cloud = util3d::cloudFromSensorData(
|
cloud = util3d::voxelize(cloud, indices, _ui->doubleSpinBox_voxelSize->value());
|
||||||
data,
|
|
||||||
_ui->spinBox_decimation->value(),
|
|
||||||
_ui->doubleSpinBox_maxDepth->value(),
|
|
||||||
_ui->doubleSpinBox_minDepth->value(),
|
|
||||||
indices.get(),
|
|
||||||
parameters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(indices->size())
|
cloud = util3d::transformPointCloud(cloud, iter->second);
|
||||||
|
|
||||||
|
points+=cloud->size();
|
||||||
|
|
||||||
|
*map += *cloud;
|
||||||
|
|
||||||
|
sequence.insert(std::make_pair(iter->first, data));
|
||||||
|
|
||||||
|
cv::Size size = depth.size();
|
||||||
|
if(_model &&
|
||||||
|
(_model->getWidth()!=size.width ||
|
||||||
|
_model->getHeight()!=size.height))
|
||||||
{
|
{
|
||||||
if(_ui->doubleSpinBox_voxelSize->value() > 0.0)
|
QString msg = tr("Depth images (%1x%2) in the map don't have the "
|
||||||
{
|
"same size then in the current model (%3x%4). You may want "
|
||||||
cloud = util3d::voxelize(cloud, indices, _ui->doubleSpinBox_voxelSize->value());
|
"to check \"Reset previous model\" before trying again.")
|
||||||
}
|
.arg(size.width).arg(size.height)
|
||||||
|
.arg(_model->getWidth()).arg(_model->getHeight());
|
||||||
cloud = util3d::transformPointCloud(cloud, iter->second);
|
QMessageBox::warning(this, tr("Depth Calibration"), msg);
|
||||||
|
_progressDialog->appendText(msg, Qt::darkRed);
|
||||||
points+=cloud->size();
|
_progressDialog->setAutoClose(false);
|
||||||
|
return;
|
||||||
*map += *cloud;
|
|
||||||
|
|
||||||
sequence.insert(std::make_pair(iter->first, data));
|
|
||||||
|
|
||||||
cv::Size size = data.cameraModels()[0].imageSize();
|
|
||||||
if(_model &&
|
|
||||||
(_model->getWidth()!=size.width ||
|
|
||||||
_model->getHeight()!=size.height))
|
|
||||||
{
|
|
||||||
QString msg = tr("Depth images (%1x%2) in the map don't have the "
|
|
||||||
"same size then in the current model (%3x%4). You may want "
|
|
||||||
"to check \"Reset previous model\" before trying again.")
|
|
||||||
.arg(size.width).arg(size.height)
|
|
||||||
.arg(_model->getWidth()).arg(_model->getHeight());
|
|
||||||
QMessageBox::warning(this, tr("Depth Calibration"), msg);
|
|
||||||
_progressDialog->appendText(msg, Qt::darkRed);
|
|
||||||
_progressDialog->setAutoClose(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -434,7 +461,7 @@ void DepthCalibrationDialog::calibrate(
|
|||||||
QDialog * dialog = new QDialog(this->parentWidget()?this->parentWidget():this, Qt::Window);
|
QDialog * dialog = new QDialog(this->parentWidget()?this->parentWidget():this, Qt::Window);
|
||||||
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
|
dialog->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||||
dialog->setWindowTitle(tr("Original/Map"));
|
dialog->setWindowTitle(tr("Original/Map"));
|
||||||
dialog->setMinimumWidth(sequence.begin()->second.cameraModels()[0].imageWidth());
|
dialog->setMinimumWidth(_imageSize.width);
|
||||||
ImageView * imageView1 = new ImageView(dialog);
|
ImageView * imageView1 = new ImageView(dialog);
|
||||||
imageView1->setMinimumSize(320, 240);
|
imageView1->setMinimumSize(320, 240);
|
||||||
ImageView * imageView2 = new ImageView(dialog);
|
ImageView * imageView2 = new ImageView(dialog);
|
||||||
@@ -450,7 +477,7 @@ void DepthCalibrationDialog::calibrate(
|
|||||||
}
|
}
|
||||||
|
|
||||||
//clams::DiscreteDepthDistortionModel model = clams::calibrate(sequence, poses, map);
|
//clams::DiscreteDepthDistortionModel model = clams::calibrate(sequence, poses, map);
|
||||||
const cv::Size & imageSize = sequence.begin()->second.cameraModels()[0].imageSize();
|
const cv::Size & imageSize = _imageSize;
|
||||||
if(_model == 0)
|
if(_model == 0)
|
||||||
{
|
{
|
||||||
size_t bin_width = _ui->spinBox_bin_width->value();
|
size_t bin_width = _ui->spinBox_bin_width->value();
|
||||||
@@ -487,24 +514,33 @@ void DepthCalibrationDialog::calibrate(
|
|||||||
cv::Mat depthImage;
|
cv::Mat depthImage;
|
||||||
ster->second.uncompressDataConst(0, &depthImage);
|
ster->second.uncompressDataConst(0, &depthImage);
|
||||||
|
|
||||||
cv::Mat mapDepth;
|
if(ster->second.cameraModels().size() == 1 && ster->second.cameraModels()[0].isValidForProjection() && !depthImage.empty())
|
||||||
clams::FrameProjector projector(ster->second.cameraModels()[0]);
|
|
||||||
mapDepth = projector.estimateMapDepth(
|
|
||||||
map,
|
|
||||||
iter->second.inverse(),
|
|
||||||
depthImage,
|
|
||||||
_ui->doubleSpinBox_coneRadius->value(),
|
|
||||||
_ui->doubleSpinBox_coneStdDevThresh->value());
|
|
||||||
|
|
||||||
if(ULogger::level() == ULogger::kDebug)
|
|
||||||
{
|
{
|
||||||
imageView1->setImage(uCvMat2QImage(depthImage));
|
cv::Mat mapDepth;
|
||||||
imageView2->setImage(uCvMat2QImage(mapDepth));
|
CameraModel model = ster->second.cameraModels()[0];
|
||||||
}
|
if(model.imageWidth() != depthImage.cols)
|
||||||
|
{
|
||||||
|
UASSERT_MSG(model.imageHeight() % depthImage.rows == 0, uFormat("rgb=%d depth=%d", model.imageHeight(), depthImage.rows).c_str());
|
||||||
|
model = model.scaled(double(depthImage.rows) / double(model.imageHeight()));
|
||||||
|
}
|
||||||
|
clams::FrameProjector projector(model);
|
||||||
|
mapDepth = projector.estimateMapDepth(
|
||||||
|
map,
|
||||||
|
iter->second.inverse(),
|
||||||
|
depthImage,
|
||||||
|
_ui->doubleSpinBox_coneRadius->value(),
|
||||||
|
_ui->doubleSpinBox_coneStdDevThresh->value());
|
||||||
|
|
||||||
counts = _model->accumulate(mapDepth, depthImage);
|
if(ULogger::level() == ULogger::kDebug)
|
||||||
_progressDialog->appendText(tr("Added %1 training examples from node %2 (%3/%4).").arg(counts).arg(iter->first).arg(++index).arg(sequence.size()));
|
{
|
||||||
}
|
imageView1->setImage(uCvMat2QImage(depthImage));
|
||||||
|
imageView2->setImage(uCvMat2QImage(mapDepth));
|
||||||
|
}
|
||||||
|
|
||||||
|
counts = _model->accumulate(mapDepth, depthImage);
|
||||||
|
_progressDialog->appendText(tr("Added %1 training examples from node %2 (%3/%4).").arg(counts).arg(iter->first).arg(++index).arg(sequence.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
_progressDialog->incrementStep();
|
_progressDialog->incrementStep();
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <QtGui/QDesktopServices>
|
#include <QtGui/QDesktopServices>
|
||||||
#include <QtGui/QContextMenuEvent>
|
#include <QtGui/QContextMenuEvent>
|
||||||
#include <QColorDialog>
|
#include <QColorDialog>
|
||||||
|
#ifdef QT_SVG_LIB
|
||||||
#include <QtSvg/QSvgGenerator>
|
#include <QtSvg/QSvgGenerator>
|
||||||
|
#endif
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
@@ -1176,19 +1178,19 @@ void GraphViewer::setMaxLinkLength(float value)
|
|||||||
}
|
}
|
||||||
void GraphViewer::setGraphVisible(bool visible)
|
void GraphViewer::setGraphVisible(bool visible)
|
||||||
{
|
{
|
||||||
_graphRoot->setVisible(!_graphRoot->isVisible());
|
_graphRoot->setVisible(visible);
|
||||||
}
|
}
|
||||||
void GraphViewer::setGlobalPathVisible(bool visible)
|
void GraphViewer::setGlobalPathVisible(bool visible)
|
||||||
{
|
{
|
||||||
_globalPathRoot->setVisible(!_globalPathRoot->isVisible());
|
_globalPathRoot->setVisible(visible);
|
||||||
}
|
}
|
||||||
void GraphViewer::setLocalPathVisible(bool visible)
|
void GraphViewer::setLocalPathVisible(bool visible)
|
||||||
{
|
{
|
||||||
_localPathRoot->setVisible(!_localPathRoot->isVisible());
|
_localPathRoot->setVisible(visible);
|
||||||
}
|
}
|
||||||
void GraphViewer::setGtGraphVisible(bool visible)
|
void GraphViewer::setGtGraphVisible(bool visible)
|
||||||
{
|
{
|
||||||
_gtGraphRoot->setVisible(!_gtGraphRoot->isVisible());
|
_gtGraphRoot->setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphViewer::restoreDefaults()
|
void GraphViewer::restoreDefaults()
|
||||||
@@ -1233,6 +1235,9 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
|
|||||||
QMenu menu;
|
QMenu menu;
|
||||||
QAction * aScreenShotPNG = menu.addAction(tr("Take a screenshot (PNG)"));
|
QAction * aScreenShotPNG = menu.addAction(tr("Take a screenshot (PNG)"));
|
||||||
QAction * aScreenShotSVG = menu.addAction(tr("Take a screenshot (SVG)"));
|
QAction * aScreenShotSVG = menu.addAction(tr("Take a screenshot (SVG)"));
|
||||||
|
#ifndef QT_SVG_LIB
|
||||||
|
aScreenShotSVG->setEnabled(false);
|
||||||
|
#endif
|
||||||
menu.addSeparator();
|
menu.addSeparator();
|
||||||
|
|
||||||
QAction * aChangeNodeColor = menu.addAction(createIcon(_nodeColor), tr("Set node color..."));
|
QAction * aChangeNodeColor = menu.addAction(createIcon(_nodeColor), tr("Set node color..."));
|
||||||
@@ -1361,7 +1366,6 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
|
|||||||
{
|
{
|
||||||
aShowHideGtGraph = menu.addAction(tr("Show ground truth graph"));
|
aShowHideGtGraph = menu.addAction(tr("Show ground truth graph"));
|
||||||
}
|
}
|
||||||
aShowHideGridMap->setEnabled(!_gridMap->pixmap().isNull());
|
|
||||||
aShowHideGraph->setEnabled(_nodeItems.size());
|
aShowHideGraph->setEnabled(_nodeItems.size());
|
||||||
aShowHideGlobalPath->setEnabled(_globalPathLinkItems.size());
|
aShowHideGlobalPath->setEnabled(_globalPathLinkItems.size());
|
||||||
aShowHideLocalPath->setEnabled(_localPathLinkItems.size());
|
aShowHideLocalPath->setEnabled(_localPathLinkItems.size());
|
||||||
@@ -1423,6 +1427,7 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef QT_SVG_LIB
|
||||||
QSvgGenerator svgGen;
|
QSvgGenerator svgGen;
|
||||||
|
|
||||||
svgGen.setFileName( targetDir + name );
|
svgGen.setFileName( targetDir + name );
|
||||||
@@ -1434,6 +1439,9 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
|
|||||||
QPainter painter( &svgGen );
|
QPainter painter( &svgGen );
|
||||||
|
|
||||||
this->scene()->render(&painter);
|
this->scene()->render(&painter);
|
||||||
|
#else
|
||||||
|
UERROR("RTAB-MAp is not built with Qt's SVG library, cannot save picture in svg format.");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//reset scale
|
//reset scale
|
||||||
@@ -1626,6 +1634,10 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
|
|||||||
else if(r == aShowHideGridMap)
|
else if(r == aShowHideGridMap)
|
||||||
{
|
{
|
||||||
this->setGridMapVisible(!this->isGridMapVisible());
|
this->setGridMapVisible(!this->isGridMapVisible());
|
||||||
|
if(_gridMap->isVisible())
|
||||||
|
{
|
||||||
|
emit mapShownRequested();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(r == aShowHideOrigin)
|
else if(r == aShowHideOrigin)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5008,9 +5008,11 @@ void MainWindow::postProcessing()
|
|||||||
bool optimizeFromGraphEnd = Parameters::defaultRGBDOptimizeFromGraphEnd();
|
bool optimizeFromGraphEnd = Parameters::defaultRGBDOptimizeFromGraphEnd();
|
||||||
float optimizeMaxError = Parameters::defaultRGBDOptimizeMaxError();
|
float optimizeMaxError = Parameters::defaultRGBDOptimizeMaxError();
|
||||||
int optimizeIterations = Parameters::defaultOptimizerIterations();
|
int optimizeIterations = Parameters::defaultOptimizerIterations();
|
||||||
|
bool reextractFeatures = Parameters::defaultRGBDLoopClosureReextractFeatures();
|
||||||
Parameters::parse(parameters, Parameters::kRGBDOptimizeFromGraphEnd(), optimizeFromGraphEnd);
|
Parameters::parse(parameters, Parameters::kRGBDOptimizeFromGraphEnd(), optimizeFromGraphEnd);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDOptimizeMaxError(), optimizeMaxError);
|
Parameters::parse(parameters, Parameters::kRGBDOptimizeMaxError(), optimizeMaxError);
|
||||||
Parameters::parse(parameters, Parameters::kOptimizerIterations(), optimizeIterations);
|
Parameters::parse(parameters, Parameters::kOptimizerIterations(), optimizeIterations);
|
||||||
|
Parameters::parse(parameters, Parameters::kRGBDLoopClosureReextractFeatures(), reextractFeatures);
|
||||||
|
|
||||||
bool warn = false;
|
bool warn = false;
|
||||||
int loopClosuresAdded = 0;
|
int loopClosuresAdded = 0;
|
||||||
@@ -5089,6 +5091,40 @@ void MainWindow::postProcessing()
|
|||||||
uInsert(parameters, ParametersPair(Parameters::kRegStrategy(), "2"));
|
uInsert(parameters, ParametersPair(Parameters::kRegStrategy(), "2"));
|
||||||
}
|
}
|
||||||
Registration * registration = Registration::create(parameters);
|
Registration * registration = Registration::create(parameters);
|
||||||
|
|
||||||
|
if(reextractFeatures)
|
||||||
|
{
|
||||||
|
signatureFrom.sensorData().uncompressData();
|
||||||
|
signatureTo.sensorData().uncompressData();
|
||||||
|
|
||||||
|
if(signatureFrom.sensorData().imageRaw().empty() &&
|
||||||
|
signatureTo.sensorData().imageRaw().empty())
|
||||||
|
{
|
||||||
|
UWARN("\"%s\" is false and signatures (%d and %d) don't have raw "
|
||||||
|
"images. Update the cache.",
|
||||||
|
Parameters::kRGBDLoopClosureReextractFeatures().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
signatureFrom.setWords(std::multimap<int, cv::KeyPoint>());
|
||||||
|
signatureFrom.setWords3(std::multimap<int, cv::Point3f>());
|
||||||
|
signatureFrom.setWordsDescriptors(std::multimap<int, cv::Mat>());
|
||||||
|
signatureFrom.sensorData().setFeatures(std::vector<cv::KeyPoint>(), std::vector<cv::Point3f>(), cv::Mat());
|
||||||
|
signatureTo.setWords(std::multimap<int, cv::KeyPoint>());
|
||||||
|
signatureTo.setWords3(std::multimap<int, cv::Point3f>());
|
||||||
|
signatureTo.setWordsDescriptors(std::multimap<int, cv::Mat>());
|
||||||
|
signatureTo.sensorData().setFeatures(std::vector<cv::KeyPoint>(), std::vector<cv::Point3f>(), cv::Mat());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!reextractFeatures && signatureFrom.getWords().empty() && signatureTo.getWords().empty())
|
||||||
|
{
|
||||||
|
UWARN("\"%s\" is false and signatures (%d and %d) don't have words, "
|
||||||
|
"registration will not be possible. Set \"%s\" to true.",
|
||||||
|
Parameters::kRGBDLoopClosureReextractFeatures().c_str(),
|
||||||
|
signatureFrom.id(),
|
||||||
|
signatureTo.id(),
|
||||||
|
Parameters::kRGBDLoopClosureReextractFeatures().c_str());
|
||||||
|
}
|
||||||
transform = registration->computeTransformation(signatureFrom, signatureTo, Transform(), &info);
|
transform = registration->computeTransformation(signatureFrom, signatureTo, Transform(), &info);
|
||||||
delete registration;
|
delete registration;
|
||||||
if(!transform.isNull())
|
if(!transform.isNull())
|
||||||
@@ -5218,13 +5254,13 @@ void MainWindow::postProcessing()
|
|||||||
_currentLinksMap.insert(std::make_pair(from, Link(from, to, Link::kUserClosure, transform, info.covariance.inv())));
|
_currentLinksMap.insert(std::make_pair(from, Link(from, to, Link::kUserClosure, transform, info.covariance.inv())));
|
||||||
++loopClosuresAdded;
|
++loopClosuresAdded;
|
||||||
_initProgressDialog->appendText(tr("Detected loop closure %1->%2! (%3/%4)").arg(from).arg(to).arg(i+1).arg(clusters.size()));
|
_initProgressDialog->appendText(tr("Detected loop closure %1->%2! (%3/%4)").arg(from).arg(to).arg(i+1).arg(clusters.size()));
|
||||||
QApplication::processEvents();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QApplication::processEvents();
|
||||||
_initProgressDialog->incrementStep();
|
_initProgressDialog->incrementStep();
|
||||||
}
|
}
|
||||||
_initProgressDialog->appendText(tr("Iteration %1/%2: Detected %3 loop closures!").arg(n+1).arg(detectLoopClosureIterations).arg(addedLinks.size()/2));
|
_initProgressDialog->appendText(tr("Iteration %1/%2: Detected %3 loop closures!").arg(n+1).arg(detectLoopClosureIterations).arg(addedLinks.size()/2));
|
||||||
|
|||||||
@@ -197,8 +197,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
#if CV_MAJOR_VERSION >= 3
|
#if CV_MAJOR_VERSION >= 3
|
||||||
_ui->groupBox_fast_opencv2->setEnabled(false);
|
_ui->groupBox_fast_opencv2->setEnabled(false);
|
||||||
#else
|
#else
|
||||||
_ui->comboBox_detector_strategy->setItemData(9, 0, Qt::UserRole - 1); // No FREAK (detector+descriptor version)
|
_ui->comboBox_detector_strategy->setItemData(9, 0, Qt::UserRole - 1); // No KAZE
|
||||||
_ui->reextract_type->setItemData(9, 0, Qt::UserRole - 1); // No FREAK (detector+descriptor version)
|
_ui->reextract_type->setItemData(9, 0, Qt::UserRole - 1); // No KAZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_ui->comboBox_cameraImages_odomFormat->setItemData(4, 0, Qt::UserRole - 1);
|
_ui->comboBox_cameraImages_odomFormat->setItemData(4, 0, Qt::UserRole - 1);
|
||||||
@@ -746,8 +746,16 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
_ui->spinBox_BRISK_octaves->setObjectName(Parameters::kBRISKOctaves().c_str());
|
_ui->spinBox_BRISK_octaves->setObjectName(Parameters::kBRISKOctaves().c_str());
|
||||||
_ui->doubleSpinBox_BRISK_patterScale->setObjectName(Parameters::kBRISKPatternScale().c_str());
|
_ui->doubleSpinBox_BRISK_patterScale->setObjectName(Parameters::kBRISKPatternScale().c_str());
|
||||||
|
|
||||||
|
//KAZE
|
||||||
|
_ui->checkBox_kaze_extended->setObjectName(Parameters::kKAZEExtended().c_str());
|
||||||
|
_ui->checkBox_kaze_upright->setObjectName(Parameters::kKAZEUpright().c_str());
|
||||||
|
_ui->doubleSpinBox_kaze_threshold->setObjectName(Parameters::kKAZEThreshold().c_str());
|
||||||
|
_ui->spinBox_kaze_octaves->setObjectName(Parameters::kKAZENOctaves().c_str());
|
||||||
|
_ui->spinBox_kaze_octavelayers->setObjectName(Parameters::kKAZENOctaveLayers().c_str());
|
||||||
|
_ui->spinBox_kaze_diffusivity->setObjectName(Parameters::kKAZEDiffusivity().c_str());
|
||||||
|
|
||||||
// verifyHypotheses
|
// verifyHypotheses
|
||||||
_ui->comboBox_vh_strategy->setObjectName(Parameters::kRtabmapVhStrategy().c_str());
|
_ui->groupBox_vh_epipolar2->setObjectName(Parameters::kVhEpEnabled().c_str());
|
||||||
_ui->surf_spinBox_matchCountMinAccepted->setObjectName(Parameters::kVhEpMatchCountMin().c_str());
|
_ui->surf_spinBox_matchCountMinAccepted->setObjectName(Parameters::kVhEpMatchCountMin().c_str());
|
||||||
_ui->surf_doubleSpinBox_ransacParam1->setObjectName(Parameters::kVhEpRansacParam1().c_str());
|
_ui->surf_doubleSpinBox_ransacParam1->setObjectName(Parameters::kVhEpRansacParam1().c_str());
|
||||||
_ui->surf_doubleSpinBox_ransacParam2->setObjectName(Parameters::kVhEpRansacParam2().c_str());
|
_ui->surf_doubleSpinBox_ransacParam2->setObjectName(Parameters::kVhEpRansacParam2().c_str());
|
||||||
@@ -1603,6 +1611,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
|||||||
if(groupBox->objectName() == _ui->groupBox_odometry1->objectName())
|
if(groupBox->objectName() == _ui->groupBox_odometry1->objectName())
|
||||||
{
|
{
|
||||||
_ui->odom_registration->setCurrentIndex(3);
|
_ui->odom_registration->setCurrentIndex(3);
|
||||||
|
updateOdometryVisibility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2363,19 +2372,33 @@ bool PreferencesDialog::validateForm()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CV_MAJOR_VERSION < 3
|
#if CV_MAJOR_VERSION < 3
|
||||||
if (_ui->comboBox_detector_strategy->currentIndex() == Feature2D::kFeatureFreak)
|
if (_ui->comboBox_detector_strategy->currentIndex() == Feature2D::kFeatureKaze)
|
||||||
{
|
{
|
||||||
|
#ifdef RTABMAP_NONFREE
|
||||||
QMessageBox::warning(this, tr("Parameter warning"),
|
QMessageBox::warning(this, tr("Parameter warning"),
|
||||||
tr("Selected feature type (FREAK detector) is not available on OpenCV2. ORB is set instead "
|
tr("Selected feature type (KAZE) is not available on OpenCV2. SURF is set instead "
|
||||||
|
"for the bag-of-words dictionary."));
|
||||||
|
_ui->comboBox_detector_strategy->setCurrentIndex(Feature2D::kFeatureSurf);
|
||||||
|
#else
|
||||||
|
QMessageBox::warning(this, tr("Parameter warning"),
|
||||||
|
tr("Selected feature type (KAZE) is not available on OpenCV2. ORB is set instead "
|
||||||
"for the bag-of-words dictionary."));
|
"for the bag-of-words dictionary."));
|
||||||
_ui->comboBox_detector_strategy->setCurrentIndex(Feature2D::kFeatureOrb);
|
_ui->comboBox_detector_strategy->setCurrentIndex(Feature2D::kFeatureOrb);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (_ui->reextract_type->currentIndex() == Feature2D::kFeatureFreak)
|
if (_ui->reextract_type->currentIndex() == Feature2D::kFeatureKaze)
|
||||||
{
|
{
|
||||||
|
#ifdef RTABMAP_NONFREE
|
||||||
QMessageBox::warning(this, tr("Parameter warning"),
|
QMessageBox::warning(this, tr("Parameter warning"),
|
||||||
tr("Selected feature type (FREAK detector) is not available on OpenCV2. ORB is set instead "
|
tr("Selected feature type (KAZE) is not available on OpenCV2. SURF is set instead "
|
||||||
|
"for the re-extraction of features on loop closure."));
|
||||||
|
_ui->reextract_type->setCurrentIndex(Feature2D::kFeatureSurf);
|
||||||
|
#else
|
||||||
|
QMessageBox::warning(this, tr("Parameter warning"),
|
||||||
|
tr("Selected feature type (KAZE) is not available on OpenCV2. ORB is set instead "
|
||||||
"for the re-extraction of features on loop closure."));
|
"for the re-extraction of features on loop closure."));
|
||||||
_ui->reextract_type->setCurrentIndex(Feature2D::kFeatureOrb);
|
_ui->reextract_type->setCurrentIndex(Feature2D::kFeatureOrb);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+264
-134
@@ -63,7 +63,7 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>-637</y>
|
<y>0</y>
|
||||||
<width>678</width>
|
<width>678</width>
|
||||||
<height>2739</height>
|
<height>2739</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>18</number>
|
<number>34</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_22">
|
<widget class="QWidget" name="page_22">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||||
@@ -6732,7 +6732,7 @@ generate the number of words requested.</string>
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>FREAK</string>
|
<string>KAZE</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -7480,13 +7480,13 @@ see Sqlite3 doc 'PRAGMA temp_store'.</string>
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_23">
|
<widget class="QWidget" name="page_23">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_bayes1">
|
<widget class="QGroupBox" name="groupBox_bayes1">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Loop Closure Detection</string>
|
<string>Loop Closure Detection</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_22">
|
<layout class="QVBoxLayout" name="verticalLayout_22" stretch="0,0,0,1,0,0">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -7630,139 +7630,96 @@ see Sqlite3 doc 'PRAGMA temp_store'.</string>
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_vh_strategy2">
|
<widget class="QGroupBox" name="groupBox_vh_epipolar2">
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Hypothesis Verification</string>
|
<string>Hypothesis Verification</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<property name="checkable">
|
||||||
<item>
|
<bool>true</bool>
|
||||||
<layout class="QGridLayout" name="gridLayout_10" columnstretch="0,1">
|
</property>
|
||||||
<item row="0" column="0">
|
<layout class="QGridLayout" name="gridLayout" columnstretch="0,10">
|
||||||
<widget class="QComboBox" name="comboBox_vh_strategy">
|
<item row="0" column="0">
|
||||||
<property name="sizeAdjustPolicy">
|
<widget class="QSpinBox" name="surf_spinBox_matchCountMinAccepted">
|
||||||
<enum>QComboBox::AdjustToContents</enum>
|
<property name="minimum">
|
||||||
</property>
|
<number>8</number>
|
||||||
<item>
|
</property>
|
||||||
<property name="text">
|
<property name="maximum">
|
||||||
<string>No verification</string>
|
<number>100000</number>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<property name="value">
|
||||||
<item>
|
<number>11</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Epipolar constraints</string>
|
</widget>
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="label_50">
|
|
||||||
<property name="text">
|
|
||||||
<string>Hypothesis verification.</string>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="0" column="1">
|
||||||
<widget class="QGroupBox" name="groupBox_vh_epipolar2">
|
<widget class="QLabel" name="label_25">
|
||||||
<property name="title">
|
<property name="text">
|
||||||
<string>Epipolar Constraints</string>
|
<string>Minimum match count to accept a loop closure.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="surf_doubleSpinBox_ransacParam1">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>10.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.100000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>3.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_27">
|
||||||
|
<property name="text">
|
||||||
|
<string>Fundamental Matrix : Distance (pixels) for inliers.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="surf_doubleSpinBox_ransacParam2">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>0.990000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.990000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="label_28">
|
||||||
|
<property name="text">
|
||||||
|
<string>Fundamental Matrix : Ransac performance.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,10">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QSpinBox" name="surf_spinBox_matchCountMinAccepted">
|
|
||||||
<property name="minimum">
|
|
||||||
<number>8</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>100000</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>11</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="label_25">
|
|
||||||
<property name="text">
|
|
||||||
<string>Minimum match count to accept a loop closure.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="surf_doubleSpinBox_ransacParam1">
|
|
||||||
<property name="decimals">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>10.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.100000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>3.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="label_27">
|
|
||||||
<property name="text">
|
|
||||||
<string>Fundamental Matrix : Distance (pixels) for inliers.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="surf_doubleSpinBox_ransacParam2">
|
|
||||||
<property name="decimals">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>0.990000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.010000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.990000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="label_28">
|
|
||||||
<property name="text">
|
|
||||||
<string>Fundamental Matrix : Ransac performance.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@@ -13288,7 +13245,7 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
|||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>FREAK</string>
|
<string>KAZE</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
@@ -15906,6 +15863,179 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_71">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_detector_kaze2">
|
||||||
|
<property name="title">
|
||||||
|
<string>KAZE</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_95" columnstretch="0,1">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_kaze_extended">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_420">
|
||||||
|
<property name="text">
|
||||||
|
<string>Set to enable use of upright descriptors (non rotation-invariant).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_416">
|
||||||
|
<property name="text">
|
||||||
|
<string>Maximum octave evolution of the image.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_kaze_upright">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLabel" name="label_417">
|
||||||
|
<property name="text">
|
||||||
|
<string>Default number of sublevels per scale level.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QSpinBox" name="spinBox_kaze_octavelayers">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>16</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QSpinBox" name="spinBox_kaze_octaves">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>16</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>16</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLabel" name="label_419">
|
||||||
|
<property name="text">
|
||||||
|
<string>Set to enable extraction of extended (128-byte) descriptor.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_kaze_threshold">
|
||||||
|
<property name="decimals">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000100000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>9999.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.001000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLabel" name="label_418">
|
||||||
|
<property name="text">
|
||||||
|
<string>Detector response threshold to accept point.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="label_421">
|
||||||
|
<property name="text">
|
||||||
|
<string>Diffusivity type: 0=DIFF_PM_G1, 1=DIFF_PM_G2, 2=DIFF_WEICKERT or 3=DIFF_CHARBONNIER.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QSpinBox" name="spinBox_kaze_diffusivity">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_65">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>2487</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<package>
|
<package>
|
||||||
<name>rtabmap</name>
|
<name>rtabmap</name>
|
||||||
<version>0.13.0</version>
|
<version>0.13.2</version>
|
||||||
<description>RTAB-Map's standalone library. RTAB-Map is a RGB-D SLAM approach with real-time constraints.</description>
|
<description>RTAB-Map's standalone library. RTAB-Map is a RGB-D SLAM approach with real-time constraints.</description>
|
||||||
<maintainer email="matlabbe@gmail.com">Mathieu Labbe</maintainer>
|
<maintainer email="matlabbe@gmail.com">Mathieu Labbe</maintainer>
|
||||||
<author>Mathieu Labbe</author>
|
<author>Mathieu Labbe</author>
|
||||||
|
|||||||
@@ -6,4 +6,7 @@ if(UNIX AND NOT ANDROID)
|
|||||||
ENDIF(UNIX AND NOT ANDROID)
|
ENDIF(UNIX AND NOT ANDROID)
|
||||||
|
|
||||||
ADD_SUBDIRECTORY( src )
|
ADD_SUBDIRECTORY( src )
|
||||||
ADD_SUBDIRECTORY( resource_generator )
|
|
||||||
|
IF(NOT ANDROID)
|
||||||
|
ADD_SUBDIRECTORY( resource_generator )
|
||||||
|
ENDIF(NOT ANDROID)
|
||||||
Reference in New Issue
Block a user