mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Tango: Added "Adjust colors" post-processing option. Updated ICP parameters. Added "Mem/LaserScanNormalK" parameter for convenience.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<!-- BEGIN_INCLUDE(manifest) -->
|
<!-- BEGIN_INCLUDE(manifest) -->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.introlab.rtabmap"
|
package="com.introlab.rtabmap"
|
||||||
android:versionCode="10"
|
android:versionCode="11"
|
||||||
android:versionName="@RTABMAP_VERSION@">
|
android:versionName="@RTABMAP_VERSION@">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/core/Optimizer.h>
|
#include <rtabmap/core/Optimizer.h>
|
||||||
#include <rtabmap/core/VWDictionary.h>
|
#include <rtabmap/core/VWDictionary.h>
|
||||||
#include <rtabmap/core/Memory.h>
|
#include <rtabmap/core/Memory.h>
|
||||||
|
#include <rtabmap/core/GainCompensator.h>
|
||||||
#include <pcl/filters/extract_indices.h>
|
#include <pcl/filters/extract_indices.h>
|
||||||
#include <pcl/io/ply_io.h>
|
#include <pcl/io/ply_io.h>
|
||||||
#include <pcl/io/obj_io.h>
|
#include <pcl/io/obj_io.h>
|
||||||
@@ -90,10 +91,13 @@ rtabmap::ParametersMap RTABMapApp::getRtabmapParameters()
|
|||||||
|
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRGBDNeighborLinkRefining(), uBool2Str(driftCorrection_)));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRGBDNeighborLinkRefining(), uBool2Str(driftCorrection_)));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRegStrategy(), std::string(driftCorrection_?"1":"0")));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kRegStrategy(), std::string(driftCorrection_?"1":"0")));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpPointToPlane(), std::string("false")));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpPointToPlane(), std::string("true")));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpPointToPlaneNormalNeighbors(), std::string("6")));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kMemLaserScanNormalK(), std::string("6")));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpIterations(), std::string("10")));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpIterations(), std::string("10")));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpEpsilon(), std::string("0.001")));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpEpsilon(), std::string("0.001")));
|
||||||
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpMaxRotation(), std::string("0.17"))); // 10 degrees
|
||||||
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpMaxTranslation(), std::string("0.05")));
|
||||||
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpCorrespondenceRatio(), std::string("0.3")));
|
||||||
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpMaxCorrespondenceDistance(), std::string("0.05")));
|
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kIcpMaxCorrespondenceDistance(), std::string("0.05")));
|
||||||
|
|
||||||
return parameters;
|
return parameters;
|
||||||
@@ -117,6 +121,7 @@ RTABMapApp::RTABMapApp() :
|
|||||||
meshAngleToleranceDeg_(15.0),
|
meshAngleToleranceDeg_(15.0),
|
||||||
clearSceneOnNextRender_(false),
|
clearSceneOnNextRender_(false),
|
||||||
filterPolygonsOnNextRender_(false),
|
filterPolygonsOnNextRender_(false),
|
||||||
|
gainCompensationOnNextRender_(false),
|
||||||
totalPoints_(0),
|
totalPoints_(0),
|
||||||
totalPolygons_(0),
|
totalPolygons_(0),
|
||||||
lastDrawnCloudsCount_(0),
|
lastDrawnCloudsCount_(0),
|
||||||
@@ -171,8 +176,6 @@ void RTABMapApp::onCreate(JNIEnv* env, jobject caller_activity)
|
|||||||
{
|
{
|
||||||
logHandler_ = new LogHandler();
|
logHandler_ = new LogHandler();
|
||||||
}
|
}
|
||||||
ULogger::setEventLevel(ULogger::kInfo);
|
|
||||||
ULogger::setPrintThreadId(true);
|
|
||||||
|
|
||||||
this->registerToEventsManager();
|
this->registerToEventsManager();
|
||||||
|
|
||||||
@@ -300,6 +303,8 @@ private:
|
|||||||
// OpenGL thread
|
// OpenGL thread
|
||||||
int RTABMapApp::Render()
|
int RTABMapApp::Render()
|
||||||
{
|
{
|
||||||
|
boost::mutex::scoped_lock lock(renderingMutex_);
|
||||||
|
|
||||||
// should be before clearSceneOnNextRender_ in case openDatabase is called
|
// should be before clearSceneOnNextRender_ in case openDatabase is called
|
||||||
std::list<rtabmap::Statistics> rtabmapEvents;
|
std::list<rtabmap::Statistics> rtabmapEvents;
|
||||||
{
|
{
|
||||||
@@ -464,11 +469,11 @@ int RTABMapApp::Render()
|
|||||||
|
|
||||||
main_scene_.addCloud(id, outputCloud, outputPolygons, iter->second, data.imageRaw());
|
main_scene_.addCloud(id, outputCloud, outputPolygons, iter->second, data.imageRaw());
|
||||||
|
|
||||||
|
|
||||||
// protect createdMeshes_ used also by exportMesh() method
|
// protect createdMeshes_ used also by exportMesh() method
|
||||||
std::pair<std::map<int, Mesh>::iterator, bool> inserted = createdMeshes_.insert(std::make_pair(id, Mesh()));
|
std::pair<std::map<int, Mesh>::iterator, bool> inserted = createdMeshes_.insert(std::make_pair(id, Mesh()));
|
||||||
UASSERT(inserted.second);
|
UASSERT(inserted.second);
|
||||||
inserted.first->second.cloud = outputCloud;
|
inserted.first->second.cloud = outputCloud;
|
||||||
|
inserted.first->second.indices = indices;
|
||||||
inserted.first->second.polygons = outputPolygons;
|
inserted.first->second.polygons = outputPolygons;
|
||||||
inserted.first->second.pose = iter->second;
|
inserted.first->second.pose = iter->second;
|
||||||
inserted.first->second.texture = data.imageCompressed();
|
inserted.first->second.texture = data.imageCompressed();
|
||||||
@@ -545,8 +550,7 @@ int RTABMapApp::Render()
|
|||||||
event.data().imageRaw().cols, event.data().imageRaw().rows,
|
event.data().imageRaw().cols, event.data().imageRaw().rows,
|
||||||
event.data().depthRaw().cols, event.data().depthRaw().rows,
|
event.data().depthRaw().cols, event.data().depthRaw().rows,
|
||||||
(int)cloud->width, (int)cloud->height);
|
(int)cloud->width, (int)cloud->height);
|
||||||
std::vector<pcl::Vertices> polygons = rtabmap::util3d::organizedFastMesh(cloud, meshAngleToleranceDeg_*M_PI/180.0, false, meshTrianglePix_);
|
main_scene_.addCloud(-1, cloud, std::vector<pcl::Vertices>(), opengl_world_T_rtabmap_world*event.pose());
|
||||||
main_scene_.addCloud(-1, cloud, polygons, opengl_world_T_rtabmap_world*event.pose(), event.data().imageRaw());
|
|
||||||
main_scene_.setCloudVisible(-1, true);
|
main_scene_.setCloudVisible(-1, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -562,6 +566,39 @@ int RTABMapApp::Render()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(gainCompensationOnNextRender_)
|
||||||
|
{
|
||||||
|
gainCompensationOnNextRender_ = false;
|
||||||
|
rtabmap::GainCompensator compensator;
|
||||||
|
std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr > clouds;
|
||||||
|
std::map<int, pcl::IndicesPtr> indices;
|
||||||
|
for(std::map<int, Mesh>::iterator iter = createdMeshes_.begin(); iter!=createdMeshes_.end(); ++iter)
|
||||||
|
{
|
||||||
|
clouds.insert(std::make_pair(iter->first, iter->second.cloud));
|
||||||
|
indices.insert(std::make_pair(iter->first, iter->second.indices));
|
||||||
|
}
|
||||||
|
std::map<int, rtabmap::Transform> poses;
|
||||||
|
std::multimap<int, rtabmap::Link> links;
|
||||||
|
rtabmap_->getGraph(poses, links, false, true);
|
||||||
|
compensator.feed(clouds, indices, links);
|
||||||
|
for(std::map<int, Mesh>::iterator iter = createdMeshes_.begin(); iter!=createdMeshes_.end(); ++iter)
|
||||||
|
{
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudCpy(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||||
|
*cloudCpy = *iter->second.cloud;
|
||||||
|
cv::Mat imageCpy = rtabmap::uncompressImage(iter->second.texture);
|
||||||
|
if(!cloudCpy->empty())
|
||||||
|
{
|
||||||
|
compensator.apply(iter->first, cloudCpy, iter->second.indices);
|
||||||
|
if(!imageCpy.empty())
|
||||||
|
{
|
||||||
|
compensator.apply(iter->first, imageCpy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main_scene_.updateCloudColors(iter->first, cloudCpy, imageCpy);
|
||||||
|
}
|
||||||
|
notifyDataLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(filterPolygonsOnNextRender_)
|
if(filterPolygonsOnNextRender_)
|
||||||
{
|
{
|
||||||
filterPolygonsOnNextRender_ = false;
|
filterPolygonsOnNextRender_ = false;
|
||||||
@@ -1021,7 +1058,7 @@ int RTABMapApp::postProcessing(int approach)
|
|||||||
LOGE("g2o not available!");
|
LOGE("g2o not available!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if(approach!=4 || approach!=5)
|
||||||
{
|
{
|
||||||
// simple graph optmimization
|
// simple graph optmimization
|
||||||
rtabmap_->getGraph(poses, links, true, true);
|
rtabmap_->getGraph(poses, links, true, true);
|
||||||
@@ -1038,18 +1075,29 @@ int RTABMapApp::postProcessing(int approach)
|
|||||||
|
|
||||||
rtabmap_->setOptimizedPoses(poses);
|
rtabmap_->setOptimizedPoses(poses);
|
||||||
}
|
}
|
||||||
else
|
else if(approach!=4 || approach!=5)
|
||||||
{
|
{
|
||||||
returnedValue = -1;
|
returnedValue = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if(returnedValue >=0)
|
||||||
|
{
|
||||||
// filter polygons
|
// filter polygons
|
||||||
if(approach == 4)
|
if(approach == 4)
|
||||||
{
|
{
|
||||||
|
boost::mutex::scoped_lock lock(renderingMutex_);
|
||||||
filterPolygonsOnNextRender_ = true;
|
filterPolygonsOnNextRender_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gain compensation
|
||||||
|
if(approach == -1 || approach == 5)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(renderingMutex_);
|
||||||
|
gainCompensationOnNextRender_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return returnedValue;
|
return returnedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
|
|
||||||
bool clearSceneOnNextRender_;
|
bool clearSceneOnNextRender_;
|
||||||
bool filterPolygonsOnNextRender_;
|
bool filterPolygonsOnNextRender_;
|
||||||
|
bool gainCompensationOnNextRender_;
|
||||||
int totalPoints_;
|
int totalPoints_;
|
||||||
int totalPolygons_;
|
int totalPolygons_;
|
||||||
int lastDrawnCloudsCount_;
|
int lastDrawnCloudsCount_;
|
||||||
@@ -178,10 +179,12 @@ class RTABMapApp : public UEventsHandler {
|
|||||||
boost::mutex meshesMutex_;
|
boost::mutex meshesMutex_;
|
||||||
boost::mutex odomMutex_;
|
boost::mutex odomMutex_;
|
||||||
boost::mutex poseMutex_;
|
boost::mutex poseMutex_;
|
||||||
|
boost::mutex renderingMutex_;
|
||||||
|
|
||||||
struct Mesh
|
struct Mesh
|
||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
||||||
|
pcl::IndicesPtr indices;
|
||||||
std::vector<pcl::Vertices> polygons;
|
std::vector<pcl::Vertices> polygons;
|
||||||
rtabmap::Transform pose;
|
rtabmap::Transform pose;
|
||||||
cv::Mat texture;
|
cv::Mat texture;
|
||||||
|
|||||||
@@ -48,8 +48,74 @@ PointCloudDrawable::PointCloudDrawable(
|
|||||||
visible_(true),
|
visible_(true),
|
||||||
cloud_shader_program_(cloudShaderProgram),
|
cloud_shader_program_(cloudShaderProgram),
|
||||||
texture_shader_program_(textureShaderProgram)
|
texture_shader_program_(textureShaderProgram)
|
||||||
|
{
|
||||||
|
updateCloud(cloud, image);
|
||||||
|
updatePolygons(polygons);
|
||||||
|
}
|
||||||
|
|
||||||
|
PointCloudDrawable::~PointCloudDrawable()
|
||||||
|
{
|
||||||
|
LOGI("Freeing cloud buffer %d", vertex_buffers_);
|
||||||
|
if (vertex_buffers_)
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &vertex_buffers_);
|
||||||
|
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
|
||||||
|
vertex_buffers_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (textures_)
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &textures_);
|
||||||
|
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
|
||||||
|
textures_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons)
|
||||||
|
{
|
||||||
|
polygons_.clear();
|
||||||
|
if(polygons.size())
|
||||||
|
{
|
||||||
|
int polygonSize = polygons[0].vertices.size();
|
||||||
|
UASSERT(polygonSize == 3);
|
||||||
|
polygons_.resize(polygons.size() * polygonSize);
|
||||||
|
int oi = 0;
|
||||||
|
for(unsigned int i=0; i<polygons.size(); ++i)
|
||||||
|
{
|
||||||
|
UASSERT((int)polygons[i].vertices.size() == polygonSize);
|
||||||
|
for(int j=0; j<polygonSize; ++j)
|
||||||
|
{
|
||||||
|
polygons_[oi++] = (unsigned short)polygons[i].vertices[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointCloudDrawable::updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const cv::Mat & image)
|
||||||
{
|
{
|
||||||
UASSERT(!cloud->empty());
|
UASSERT(!cloud->empty());
|
||||||
|
if(nPoints_)
|
||||||
|
{
|
||||||
|
UASSERT((int)cloud->size() == nPoints_);
|
||||||
|
}
|
||||||
|
nPoints_ = 0;
|
||||||
|
|
||||||
|
if (vertex_buffers_)
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &vertex_buffers_);
|
||||||
|
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
|
||||||
|
vertex_buffers_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!image.empty())
|
||||||
|
{
|
||||||
|
if (textures_)
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &textures_);
|
||||||
|
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
|
||||||
|
textures_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
glGenBuffers(1, &vertex_buffers_);
|
glGenBuffers(1, &vertex_buffers_);
|
||||||
if(!vertex_buffers_)
|
if(!vertex_buffers_)
|
||||||
@@ -61,7 +127,7 @@ PointCloudDrawable::PointCloudDrawable(
|
|||||||
if(!cloud->is_dense && !image.empty())
|
if(!cloud->is_dense && !image.empty())
|
||||||
{
|
{
|
||||||
LOGI("cloud=%dx%d image=%dx%d\n", (int)cloud->width, (int)cloud->height, image.cols, image.rows);
|
LOGI("cloud=%dx%d image=%dx%d\n", (int)cloud->width, (int)cloud->height, image.cols, image.rows);
|
||||||
UASSERT(polygons.size() && !cloud->is_dense && !image.empty() && image.type() == CV_8UC3);
|
UASSERT(!cloud->is_dense && !image.empty() && image.type() == CV_8UC3);
|
||||||
glGenTextures(1, &textures_);
|
glGenTextures(1, &textures_);
|
||||||
if(!textures_)
|
if(!textures_)
|
||||||
{
|
{
|
||||||
@@ -114,12 +180,12 @@ PointCloudDrawable::PointCloudDrawable(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(textures_)
|
if(textures_ && !image.empty())
|
||||||
{
|
{
|
||||||
// gen texture from image
|
// gen texture from image
|
||||||
glBindTexture(GL_TEXTURE_2D, textures_);
|
glBindTexture(GL_TEXTURE_2D, textures_);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
cv::Mat rgbImage;
|
cv::Mat rgbImage;
|
||||||
cv::cvtColor(image, rgbImage, CV_BGR2RGB);
|
cv::cvtColor(image, rgbImage, CV_BGR2RGB);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rgbImage.cols, rgbImage.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, rgbImage.data);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rgbImage.cols, rgbImage.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, rgbImage.data);
|
||||||
@@ -137,46 +203,6 @@ PointCloudDrawable::PointCloudDrawable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
nPoints_ = cloud->size();
|
nPoints_ = cloud->size();
|
||||||
|
|
||||||
updatePolygons(polygons);
|
|
||||||
}
|
|
||||||
|
|
||||||
PointCloudDrawable::~PointCloudDrawable()
|
|
||||||
{
|
|
||||||
LOGI("Freeing cloud buffer %d", vertex_buffers_);
|
|
||||||
if (vertex_buffers_)
|
|
||||||
{
|
|
||||||
glDeleteBuffers(1, &vertex_buffers_);
|
|
||||||
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
|
|
||||||
vertex_buffers_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textures_)
|
|
||||||
{
|
|
||||||
glDeleteTextures(1, &textures_);
|
|
||||||
tango_gl::util::CheckGlError("PointCloudDrawable::~PointCloudDrawable()");
|
|
||||||
textures_ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PointCloudDrawable::updatePolygons(const std::vector<pcl::Vertices> & polygons)
|
|
||||||
{
|
|
||||||
polygons_.clear();
|
|
||||||
if(polygons.size())
|
|
||||||
{
|
|
||||||
int polygonSize = polygons[0].vertices.size();
|
|
||||||
UASSERT(polygonSize == 3);
|
|
||||||
polygons_.resize(polygons.size() * polygonSize);
|
|
||||||
int oi = 0;
|
|
||||||
for(unsigned int i=0; i<polygons.size(); ++i)
|
|
||||||
{
|
|
||||||
UASSERT((int)polygons[i].vertices.size() == polygonSize);
|
|
||||||
for(int j=0; j<polygonSize; ++j)
|
|
||||||
{
|
|
||||||
polygons_[oi++] = (unsigned short)polygons[i].vertices[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PointCloudDrawable::setPose(const rtabmap::Transform & pose)
|
void PointCloudDrawable::setPose(const rtabmap::Transform & pose)
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ class PointCloudDrawable {
|
|||||||
virtual ~PointCloudDrawable();
|
virtual ~PointCloudDrawable();
|
||||||
|
|
||||||
void updatePolygons(const std::vector<pcl::Vertices> & polygons);
|
void updatePolygons(const std::vector<pcl::Vertices> & polygons);
|
||||||
|
void updateCloud(const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const cv::Mat & image = cv::Mat());
|
||||||
void setPose(const rtabmap::Transform & pose);
|
void setPose(const rtabmap::Transform & pose);
|
||||||
void setVisible(bool visible) {visible_=visible;}
|
void setVisible(bool visible) {visible_=visible;}
|
||||||
rtabmap::Transform getPose() const {return glmToTransform(pose_);}
|
rtabmap::Transform getPose() const {return glmToTransform(pose_);}
|
||||||
|
|||||||
@@ -480,3 +480,12 @@ void Scene::updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polyg
|
|||||||
iter->second->updatePolygons(polygons);
|
iter->second->updatePolygons(polygons);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::updateCloudColors(int id, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const cv::Mat & image)
|
||||||
|
{
|
||||||
|
std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
|
||||||
|
if(iter != pointClouds_.end())
|
||||||
|
{
|
||||||
|
iter->second->updateCloud(cloud, image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ class Scene {
|
|||||||
bool hasCloud(int id) const;
|
bool hasCloud(int id) const;
|
||||||
std::set<int> getAddedClouds() const;
|
std::set<int> getAddedClouds() const;
|
||||||
void updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons);
|
void updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons);
|
||||||
|
void updateCloudColors(int id, const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud, const cv::Mat & image = cv::Mat());
|
||||||
|
|
||||||
void setMapRendering(bool enabled) {mapRendering_ = enabled;}
|
void setMapRendering(bool enabled) {mapRendering_ = enabled;}
|
||||||
void setMeshRendering(bool enabled, bool withTexture) {meshRendering_ = enabled; meshRenderingTexture_ = withTexture;}
|
void setMeshRendering(bool enabled, bool withTexture) {meshRendering_ = enabled; meshRenderingTexture_ = withTexture;}
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ class LogHandler : public UEventsHandler
|
|||||||
public:
|
public:
|
||||||
LogHandler()
|
LogHandler()
|
||||||
{
|
{
|
||||||
|
ULogger::setEventLevel(ULogger::kWarning);
|
||||||
|
ULogger::setPrintThreadId(true);
|
||||||
|
|
||||||
registerToEventsManager();
|
registerToEventsManager();
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
<item android:id="@+id/global_graph_optimization" android:title="Global Graph Optimization" />
|
<item android:id="@+id/global_graph_optimization" android:title="Global Graph Optimization" />
|
||||||
<item android:id="@+id/detect_more_loop_closures" android:title="Detect More Loop Closures" />
|
<item android:id="@+id/detect_more_loop_closures" android:title="Detect More Loop Closures" />
|
||||||
<item android:id="@+id/icp_refining" android:title="ICP Refining" />
|
<item android:id="@+id/icp_refining" android:title="ICP Refining" />
|
||||||
|
<item android:id="@+id/gain_compensation" android:title="Adjust Colors" />
|
||||||
<item android:id="@+id/sba" android:title="Bundle Adjustement" />
|
<item android:id="@+id/sba" android:title="Bundle Adjustement" />
|
||||||
<item android:id="@+id/polygons_filtering" android:title="Noise Filtering" />
|
<item android:id="@+id/polygons_filtering" android:title="Noise Filtering" />
|
||||||
</menu>
|
</menu>
|
||||||
|
|||||||
@@ -670,11 +670,10 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
final int loopDetected = RTABMapLib.postProcessing(-1);
|
final int loopDetected = RTABMapLib.postProcessing(-1);
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
mProgressDialog.dismiss();
|
|
||||||
if(loopDetected >= 0)
|
if(loopDetected >= 0)
|
||||||
{
|
{
|
||||||
mTotalLoopClosures+=loopDetected;
|
mTotalLoopClosures+=loopDetected;
|
||||||
mToast.makeText(getActivity(), String.format("Optimization done!"), mToast.LENGTH_SHORT).show();
|
mToast.makeText(getActivity(), String.format("Optimization done! Adjusting colors..."), mToast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
else if(loopDetected < 0)
|
else if(loopDetected < 0)
|
||||||
{
|
{
|
||||||
@@ -772,6 +771,13 @@ public class RTABMapActivity extends Activity implements OnClickListener {
|
|||||||
mProgressDialog.show();
|
mProgressDialog.show();
|
||||||
RTABMapLib.postProcessing(4);
|
RTABMapLib.postProcessing(4);
|
||||||
}
|
}
|
||||||
|
else if (itemId == R.id.gain_compensation)
|
||||||
|
{
|
||||||
|
mProgressDialog.setTitle("Post-Processing");
|
||||||
|
mProgressDialog.setMessage(String.format("Gain compensation..."));
|
||||||
|
mProgressDialog.show();
|
||||||
|
RTABMapLib.postProcessing(5);
|
||||||
|
}
|
||||||
else if (itemId == R.id.sba)
|
else if (itemId == R.id.sba)
|
||||||
{
|
{
|
||||||
mProgressDialog.setTitle("Post-Processing");
|
mProgressDialog.setTitle("Post-Processing");
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ private:
|
|||||||
int _imagePreDecimation;
|
int _imagePreDecimation;
|
||||||
int _imagePostDecimation;
|
int _imagePostDecimation;
|
||||||
float _laserScanDownsampleStepSize;
|
float _laserScanDownsampleStepSize;
|
||||||
|
int _laserScanNormalK;
|
||||||
bool _reextractLoopClosureFeatures;
|
bool _reextractLoopClosureFeatures;
|
||||||
float _rehearsalMaxDistance;
|
float _rehearsalMaxDistance;
|
||||||
float _rehearsalMaxAngle;
|
float _rehearsalMaxAngle;
|
||||||
|
|||||||
@@ -210,6 +210,7 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Mem, ImagePreDecimation, int, 1, "Image decimation (>=1) before features extraction.");
|
RTABMAP_PARAM(Mem, ImagePreDecimation, int, 1, "Image decimation (>=1) before features extraction.");
|
||||||
RTABMAP_PARAM(Mem, ImagePostDecimation, int, 1, "Image decimation (>=1) of saved data in created signatures (after features extraction). Decimation is done from the original image.");
|
RTABMAP_PARAM(Mem, ImagePostDecimation, int, 1, "Image decimation (>=1) of saved data in created signatures (after features extraction). Decimation is done from the original image.");
|
||||||
RTABMAP_PARAM(Mem, LaserScanDownsampleStepSize, int, 1, "If > 1, downsample the laser scans when creating a signature.");
|
RTABMAP_PARAM(Mem, LaserScanDownsampleStepSize, int, 1, "If > 1, downsample the laser scans when creating a signature.");
|
||||||
|
RTABMAP_PARAM(Mem, LaserScanNormalK, int, 0, "If > 0 and laser scans are 3D without normals, normals will be computed with K search neighbors when creating a signature.");
|
||||||
RTABMAP_PARAM(Mem, UseOdomFeatures, bool, false, "Use odometry features.");
|
RTABMAP_PARAM(Mem, UseOdomFeatures, bool, false, "Use odometry features.");
|
||||||
|
|
||||||
// KeypointMemory (Keypoint-based)
|
// KeypointMemory (Keypoint-based)
|
||||||
|
|||||||
@@ -127,7 +127,8 @@ class RTABMAP_EXP Statistics
|
|||||||
RTABMAP_STATS(TimingMem, Add_new_words, ms);
|
RTABMAP_STATS(TimingMem, Add_new_words, ms);
|
||||||
RTABMAP_STATS(TimingMem, Compressing_data, ms);
|
RTABMAP_STATS(TimingMem, Compressing_data, ms);
|
||||||
RTABMAP_STATS(TimingMem, Post_decimation, ms);
|
RTABMAP_STATS(TimingMem, Post_decimation, ms);
|
||||||
RTABMAP_STATS(TimingMem, Downsampling_scan, ms);
|
RTABMAP_STATS(TimingMem, Scan_downsampling, ms);
|
||||||
|
RTABMAP_STATS(TimingMem, Scan_normals, ms);
|
||||||
RTABMAP_STATS(TimingMem, Occupancy_grid, ms);
|
RTABMAP_STATS(TimingMem, Occupancy_grid, ms);
|
||||||
|
|
||||||
RTABMAP_STATS(Keypoint, Dictionary_size, words);
|
RTABMAP_STATS(Keypoint, Dictionary_size, words);
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ pcl::PointCloud<pcl::PointXYZ> RTABMAP_EXP laserScanFromDepthImages(
|
|||||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform());
|
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const Transform & transform = Transform());
|
||||||
// return CV_32FC6
|
// return CV_32FC6
|
||||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform());
|
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud, const Transform & transform = Transform());
|
||||||
|
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform = Transform());
|
||||||
// return CV_32FC4
|
// return CV_32FC4
|
||||||
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const Transform & transform = Transform());
|
cv::Mat RTABMAP_EXP laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud, const Transform & transform = Transform());
|
||||||
// return CV_32FC2
|
// return CV_32FC2
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ Memory::Memory(const ParametersMap & parameters) :
|
|||||||
_imagePreDecimation(Parameters::defaultMemImagePreDecimation()),
|
_imagePreDecimation(Parameters::defaultMemImagePreDecimation()),
|
||||||
_imagePostDecimation(Parameters::defaultMemImagePostDecimation()),
|
_imagePostDecimation(Parameters::defaultMemImagePostDecimation()),
|
||||||
_laserScanDownsampleStepSize(Parameters::defaultMemLaserScanDownsampleStepSize()),
|
_laserScanDownsampleStepSize(Parameters::defaultMemLaserScanDownsampleStepSize()),
|
||||||
|
_laserScanNormalK(Parameters::defaultMemLaserScanNormalK()),
|
||||||
_reextractLoopClosureFeatures(Parameters::defaultRGBDLoopClosureReextractFeatures()),
|
_reextractLoopClosureFeatures(Parameters::defaultRGBDLoopClosureReextractFeatures()),
|
||||||
_rehearsalMaxDistance(Parameters::defaultRGBDLinearUpdate()),
|
_rehearsalMaxDistance(Parameters::defaultRGBDLinearUpdate()),
|
||||||
_rehearsalMaxAngle(Parameters::defaultRGBDAngularUpdate()),
|
_rehearsalMaxAngle(Parameters::defaultRGBDAngularUpdate()),
|
||||||
@@ -407,6 +408,7 @@ void Memory::parseParameters(const ParametersMap & parameters)
|
|||||||
Parameters::parse(parameters, Parameters::kMemImagePreDecimation(), _imagePreDecimation);
|
Parameters::parse(parameters, Parameters::kMemImagePreDecimation(), _imagePreDecimation);
|
||||||
Parameters::parse(parameters, Parameters::kMemImagePostDecimation(), _imagePostDecimation);
|
Parameters::parse(parameters, Parameters::kMemImagePostDecimation(), _imagePostDecimation);
|
||||||
Parameters::parse(parameters, Parameters::kMemLaserScanDownsampleStepSize(), _laserScanDownsampleStepSize);
|
Parameters::parse(parameters, Parameters::kMemLaserScanDownsampleStepSize(), _laserScanDownsampleStepSize);
|
||||||
|
Parameters::parse(parameters, Parameters::kMemLaserScanNormalK(), _laserScanNormalK);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDLoopClosureReextractFeatures(), _reextractLoopClosureFeatures);
|
Parameters::parse(parameters, Parameters::kRGBDLoopClosureReextractFeatures(), _reextractLoopClosureFeatures);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDLinearUpdate(), _rehearsalMaxDistance);
|
Parameters::parse(parameters, Parameters::kRGBDLinearUpdate(), _rehearsalMaxDistance);
|
||||||
Parameters::parse(parameters, Parameters::kRGBDAngularUpdate(), _rehearsalMaxAngle);
|
Parameters::parse(parameters, Parameters::kRGBDAngularUpdate(), _rehearsalMaxAngle);
|
||||||
@@ -3495,9 +3497,20 @@ Signature * Memory::createSignature(const SensorData & data, const Transform & p
|
|||||||
maxLaserScanMaxPts /= _laserScanDownsampleStepSize;
|
maxLaserScanMaxPts /= _laserScanDownsampleStepSize;
|
||||||
|
|
||||||
t = timer.ticks();
|
t = timer.ticks();
|
||||||
if(stats) stats->addStatistic(Statistics::kTimingMemDownsampling_scan(), t*1000.0f);
|
if(stats) stats->addStatistic(Statistics::kTimingMemScan_downsampling(), t*1000.0f);
|
||||||
UDEBUG("time downsampling scan = %fs", t);
|
UDEBUG("time downsampling scan = %fs", t);
|
||||||
}
|
}
|
||||||
|
if(!laserScan.empty() && _laserScanNormalK > 0 && laserScan.channels() == 3)
|
||||||
|
{
|
||||||
|
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = util3d::laserScanToPointCloud(laserScan);
|
||||||
|
float x,y,z;
|
||||||
|
data.laserScanInfo().localTransform().getTranslation(x,y,z);
|
||||||
|
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, _laserScanNormalK, Eigen::Vector3f(x,y,z));
|
||||||
|
laserScan = util3d::laserScanFromPointCloud(*cloud, *normals);
|
||||||
|
t = timer.ticks();
|
||||||
|
if(stats) stats->addStatistic(Statistics::kTimingMemScan_normals(), t*1000.0f);
|
||||||
|
UDEBUG("time normals scan = %fs", t);
|
||||||
|
}
|
||||||
|
|
||||||
Signature * s;
|
Signature * s;
|
||||||
if(this->isBinDataKept())
|
if(this->isBinDataKept())
|
||||||
|
|||||||
@@ -1047,18 +1047,19 @@ cv::Mat laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, co
|
|||||||
Eigen::Affine3f transform3f = transform.toEigen3f();
|
Eigen::Affine3f transform3f = transform.toEigen3f();
|
||||||
for(unsigned int i=0; i<cloud.size(); ++i)
|
for(unsigned int i=0; i<cloud.size(); ++i)
|
||||||
{
|
{
|
||||||
|
float * ptr = laserScan.ptr<float>(0, i);
|
||||||
if(!nullTransform)
|
if(!nullTransform)
|
||||||
{
|
{
|
||||||
pcl::PointXYZ pt = pcl::transformPoint(cloud.at(i), transform3f);
|
pcl::PointXYZ pt = pcl::transformPoint(cloud.at(i), transform3f);
|
||||||
laserScan.at<cv::Vec3f>(i)[0] = pt.x;
|
ptr[0] = pt.x;
|
||||||
laserScan.at<cv::Vec3f>(i)[1] = pt.y;
|
ptr[1] = pt.y;
|
||||||
laserScan.at<cv::Vec3f>(i)[2] = pt.z;
|
ptr[2] = pt.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
laserScan.at<cv::Vec3f>(i)[0] = cloud.at(i).x;
|
ptr[0] = cloud.at(i).x;
|
||||||
laserScan.at<cv::Vec3f>(i)[1] = cloud.at(i).y;
|
ptr[1] = cloud.at(i).y;
|
||||||
laserScan.at<cv::Vec3f>(i)[2] = cloud.at(i).z;
|
ptr[2] = cloud.at(i).z;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1071,24 +1072,63 @@ cv::Mat laserScanFromPointCloud(const pcl::PointCloud<pcl::PointNormal> & cloud,
|
|||||||
bool nullTransform = transform.isNull() || transform.isIdentity();
|
bool nullTransform = transform.isNull() || transform.isIdentity();
|
||||||
for(unsigned int i=0; i<cloud.size(); ++i)
|
for(unsigned int i=0; i<cloud.size(); ++i)
|
||||||
{
|
{
|
||||||
|
float * ptr = laserScan.ptr<float>(0, i);
|
||||||
if(!nullTransform)
|
if(!nullTransform)
|
||||||
{
|
{
|
||||||
pcl::PointNormal pt = util3d::transformPoint(cloud.at(i), transform);
|
pcl::PointNormal pt = util3d::transformPoint(cloud.at(i), transform);
|
||||||
laserScan.at<cv::Vec6f>(i)[0] = pt.x;
|
ptr[0] = pt.x;
|
||||||
laserScan.at<cv::Vec6f>(i)[1] = pt.y;
|
ptr[1] = pt.y;
|
||||||
laserScan.at<cv::Vec6f>(i)[2] = pt.z;
|
ptr[2] = pt.z;
|
||||||
laserScan.at<cv::Vec6f>(i)[3] = pt.normal_x;
|
ptr[3] = pt.normal_x;
|
||||||
laserScan.at<cv::Vec6f>(i)[4] = pt.normal_y;
|
ptr[4] = pt.normal_y;
|
||||||
laserScan.at<cv::Vec6f>(i)[5] = pt.normal_z;
|
ptr[5] = pt.normal_z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
laserScan.at<cv::Vec6f>(i)[0] = cloud.at(i).x;
|
ptr[0] = cloud.at(i).x;
|
||||||
laserScan.at<cv::Vec6f>(i)[1] = cloud.at(i).y;
|
ptr[1] = cloud.at(i).y;
|
||||||
laserScan.at<cv::Vec6f>(i)[2] = cloud.at(i).z;
|
ptr[2] = cloud.at(i).z;
|
||||||
laserScan.at<cv::Vec6f>(i)[3] = cloud.at(i).normal_x;
|
ptr[3] = cloud.at(i).normal_x;
|
||||||
laserScan.at<cv::Vec6f>(i)[4] = cloud.at(i).normal_y;
|
ptr[4] = cloud.at(i).normal_y;
|
||||||
laserScan.at<cv::Vec6f>(i)[5] = cloud.at(i).normal_z;
|
ptr[5] = cloud.at(i).normal_z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return laserScan;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud, const pcl::PointCloud<pcl::Normal> & normals, const Transform & transform)
|
||||||
|
{
|
||||||
|
UASSERT(cloud.size() == normals.size());
|
||||||
|
cv::Mat laserScan(1, (int)cloud.size(), CV_32FC(6));
|
||||||
|
bool nullTransform = transform.isNull() || transform.isIdentity();
|
||||||
|
for(unsigned int i=0; i<cloud.size(); ++i)
|
||||||
|
{
|
||||||
|
float * ptr = laserScan.ptr<float>(0, i);
|
||||||
|
if(!nullTransform)
|
||||||
|
{
|
||||||
|
pcl::PointNormal pt;
|
||||||
|
pt.x = cloud.at(i).x;
|
||||||
|
pt.y = cloud.at(i).y;
|
||||||
|
pt.z = cloud.at(i).z;
|
||||||
|
pt.normal_x = normals.at(i).normal_x;
|
||||||
|
pt.normal_y = normals.at(i).normal_y;
|
||||||
|
pt.normal_z = normals.at(i).normal_z;
|
||||||
|
pt = util3d::transformPoint(pt, transform);
|
||||||
|
ptr[0] = pt.x;
|
||||||
|
ptr[1] = pt.y;
|
||||||
|
ptr[2] = pt.z;
|
||||||
|
ptr[3] = pt.normal_x;
|
||||||
|
ptr[4] = pt.normal_y;
|
||||||
|
ptr[5] = pt.normal_z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ptr[0] = cloud.at(i).x;
|
||||||
|
ptr[1] = cloud.at(i).y;
|
||||||
|
ptr[2] = cloud.at(i).z;
|
||||||
|
ptr[3] = normals.at(i).normal_x;
|
||||||
|
ptr[4] = normals.at(i).normal_y;
|
||||||
|
ptr[5] = normals.at(i).normal_z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return laserScan;
|
return laserScan;
|
||||||
@@ -1101,20 +1141,22 @@ cv::Mat laserScanFromPointCloud(const pcl::PointCloud<pcl::PointXYZRGB> & cloud,
|
|||||||
Eigen::Affine3f transform3f = transform.toEigen3f();
|
Eigen::Affine3f transform3f = transform.toEigen3f();
|
||||||
for(unsigned int i=0; i<cloud.size(); ++i)
|
for(unsigned int i=0; i<cloud.size(); ++i)
|
||||||
{
|
{
|
||||||
|
float * ptr = laserScan.ptr<float>(0, i);
|
||||||
if(!nullTransform)
|
if(!nullTransform)
|
||||||
{
|
{
|
||||||
pcl::PointXYZRGB pt = pcl::transformPoint(cloud.at(i), transform3f);
|
pcl::PointXYZRGB pt = pcl::transformPoint(cloud.at(i), transform3f);
|
||||||
laserScan.at<cv::Vec4f>(i)[0] = pt.x;
|
ptr[0] = pt.x;
|
||||||
laserScan.at<cv::Vec4f>(i)[1] = pt.y;
|
ptr[1] = pt.y;
|
||||||
laserScan.at<cv::Vec4f>(i)[2] = pt.z;
|
ptr[2] = pt.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
laserScan.at<cv::Vec4f>(i)[0] = cloud.at(i).x;
|
ptr[0] = cloud.at(i).x;
|
||||||
laserScan.at<cv::Vec4f>(i)[1] = cloud.at(i).y;
|
ptr[1] = cloud.at(i).y;
|
||||||
laserScan.at<cv::Vec4f>(i)[2] = cloud.at(i).z;
|
ptr[2] = cloud.at(i).z;
|
||||||
}
|
}
|
||||||
laserScan.at<cv::Vec4i>(i)[3] = int(cloud.at(i).b) | (int(cloud.at(i).g) << 8) | (int(cloud.at(i).r) << 16);
|
int * ptrInt = (int*)ptr;
|
||||||
|
ptrInt[3] = int(cloud.at(i).b) | (int(cloud.at(i).g) << 8) | (int(cloud.at(i).r) << 16);
|
||||||
}
|
}
|
||||||
return laserScan;
|
return laserScan;
|
||||||
}
|
}
|
||||||
@@ -1126,16 +1168,17 @@ cv::Mat laserScan2dFromPointCloud(const pcl::PointCloud<pcl::PointXYZ> & cloud,
|
|||||||
Eigen::Affine3f transform3f = transform.toEigen3f();
|
Eigen::Affine3f transform3f = transform.toEigen3f();
|
||||||
for(unsigned int i=0; i<cloud.size(); ++i)
|
for(unsigned int i=0; i<cloud.size(); ++i)
|
||||||
{
|
{
|
||||||
|
float * ptr = laserScan.ptr<float>(0, i);
|
||||||
if(!nullTransform)
|
if(!nullTransform)
|
||||||
{
|
{
|
||||||
pcl::PointXYZ pt = pcl::transformPoint(cloud.at(i), transform3f);
|
pcl::PointXYZ pt = pcl::transformPoint(cloud.at(i), transform3f);
|
||||||
laserScan.at<cv::Vec2f>(i)[0] = pt.x;
|
ptr[0] = pt.x;
|
||||||
laserScan.at<cv::Vec2f>(i)[1] = pt.y;
|
ptr[1] = pt.y;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
laserScan.at<cv::Vec2f>(i)[0] = cloud.at(i).x;
|
ptr[0] = cloud.at(i).x;
|
||||||
laserScan.at<cv::Vec2f>(i)[1] = cloud.at(i).y;
|
ptr[1] = cloud.at(i).y;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1203,28 +1246,12 @@ pcl::PointXYZ laserScanToPoint(const cv::Mat & laserScan, int index)
|
|||||||
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
||||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6));
|
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6));
|
||||||
pcl::PointXYZ output;
|
pcl::PointXYZ output;
|
||||||
if(laserScan.type() == CV_32FC2)
|
const float * ptr = laserScan.ptr<float>(0, index);
|
||||||
|
output.x = ptr[0];
|
||||||
|
output.y = ptr[1];
|
||||||
|
if(laserScan.channels() >= 3)
|
||||||
{
|
{
|
||||||
output.x = laserScan.at<cv::Vec2f>(index)[0];
|
output.z = ptr[2];
|
||||||
output.y = laserScan.at<cv::Vec2f>(index)[1];
|
|
||||||
}
|
|
||||||
else if(laserScan.type() == CV_32FC3)
|
|
||||||
{
|
|
||||||
output.x = laserScan.at<cv::Vec3f>(index)[0];
|
|
||||||
output.y = laserScan.at<cv::Vec3f>(index)[1];
|
|
||||||
output.z = laserScan.at<cv::Vec3f>(index)[2];
|
|
||||||
}
|
|
||||||
else if(laserScan.type() == CV_32FC(4))
|
|
||||||
{
|
|
||||||
output.x = laserScan.at<cv::Vec4f>(index)[0];
|
|
||||||
output.y = laserScan.at<cv::Vec4f>(index)[1];
|
|
||||||
output.z = laserScan.at<cv::Vec4f>(index)[2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
output.x = laserScan.at<cv::Vec6f>(index)[0];
|
|
||||||
output.y = laserScan.at<cv::Vec6f>(index)[1];
|
|
||||||
output.z = laserScan.at<cv::Vec6f>(index)[2];
|
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@@ -1234,31 +1261,18 @@ pcl::PointNormal laserScanToPointNormal(const cv::Mat & laserScan, int index)
|
|||||||
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
||||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6));
|
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6));
|
||||||
pcl::PointNormal output;
|
pcl::PointNormal output;
|
||||||
if(laserScan.type() == CV_32FC2)
|
const float * ptr = laserScan.ptr<float>(0, index);
|
||||||
|
output.x = ptr[0];
|
||||||
|
output.y = ptr[1];
|
||||||
|
if(laserScan.channels() >= 3)
|
||||||
{
|
{
|
||||||
output.x = laserScan.at<cv::Vec2f>(index)[0];
|
output.z = ptr[2];
|
||||||
output.y = laserScan.at<cv::Vec2f>(index)[1];
|
|
||||||
}
|
}
|
||||||
else if(laserScan.type() == CV_32FC3)
|
if(laserScan.channels() == 6)
|
||||||
{
|
{
|
||||||
output.x = laserScan.at<cv::Vec3f>(index)[0];
|
output.normal_x = ptr[3];
|
||||||
output.y = laserScan.at<cv::Vec3f>(index)[1];
|
output.normal_y = ptr[4];
|
||||||
output.z = laserScan.at<cv::Vec3f>(index)[2];
|
output.normal_z = ptr[5];
|
||||||
}
|
|
||||||
else if(laserScan.type() == CV_32FC(4))
|
|
||||||
{
|
|
||||||
output.x = laserScan.at<cv::Vec4f>(index)[0];
|
|
||||||
output.y = laserScan.at<cv::Vec4f>(index)[1];
|
|
||||||
output.z = laserScan.at<cv::Vec4f>(index)[2];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
output.x = laserScan.at<cv::Vec6f>(index)[0];
|
|
||||||
output.y = laserScan.at<cv::Vec6f>(index)[1];
|
|
||||||
output.z = laserScan.at<cv::Vec6f>(index)[2];
|
|
||||||
output.normal_x = laserScan.at<cv::Vec6f>(index)[3];
|
|
||||||
output.normal_y = laserScan.at<cv::Vec6f>(index)[4];
|
|
||||||
output.normal_z = laserScan.at<cv::Vec6f>(index)[5];
|
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@@ -1268,31 +1282,19 @@ pcl::PointXYZRGB laserScanToPointRGB(const cv::Mat & laserScan, int index)
|
|||||||
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
UASSERT(!laserScan.empty() && index < laserScan.cols);
|
||||||
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6));
|
UASSERT(laserScan.type() == CV_32FC2 || laserScan.type() == CV_32FC3 || laserScan.type() == CV_32FC(4) || laserScan.type() == CV_32FC(6));
|
||||||
pcl::PointXYZRGB output;
|
pcl::PointXYZRGB output;
|
||||||
if(laserScan.type() == CV_32FC2)
|
const float * ptr = laserScan.ptr<float>(0, index);
|
||||||
|
output.x = ptr[0];
|
||||||
|
output.y = ptr[1];
|
||||||
|
if(laserScan.type() >= 3)
|
||||||
{
|
{
|
||||||
output.x = laserScan.at<cv::Vec2f>(index)[0];
|
output.z = ptr[2];
|
||||||
output.y = laserScan.at<cv::Vec2f>(index)[1];
|
|
||||||
}
|
}
|
||||||
else if(laserScan.type() == CV_32FC3)
|
if(laserScan.channels() == 4)
|
||||||
{
|
{
|
||||||
output.x = laserScan.at<cv::Vec3f>(index)[0];
|
int * ptrInt = (int*)ptr;
|
||||||
output.y = laserScan.at<cv::Vec3f>(index)[1];
|
output.b = (unsigned char)(ptrInt[3] & 0xFF);
|
||||||
output.z = laserScan.at<cv::Vec3f>(index)[2];
|
output.g = (unsigned char)((ptrInt[3] >> 8) & 0xFF);
|
||||||
}
|
output.r = (unsigned char)((ptrInt[3] >> 16) & 0xFF);
|
||||||
else if(laserScan.type() == CV_32FC(4))
|
|
||||||
{
|
|
||||||
output.x = laserScan.at<cv::Vec4f>(index)[0];
|
|
||||||
output.y = laserScan.at<cv::Vec4f>(index)[1];
|
|
||||||
output.z = laserScan.at<cv::Vec4f>(index)[2];
|
|
||||||
output.b = (unsigned char)(laserScan.at<cv::Vec4i>(index)[3] & 0xFF);
|
|
||||||
output.g = (unsigned char)((laserScan.at<cv::Vec4i>(index)[3] >> 8) & 0xFF);
|
|
||||||
output.r = (unsigned char)((laserScan.at<cv::Vec4i>(index)[3] >> 16) & 0xFF);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
output.x = laserScan.at<cv::Vec6f>(index)[0];
|
|
||||||
output.y = laserScan.at<cv::Vec6f>(index)[1];
|
|
||||||
output.z = laserScan.at<cv::Vec6f>(index)[2];
|
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -573,6 +573,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
_ui->spinBox_imagePreDecimation->setObjectName(Parameters::kMemImagePreDecimation().c_str());
|
_ui->spinBox_imagePreDecimation->setObjectName(Parameters::kMemImagePreDecimation().c_str());
|
||||||
_ui->spinBox_imagePostDecimation->setObjectName(Parameters::kMemImagePostDecimation().c_str());
|
_ui->spinBox_imagePostDecimation->setObjectName(Parameters::kMemImagePostDecimation().c_str());
|
||||||
_ui->general_spinBox_laserScanDownsample->setObjectName(Parameters::kMemLaserScanDownsampleStepSize().c_str());
|
_ui->general_spinBox_laserScanDownsample->setObjectName(Parameters::kMemLaserScanDownsampleStepSize().c_str());
|
||||||
|
_ui->general_spinBox_laserScanNormalK->setObjectName(Parameters::kMemLaserScanNormalK().c_str());
|
||||||
_ui->checkBox_useOdomFeatures->setObjectName(Parameters::kMemUseOdomFeatures().c_str());
|
_ui->checkBox_useOdomFeatures->setObjectName(Parameters::kMemUseOdomFeatures().c_str());
|
||||||
|
|
||||||
// Database
|
// Database
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>-279</y>
|
||||||
<width>673</width>
|
<width>673</width>
|
||||||
<height>2496</height>
|
<height>2496</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>1</number>
|
<number>8</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">
|
||||||
@@ -5356,19 +5356,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_42" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_42" columnstretch="0,1">
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QLabel" name="label_retrieved_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>True=Generate location Ids, False=use input image ids.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QSpinBox" name="general_spinBox_maxStMemSize">
|
<widget class="QSpinBox" name="general_spinBox_maxStMemSize">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
@@ -5382,6 +5369,208 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QLabel" name="label_retrieved_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reduce graph. Merge nodes when loop closures are added (ignoring those with user data set).</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="general_doubleSpinBox_recentWmRatio">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>0.010000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.200000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="1">
|
||||||
|
<widget class="QLabel" name="label_retrieved_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Initialize the Woking Memory with all nodes from Long-Term memory, instead of only nodes of the last session. This may be useful in localization mode, where less processing time is required than in SLAM mode, so more nodes can be kept in Working Memory.</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="QSpinBox" name="general_spinBox_maxRetrieved">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>999</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="1">
|
||||||
|
<widget class="QLabel" name="label_retrieved_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Bad signatures are ignored.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="0">
|
||||||
|
<widget class="QCheckBox" name="general_checkBox_initWMWithAllNodes">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="QLabel" name="label_retrieved_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Keep raw sensor data. Only useful to save loop closure computation time when features re-extraction is enabled. Disable to save RAM memory.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="0">
|
||||||
|
<widget class="QCheckBox" name="general_checkBox_keepRawData">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QCheckBox" name="general_checkBox_reduceGraph">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="label_retrieved_11">
|
||||||
|
<property name="text">
|
||||||
|
<string>Create map labels. The first node of a map will be labelled as "map#" where # is the map ID.</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="QCheckBox" name="general_checkBox_createMapLabels">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="14" column="0">
|
||||||
|
<widget class="QSpinBox" name="general_spinBox_laserScanDownsample">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>9999</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="1">
|
||||||
|
<widget class="QLabel" name="label_retrieved_12">
|
||||||
|
<property name="text">
|
||||||
|
<string>Raw descriptors kept in memory.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="0">
|
||||||
|
<widget class="QCheckBox" name="general_checkBox_keepDescriptors">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="12" column="1">
|
||||||
|
<widget class="QLabel" name="label_retrieved_13">
|
||||||
|
<property name="text">
|
||||||
|
<string>Image pre decimation. This option can be used to reduce image size before features extraction.</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="1">
|
||||||
|
<widget class="QLabel" name="label_retrieved_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>True=Generate location Ids, False=use input image ids.</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="1">
|
<item row="2" column="1">
|
||||||
<widget class="QLabel" name="label_retrieved">
|
<widget class="QLabel" name="label_retrieved">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -5438,51 +5627,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="QLabel" name="label_retrieved_10">
|
|
||||||
<property name="text">
|
|
||||||
<string>Reduce graph. Merge nodes when loop closures are added (ignoring those with user data set).</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="general_doubleSpinBox_recentWmRatio">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>50</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>0.010000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.200000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="1">
|
|
||||||
<widget class="QLabel" name="label_retrieved_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Initialize the Woking Memory with all nodes from Long-Term memory, instead of only nodes of the last session. This may be useful in localization mode, where less processing time is required than in SLAM mode, so more nodes can be kept in Working Memory.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_29">
|
<widget class="QLabel" name="label_29">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -5509,19 +5653,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QSpinBox" name="general_spinBox_maxRetrieved">
|
|
||||||
<property name="maximum">
|
|
||||||
<number>999</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
<item row="6" column="0">
|
||||||
<widget class="QCheckBox" name="general_checkBox_badSignaturesIgnored">
|
<widget class="QCheckBox" name="general_checkBox_badSignaturesIgnored">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -5532,52 +5663,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
|
||||||
<widget class="QLabel" name="label_retrieved_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Bad signatures are ignored.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="0">
|
|
||||||
<widget class="QCheckBox" name="general_checkBox_initWMWithAllNodes">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
|
||||||
<widget class="QLabel" name="label_retrieved_5">
|
|
||||||
<property name="text">
|
|
||||||
<string>Keep raw sensor data. Only useful to save loop closure computation time when features re-extraction is enabled. Disable to save RAM memory.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="0">
|
|
||||||
<widget class="QCheckBox" name="general_checkBox_keepRawData">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="13" column="1">
|
<item row="13" column="1">
|
||||||
<widget class="QLabel" name="label_retrieved_6">
|
<widget class="QLabel" name="label_retrieved_6">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -5617,55 +5702,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0">
|
|
||||||
<widget class="QCheckBox" name="general_checkBox_reduceGraph">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QLabel" name="label_retrieved_11">
|
|
||||||
<property name="text">
|
|
||||||
<string>Create map labels. The first node of a map will be labelled as "map#" where # is the map ID.</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="QCheckBox" name="general_checkBox_createMapLabels">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="14" column="0">
|
|
||||||
<widget class="QSpinBox" name="general_spinBox_laserScanDownsample">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>50</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>9999</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="11" column="0">
|
<item row="11" column="0">
|
||||||
<widget class="QCheckBox" name="general_checkBox_saveDepth16bits">
|
<widget class="QCheckBox" name="general_checkBox_saveDepth16bits">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -5676,29 +5712,6 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
|
||||||
<widget class="QLabel" name="label_retrieved_12">
|
|
||||||
<property name="text">
|
|
||||||
<string>Raw descriptors kept in memory.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="10" column="0">
|
|
||||||
<widget class="QCheckBox" name="general_checkBox_keepDescriptors">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="12" column="0">
|
<item row="12" column="0">
|
||||||
<widget class="QSpinBox" name="spinBox_imagePreDecimation">
|
<widget class="QSpinBox" name="spinBox_imagePreDecimation">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
@@ -5709,10 +5722,10 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="1">
|
<item row="15" column="1">
|
||||||
<widget class="QLabel" name="label_retrieved_13">
|
<widget class="QLabel" name="label_retrieved_14">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Image pre decimation. This option can be used to reduce image size before features extraction.</string>
|
<string>If > 0 and laser scans are 3D without normals, normals will be computed with K search neighbors when creating a signature.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -5722,6 +5735,25 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="15" column="0">
|
||||||
|
<widget class="QSpinBox" name="general_spinBox_laserScanNormalK">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
Reference in New Issue
Block a user