From 9f296c67b267ff00266c1fb9642ecc0bba9ba696 Mon Sep 17 00:00:00 2001 From: matlabbe Date: Fri, 10 Jun 2016 20:12:13 -0400 Subject: [PATCH] GUI: Added more parameters for 3D projection grid map --- .../include/rtabmap/gui/PreferencesDialog.h | 13 +- guilib/src/MainWindow.cpp | 254 +++++++----- guilib/src/PreferencesDialog.cpp | 96 ++++- guilib/src/ui/DatabaseViewer.ui | 165 ++++---- guilib/src/ui/preferencesDialog.ui | 392 ++++++++++++++---- 5 files changed, 666 insertions(+), 254 deletions(-) diff --git a/guilib/include/rtabmap/gui/PreferencesDialog.h b/guilib/include/rtabmap/gui/PreferencesDialog.h index dca639f3..14a86f0b 100644 --- a/guilib/include/rtabmap/gui/PreferencesDialog.h +++ b/guilib/include/rtabmap/gui/PreferencesDialog.h @@ -147,6 +147,9 @@ public: bool isGraphsShown() const; bool isLabelsShown() const; + double getMapVoxel() const; + double getMapNoiseRadius() const; + int getMapNoiseMinNeighbors() const; bool isCloudsShown(int index) const; // 0=map, 1=odom int getCloudDecimation(int index) const; // 0=map, 1=odom double getCloudMaxDepth(int index) const; // 0=map, 1=odom @@ -172,9 +175,15 @@ public: double getSubtractFilteringAngle() const; bool getGridMapShown() const; - double getGridMapResolution() const; - bool isGridMapFrom3DCloud() const; + double getGridMapResolution() const;; bool isGridMapEroded() const; + bool isGridMapFrom3DCloud() const; + bool projMapFrame() const; + double projMaxGroundAngle() const; + double projMaxGroundHeight() const; + int projMinClusterSize() const; + double projMaxObstaclesHeight() const; + bool projFlatObstaclesDetected() const; double getGridMapOpacity() const; bool isCloudMeshing() const; diff --git a/guilib/src/MainWindow.cpp b/guilib/src/MainWindow.cpp index 0597be3b..1ebd7563 100644 --- a/guilib/src/MainWindow.cpp +++ b/guilib/src/MainWindow.cpp @@ -1891,10 +1891,14 @@ void MainWindow::updateMapCloud( } else if(_createdClouds.find(iter->first) == _createdClouds.end() && _cachedSignatures.contains(iter->first)) { - this->createAndAddCloudToMap(iter->first, iter->second, uValue(mapIds, iter->first, -1)); - if(_createdClouds.find(iter->first) != _createdClouds.end()) + if((_cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)) || + _projectionLocalMaps.find(iter->first) == _projectionLocalMaps.end()) { - _cloudViewer->setCloudVisibility(cloudName.c_str(), _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)); + this->createAndAddCloudToMap(iter->first, iter->second, uValue(mapIds, iter->first, -1)); + if(_createdClouds.find(iter->first) != _createdClouds.end()) + { + _cloudViewer->setCloudVisibility(cloudName.c_str(), _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)); + } } } } @@ -2255,135 +2259,185 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int indices.get(), _preferencesDialog->getAllParameters()); + // filtering pipeline + if(indices->size() && _preferencesDialog->getMapVoxel() > 0.0) + { + cloudWithoutNormals = util3d::voxelize(cloudWithoutNormals, indices, _preferencesDialog->getMapVoxel()); + //generate indices for all points (they are all valid) + indices->resize(cloudWithoutNormals->size()); + for(unsigned int i=0; isize(); ++i) + { + indices->at(i) = i; + } + } + + // Do radius filtering after voxel filtering ( a lot faster) + if(indices->size() && + _preferencesDialog->getMapNoiseRadius() > 0.0 && + _preferencesDialog->getMapNoiseMinNeighbors() > 0) + { + indices = rtabmap::util3d::radiusFiltering( + cloudWithoutNormals, + indices, + _preferencesDialog->getMapNoiseRadius(), + _preferencesDialog->getMapNoiseMinNeighbors()); + } + //compute normals pcl::PointCloud::Ptr cloud = util3d::computeNormals(cloudWithoutNormals, 10); - if(indices->size() && _preferencesDialog->isGridMapFrom3DCloud()) + if(indices->size() && + _preferencesDialog->isGridMapFrom3DCloud() && + _projectionLocalMaps.find(nodeId) == _projectionLocalMaps.end()) { UTimer timer; - float cellSize = _preferencesDialog->getGridMapResolution(); - float groundNormalMaxAngle = M_PI_4; - int minClusterSize = 20; cv::Mat ground, obstacles; - pcl::PointCloud::Ptr voxelCloud = util3d::voxelize(cloudWithoutNormals, indices, cellSize); + pcl::PointCloud::Ptr voxelCloud = cloudWithoutNormals; + + // voxelize to grid cell size + if(_preferencesDialog->getMapVoxel() < _preferencesDialog->getGridMapResolution()) + { + voxelCloud = util3d::voxelize(voxelCloud, indices, _preferencesDialog->getGridMapResolution()); + } // add pose rotation without yaw - float roll, pitch, yaw; - pose.getEulerAngles(roll, pitch, yaw); - voxelCloud = util3d::transformPointCloud(voxelCloud, Transform(0,0,0, roll, pitch, 0)); + if(_preferencesDialog->projMapFrame()) + { + float roll, pitch, yaw; + pose.getEulerAngles(roll, pitch, yaw); + voxelCloud = util3d::transformPointCloud(voxelCloud, Transform(0,0, pose.z(), roll, pitch, 0)); + } + + if(_preferencesDialog->projMaxObstaclesHeight()) + { + voxelCloud = util3d::passThrough(voxelCloud, "z", std::numeric_limits::min(), _preferencesDialog->projMaxObstaclesHeight()); + } util3d::occupancy2DFromCloud3D( voxelCloud, ground, obstacles, - cellSize, - groundNormalMaxAngle, - minClusterSize); + _preferencesDialog->getGridMapResolution(), + _preferencesDialog->projMaxGroundAngle(), + _preferencesDialog->projMinClusterSize(), + _preferencesDialog->projFlatObstaclesDetected(), + _preferencesDialog->projMaxGroundHeight()); if(!ground.empty() || !obstacles.empty()) { _projectionLocalMaps.insert(std::make_pair(nodeId, std::make_pair(ground, obstacles))); } - UDEBUG("time gridMapFrom2DCloud = %f s", timer.ticks()); + UDEBUG("time gridMapFrom3DCloud = %f s", timer.ticks()); } - if(_preferencesDialog->isSubtractFiltering() && - _preferencesDialog->getSubtractFilteringRadius() > 0.0) + if(_cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)) { - pcl::IndicesPtr beforeFiltering = indices; - if( cloud->size() && - _previousCloud.first>0 && - _previousCloud.second.first.get() != 0 && - _previousCloud.second.second.get() != 0 && - _previousCloud.second.second->size() && - _currentPosesMap.find(_previousCloud.first) != _currentPosesMap.end()) + if(_preferencesDialog->isSubtractFiltering() && + _preferencesDialog->getSubtractFilteringRadius() > 0.0) { - UTimer time; + pcl::IndicesPtr beforeFiltering = indices; + if( cloud->size() && + _previousCloud.first>0 && + _previousCloud.second.first.get() != 0 && + _previousCloud.second.second.get() != 0 && + _previousCloud.second.second->size() && + _currentPosesMap.find(_previousCloud.first) != _currentPosesMap.end()) + { + UTimer time; - rtabmap::Transform t = pose.inverse() * _currentPosesMap.at(_previousCloud.first); - pcl::PointCloud::Ptr previousCloud = rtabmap::util3d::transformPointCloud(_previousCloud.second.first, t); + rtabmap::Transform t = pose.inverse() * _currentPosesMap.at(_previousCloud.first); + pcl::PointCloud::Ptr previousCloud = rtabmap::util3d::transformPointCloud(_previousCloud.second.first, t); - //UWARN("saved new.pcd and old.pcd"); - //pcl::io::savePCDFile("new.pcd", *cloud, *indices); - //pcl::io::savePCDFile("old.pcd", *previousCloud, *_previousCloud.second.second); + //UWARN("saved new.pcd and old.pcd"); + //pcl::io::savePCDFile("new.pcd", *cloud, *indices); + //pcl::io::savePCDFile("old.pcd", *previousCloud, *_previousCloud.second.second); - indices = rtabmap::util3d::subtractFiltering( - cloud, - indices, - previousCloud, - _previousCloud.second.second, - _preferencesDialog->getSubtractFilteringRadius(), - _preferencesDialog->getSubtractFilteringAngle(), - _preferencesDialog->getSubtractFilteringMinPts()); - UWARN("Time subtract filtering %d from %d -> %d (%fs)", - (int)_previousCloud.second.second->size(), - (int)beforeFiltering->size(), - (int)indices->size(), - time.ticks()); + indices = rtabmap::util3d::subtractFiltering( + cloud, + indices, + previousCloud, + _previousCloud.second.second, + _preferencesDialog->getSubtractFilteringRadius(), + _preferencesDialog->getSubtractFilteringAngle(), + _preferencesDialog->getSubtractFilteringMinPts()); + UWARN("Time subtract filtering %d from %d -> %d (%fs)", + (int)_previousCloud.second.second->size(), + (int)beforeFiltering->size(), + (int)indices->size(), + time.ticks()); + } + // keep all indices for next subtraction + _previousCloud.first = nodeId; + _previousCloud.second.first = cloud; + _previousCloud.second.second = beforeFiltering; } - // keep all indices for next subtraction - _previousCloud.first = nodeId; - _previousCloud.second.first = cloud; - _previousCloud.second.second = beforeFiltering; - } - // keep substracted clouds - _createdClouds.insert(std::make_pair(nodeId, std::make_pair(cloud, indices))); + // keep substracted clouds + _createdClouds.insert(std::make_pair(nodeId, std::make_pair(cloud, indices))); - if(indices->size()) - { - if(_preferencesDialog->isCloudMeshing() && cloud->isOrganized()) + if(indices->size()) { - // Fast organized mesh - pcl::PointCloud::Ptr output; - // we need to extract indices as pcl::OrganizedFastMesh doesn't take indices - output = util3d::extractIndices(cloud, indices, false, true); - Eigen::Vector3f viewpoint(0.0f,0.0f,0.0f); - if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull()) + if(_preferencesDialog->isCloudMeshing() && cloud->isOrganized()) { - viewpoint[0] = data.cameraModels()[0].localTransform().x(); - viewpoint[1] = data.cameraModels()[0].localTransform().y(); - viewpoint[2] = data.cameraModels()[0].localTransform().z(); - } - else if(!data.stereoCameraModel().localTransform().isNull()) - { - viewpoint[0] = data.stereoCameraModel().localTransform().x(); - viewpoint[1] = data.stereoCameraModel().localTransform().y(); - viewpoint[2] = data.stereoCameraModel().localTransform().z(); - } - std::vector polygons = util3d::organizedFastMesh( - output, - _preferencesDialog->getCloudMeshingAngle(), - _preferencesDialog->isCloudMeshingQuad(), - _preferencesDialog->getCloudMeshingTriangleSize(), - viewpoint); - if(polygons.size()) - { - // remove unused vertices to save memory - pcl::PointCloud::Ptr outputFiltered(new pcl::PointCloud); - std::vector outputPolygons; - util3d::filterNotUsedVerticesFromMesh(*output, polygons, *outputFiltered, outputPolygons); - if(!_cloudViewer->addCloudMesh(cloudName, outputFiltered, outputPolygons, pose)) + // Fast organized mesh + pcl::PointCloud::Ptr output; + // we need to extract indices as pcl::OrganizedFastMesh doesn't take indices + output = util3d::extractIndices(cloud, indices, false, true); + Eigen::Vector3f viewpoint(0.0f,0.0f,0.0f); + if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull()) { - UERROR("Adding mesh cloud %d to viewer failed!", nodeId); + viewpoint[0] = data.cameraModels()[0].localTransform().x(); + viewpoint[1] = data.cameraModels()[0].localTransform().y(); + viewpoint[2] = data.cameraModels()[0].localTransform().z(); + } + else if(!data.stereoCameraModel().localTransform().isNull()) + { + viewpoint[0] = data.stereoCameraModel().localTransform().x(); + viewpoint[1] = data.stereoCameraModel().localTransform().y(); + viewpoint[2] = data.stereoCameraModel().localTransform().z(); + } + std::vector polygons = util3d::organizedFastMesh( + output, + _preferencesDialog->getCloudMeshingAngle(), + _preferencesDialog->isCloudMeshingQuad(), + _preferencesDialog->getCloudMeshingTriangleSize(), + viewpoint); + if(polygons.size()) + { + // remove unused vertices to save memory + pcl::PointCloud::Ptr outputFiltered(new pcl::PointCloud); + std::vector outputPolygons; + util3d::filterNotUsedVerticesFromMesh(*output, polygons, *outputFiltered, outputPolygons); + if(!_cloudViewer->addCloudMesh(cloudName, outputFiltered, outputPolygons, pose)) + { + UERROR("Adding mesh cloud %d to viewer failed!", nodeId); + } + } + } + else + { + if(_preferencesDialog->isCloudMeshing()) + { + UWARN("Online meshing is activated but the generated cloud is " + "dense (voxel filtering is used or multiple cameras are used). Disable " + "online meshing in Preferences->3D Rendering to hide this warning."); + } + pcl::PointCloud::Ptr output; + // don't keep organized to save memory + output = util3d::extractIndices(cloud, indices, false, false); + QColor color = Qt::gray; + if(mapId >= 0) + { + color = (Qt::GlobalColor)(mapId+3 % 12 + 7 ); + } + + if(!_cloudViewer->addCloud(cloudName, output, pose, color)) + { + UERROR("Adding cloud %d to viewer failed!", nodeId); } } } - else - { - pcl::PointCloud::Ptr output; - // don't keep organized to save memory - output = util3d::extractIndices(cloud, indices, false, false); - QColor color = Qt::gray; - if(mapId >= 0) - { - color = (Qt::GlobalColor)(mapId+3 % 12 + 7 ); - } - - if(!_cloudViewer->addCloud(cloudName, output, pose, color)) - { - UERROR("Adding cloud %d to viewer failed!", nodeId); - } - } + _cloudViewer->setCloudOpacity(cloudName, _preferencesDialog->getCloudOpacity(0)); + _cloudViewer->setCloudPointSize(cloudName, _preferencesDialog->getCloudPointSize(0)); } } else @@ -2391,8 +2445,6 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int return; } - _cloudViewer->setCloudOpacity(cloudName, _preferencesDialog->getCloudOpacity(0)); - _cloudViewer->setCloudPointSize(cloudName, _preferencesDialog->getCloudPointSize(0)); UDEBUG(""); } diff --git a/guilib/src/PreferencesDialog.cpp b/guilib/src/PreferencesDialog.cpp index e99c1cbd..74872617 100644 --- a/guilib/src/PreferencesDialog.cpp +++ b/guilib/src/PreferencesDialog.cpp @@ -348,6 +348,9 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) : connect(_3dRenderingPtSizeScan[i], SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_3dRenderingPtSizeFeatures[i], SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); } + connect(_ui->doubleSpinBox_voxel, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->doubleSpinBox_noiseRadius, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->spinBox_noiseMinNeighbors, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_ui->checkBox_showGraphs, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_ui->checkBox_showLabels, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); @@ -364,8 +367,14 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) : connect(_ui->checkBox_map_shown, SIGNAL(clicked(bool)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_ui->doubleSpinBox_map_resolution, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_ui->doubleSpinBox_map_opacity, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); - connect(_ui->checkBox_map_occupancyFrom3DCloud, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_ui->checkBox_map_erode, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->groupBox_map_occupancyFrom3DCloud, SIGNAL(clicked(bool)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->checkBox_projMapFrame, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->doubleSpinBox_projMaxGroundAngle, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->doubleSpinBox_projMaxGroundHeight, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->spinBox_projMinClusterSize, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->doubleSpinBox_projMaxObstaclesHeight, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); + connect(_ui->checkBox_projFlatObstaclesDetected, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_ui->groupBox_organized, SIGNAL(clicked(bool)), this, SLOT(makeObsoleteCloudRenderingPanel())); connect(_ui->doubleSpinBox_mesh_angleTolerance, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteCloudRenderingPanel())); @@ -1167,6 +1176,9 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox) _3dRenderingPtSizeScan[i]->setValue(2); _3dRenderingPtSizeFeatures[i]->setValue(3); } + _ui->doubleSpinBox_voxel->setValue(0); + _ui->doubleSpinBox_noiseRadius->setValue(0); + _ui->spinBox_noiseMinNeighbors->setValue(5); _ui->checkBox_showGraphs->setChecked(true); _ui->checkBox_showLabels->setChecked(false); @@ -1182,9 +1194,15 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox) _ui->checkBox_map_shown->setChecked(false); _ui->doubleSpinBox_map_resolution->setValue(0.05); - _ui->checkBox_map_occupancyFrom3DCloud->setChecked(false); _ui->checkBox_map_erode->setChecked(false); _ui->doubleSpinBox_map_opacity->setValue(0.75); + _ui->groupBox_map_occupancyFrom3DCloud->setChecked(false); + _ui->checkBox_projMapFrame->setChecked(true); + _ui->doubleSpinBox_projMaxGroundAngle->setValue(30); + _ui->doubleSpinBox_projMaxGroundHeight->setValue(0); + _ui->spinBox_projMinClusterSize->setValue(20); + _ui->doubleSpinBox_projMaxObstaclesHeight->setValue(0); + _ui->checkBox_projFlatObstaclesDetected->setChecked(true); _ui->doubleSpinBox_mesh_angleTolerance->setValue(15.0); #if PCL_VERSION_COMPARE(>=, 1, 7, 2) @@ -1512,6 +1530,10 @@ void PreferencesDialog::readGuiSettings(const QString & filePath) _3dRenderingPtSizeScan[i]->setValue(settings.value(QString("ptSizeScan%1").arg(i), _3dRenderingPtSizeScan[i]->value()).toInt()); _3dRenderingPtSizeFeatures[i]->setValue(settings.value(QString("ptSizeFeatures%1").arg(i), _3dRenderingPtSizeFeatures[i]->value()).toInt()); } + _ui->doubleSpinBox_voxel->setValue(settings.value("cloudVoxel", _ui->doubleSpinBox_voxel->value()).toDouble()); + _ui->doubleSpinBox_noiseRadius->setValue(settings.value("cloudNoiseRadius", _ui->doubleSpinBox_noiseRadius->value()).toDouble()); + _ui->spinBox_noiseMinNeighbors->setValue(settings.value("cloudNoiseMinNeighbors", _ui->spinBox_noiseMinNeighbors->value()).toInt()); + _ui->checkBox_showGraphs->setChecked(settings.value("showGraphs", _ui->checkBox_showGraphs->isChecked()).toBool()); _ui->checkBox_showLabels->setChecked(settings.value("showLabels", _ui->checkBox_showLabels->isChecked()).toBool()); @@ -1526,9 +1548,15 @@ void PreferencesDialog::readGuiSettings(const QString & filePath) _ui->checkBox_map_shown->setChecked(settings.value("gridMapShown", _ui->checkBox_map_shown->isChecked()).toBool()); _ui->doubleSpinBox_map_resolution->setValue(settings.value("gridMapResolution", _ui->doubleSpinBox_map_resolution->value()).toDouble()); - _ui->checkBox_map_occupancyFrom3DCloud->setChecked(settings.value("gridMapOccupancyFrom3DCloud", _ui->checkBox_map_occupancyFrom3DCloud->isChecked()).toBool()); _ui->checkBox_map_erode->setChecked(settings.value("gridMapEroded", _ui->checkBox_map_erode->isChecked()).toBool()); _ui->doubleSpinBox_map_opacity->setValue(settings.value("gridMapOpacity", _ui->doubleSpinBox_map_opacity->value()).toDouble()); + _ui->groupBox_map_occupancyFrom3DCloud->setChecked(settings.value("gridMapOccupancyFrom3DCloud", _ui->groupBox_map_occupancyFrom3DCloud->isChecked()).toBool()); + _ui->checkBox_projMapFrame->setChecked(settings.value("projMapFrame", _ui->checkBox_projMapFrame->isChecked()).toBool()); + _ui->doubleSpinBox_projMaxGroundAngle->setValue(settings.value("projMaxGroundAngle", _ui->doubleSpinBox_projMaxGroundAngle->value()).toDouble()); + _ui->doubleSpinBox_projMaxGroundHeight->setValue(settings.value("projMaxGroundHeight", _ui->doubleSpinBox_projMaxGroundHeight->value()).toDouble()); + _ui->spinBox_projMinClusterSize->setValue(settings.value("projMinClusterSize", _ui->spinBox_projMinClusterSize->value()).toInt()); + _ui->doubleSpinBox_projMaxObstaclesHeight->setValue(settings.value("projMaxObstaclesHeight", _ui->doubleSpinBox_projMaxObstaclesHeight->value()).toDouble()); + _ui->checkBox_projFlatObstaclesDetected->setChecked(settings.value("projFlatObstaclesDetected", _ui->checkBox_projFlatObstaclesDetected->isChecked()).toBool()); _ui->groupBox_organized->setChecked(settings.value("meshing", _ui->groupBox_organized->isChecked()).toBool()); _ui->doubleSpinBox_mesh_angleTolerance->setValue(settings.value("meshing_angle", _ui->doubleSpinBox_mesh_angleTolerance->value()).toDouble()); @@ -1904,6 +1932,10 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const settings.setValue(QString("ptSizeScan%1").arg(i), _3dRenderingPtSizeScan[i]->value()); settings.setValue(QString("ptSizeFeatures%1").arg(i), _3dRenderingPtSizeFeatures[i]->value()); } + settings.setValue("cloudVoxel", _ui->doubleSpinBox_voxel->value()); + settings.setValue("cloudNoiseRadius", _ui->doubleSpinBox_noiseRadius->value()); + settings.setValue("cloudNoiseMinNeighbors", _ui->spinBox_noiseMinNeighbors->value()); + settings.setValue("showGraphs", _ui->checkBox_showGraphs->isChecked()); settings.setValue("showLabels", _ui->checkBox_showLabels->isChecked()); @@ -1914,14 +1946,22 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const settings.setValue("subtractFiltering", _ui->radioButton_subtractFiltering->isChecked()); settings.setValue("subtractFilteringMinPts", _ui->spinBox_subtractFilteringMinPts->value()); settings.setValue("subtractFilteringRadius", _ui->doubleSpinBox_subtractFilteringRadius->value()); - settings.setValue("subtractFilteringAngle", _ui->doubleSpinBox_subtractFilteringAngle->value()); + settings.setValue("subtractFilteringAngle", _ui->doubleSpinBox_subtractFilteringAngle->value()); settings.setValue("gridMapShown", _ui->checkBox_map_shown->isChecked()); settings.setValue("gridMapResolution", _ui->doubleSpinBox_map_resolution->value()); - settings.setValue("gridMapOccupancyFrom3DCloud", _ui->checkBox_map_occupancyFrom3DCloud->isChecked()); settings.setValue("gridMapEroded", _ui->checkBox_map_erode->isChecked()); settings.setValue("gridMapOpacity", _ui->doubleSpinBox_map_opacity->value()); + settings.setValue("gridMapOccupancyFrom3DCloud", _ui->groupBox_map_occupancyFrom3DCloud->isChecked()); + settings.setValue("projMapFrame", _ui->checkBox_projMapFrame->isChecked()); + settings.setValue("projMaxGroundAngle", _ui->doubleSpinBox_projMaxGroundAngle->value()); + settings.setValue("projMaxGroundHeight", _ui->doubleSpinBox_projMaxGroundHeight->value()); + settings.setValue("projMinClusterSize", _ui->spinBox_projMinClusterSize->value()); + settings.setValue("projMaxObstaclesHeight", _ui->doubleSpinBox_projMaxObstaclesHeight->value()); + settings.setValue("projFlatObstaclesDetected", _ui->checkBox_projFlatObstaclesDetected->isChecked()); + + settings.setValue("meshing", _ui->groupBox_organized->isChecked()); settings.setValue("meshing_angle", _ui->doubleSpinBox_mesh_angleTolerance->value()); settings.setValue("meshing_quad", _ui->checkBox_mesh_quad->isChecked()); @@ -3558,6 +3598,20 @@ bool PreferencesDialog::isCloudsShown(int index) const UASSERT(index >= 0 && index <= 1); return _3dRenderingShowClouds[index]->isChecked(); } + +double PreferencesDialog::getMapVoxel() const +{ + return _ui->doubleSpinBox_voxel->value(); +} +double PreferencesDialog::getMapNoiseRadius() const +{ + return _ui->doubleSpinBox_noiseRadius->value(); +} +int PreferencesDialog::getMapNoiseMinNeighbors() const +{ + return _ui->spinBox_noiseMinNeighbors->value(); +} + bool PreferencesDialog::isGraphsShown() const { return _ui->checkBox_showGraphs->isChecked(); @@ -3681,14 +3735,38 @@ double PreferencesDialog::getGridMapResolution() const { return _ui->doubleSpinBox_map_resolution->value(); } -bool PreferencesDialog::isGridMapFrom3DCloud() const -{ - return _ui->checkBox_map_occupancyFrom3DCloud->isChecked(); -} bool PreferencesDialog::isGridMapEroded() const { return _ui->checkBox_map_erode->isChecked(); } +bool PreferencesDialog::isGridMapFrom3DCloud() const +{ + return _ui->groupBox_map_occupancyFrom3DCloud->isChecked(); +} +bool PreferencesDialog::projMapFrame() const +{ + return _ui->checkBox_projMapFrame->isChecked(); +} +double PreferencesDialog::projMaxGroundAngle() const +{ + return _ui->doubleSpinBox_projMaxGroundAngle->value()*M_PI/180.0; +} +double PreferencesDialog::projMaxGroundHeight() const +{ + return _ui->doubleSpinBox_projMaxGroundHeight->value(); +} +int PreferencesDialog::projMinClusterSize() const +{ + return _ui->spinBox_projMinClusterSize->value(); +} +double PreferencesDialog::projMaxObstaclesHeight() const +{ + return _ui->doubleSpinBox_projMaxObstaclesHeight->value(); +} +bool PreferencesDialog::projFlatObstaclesDetected() const +{ + return _ui->checkBox_projFlatObstaclesDetected->isChecked(); +} double PreferencesDialog::getGridMapOpacity() const { return _ui->doubleSpinBox_map_opacity->value(); diff --git a/guilib/src/ui/DatabaseViewer.ui b/guilib/src/ui/DatabaseViewer.ui index e81065ef..aab22087 100644 --- a/guilib/src/ui/DatabaseViewer.ui +++ b/guilib/src/ui/DatabaseViewer.ui @@ -21,16 +21,7 @@ 0 - - 0 - - - 0 - - - 0 - - + 0 @@ -61,7 +52,7 @@ 0 0 - 205 + 201 196 @@ -219,7 +210,7 @@ 0 0 - 204 + 201 196 @@ -366,16 +357,7 @@ - - 12 - - - 12 - - - 12 - - + 12 @@ -431,16 +413,7 @@ - - 12 - - - 12 - - - 12 - - + 12 @@ -1007,14 +980,14 @@ - 3 + 1 0 0 - 340 + 333 186 @@ -1149,9 +1122,9 @@ 0 - 0 - 282 - 611 + -236 + 297 + 704 @@ -1225,7 +1198,7 @@ true - false + true @@ -1355,6 +1328,81 @@ + + + + Flat obstacles detected + + + + + + + m + + + 2 + + + 0.000000000000000 + + + 999.000000000000000 + + + 1.000000000000000 + + + 0.000000000000000 + + + + + + + Max ground height + + + + + + + Max obstacles height + + + + + + + m + + + 2 + + + 0.000000000000000 + + + 999.000000000000000 + + + 1.000000000000000 + + + 0.000000000000000 + + + + + + + + + + true + + + @@ -1561,8 +1609,8 @@ 0 0 - 205 - 117 + 290 + 182 @@ -1661,8 +1709,8 @@ 0 0 - 267 - 157 + 290 + 182 @@ -1761,16 +1809,7 @@ 0 - - 0 - - - 0 - - - 0 - - + 0 @@ -1883,16 +1922,7 @@ 0 - - 0 - - - 0 - - - 0 - - + 0 @@ -1946,16 +1976,7 @@ - - 0 - - - 0 - - - 0 - - + 0 diff --git a/guilib/src/ui/preferencesDialog.ui b/guilib/src/ui/preferencesDialog.ui index 283baa0c..58c727b2 100644 --- a/guilib/src/ui/preferencesDialog.ui +++ b/guilib/src/ui/preferencesDialog.ui @@ -63,7 +63,7 @@ 0 - -477 + -269 686 2023 @@ -86,7 +86,7 @@ QFrame::Raised - 3 + 1 @@ -629,7 +629,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - When the Graph view is visible or if the "Show in 3D map view" below is checked, the grid map is generated using the laser scans. + When the Graph View is visible or if the "Show in 3D map view" below is checked, the grid map is generated using the laser scans or from 3D projection of the clouds (when activated below). true @@ -713,30 +713,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - - - - - - - false - - - - - - Occupancy from 3D cloud projection on the ground. Laser scans are ignored when activated. - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - Erode. @@ -749,7 +726,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -761,6 +738,191 @@ Show a yellow background when the number of odometry inliers goes under this thr + + + + Occupancy from 3D cloud projection on the ground + + + true + + + + + + Note that 3D cloud filtering stuff under Map columns below are applied before the projection (except for floor and ceiling filterings). + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + + + + false + + + + + + + Projection in map frame. On a 3D terrain and a fixed local camera transform (the cloud is created relative to ground), you may want to disable this to do the projection in robot frame instead. + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + deg + + + 0 + + + 0.000000000000000 + + + 180.000000000000000 + + + 30.000000000000000 + + + + + + + Maximum ground normal angle + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + 1 + + + 10000 + + + 20 + + + + + + + Mininum cluster size. + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + + + false + + + + + + + Flat obstacles detected + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + m + + + 2 + + + 99999.000000000000000 + + + + + + + Maximum ground height (0=disabled). + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + m + + + 2 + + + 9999.000000000000000 + + + + + + + Maximum obstacles height (0=disabled). + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + @@ -773,7 +935,7 @@ Show a yellow background when the number of odometry inliers goes under this thr QFrame::Raised - + @@ -783,7 +945,20 @@ Show a yellow background when the number of odometry inliers goes under this thr - + + + + Show scans. + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + @@ -802,19 +977,6 @@ Show a yellow background when the number of odometry inliers goes under this thr - - - - Show scans. - - - true - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - @@ -828,7 +990,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -838,7 +1000,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -912,7 +1074,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 1 @@ -925,7 +1087,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -970,7 +1132,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 3D cloud opacity. @@ -983,7 +1145,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 1 @@ -996,7 +1158,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 1 @@ -1006,7 +1168,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + Scan point size (1..64). @@ -1019,7 +1181,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + m @@ -1038,7 +1200,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + Scan voxel size. @@ -1051,7 +1213,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 1 @@ -1061,7 +1223,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + Scan opacity. @@ -1097,7 +1259,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -1116,7 +1278,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -1126,7 +1288,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + Show graphs. @@ -1139,7 +1301,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -1149,7 +1311,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -1168,7 +1330,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 1 @@ -1188,7 +1350,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + Show labels. @@ -1201,7 +1363,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + @@ -1211,7 +1373,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + m @@ -1230,7 +1392,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + Scan downsampling step size. @@ -1243,7 +1405,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 1 @@ -1253,7 +1415,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 3D cloud point size (1..64). @@ -1279,7 +1441,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + Show 3D features. @@ -1292,7 +1454,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + Feature point size. @@ -1305,7 +1467,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 1 @@ -1315,7 +1477,7 @@ Show a yellow background when the number of odometry inliers goes under this thr - + 1 @@ -1379,6 +1541,96 @@ Show a yellow background when the number of odometry inliers goes under this thr + + + + m + + + 3 + + + 1.000000000000000 + + + 0.010000000000000 + + + 0.000000000000000 + + + + + + + 3D cloud voxel filtering size (0=disabled). + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + 1 + + + 1000 + + + 5 + + + + + + + 3D cloud noise filtering radius (0=disabled). Done after voxel filtering. + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + m + + + 3 + + + 1.000000000000000 + + + 0.050000000000000 + + + 0.000000000000000 + + + + + + + 3D cloud noise filtering min neighbors. + + + true + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + +