mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Added visualization cloud filtering
git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@1077 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
@@ -122,8 +122,6 @@ protected:
|
||||
|
||||
private:
|
||||
void createMenu();
|
||||
bool frustumCulling(const pcl::PointXYZ & cloud);
|
||||
pcl::IndicesPtr frustumCulling(const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud);
|
||||
void mouseEventOccurred (const pcl::visualization::MouseEvent &event, void* viewer_void);
|
||||
|
||||
private:
|
||||
@@ -137,14 +135,12 @@ private:
|
||||
QAction * _aClearTrajectory;
|
||||
QAction * _aShowGrid;
|
||||
QAction * _aSetBackgroundColor;
|
||||
QAction * _setFarPlaneDistance;
|
||||
QMenu * _menu;
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr _trajectory;
|
||||
unsigned int _maxTrajectorySize;
|
||||
QMap<std::string, Transform> _addedClouds; // include meshes
|
||||
QMap<std::string, Transform> _addedClouds; // include cloud, scan, meshes
|
||||
Transform _lastPose;
|
||||
std::list<std::string> _gridLines;
|
||||
float _farPlaneDistance;
|
||||
QSet<Qt::Key> _keysPressed;
|
||||
};
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ signals:
|
||||
private:
|
||||
void update3DMapVisibility(bool cloudsShown, bool scansShown);
|
||||
void updateMapCloud(const std::map<int, Transform> & poses, const Transform & pose);
|
||||
std::map<int, Transform> radiusPosesFiltering(const std::map<int, Transform> & poses) const;
|
||||
void drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords, const std::multimap<int, cv::KeyPoint> & loopWords);
|
||||
void setupMainLayout(bool vertical);
|
||||
void updateSelectSourceImageMenu(int type);
|
||||
|
||||
@@ -125,6 +125,10 @@ public:
|
||||
double getScanOpacity(int index) const; // 0=map, 1=odom, 2=save
|
||||
int getScanPointSize(int index) const; // 0=map, 1=odom, 2=save
|
||||
|
||||
bool isCloudFiltering() const;
|
||||
double getCloudFilteringRadius() const;
|
||||
double getCloudFilteringAngle() const;
|
||||
|
||||
QString getWorkingDirectory() const;
|
||||
QString getDatabasePath() const;
|
||||
|
||||
|
||||
@@ -51,12 +51,10 @@ CloudViewer::CloudViewer(QWidget *parent) :
|
||||
_aClearTrajectory(0),
|
||||
_aShowGrid(0),
|
||||
_aSetBackgroundColor(0),
|
||||
_setFarPlaneDistance(0),
|
||||
_menu(0),
|
||||
_trajectory(new pcl::PointCloud<pcl::PointXYZ>),
|
||||
_maxTrajectorySize(100),
|
||||
_lastPose(Transform::getIdentity()),
|
||||
_farPlaneDistance(10000)
|
||||
_lastPose(Transform::getIdentity())
|
||||
{
|
||||
this->setMinimumSize(200, 200);
|
||||
|
||||
@@ -106,7 +104,6 @@ void CloudViewer::createMenu()
|
||||
_aShowGrid = new QAction("Show grid", this);
|
||||
_aShowGrid->setCheckable(true);
|
||||
_aSetBackgroundColor = new QAction("Set background color...", this);
|
||||
_setFarPlaneDistance = new QAction("Set far plane distance...", this);
|
||||
|
||||
QMenu * cameraMenu = new QMenu("Camera", this);
|
||||
cameraMenu->addAction(_aLockCamera);
|
||||
@@ -114,7 +111,6 @@ void CloudViewer::createMenu()
|
||||
cameraMenu->addAction(freeCamera);
|
||||
cameraMenu->addSeparator();
|
||||
cameraMenu->addAction(_aLockViewZ);
|
||||
cameraMenu->addAction(_setFarPlaneDistance);
|
||||
cameraMenu->addAction(_aResetCamera);
|
||||
QActionGroup * group = new QActionGroup(this);
|
||||
group->addAction(_aLockCamera);
|
||||
@@ -483,81 +479,9 @@ void CloudViewer::render()
|
||||
|
||||
}
|
||||
|
||||
// frustum
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
cloud->resize(_addedClouds.size());
|
||||
int i=0;
|
||||
for(QMap<std::string, Transform>::iterator iter = _addedClouds.begin(); iter!=_addedClouds.end(); ++iter)
|
||||
{
|
||||
(*cloud)[i++] = pcl::PointXYZ(iter.value().x(), iter.value().y(), iter.value().z());
|
||||
}
|
||||
|
||||
pcl::IndicesPtr indices = frustumCulling(cloud);
|
||||
std::set<int> visibleClouds(indices->begin(), indices->end());
|
||||
i=0;
|
||||
for(QMap<std::string, Transform>::iterator iter = _addedClouds.begin(); iter!=_addedClouds.end(); ++iter)
|
||||
{
|
||||
this->setCloudVisibility(iter.key(), visibleClouds.find(i) != visibleClouds.end());
|
||||
++i;
|
||||
}
|
||||
|
||||
this->GetRenderWindow()->Render();
|
||||
}
|
||||
|
||||
bool CloudViewer::frustumCulling(const pcl::PointXYZ & point)
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
cloud->push_back(point);
|
||||
pcl::IndicesPtr indices = frustumCulling(cloud);
|
||||
return indices->size() != 0;
|
||||
}
|
||||
|
||||
pcl::IndicesPtr CloudViewer::frustumCulling(const pcl::PointCloud<pcl::PointXYZ>::Ptr & cloud)
|
||||
{
|
||||
pcl::IndicesPtr indices(new std::vector<int>());
|
||||
if(cloud->size())
|
||||
{
|
||||
if(_farPlaneDistance)
|
||||
{
|
||||
std::vector<pcl::visualization::Camera> cameras;
|
||||
_visualizer->getCameras(cameras);
|
||||
|
||||
Eigen::Vector3f vPosToFocal = Eigen::Vector3f(cameras.front().focal[0] - cameras.front().pos[0],
|
||||
cameras.front().focal[1] - cameras.front().pos[1],
|
||||
cameras.front().focal[2] - cameras.front().pos[2]).normalized();
|
||||
Eigen::Vector3f zAxis(cameras.front().view[0], cameras.front().view[1], cameras.front().view[2]);
|
||||
Eigen::Vector3f yAxis = zAxis.cross(vPosToFocal);
|
||||
Eigen::Vector3f xAxis = vPosToFocal.normalized();
|
||||
zAxis = xAxis.cross(yAxis);
|
||||
Transform PR(xAxis[0], yAxis[0], zAxis[0],0,
|
||||
xAxis[1], yAxis[1], zAxis[1],0,
|
||||
xAxis[2], yAxis[2], zAxis[2],0);
|
||||
Transform P(PR[0], PR[1], PR[2], cameras.front().pos[0],
|
||||
PR[4], PR[5], PR[6], cameras.front().pos[1],
|
||||
PR[8], PR[9], PR[10], cameras.front().pos[2]);
|
||||
|
||||
pcl::FrustumCulling<pcl::PointXYZ> fc;
|
||||
fc.setInputCloud (cloud);
|
||||
fc.setNearPlaneDistance (0.0);
|
||||
fc.setFarPlaneDistance (_farPlaneDistance);
|
||||
//float fov = cameras.front().fovy*180.0f/3.14159265359;
|
||||
fc.setVerticalFOV (52);
|
||||
fc.setHorizontalFOV (52);
|
||||
fc.setCameraPose (util3d::transformToEigen4f(P));
|
||||
fc.filter (*indices);
|
||||
}
|
||||
else
|
||||
{
|
||||
indices->resize(cloud->size());
|
||||
for(unsigned int i=0; i<indices->size(); ++i)
|
||||
{
|
||||
indices->at(i) = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
||||
void CloudViewer::setBackgroundColor(const QColor & color)
|
||||
{
|
||||
_visualizer->setBackgroundColor(color.redF(), color.greenF(), color.blueF());
|
||||
@@ -612,7 +536,40 @@ void CloudViewer::setCloudPointSize(const std::string & id, int size)
|
||||
}
|
||||
}
|
||||
|
||||
Eigen::Vector3f rotatePointAroundAxe(
|
||||
const Eigen::Vector3f & point,
|
||||
const Eigen::Vector3f & axis,
|
||||
float angle)
|
||||
{
|
||||
Eigen::Vector3f direction = point;
|
||||
Eigen::Vector3f zAxis = axis;
|
||||
float dotProdZ = zAxis.dot(direction);
|
||||
Eigen::Vector3f ptOnZaxis = zAxis * dotProdZ;
|
||||
direction -= ptOnZaxis;
|
||||
Eigen::Vector3f xAxis = direction.normalized();
|
||||
Eigen::Vector3f yAxis = zAxis.cross(xAxis);
|
||||
|
||||
Eigen::Matrix3f newFrame;
|
||||
newFrame << xAxis[0], yAxis[0], zAxis[0],
|
||||
xAxis[1], yAxis[1], zAxis[1],
|
||||
xAxis[2], yAxis[2], zAxis[2];
|
||||
|
||||
// transform to axe frame
|
||||
// transpose=inverse for orthogonal matrices
|
||||
Eigen::Vector3f newDirection = newFrame.transpose() * direction;
|
||||
|
||||
// rotate about z
|
||||
float cosTheta = cos(angle);
|
||||
float sinTheta = sin(angle);
|
||||
float magnitude = newDirection.norm();
|
||||
newDirection[0] = ( magnitude * cosTheta );
|
||||
newDirection[1] = ( magnitude * sinTheta );
|
||||
|
||||
// transform back to global frame
|
||||
direction = newFrame * newDirection;
|
||||
|
||||
return direction + ptOnZaxis;
|
||||
}
|
||||
|
||||
void CloudViewer::keyReleaseEvent(QKeyEvent * event) {
|
||||
if(event->key() == Qt::Key_Up ||
|
||||
@@ -643,9 +600,11 @@ void CloudViewer::keyPressEvent(QKeyEvent * event)
|
||||
//update camera position
|
||||
Eigen::Vector3f pos(cameras.front().pos[0], cameras.front().pos[1], _aLockViewZ->isChecked()?0:cameras.front().pos[2]);
|
||||
Eigen::Vector3f focal(cameras.front().focal[0], cameras.front().focal[1], _aLockViewZ->isChecked()?0:cameras.front().focal[2]);
|
||||
Eigen::Vector3f viewUp(0, 0, 1);
|
||||
Eigen::Vector3f viewUp(cameras.front().view[0], cameras.front().view[1], cameras.front().view[2]);
|
||||
Eigen::Vector3f cummulatedDir(0,0,0);
|
||||
Eigen::Vector3f cummulatedFocalDir(0,0,0);
|
||||
float step = 0.2f;
|
||||
float stepRot = 0.02f; // radian
|
||||
if(_keysPressed.contains(Qt::Key_Up))
|
||||
{
|
||||
Eigen::Vector3f dir;
|
||||
@@ -674,21 +633,43 @@ void CloudViewer::keyPressEvent(QKeyEvent * event)
|
||||
}
|
||||
if(_keysPressed.contains(Qt::Key_Right))
|
||||
{
|
||||
Eigen::Vector3f dir = ((focal-pos).cross(viewUp)).normalized() * step; // strafing right
|
||||
cummulatedDir += dir;
|
||||
if(event->modifiers() & Qt::ShiftModifier)
|
||||
{
|
||||
// rotate right
|
||||
Eigen::Vector3f point = (focal-pos);
|
||||
Eigen::Vector3f newPoint = rotatePointAroundAxe(point, viewUp, -stepRot);
|
||||
Eigen::Vector3f diff = newPoint - point;
|
||||
cummulatedFocalDir += diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
Eigen::Vector3f dir = ((focal-pos).cross(viewUp)).normalized() * step; // strafing right
|
||||
cummulatedDir += dir;
|
||||
}
|
||||
}
|
||||
if(_keysPressed.contains(Qt::Key_Left))
|
||||
{
|
||||
Eigen::Vector3f dir = ((focal-pos).cross(viewUp)).normalized() * -step; // strafing left
|
||||
cummulatedDir += dir;
|
||||
if(event->modifiers() & Qt::ShiftModifier)
|
||||
{
|
||||
// rotate left
|
||||
Eigen::Vector3f point = (focal-pos);
|
||||
Eigen::Vector3f newPoint = rotatePointAroundAxe(point, viewUp, stepRot);
|
||||
Eigen::Vector3f diff = newPoint - point;
|
||||
cummulatedFocalDir += diff;
|
||||
}
|
||||
else
|
||||
{
|
||||
Eigen::Vector3f dir = ((focal-pos).cross(viewUp)).normalized() * -step; // strafing left
|
||||
cummulatedDir += dir;
|
||||
}
|
||||
}
|
||||
|
||||
cameras.front().pos[0] += cummulatedDir[0];
|
||||
cameras.front().pos[1] += cummulatedDir[1];
|
||||
cameras.front().pos[2] += cummulatedDir[2];
|
||||
cameras.front().focal[0] += cummulatedDir[0];
|
||||
cameras.front().focal[1] += cummulatedDir[1];
|
||||
cameras.front().focal[2] += cummulatedDir[2];
|
||||
cameras.front().focal[0] += cummulatedDir[0] + cummulatedFocalDir[0];
|
||||
cameras.front().focal[1] += cummulatedDir[1] + cummulatedFocalDir[1];
|
||||
cameras.front().focal[2] += cummulatedDir[2] + cummulatedFocalDir[2];
|
||||
_visualizer->setCameraPosition(
|
||||
cameras.front().pos[0], cameras.front().pos[1], cameras.front().pos[2],
|
||||
cameras.front().focal[0], cameras.front().focal[1], cameras.front().focal[2],
|
||||
@@ -734,7 +715,6 @@ void CloudViewer::handleAction(QAction * a)
|
||||
-1, 0, 0,
|
||||
0, 0, 0,
|
||||
0, 0, 1);
|
||||
_farPlaneDistance = 10000;
|
||||
this->render();
|
||||
}
|
||||
else if(a == _aShowGrid)
|
||||
@@ -779,15 +759,6 @@ void CloudViewer::handleAction(QAction * a)
|
||||
color = QColorDialog::getColor(color, this);
|
||||
this->setBackgroundColor(color);
|
||||
}
|
||||
else if(a == _setFarPlaneDistance)
|
||||
{
|
||||
bool ok;
|
||||
double distance = QInputDialog::getDouble(this, tr("Far plane distance"), tr("Clipping plane distance"), _farPlaneDistance, 1, 10000, 0, &ok);
|
||||
if(ok)
|
||||
{
|
||||
_farPlaneDistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace rtabmap */
|
||||
|
||||
@@ -133,7 +133,7 @@ GraphViewer::GraphViewer(QWidget * parent) :
|
||||
_loopClosureColor(Qt::red),
|
||||
_root(0),
|
||||
_nodeRadius(0.1),
|
||||
_linkWidth(0.15),
|
||||
_linkWidth(0),
|
||||
_gridMap(0)
|
||||
{
|
||||
this->setScene(new QGraphicsScene(this));
|
||||
|
||||
@@ -71,10 +71,12 @@
|
||||
#include "rtabmap/core/util3d.h"
|
||||
#include <pcl/visualization/cloud_viewer.h>
|
||||
#include <pcl/common/transforms.h>
|
||||
#include <pcl/common/common.h>
|
||||
#include <pcl/io/pcd_io.h>
|
||||
#include <pcl/io/ply_io.h>
|
||||
#include <pcl/io/vtk_io.h>
|
||||
#include <pcl/filters/filter.h>
|
||||
#include <pcl/search/kdtree.h>
|
||||
|
||||
#define LOG_FILE_NAME "LogRtabmap.txt"
|
||||
#define SHARE_SHOW_LOG_FILE "share/rtabmap/showlogs.m"
|
||||
@@ -128,17 +130,6 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
||||
_ui->setupUi(this);
|
||||
|
||||
QString title("RTAB-Map: Real-Time Appearance-Based Mapping");
|
||||
#if DEMO_BUILD
|
||||
title.append(" [DEMO]");
|
||||
_ui->actionDump_the_prediction_matrix->setVisible(false);
|
||||
_ui->actionDump_the_memory->setVisible(false);
|
||||
_ui->actionGenerate_map->setVisible(false);
|
||||
_ui->actionGenerate_local_map->setVisible(false);
|
||||
_ui->actionPause_on_local_loop_detection->setVisible(false);
|
||||
_ui->menuImage->setEnabled(false);
|
||||
_ui->doubleSpinBox_stats_timeLimit->setEnabled(false);
|
||||
_ui->label_timeLimit->setEnabled(false);
|
||||
#endif
|
||||
this->setWindowTitle(title);
|
||||
this->setWindowIconText(tr("RTAB-Map"));
|
||||
|
||||
@@ -1021,11 +1012,11 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
||||
_processingStatistics = false;
|
||||
}
|
||||
|
||||
void MainWindow::updateMapCloud(const std::map<int, Transform> & poses, const Transform & currentPose)
|
||||
void MainWindow::updateMapCloud(const std::map<int, Transform> & posesIn, const Transform & currentPose)
|
||||
{
|
||||
if(poses.size())
|
||||
if(posesIn.size())
|
||||
{
|
||||
_currentPosesMap = poses;
|
||||
_currentPosesMap = posesIn;
|
||||
if(_currentPosesMap.size() && !_ui->actionSave_point_cloud->isEnabled())
|
||||
{
|
||||
//enable save cloud action
|
||||
@@ -1036,6 +1027,17 @@ void MainWindow::updateMapCloud(const std::map<int, Transform> & poses, const Tr
|
||||
}
|
||||
}
|
||||
|
||||
// filter duplicated poses
|
||||
std::map<int, Transform> poses;
|
||||
if(_preferencesDialog->isCloudFiltering())
|
||||
{
|
||||
poses = radiusPosesFiltering(posesIn);
|
||||
}
|
||||
else
|
||||
{
|
||||
poses = posesIn;
|
||||
}
|
||||
|
||||
// Map updated! regenerate the assembled cloud, last pose is the new one
|
||||
UDEBUG("Update map with %d locations (currentPose=%s)", poses.size(), currentPose.prettyPrint().c_str());
|
||||
QMap<std::string, Transform> viewerClouds = _ui->widget_cloudViewer->getAddedClouds();
|
||||
@@ -1227,6 +1229,89 @@ void MainWindow::updateNodeVisibility(int nodeId, bool visible)
|
||||
_ui->widget_cloudViewer->render();
|
||||
}
|
||||
|
||||
std::map<int, Transform> MainWindow::radiusPosesFiltering(const std::map<int, Transform> & poses) const
|
||||
{
|
||||
float radius = _preferencesDialog->getCloudFilteringRadius();
|
||||
float angle = _preferencesDialog->getCloudFilteringAngle()*3.14159265359/180.0; // convert to rad
|
||||
if(poses.size() > 1 && radius > 0.0f && angle>0.0f)
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
|
||||
cloud->resize(poses.size());
|
||||
int i=0;
|
||||
for(std::map<int, Transform>::const_iterator iter = poses.begin(); iter!=poses.end(); ++iter)
|
||||
{
|
||||
(*cloud)[i++] = pcl::PointXYZ(iter->second.x(), iter->second.y(), iter->second.z());
|
||||
}
|
||||
|
||||
// radius filtering
|
||||
std::vector<int> names = uKeys(poses);
|
||||
std::vector<Transform> transforms = uValues(poses);
|
||||
|
||||
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ> (false));
|
||||
tree->setInputCloud(cloud);
|
||||
std::set<int> indicesChecked;
|
||||
std::set<int> indicesKept;
|
||||
|
||||
for(unsigned int i=0; i<cloud->size(); ++i)
|
||||
{
|
||||
// ignore scans
|
||||
if(indicesChecked.find(i) == indicesChecked.end())
|
||||
{
|
||||
std::vector<int> kIndices;
|
||||
std::vector<float> kDistances;
|
||||
tree->radiusSearch(cloud->at(i), radius, kIndices, kDistances);
|
||||
|
||||
std::set<int> cloudIndices;
|
||||
const Transform & currentT = transforms.at(i);
|
||||
Eigen::Vector3f vA = util3d::transformToEigen3f(currentT).rotation()*Eigen::Vector3f(1,0,0);
|
||||
for(unsigned int j=0; j<kIndices.size(); ++j)
|
||||
{
|
||||
if(indicesChecked.find(kIndices[j]) == indicesChecked.end())
|
||||
{
|
||||
const Transform & checkT = transforms.at(kIndices[j]);
|
||||
// same orientation?
|
||||
Eigen::Vector3f vB = util3d::transformToEigen3f(checkT).rotation()*Eigen::Vector3f(1,0,0);
|
||||
double a = pcl::getAngle3D(Eigen::Vector4f(vA[0], vA[1], vA[2], 0), Eigen::Vector4f(vB[0], vB[1], vB[2], 0));
|
||||
if(a <= angle)
|
||||
{
|
||||
cloudIndices.insert(kIndices[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool firstAdded = false;
|
||||
for(std::set<int>::reverse_iterator iter = cloudIndices.rbegin(); iter!=cloudIndices.rend(); ++iter)
|
||||
{
|
||||
if(!firstAdded)
|
||||
{
|
||||
indicesKept.insert(*iter);
|
||||
firstAdded = true;
|
||||
}
|
||||
indicesChecked.insert(*iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//pcl::IndicesPtr indicesOut(new std::vector<int>);
|
||||
//indicesOut->insert(indicesOut->end(), indicesKept.begin(), indicesKept.end());
|
||||
UINFO("Cloud filtered In = %d, Out = %d", cloud->size(), indicesKept.size());
|
||||
//pcl::io::savePCDFile("duplicateIn.pcd", *cloud);
|
||||
//pcl::io::savePCDFile("duplicateOut.pcd", *cloud, *indicesOut);
|
||||
|
||||
std::map<int, Transform> keptPoses;
|
||||
for(std::set<int>::iterator iter = indicesKept.begin(); iter!=indicesKept.end(); ++iter)
|
||||
{
|
||||
keptPoses.insert(std::make_pair(names.at(*iter), transforms.at(*iter)));
|
||||
}
|
||||
|
||||
return keptPoses;
|
||||
}
|
||||
else
|
||||
{
|
||||
return poses;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::processRtabmapEventInit(int status, const QString & info)
|
||||
{
|
||||
if((RtabmapEventInit::Status)status == RtabmapEventInit::kInitializing)
|
||||
|
||||
@@ -69,63 +69,12 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui = new Ui_preferencesDialog();
|
||||
_ui->setupUi(this);
|
||||
|
||||
#ifdef DEMO_BUILD
|
||||
_ui->groupBox_sourceImage->setEnabled(false);
|
||||
_ui->general_checkBox_activateRGBD->setEnabled(false);
|
||||
_ui->general_checkBox_activateRGBD_2->setEnabled(false);
|
||||
_ui->label_activateRGBD->setEnabled(false);
|
||||
_ui->label_activateRGBD_2->setEnabled(false);
|
||||
_ui->general_doubleSpinBox_timeThr->setEnabled(false);
|
||||
_ui->general_doubleSpinBox_timeThr_2->setEnabled(false);
|
||||
_ui->label_timeLimit->setEnabled(false);
|
||||
_ui->label_timeLimit_2->setEnabled(false);
|
||||
_ui->doubleSpinBox_similarityThreshold->setEnabled(false);
|
||||
_ui->doubleSpinBox_similarityThreshold_2->setEnabled(false);
|
||||
_ui->label_similarity->setEnabled(false);
|
||||
_ui->label_similarity_2->setEnabled(false);
|
||||
_ui->general_checkBox_publishStats->setEnabled(false);
|
||||
_ui->general_checkBox_publishStats_2->setEnabled(false);
|
||||
_ui->label_publishStat->setEnabled(false);
|
||||
_ui->general_spinBox_memoryThr->setEnabled(false);
|
||||
_ui->label_maxWmSize->setEnabled(false);
|
||||
_ui->groupBox_publishing->setEnabled(false);
|
||||
_ui->groupBox_statistics->setEnabled(false);
|
||||
_ui->general_doubleSpinBox_recentWmRatio->setEnabled(false);
|
||||
_ui->label_ratioRecent->setEnabled(false);
|
||||
_ui->general_spinBox_maxRetrieved->setEnabled(false);
|
||||
_ui->label_retrieved->setEnabled(false);
|
||||
_ui->general_checkBox_RehearsalIdUpdatedToNewOne->setEnabled(false);
|
||||
_ui->label_rehearsalIdUpdate->setEnabled(false);
|
||||
_ui->general_checkBox_keepRawData->setEnabled(false);
|
||||
_ui->label_keepRawData->setEnabled(false);
|
||||
_ui->general_checkBox_keepRehearsedNodes->setEnabled(false);
|
||||
_ui->label_keepRehearsed->setEnabled(false);
|
||||
_ui->checkBox_kp_publishKeypoints->setEnabled(false);
|
||||
_ui->label_publishWords->setEnabled(false);
|
||||
_ui->checkBox_dictionary_incremental->setEnabled(false);
|
||||
_ui->label_incrementalDict->setEnabled(false);
|
||||
_ui->label_dictionaryPath->setEnabled(false);
|
||||
_ui->lineEdit_dictionaryPath->setEnabled(false);
|
||||
_ui->toolButton_dictionaryPath->setEnabled(false);
|
||||
_ui->groupBox_vh_strategy1->setEnabled(false);
|
||||
_ui->odomScanHistory->setEnabled(false);
|
||||
_ui->label_scanMatching->setEnabled(false);
|
||||
_ui->localDetection_maxNeighbors->setEnabled(false);
|
||||
_ui->localDetection_space->setEnabled(false);
|
||||
_ui->localDetection_radius->setEnabled(false);
|
||||
_ui->label_space1->setEnabled(false);
|
||||
_ui->label_space2->setEnabled(false);
|
||||
_ui->label_space3->setEnabled(false);
|
||||
_ui->loopClosure_icpType->setEnabled(false);
|
||||
_ui->surf_checkBox_gpuVersion->setEnabled(false);
|
||||
_ui->label_surf_checkBox_gpuVersion->setEnabled(false);
|
||||
#else
|
||||
if(cv::gpu::getCudaEnabledDeviceCount() == 0)
|
||||
{
|
||||
_ui->surf_checkBox_gpuVersion->setEnabled(false);
|
||||
_ui->label_surf_checkBox_gpuVersion->setEnabled(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
_ui->predictionPlot->showLegend(false);
|
||||
|
||||
QButtonGroup * buttonGroup = new QButtonGroup(this);
|
||||
@@ -217,6 +166,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
}
|
||||
}
|
||||
|
||||
connect(_ui->groupBox_poseFiltering, SIGNAL(clicked(bool)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->doubleSpinBox_cloudFilterRadius, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
connect(_ui->doubleSpinBox_cloudFilterAngle, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel()));
|
||||
|
||||
//Logging panel
|
||||
connect(_ui->comboBox_loggerLevel, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteLoggingPanel()));
|
||||
connect(_ui->comboBox_loggerEventLevel, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteLoggingPanel()));
|
||||
@@ -748,6 +701,10 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
||||
_3dRenderingMeshing[i]->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
_ui->groupBox_poseFiltering->setChecked(false);
|
||||
_ui->doubleSpinBox_cloudFilterRadius->setValue(0.5);
|
||||
_ui->doubleSpinBox_cloudFilterAngle->setValue(30);
|
||||
}
|
||||
else if(groupBox->objectName() == _ui->groupBox_logging1->objectName())
|
||||
{
|
||||
@@ -857,15 +814,11 @@ QString PreferencesDialog::getDatabasePath() const
|
||||
|
||||
QString PreferencesDialog::getIniFilePath() const
|
||||
{
|
||||
#ifdef DEMO_BUILD
|
||||
QString privatePath = ".";
|
||||
#else
|
||||
QString privatePath = QDir::homePath() + "/.rtabmap";
|
||||
if(!QDir(privatePath).exists())
|
||||
{
|
||||
QDir::home().mkdir(".rtabmap");
|
||||
}
|
||||
#endif
|
||||
return privatePath + "/rtabmap.ini";
|
||||
}
|
||||
|
||||
@@ -961,6 +914,10 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
|
||||
}
|
||||
}
|
||||
|
||||
_ui->groupBox_poseFiltering->setChecked(settings.value("cloudFiltering", _ui->groupBox_poseFiltering->isChecked()).toBool());
|
||||
_ui->doubleSpinBox_cloudFilterRadius->setValue(settings.value("cloudFilteringRadius", _ui->doubleSpinBox_cloudFilterRadius->value()).toDouble());
|
||||
_ui->doubleSpinBox_cloudFilterAngle->setValue(settings.value("cloudFilteringAngle", _ui->doubleSpinBox_cloudFilterAngle->value()).toDouble());
|
||||
|
||||
settings.endGroup(); // General
|
||||
|
||||
settings.endGroup(); // rtabmap
|
||||
@@ -1159,6 +1116,9 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath)
|
||||
settings.setValue(tr("meshing%1").arg(i), _3dRenderingMeshing[i]->isChecked());
|
||||
}
|
||||
}
|
||||
settings.setValue("cloudFiltering", _ui->groupBox_poseFiltering->isChecked());
|
||||
settings.setValue("cloudFilteringRadius", _ui->doubleSpinBox_cloudFilterRadius->value());
|
||||
settings.setValue("cloudFilteringAngle", _ui->doubleSpinBox_cloudFilterAngle->value());
|
||||
|
||||
settings.endGroup(); // General
|
||||
|
||||
@@ -1325,11 +1285,11 @@ void PreferencesDialog::showEvent ( QShowEvent * event )
|
||||
_ui->lineEdit_workingDirectory->setEnabled(true);
|
||||
_ui->toolButton_workingDirectory->setEnabled(true);
|
||||
_ui->label_workingDirectory->setEnabled(true);
|
||||
#ifndef DEMO_BUILD
|
||||
|
||||
_ui->lineEdit_dictionaryPath->setEnabled(true);
|
||||
_ui->toolButton_dictionaryPath->setEnabled(true);
|
||||
_ui->label_dictionaryPath->setEnabled(true);
|
||||
#endif
|
||||
|
||||
_ui->groupBox_source0->setEnabled(true);
|
||||
_ui->groupBox_odometry2->setEnabled(true);
|
||||
|
||||
@@ -2375,6 +2335,18 @@ int PreferencesDialog::getScanPointSize(int index) const
|
||||
UASSERT(index >= 0 && index <= 1);
|
||||
return _3dRenderingPtSizeScan[index]->value();
|
||||
}
|
||||
bool PreferencesDialog::isCloudFiltering() const
|
||||
{
|
||||
return _ui->groupBox_poseFiltering->isChecked();
|
||||
}
|
||||
double PreferencesDialog::getCloudFilteringRadius() const
|
||||
{
|
||||
return _ui->doubleSpinBox_cloudFilterRadius->value();
|
||||
}
|
||||
double PreferencesDialog::getCloudFilteringAngle() const
|
||||
{
|
||||
return _ui->doubleSpinBox_cloudFilterAngle->value();
|
||||
}
|
||||
|
||||
// Source
|
||||
double PreferencesDialog::getGeneralInputRate() const
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user