mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
StereoCameraModel: baseline computed with Tx of left camera too. Fixed QMultiComboBox not showing on windows. Avoid updating grid view if there are no local grids in signatrues. Clear cached data of StatsItem when detecting smaller timestamp than last ones.
This commit is contained in:
@@ -97,7 +97,7 @@ public:
|
|||||||
bool save(const std::string & directory, bool ignoreStereoTransform = true) const;
|
bool save(const std::string & directory, bool ignoreStereoTransform = true) const;
|
||||||
bool saveStereoTransform(const std::string & directory) const;
|
bool saveStereoTransform(const std::string & directory) const;
|
||||||
|
|
||||||
double baseline() const {return right_.fx()!=0.0?-right_.Tx()/right_.fx():0.0;}
|
double baseline() const {return right_.fx()!=0.0 && left_.fx() != 0.0 ? left_.Tx() / left_.fx() - right_.Tx()/right_.fx():0.0;}
|
||||||
|
|
||||||
float computeDepth(float disparity) const;
|
float computeDepth(float disparity) const;
|
||||||
float computeDisparity(float depth) const; // m
|
float computeDisparity(float depth) const; // m
|
||||||
|
|||||||
@@ -2918,13 +2918,19 @@ std::map<int, std::map<int, Transform> > Rtabmap::getPaths(std::map<int, Transfo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UASSERT_MSG(path.size(), uFormat("nearestId=%d ids=%d", nearestId, (int)ids.size()).c_str());
|
if (path.size())
|
||||||
if(maxGraphDepth > 0 && !_memory->isGraphReduced() && (int)path.size() > maxGraphDepth*2+1)
|
|
||||||
{
|
{
|
||||||
UWARN("%s=Off but path(%d) > maxGraphDepth(%d)*2+1, nearestId=%d ids=%d. Is reduce graph activated before?",
|
if (maxGraphDepth > 0 && !_memory->isGraphReduced() && (int)path.size() > maxGraphDepth * 2 + 1)
|
||||||
Parameters::kMemReduceGraph().c_str(), (int)path.size(), maxGraphDepth, nearestId, (int)ids.size());
|
{
|
||||||
|
UWARN("%s=Off but path(%d) > maxGraphDepth(%d)*2+1, nearestId=%d ids=%d. Is reduce graph activated before?",
|
||||||
|
Parameters::kMemReduceGraph().c_str(), (int)path.size(), maxGraphDepth, nearestId, (int)ids.size());
|
||||||
|
}
|
||||||
|
paths.insert(std::make_pair(nearestId, path));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UWARN(uFormat("path.size()=0!? nearestId=%d ids=%d", (int)path.size(), nearestId, (int)ids.size()).c_str());
|
||||||
}
|
}
|
||||||
paths.insert(std::make_pair(nearestId, path));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ public:
|
|||||||
int getOdomQualityWarnThr() const;
|
int getOdomQualityWarnThr() const;
|
||||||
bool isPosteriorGraphView() const;
|
bool isPosteriorGraphView() const;
|
||||||
bool isOdomDisabled() const;
|
bool isOdomDisabled() const;
|
||||||
|
bool isGroundTruthAligned() const;
|
||||||
|
|
||||||
bool isGraphsShown() const;
|
bool isGraphsShown() const;
|
||||||
bool isLabelsShown() const;
|
bool isLabelsShown() const;
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ public:
|
|||||||
std::vector<float> xValues() const {return _x;}
|
std::vector<float> xValues() const {return _x;}
|
||||||
std::vector<float> yValues() const {return _y;}
|
std::vector<float> yValues() const {return _y;}
|
||||||
void setCacheOn(bool on);
|
void setCacheOn(bool on);
|
||||||
|
void clearCache();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateMenu(const QMenu * menu);
|
void updateMenu(const QMenu * menu);
|
||||||
@@ -106,6 +107,7 @@ public slots:
|
|||||||
void updateStat(const QString & statFullName, float y, bool cacheOn);
|
void updateStat(const QString & statFullName, float y, bool cacheOn);
|
||||||
void updateStat(const QString & statFullName, float x, float y, bool cacheOn);
|
void updateStat(const QString & statFullName, float x, float y, bool cacheOn);
|
||||||
void updateStat(const QString & statFullName, const std::vector<float> & x, const std::vector<float> & y, bool cacheOn);
|
void updateStat(const QString & statFullName, const std::vector<float> & x, const std::vector<float> & y, bool cacheOn);
|
||||||
|
void clear();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void menuChanged(const QMenu *);
|
void menuChanged(const QMenu *);
|
||||||
|
|||||||
12
guilib/src/3rdParty/QMultiComboBox.cpp
vendored
12
guilib/src/3rdParty/QMultiComboBox.cpp
vendored
@@ -13,6 +13,7 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
|
||||||
|
#include "rtabmap/utilite/ULogger.h"
|
||||||
|
|
||||||
QMultiComboBox::QMultiComboBox(QWidget *widget ) :
|
QMultiComboBox::QMultiComboBox(QWidget *widget ) :
|
||||||
QComboBox(widget),
|
QComboBox(widget),
|
||||||
@@ -81,7 +82,6 @@ void QMultiComboBox::paintEvent(QPaintEvent *e)
|
|||||||
|
|
||||||
void QMultiComboBox::showPopup()
|
void QMultiComboBox::showPopup()
|
||||||
{
|
{
|
||||||
|
|
||||||
QRect rec = QRect(geometry());
|
QRect rec = QRect(geometry());
|
||||||
|
|
||||||
//QPoint p = this->mapToGlobal(QPoint(0,rec.height()));
|
//QPoint p = this->mapToGlobal(QPoint(0,rec.height()));
|
||||||
@@ -94,11 +94,14 @@ void QMultiComboBox::showPopup()
|
|||||||
QPoint below = this->mapToGlobal(QPoint(0,rec.height()));
|
QPoint below = this->mapToGlobal(QPoint(0,rec.height()));
|
||||||
int belowHeight = screen.bottom() - below.y();
|
int belowHeight = screen.bottom() - below.y();
|
||||||
|
|
||||||
|
// compute width
|
||||||
|
int textWidth = vlist_.sizeHint().width();
|
||||||
|
|
||||||
// first activate it with height 1px to get all the items initialized
|
// first activate it with height 1px to get all the items initialized
|
||||||
QRect rec2;
|
QRect rec2;
|
||||||
rec2.setTopLeft(below);
|
rec2.setTopLeft(below);
|
||||||
rec2.setWidth(rec.width());
|
rec2.setWidth(textWidth>rec.width()? textWidth:rec.width());
|
||||||
rec.setHeight(1);
|
rec2.setHeight(rec.height());
|
||||||
popframe_.setGeometry(rec2);
|
popframe_.setGeometry(rec2);
|
||||||
popframe_.raise();
|
popframe_.raise();
|
||||||
popframe_.show();
|
popframe_.show();
|
||||||
@@ -108,7 +111,6 @@ void QMultiComboBox::showPopup()
|
|||||||
int contheight = vlist_.count()*vlist_.sizeHintForRow(0) + 4; // +4 - should be determined by margins?
|
int contheight = vlist_.count()*vlist_.sizeHintForRow(0) + 4; // +4 - should be determined by margins?
|
||||||
belowHeight = min(abs(belowHeight)-screenbound_, contheight);
|
belowHeight = min(abs(belowHeight)-screenbound_, contheight);
|
||||||
aboveHeight = min(abs(aboveHeight)-screenbound_, contheight);
|
aboveHeight = min(abs(aboveHeight)-screenbound_, contheight);
|
||||||
|
|
||||||
if (popheight_ > 0) // fixed
|
if (popheight_ > 0) // fixed
|
||||||
{
|
{
|
||||||
rec2.setHeight(popheight_);
|
rec2.setHeight(popheight_);
|
||||||
@@ -127,7 +129,6 @@ void QMultiComboBox::showPopup()
|
|||||||
rec2.setHeight(aboveHeight);
|
rec2.setHeight(aboveHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
popframe_.setGeometry(rec2);
|
popframe_.setGeometry(rec2);
|
||||||
popframe_.raise();
|
popframe_.raise();
|
||||||
popframe_.show();
|
popframe_.show();
|
||||||
@@ -149,6 +150,7 @@ void QMultiComboBox::addItem ( const QString & text, const QVariant & userData)
|
|||||||
else
|
else
|
||||||
wi->setCheckState(Qt::Unchecked);
|
wi->setCheckState(Qt::Unchecked);
|
||||||
vlist_.addItem(wi);
|
vlist_.addItem(wi);
|
||||||
|
vlist_.setMinimumWidth(vlist_.sizeHintForColumn(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <rtabmap/utilite/UCv2Qt.h>
|
#include <rtabmap/utilite/UCv2Qt.h>
|
||||||
#include <rtabmap/utilite/UStl.h>
|
#include <rtabmap/utilite/UStl.h>
|
||||||
#include <rtabmap/utilite/ULogger.h>
|
#include <rtabmap/utilite/ULogger.h>
|
||||||
|
#include <rtabmap/utilite/UTimer.h>
|
||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
@@ -277,6 +278,7 @@ void GraphViewer::updateGraph(const std::map<int, Transform> & poses,
|
|||||||
const std::multimap<int, Link> & constraints,
|
const std::multimap<int, Link> & constraints,
|
||||||
const std::map<int, int> & mapIds)
|
const std::map<int, int> & mapIds)
|
||||||
{
|
{
|
||||||
|
UTimer timer;
|
||||||
bool wasVisible = _graphRoot->isVisible();
|
bool wasVisible = _graphRoot->isVisible();
|
||||||
_graphRoot->show();
|
_graphRoot->show();
|
||||||
|
|
||||||
@@ -488,11 +490,12 @@ void GraphViewer::updateGraph(const std::map<int, Transform> & poses,
|
|||||||
|
|
||||||
_graphRoot->setVisible(wasVisible);
|
_graphRoot->setVisible(wasVisible);
|
||||||
|
|
||||||
UDEBUG("_nodeItems=%d, _linkItems=%d", _nodeItems.size(), _linkItems.size());
|
UDEBUG("_nodeItems=%d, _linkItems=%d, timer=%fs", _nodeItems.size(), _linkItems.size(), timer.ticks());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphViewer::updateGTGraph(const std::map<int, Transform> & poses)
|
void GraphViewer::updateGTGraph(const std::map<int, Transform> & poses)
|
||||||
{
|
{
|
||||||
|
UTimer timer;
|
||||||
bool wasVisible = _gtGraphRoot->isVisible();
|
bool wasVisible = _gtGraphRoot->isVisible();
|
||||||
_gtGraphRoot->show();
|
_gtGraphRoot->show();
|
||||||
bool wasEmpty = _gtNodeItems.size() == 0 && _gtLinkItems.size() == 0;
|
bool wasEmpty = _gtNodeItems.size() == 0 && _gtLinkItems.size() == 0;
|
||||||
@@ -613,7 +616,7 @@ void GraphViewer::updateGTGraph(const std::map<int, Transform> & poses)
|
|||||||
|
|
||||||
_gtGraphRoot->setVisible(wasVisible);
|
_gtGraphRoot->setVisible(wasVisible);
|
||||||
|
|
||||||
UDEBUG("_gtNodeItems=%d, _gtLinkItems=%d", _gtNodeItems.size(), _gtLinkItems.size());
|
UDEBUG("_gtNodeItems=%d, _gtLinkItems=%d timer=%fs", _gtNodeItems.size(), _gtLinkItems.size(), timer.ticks());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphViewer::updateReferentialPosition(const Transform & t)
|
void GraphViewer::updateReferentialPosition(const Transform & t)
|
||||||
|
|||||||
@@ -942,126 +942,112 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
|
|||||||
(odom.data().cameraModels().size() || odom.data().stereoCameraModel().isValidForProjection()) &&
|
(odom.data().cameraModels().size() || odom.data().stereoCameraModel().isValidForProjection()) &&
|
||||||
_preferencesDialog->isCloudsShown(1))
|
_preferencesDialog->isCloudsShown(1))
|
||||||
{
|
{
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
||||||
if(odom.data().imageRaw().cols % _preferencesDialog->getCloudDecimation(1) != 0 ||
|
pcl::IndicesPtr indices(new std::vector<int>);
|
||||||
odom.data().imageRaw().rows % _preferencesDialog->getCloudDecimation(1) != 0)
|
cloud = util3d::cloudRGBFromSensorData(odom.data(),
|
||||||
{
|
_preferencesDialog->getCloudDecimation(1),
|
||||||
UERROR("Decimation (%d) is not modulo of the image resolution (%dx%d)! The cloud cannot be "
|
_preferencesDialog->getCloudMaxDepth(1),
|
||||||
"created. Go to Preferences->3D Rendering under \"Odom\" column to modify this parameter.",
|
_preferencesDialog->getCloudMinDepth(1),
|
||||||
_preferencesDialog->getCloudDecimation(1),
|
indices.get(),
|
||||||
odom.data().imageRaw().cols,
|
_preferencesDialog->getAllParameters());
|
||||||
odom.data().imageRaw().rows);
|
if(indices->size())
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
cloud = util3d::transformPointCloud(cloud, pose);
|
||||||
|
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
|
if(_preferencesDialog->isCloudMeshing())
|
||||||
pcl::IndicesPtr indices(new std::vector<int>);
|
|
||||||
cloud = util3d::cloudRGBFromSensorData(odom.data(),
|
|
||||||
_preferencesDialog->getCloudDecimation(1),
|
|
||||||
_preferencesDialog->getCloudMaxDepth(1),
|
|
||||||
_preferencesDialog->getCloudMinDepth(1),
|
|
||||||
indices.get(),
|
|
||||||
_preferencesDialog->getAllParameters());
|
|
||||||
if(indices->size())
|
|
||||||
{
|
{
|
||||||
cloud = util3d::transformPointCloud(cloud, pose);
|
// we need to extract indices as pcl::OrganizedFastMesh doesn't take indices
|
||||||
|
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||||
|
output = util3d::extractIndices(cloud, indices, false, true);
|
||||||
|
|
||||||
if(_preferencesDialog->isCloudMeshing())
|
// Fast organized mesh
|
||||||
|
Eigen::Vector3f viewpoint(0.0f,0.0f,0.0f);
|
||||||
|
if(odom.data().cameraModels().size() && !odom.data().cameraModels()[0].localTransform().isNull())
|
||||||
{
|
{
|
||||||
// we need to extract indices as pcl::OrganizedFastMesh doesn't take indices
|
viewpoint[0] = odom.data().cameraModels()[0].localTransform().x();
|
||||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr output(new pcl::PointCloud<pcl::PointXYZRGB>);
|
viewpoint[1] = odom.data().cameraModels()[0].localTransform().y();
|
||||||
output = util3d::extractIndices(cloud, indices, false, true);
|
viewpoint[2] = odom.data().cameraModels()[0].localTransform().z();
|
||||||
|
}
|
||||||
// Fast organized mesh
|
else if(!odom.data().stereoCameraModel().localTransform().isNull())
|
||||||
Eigen::Vector3f viewpoint(0.0f,0.0f,0.0f);
|
{
|
||||||
if(odom.data().cameraModels().size() && !odom.data().cameraModels()[0].localTransform().isNull())
|
viewpoint[0] = odom.data().stereoCameraModel().localTransform().x();
|
||||||
|
viewpoint[1] = odom.data().stereoCameraModel().localTransform().y();
|
||||||
|
viewpoint[2] = odom.data().stereoCameraModel().localTransform().z();
|
||||||
|
}
|
||||||
|
std::vector<pcl::Vertices> polygons = util3d::organizedFastMesh(
|
||||||
|
output,
|
||||||
|
_preferencesDialog->getCloudMeshingAngle(),
|
||||||
|
_preferencesDialog->isCloudMeshingQuad(),
|
||||||
|
_preferencesDialog->getCloudMeshingTriangleSize(),
|
||||||
|
Eigen::Vector3f(pose.x(), pose.y(), pose.z()) + viewpoint);
|
||||||
|
if(polygons.size())
|
||||||
|
{
|
||||||
|
if(_preferencesDialog->isCloudMeshingTexture() && !odom.data().imageRaw().empty())
|
||||||
{
|
{
|
||||||
viewpoint[0] = odom.data().cameraModels()[0].localTransform().x();
|
pcl::TextureMesh::Ptr textureMesh(new pcl::TextureMesh);
|
||||||
viewpoint[1] = odom.data().cameraModels()[0].localTransform().y();
|
pcl::toPCLPointCloud2(*cloud, textureMesh->cloud);
|
||||||
viewpoint[2] = odom.data().cameraModels()[0].localTransform().z();
|
textureMesh->tex_polygons.push_back(polygons);
|
||||||
}
|
int w = cloud->width;
|
||||||
else if(!odom.data().stereoCameraModel().localTransform().isNull())
|
int h = cloud->height;
|
||||||
{
|
UASSERT(w > 1 && h > 1);
|
||||||
viewpoint[0] = odom.data().stereoCameraModel().localTransform().x();
|
textureMesh->tex_coordinates.resize(1);
|
||||||
viewpoint[1] = odom.data().stereoCameraModel().localTransform().y();
|
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
|
||||||
viewpoint[2] = odom.data().stereoCameraModel().localTransform().z();
|
textureMesh->tex_coordinates[0].resize(nPoints);
|
||||||
}
|
for(int i=0; i<nPoints; ++i)
|
||||||
std::vector<pcl::Vertices> polygons = util3d::organizedFastMesh(
|
|
||||||
output,
|
|
||||||
_preferencesDialog->getCloudMeshingAngle(),
|
|
||||||
_preferencesDialog->isCloudMeshingQuad(),
|
|
||||||
_preferencesDialog->getCloudMeshingTriangleSize(),
|
|
||||||
Eigen::Vector3f(pose.x(), pose.y(), pose.z()) + viewpoint);
|
|
||||||
if(polygons.size())
|
|
||||||
{
|
|
||||||
if(_preferencesDialog->isCloudMeshingTexture() && !odom.data().imageRaw().empty())
|
|
||||||
{
|
{
|
||||||
pcl::TextureMesh::Ptr textureMesh(new pcl::TextureMesh);
|
//uv
|
||||||
pcl::toPCLPointCloud2(*cloud, textureMesh->cloud);
|
textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
|
||||||
textureMesh->tex_polygons.push_back(polygons);
|
float(i % w) / float(w), // u
|
||||||
int w = cloud->width;
|
float(h - i / w) / float(h)); // v
|
||||||
int h = cloud->height;
|
|
||||||
UASSERT(w > 1 && h > 1);
|
|
||||||
textureMesh->tex_coordinates.resize(1);
|
|
||||||
int nPoints = textureMesh->cloud.data.size()/textureMesh->cloud.point_step;
|
|
||||||
textureMesh->tex_coordinates[0].resize(nPoints);
|
|
||||||
for(int i=0; i<nPoints; ++i)
|
|
||||||
{
|
|
||||||
//uv
|
|
||||||
textureMesh->tex_coordinates[0][i] = Eigen::Vector2f(
|
|
||||||
float(i % w) / float(w), // u
|
|
||||||
float(h - i / w) / float(h)); // v
|
|
||||||
}
|
|
||||||
|
|
||||||
pcl::TexMaterial mesh_material;
|
|
||||||
mesh_material.tex_d = 1.0f;
|
|
||||||
mesh_material.tex_Ns = 75.0f;
|
|
||||||
mesh_material.tex_illum = 1;
|
|
||||||
|
|
||||||
mesh_material.tex_name = "material_odom";
|
|
||||||
|
|
||||||
QDir dir(_preferencesDialog->getWorkingDirectory());
|
|
||||||
ExportCloudsDialog::removeDirRecursively(_preferencesDialog->getWorkingDirectory()+QDir::separator()+"tmp_textures");
|
|
||||||
dir.mkdir("tmp_textures");
|
|
||||||
|
|
||||||
std::string tmpDirectory = dir.filePath("tmp_textures").toStdString();
|
|
||||||
mesh_material.tex_file = uFormat("%s/%s.png", tmpDirectory.c_str(), "texture_odom");
|
|
||||||
if(!cv::imwrite(mesh_material.tex_file, odom.data().imageRaw()))
|
|
||||||
{
|
|
||||||
UERROR("Cannot save texture of image odom");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UINFO("Saved temporary texture: \"%s\"", mesh_material.tex_file.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
textureMesh->tex_materials.push_back(mesh_material);
|
|
||||||
|
|
||||||
if(!_cloudViewer->addCloudTextureMesh("cloudOdom", textureMesh, _odometryCorrection))
|
|
||||||
{
|
|
||||||
UERROR("Adding cloudOdom to viewer failed!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if(!_cloudViewer->addCloudMesh("cloudOdom", output, polygons, _odometryCorrection))
|
|
||||||
|
pcl::TexMaterial mesh_material;
|
||||||
|
mesh_material.tex_d = 1.0f;
|
||||||
|
mesh_material.tex_Ns = 75.0f;
|
||||||
|
mesh_material.tex_illum = 1;
|
||||||
|
|
||||||
|
mesh_material.tex_name = "material_odom";
|
||||||
|
|
||||||
|
QDir dir(_preferencesDialog->getWorkingDirectory());
|
||||||
|
ExportCloudsDialog::removeDirRecursively(_preferencesDialog->getWorkingDirectory()+QDir::separator()+"tmp_textures");
|
||||||
|
dir.mkdir("tmp_textures");
|
||||||
|
|
||||||
|
std::string tmpDirectory = dir.filePath("tmp_textures").toStdString();
|
||||||
|
mesh_material.tex_file = uFormat("%s/%s.png", tmpDirectory.c_str(), "texture_odom");
|
||||||
|
if(!cv::imwrite(mesh_material.tex_file, odom.data().imageRaw()))
|
||||||
|
{
|
||||||
|
UERROR("Cannot save texture of image odom");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINFO("Saved temporary texture: \"%s\"", mesh_material.tex_file.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
textureMesh->tex_materials.push_back(mesh_material);
|
||||||
|
|
||||||
|
if(!_cloudViewer->addCloudTextureMesh("cloudOdom", textureMesh, _odometryCorrection))
|
||||||
{
|
{
|
||||||
UERROR("Adding cloudOdom to viewer failed!");
|
UERROR("Adding cloudOdom to viewer failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else if(!_cloudViewer->addCloudMesh("cloudOdom", output, polygons, _odometryCorrection))
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!_cloudViewer->addCloud("cloudOdom", cloud, _odometryCorrection))
|
|
||||||
{
|
{
|
||||||
UERROR("Adding cloudOdom to viewer failed!");
|
UERROR("Adding cloudOdom to viewer failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_cloudViewer->setCloudVisibility("cloudOdom", true);
|
|
||||||
_cloudViewer->setCloudOpacity("cloudOdom", _preferencesDialog->getCloudOpacity(1));
|
|
||||||
_cloudViewer->setCloudPointSize("cloudOdom", _preferencesDialog->getCloudPointSize(1));
|
|
||||||
|
|
||||||
cloudUpdated = true;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!_cloudViewer->addCloud("cloudOdom", cloud, _odometryCorrection))
|
||||||
|
{
|
||||||
|
UERROR("Adding cloudOdom to viewer failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_cloudViewer->setCloudVisibility("cloudOdom", true);
|
||||||
|
_cloudViewer->setCloudOpacity("cloudOdom", _preferencesDialog->getCloudOpacity(1));
|
||||||
|
_cloudViewer->setCloudPointSize("cloudOdom", _preferencesDialog->getCloudPointSize(1));
|
||||||
|
|
||||||
|
cloudUpdated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1436,7 +1422,9 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
signature = stat.getSignatures().at(stat.refImageId());
|
signature = stat.getSignatures().at(stat.refImageId());
|
||||||
signature.sensorData().uncompressData(); // make sure data are uncompressed
|
signature.sensorData().uncompressData(); // make sure data are uncompressed
|
||||||
|
|
||||||
if(!smallMovement && uStr2Bool(_preferencesDialog->getParameter(Parameters::kMemIncrementalMemory())))
|
if(!smallMovement &&
|
||||||
|
uStr2Bool(_preferencesDialog->getParameter(Parameters::kMemIncrementalMemory())) &&
|
||||||
|
signature.getWeight()>=0) // ignore intermediate nodes for the cache
|
||||||
{
|
{
|
||||||
_cachedSignatures.insert(signature.id(), signature);
|
_cachedSignatures.insert(signature.id(), signature);
|
||||||
_cachedMemoryUsage += signature.sensorData().getMemoryUsed();
|
_cachedMemoryUsage += signature.sensorData().getMemoryUsed();
|
||||||
@@ -2132,14 +2120,17 @@ void MainWindow::updateMapCloud(
|
|||||||
{
|
{
|
||||||
cv::Mat ground;
|
cv::Mat ground;
|
||||||
cv::Mat obstacles;
|
cv::Mat obstacles;
|
||||||
jter->sensorData().uncompressDataConst(0, 0, 0, 0, &ground, &obstacles);
|
if (jter->sensorData().gridCellSize() > 0.0f)
|
||||||
_gridLocalMaps.insert(std::make_pair(iter->first, std::make_pair(ground, obstacles)));
|
|
||||||
_gridViewPoints.insert(std::make_pair(iter->first, jter->sensorData().gridViewPoint()));
|
|
||||||
_cachedGridsMemoryUsage += ground.total()*ground.elemSize() + obstacles.total()*obstacles.elemSize();
|
|
||||||
|
|
||||||
if(ground.cols || obstacles.cols)
|
|
||||||
{
|
{
|
||||||
_occupancyGrid->addToCache(iter->first, ground, obstacles);
|
jter->sensorData().uncompressDataConst(0, 0, 0, 0, &ground, &obstacles);
|
||||||
|
_gridLocalMaps.insert(std::make_pair(iter->first, std::make_pair(ground, obstacles)));
|
||||||
|
_gridViewPoints.insert(std::make_pair(iter->first, jter->sensorData().gridViewPoint()));
|
||||||
|
_cachedGridsMemoryUsage += ground.total()*ground.elemSize() + obstacles.total()*obstacles.elemSize();
|
||||||
|
|
||||||
|
if (ground.cols || obstacles.cols)
|
||||||
|
{
|
||||||
|
_occupancyGrid->addToCache(iter->first, ground, obstacles);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef RTABMAP_OCTOMAP
|
#ifdef RTABMAP_OCTOMAP
|
||||||
@@ -3002,7 +2993,7 @@ Transform MainWindow::alignPosesToGroundTruth(
|
|||||||
const std::map<int, Transform> & groundTruth)
|
const std::map<int, Transform> & groundTruth)
|
||||||
{
|
{
|
||||||
Transform t = Transform::getIdentity();
|
Transform t = Transform::getIdentity();
|
||||||
if(groundTruth.size() && poses.size())
|
if(groundTruth.size() && poses.size() && _preferencesDialog->isGroundTruthAligned())
|
||||||
{
|
{
|
||||||
unsigned int maxSize = poses.size()>groundTruth.size()? (unsigned int)poses.size(): (unsigned int)groundTruth.size();
|
unsigned int maxSize = poses.size()>groundTruth.size()? (unsigned int)poses.size(): (unsigned int)groundTruth.size();
|
||||||
pcl::PointCloud<pcl::PointXYZ> cloud1, cloud2;
|
pcl::PointCloud<pcl::PointXYZ> cloud1, cloud2;
|
||||||
@@ -5301,6 +5292,7 @@ void MainWindow::clearTheCache()
|
|||||||
_currentLabels.clear();
|
_currentLabels.clear();
|
||||||
_odometryCorrection = Transform::getIdentity();
|
_odometryCorrection = Transform::getIdentity();
|
||||||
_lastOdomPose.setNull();
|
_lastOdomPose.setNull();
|
||||||
|
_ui->statsToolBox->clear();
|
||||||
//disable save cloud action
|
//disable save cloud action
|
||||||
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(false);
|
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(false);
|
||||||
_ui->actionExport_2D_scans_ply_pcd->setEnabled(false);
|
_ui->actionExport_2D_scans_ply_pcd->setEnabled(false);
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
connect(_ui->spinBox_odomQualityWarnThr, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
connect(_ui->spinBox_odomQualityWarnThr, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
connect(_ui->checkBox_posteriorGraphView, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
connect(_ui->checkBox_posteriorGraphView, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
connect(_ui->checkbox_odomDisabled, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
connect(_ui->checkbox_odomDisabled, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
|
connect(_ui->checkbox_groundTruthAlign, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||||
|
|
||||||
// Cloud rendering panel
|
// Cloud rendering panel
|
||||||
_3dRenderingShowClouds.resize(2);
|
_3dRenderingShowClouds.resize(2);
|
||||||
@@ -1212,6 +1213,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
|||||||
_ui->spinBox_odomQualityWarnThr->setValue(50);
|
_ui->spinBox_odomQualityWarnThr->setValue(50);
|
||||||
_ui->checkBox_posteriorGraphView->setChecked(true);
|
_ui->checkBox_posteriorGraphView->setChecked(true);
|
||||||
_ui->checkbox_odomDisabled->setChecked(false);
|
_ui->checkbox_odomDisabled->setChecked(false);
|
||||||
|
_ui->checkbox_groundTruthAlign->setChecked(true);
|
||||||
}
|
}
|
||||||
else if(groupBox->objectName() == _ui->groupBox_cloudRendering1->objectName())
|
else if(groupBox->objectName() == _ui->groupBox_cloudRendering1->objectName())
|
||||||
{
|
{
|
||||||
@@ -1595,6 +1597,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
|
|||||||
_ui->spinBox_odomQualityWarnThr->setValue(settings.value("odomQualityThr", _ui->spinBox_odomQualityWarnThr->value()).toInt());
|
_ui->spinBox_odomQualityWarnThr->setValue(settings.value("odomQualityThr", _ui->spinBox_odomQualityWarnThr->value()).toInt());
|
||||||
_ui->checkBox_posteriorGraphView->setChecked(settings.value("posteriorGraphView", _ui->checkBox_posteriorGraphView->isChecked()).toBool());
|
_ui->checkBox_posteriorGraphView->setChecked(settings.value("posteriorGraphView", _ui->checkBox_posteriorGraphView->isChecked()).toBool());
|
||||||
_ui->checkbox_odomDisabled->setChecked(settings.value("odomDisabled", _ui->checkbox_odomDisabled->isChecked()).toBool());
|
_ui->checkbox_odomDisabled->setChecked(settings.value("odomDisabled", _ui->checkbox_odomDisabled->isChecked()).toBool());
|
||||||
|
_ui->checkbox_groundTruthAlign->setChecked(settings.value("gtAlign", _ui->checkbox_groundTruthAlign->isChecked()).toBool());
|
||||||
|
|
||||||
for(int i=0; i<2; ++i)
|
for(int i=0; i<2; ++i)
|
||||||
{
|
{
|
||||||
@@ -1973,6 +1976,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
|
|||||||
settings.setValue("odomQualityThr", _ui->spinBox_odomQualityWarnThr->value());
|
settings.setValue("odomQualityThr", _ui->spinBox_odomQualityWarnThr->value());
|
||||||
settings.setValue("posteriorGraphView", _ui->checkBox_posteriorGraphView->isChecked());
|
settings.setValue("posteriorGraphView", _ui->checkBox_posteriorGraphView->isChecked());
|
||||||
settings.setValue("odomDisabled", _ui->checkbox_odomDisabled->isChecked());
|
settings.setValue("odomDisabled", _ui->checkbox_odomDisabled->isChecked());
|
||||||
|
settings.setValue("gtAlign", _ui->checkbox_groundTruthAlign->isChecked());
|
||||||
|
|
||||||
for(int i=0; i<2; ++i)
|
for(int i=0; i<2; ++i)
|
||||||
{
|
{
|
||||||
@@ -3784,6 +3788,10 @@ bool PreferencesDialog::isOdomDisabled() const
|
|||||||
{
|
{
|
||||||
return _ui->checkbox_odomDisabled->isChecked();
|
return _ui->checkbox_odomDisabled->isChecked();
|
||||||
}
|
}
|
||||||
|
bool PreferencesDialog::isGroundTruthAligned() const
|
||||||
|
{
|
||||||
|
return _ui->checkbox_groundTruthAlign->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
bool PreferencesDialog::isCloudsShown(int index) const
|
bool PreferencesDialog::isCloudsShown(int index) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,12 @@ StatItem::~StatItem()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatItem::clearCache()
|
||||||
|
{
|
||||||
|
_x.clear();
|
||||||
|
_y.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void StatItem::addValue(float y)
|
void StatItem::addValue(float y)
|
||||||
{
|
{
|
||||||
if(_cacheOn)
|
if(_cacheOn)
|
||||||
@@ -95,6 +101,11 @@ void StatItem::addValue(float x, float y)
|
|||||||
{
|
{
|
||||||
if(_cacheOn)
|
if(_cacheOn)
|
||||||
{
|
{
|
||||||
|
if (_x.size() && x <_x.back())
|
||||||
|
{
|
||||||
|
clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
if(_y.size() % 100)
|
if(_y.size() % 100)
|
||||||
{
|
{
|
||||||
_y.reserve(_y.size()+100);
|
_y.reserve(_y.size()+100);
|
||||||
@@ -511,6 +522,28 @@ void StatsToolBox::figureDeleted(QObject * obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatsToolBox::clear()
|
||||||
|
{
|
||||||
|
for (QMap<QString, QWidget*>::iterator i = _figures.begin(); i != _figures.end(); ++i)
|
||||||
|
{
|
||||||
|
QList<UPlot *> plots = i.value()->findChildren<UPlot *>();
|
||||||
|
if (plots.size() == 1)
|
||||||
|
{
|
||||||
|
QStringList names = plots[0]->curveNames();
|
||||||
|
plots[0]->clearData();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UERROR("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QList<StatItem*> items = _statBox->currentWidget()->findChildren<StatItem*>();
|
||||||
|
for (int i = 0; i<items.size(); ++i)
|
||||||
|
{
|
||||||
|
items[i]->clearCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void StatsToolBox::contextMenuEvent(QContextMenuEvent * event)
|
void StatsToolBox::contextMenuEvent(QContextMenuEvent * event)
|
||||||
{
|
{
|
||||||
QMenu topMenu(this);
|
QMenu topMenu(this);
|
||||||
@@ -524,19 +557,7 @@ void StatsToolBox::contextMenuEvent(QContextMenuEvent * event)
|
|||||||
{
|
{
|
||||||
if(action == aClearFigures)
|
if(action == aClearFigures)
|
||||||
{
|
{
|
||||||
for(QMap<QString, QWidget*>::iterator i=_figures.begin(); i!=_figures.end(); ++i)
|
this->clear();
|
||||||
{
|
|
||||||
QList<UPlot *> plots = i.value()->findChildren<UPlot *>();
|
|
||||||
if(plots.size() == 1)
|
|
||||||
{
|
|
||||||
QStringList names = plots[0]->curveNames();
|
|
||||||
plots[0]->clearData();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UERROR("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,15 +64,24 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>673</width>
|
<width>677</width>
|
||||||
<height>2520</height>
|
<height>2435</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@@ -98,16 +107,10 @@
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_28">
|
<layout class="QVBoxLayout" name="verticalLayout_28">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_39" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_39" columnstretch="0,1">
|
||||||
<item row="3" column="1">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="label_247">
|
<widget class="QCheckBox" name="checkBox_beep">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use time for figures' x-axis. Otherwise, sensor data IDs are used for camera/odometry info and for all mapping statistics, node IDs are used.</string>
|
<string/>
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="textInteractionFlags">
|
|
||||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -121,6 +124,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_247">
|
||||||
|
<property name="text">
|
||||||
|
<string>Use time for figures' x-axis. Otherwise, sensor data IDs are used for camera/odometry info and for all mapping statistics, node IDs are used.</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="1">
|
<item row="1" column="1">
|
||||||
<widget class="QLabel" name="label_313">
|
<widget class="QLabel" name="label_313">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -134,6 +150,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLabel" name="label_102">
|
||||||
|
<property name="text">
|
||||||
|
<string>Notify when a new global path is received.</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="QCheckBox" name="general_checkBox_imagesKept">
|
<widget class="QCheckBox" name="general_checkBox_imagesKept">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -144,19 +173,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QLabel" name="label_102">
|
|
||||||
<property name="text">
|
|
||||||
<string>Notify when a new global path is received.</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">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="general_checkBox_cloudsKept">
|
<widget class="QCheckBox" name="general_checkBox_cloudsKept">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -167,39 +183,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="label_59">
|
|
||||||
<property name="text">
|
|
||||||
<string>Insert new data received in the GUI cache. Used to show the loop closure image and the 3D Map.</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="QCheckBox" name="checkBox_beep">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="label_88">
|
|
||||||
<property name="text">
|
|
||||||
<string>Beep! on special events (finished processing the data set, an error has occured, ...).</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="0">
|
<item row="3" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_stamps">
|
<widget class="QCheckBox" name="checkBox_stamps">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -220,8 +203,34 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="2" column="1">
|
||||||
<widget class="QCheckBox" name="checkBox_cacheStatistics">
|
<widget class="QLabel" name="label_88">
|
||||||
|
<property name="text">
|
||||||
|
<string>Beep! on special events (finished processing the data set, an error has occured, ...).</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">
|
||||||
|
<widget class="QLabel" name="label_59">
|
||||||
|
<property name="text">
|
||||||
|
<string>Insert new data received in the GUI cache. Used to show the loop closure image and the 3D Map.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkbox_odomDisabled">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -240,8 +249,28 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QCheckBox" name="checkbox_odomDisabled">
|
<widget class="QCheckBox" name="checkBox_cacheStatistics">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QLabel" name="label_347">
|
||||||
|
<property name="text">
|
||||||
|
<string>When a ground truth is provided, align the map with it.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkbox_groundTruthAlign">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -4406,7 +4435,16 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
|||||||
<string>Directory of images (optional settings)</string>
|
<string>Directory of images (optional settings)</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_93">
|
<layout class="QVBoxLayout" name="verticalLayout_93">
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@@ -10376,7 +10414,16 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_54">
|
<widget class="QWidget" name="page_54">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_85">
|
<layout class="QVBoxLayout" name="verticalLayout_85">
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@@ -10516,7 +10563,16 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_55">
|
<widget class="QWidget" name="page_55">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_86">
|
<layout class="QVBoxLayout" name="verticalLayout_86">
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@@ -10674,7 +10730,16 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@@ -10754,7 +10819,16 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
@@ -10866,7 +10940,16 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="margin">
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
@@ -430,8 +430,8 @@ void UPlotCurve::addValue(UPlotItem * data)
|
|||||||
void UPlotCurve::addValue(float x, float y)
|
void UPlotCurve::addValue(float x, float y)
|
||||||
{
|
{
|
||||||
if(_items.size() &&
|
if(_items.size() &&
|
||||||
dynamic_cast<UPlotItem*>(_items.back()) &&
|
_minMax[0] != _minMax[1] &&
|
||||||
x < ((UPlotItem*)_items.back())->data().x())
|
x < _minMax[1])
|
||||||
{
|
{
|
||||||
UWARN("New value (%f) added to curve \"%s\" is smaller "
|
UWARN("New value (%f) added to curve \"%s\" is smaller "
|
||||||
"than the last added (%f). Clearing the curve.",
|
"than the last added (%f). Clearing the curve.",
|
||||||
|
|||||||
Reference in New Issue
Block a user