MainWindow: Added statistics about how much size the created clouds take in RAM. Avoid caching data on small movements. Export: Fixed meshing checkbox and pipeline combo box not saved/loaded. PreferencesDialog: Added option to disable caching the point clouds. computeNormals(): added viewpoint parameter. mls(): making sure that all returned normals are normalized.

This commit is contained in:
matlabbe
2016-06-12 17:53:35 -04:00
parent cb7c76889d
commit 543b8df045
12 changed files with 288 additions and 97 deletions
+3 -1
View File
@@ -281,12 +281,14 @@ private:
int _waypointsIndex;
QMap<int, Signature> _cachedSignatures;
long _cachedMemoryUsage;
std::map<int, Transform> _currentPosesMap; // <nodeId, pose>
std::map<int, Transform> _currentGTPosesMap; // <nodeId, pose>
std::multimap<int, Link> _currentLinksMap; // <nodeFromId, link>
std::map<int, int> _currentMapIds; // <nodeId, mapId>
std::map<int, std::string> _currentLabels; // <nodeId, label>
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > _createdClouds;
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > _cachedClouds;
long _createdCloudsMemoryUsage;
std::pair<int, std::pair<std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>, pcl::IndicesPtr> > _previousCloud; // used for subtraction
std::map<int, cv::Mat> _createdScans;
@@ -224,6 +224,7 @@ public:
//
bool isImagesKept() const;
bool isCloudsKept() const;
float getTimeLimit() const;
float getDetectionRate() const;
bool isSLAMMode() const;
+99 -22
View File
@@ -102,7 +102,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
connect(_ui->comboBox_upsamplingMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(updateMLSGrpVisibility()));
updateMLSGrpVisibility();
connect(_ui->groupBox_gp3, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
connect(_ui->groupBox_meshing, SIGNAL(clicked(bool)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_gp3Radius, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_gp3Mu, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
connect(_ui->doubleSpinBox_meshDecimationFactor, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
@@ -138,6 +138,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
{
settings.beginGroup(group);
}
settings.setValue("pipeline", _ui->comboBox_pipeline->currentIndex());
settings.setValue("binary", _ui->checkBox_binary->isChecked());
settings.setValue("normals_k", _ui->spinBox_normalKSearch->value());
@@ -169,7 +170,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
settings.setValue("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value());
settings.setValue("mls_dilation_iterations", _ui->spinBox_dilationSteps->value());
settings.setValue("mesh", _ui->groupBox_gp3->isChecked());
settings.setValue("mesh", _ui->groupBox_meshing->isChecked());
settings.setValue("mesh_radius", _ui->doubleSpinBox_gp3Radius->value());
settings.setValue("mesh_mu", _ui->doubleSpinBox_gp3Mu->value());
settings.setValue("mesh_decimation_factor", _ui->doubleSpinBox_meshDecimationFactor->value());
@@ -193,6 +194,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
settings.beginGroup(group);
}
_ui->comboBox_pipeline->setCurrentIndex(settings.value("pipeline", _ui->comboBox_pipeline->currentIndex()).toInt());
_ui->checkBox_binary->setChecked(settings.value("binary", _ui->checkBox_binary->isChecked()).toBool());
_ui->spinBox_normalKSearch->setValue(settings.value("normals_k", _ui->spinBox_normalKSearch->value()).toInt());
@@ -223,7 +225,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
_ui->doubleSpinBox_dilationVoxelSize->setValue(settings.value("mls_dilation_voxel_size", _ui->doubleSpinBox_dilationVoxelSize->value()).toDouble());
_ui->spinBox_dilationSteps->setValue(settings.value("mls_dilation_iterations", _ui->spinBox_dilationSteps->value()).toInt());
_ui->groupBox_gp3->setChecked(settings.value("mesh", _ui->groupBox_gp3->isChecked()).toBool());
_ui->groupBox_meshing->setChecked(settings.value("mesh", _ui->groupBox_meshing->isChecked()).toBool());
_ui->doubleSpinBox_gp3Radius->setValue(settings.value("mesh_radius", _ui->doubleSpinBox_gp3Radius->value()).toDouble());
_ui->doubleSpinBox_gp3Mu->setValue(settings.value("mesh_mu", _ui->doubleSpinBox_gp3Mu->value()).toDouble());
_ui->doubleSpinBox_meshDecimationFactor->setValue(settings.value("mesh_decimation_factor",_ui->doubleSpinBox_meshDecimationFactor->value()).toDouble());
@@ -272,7 +274,7 @@ void ExportCloudsDialog::restoreDefaults()
_ui->doubleSpinBox_dilationVoxelSize->setValue(0.01);
_ui->spinBox_dilationSteps->setValue(0);
_ui->groupBox_gp3->setChecked(false);
_ui->groupBox_meshing->setChecked(false);
_ui->doubleSpinBox_gp3Radius->setValue(0.04);
_ui->doubleSpinBox_gp3Mu->setValue(2.5);
_ui->doubleSpinBox_meshDecimationFactor->setValue(0.0);
@@ -336,7 +338,7 @@ void ExportCloudsDialog::exportClouds(
const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory,
const ParametersMap & parameters)
{
@@ -350,7 +352,7 @@ void ExportCloudsDialog::exportClouds(
poses,
mapIds,
cachedSignatures,
createdClouds,
cachedClouds,
workingDirectory,
parameters,
clouds,
@@ -388,7 +390,7 @@ void ExportCloudsDialog::viewClouds(
const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory,
const ParametersMap & parameters)
{
@@ -402,7 +404,7 @@ void ExportCloudsDialog::viewClouds(
poses,
mapIds,
cachedSignatures,
createdClouds,
cachedClouds,
workingDirectory,
parameters,
clouds,
@@ -519,7 +521,7 @@ bool ExportCloudsDialog::getExportedClouds(
const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory,
const ParametersMap & parameters,
std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & cloudsWithNormals,
@@ -555,7 +557,7 @@ bool ExportCloudsDialog::getExportedClouds(
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds = this->getClouds(
poses,
cachedSignatures,
createdClouds,
cachedClouds,
parameters);
pcl::PointCloud<pcl::PointXYZ>::Ptr rawAssembledCloud(new pcl::PointCloud<pcl::PointXYZ>);
@@ -608,10 +610,30 @@ bool ExportCloudsDialog::getExportedClouds(
clouds.insert(std::make_pair(0, std::make_pair(assembledCloud, pcl::IndicesPtr(new std::vector<int>))));
}
std::map<int, Transform> viewPoints = poses;
if(_ui->groupBox_mls->isChecked())
{
_progressDialog->appendText(tr("Smoothing the surface using Moving Least Squares (MLS) algorithm... "
"[search radius=%1m voxel=%2m]").arg(_ui->doubleSpinBox_mlsRadius->value()).arg(_ui->doubleSpinBox_voxelSize_assembled->value()));
QApplication::processEvents();
QApplication::processEvents();
// Adjust view points with local transforms
for(std::map<int, Transform>::iterator iter= viewPoints.begin(); iter!=viewPoints.end(); ++iter)
{
if(cachedSignatures.contains(iter->first))
{
const SensorData & data = cachedSignatures.find(iter->first)->sensorData();
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
{
iter->second *= data.cameraModels()[0].localTransform();
}
else if(!data.stereoCameraModel().localTransform().isNull())
{
iter->second *= data.stereoCameraModel().localTransform();
}
}
}
}
//fill cloudWithNormals
@@ -661,10 +683,11 @@ bool ExportCloudsDialog::getExportedClouds(
cloudWithNormals,
_ui->doubleSpinBox_voxelSize_assembled->value());
}
_progressDialog->appendText(tr("Update %1 normals with %2 camera views...").arg(cloudWithNormals->size()).arg(poses.size()));
util3d::adjustNormalsToViewPoints(
poses,
viewPoints,
rawAssembledCloud,
rawCameraIndices,
cloudWithNormals);
@@ -692,6 +715,7 @@ bool ExportCloudsDialog::getExportedClouds(
{
_progressDialog->appendText(tr("Organized fast mesh... "));
QApplication::processEvents();
QApplication::processEvents();
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr mergedClouds(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
std::vector<pcl::Vertices> mergedPolygons;
@@ -839,6 +863,7 @@ bool ExportCloudsDialog::getExportedClouds(
{
_progressDialog->appendText(tr("Greedy projection triangulation... [radius=%1m]").arg(_ui->doubleSpinBox_gp3Radius->value()));
QApplication::processEvents();
QApplication::processEvents();
int i=0;
for(std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr>::iterator iter=cloudsWithNormals.begin();
@@ -1018,7 +1043,7 @@ bool ExportCloudsDialog::getExportedClouds(
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > ExportCloudsDialog::getClouds(
const std::map<int, Transform> & poses,
const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const ParametersMap & parameters) const
{
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > clouds;
@@ -1065,7 +1090,22 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
}
}
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value());
// view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
if(d.cameraModels().size() && !d.cameraModels()[0].localTransform().isNull())
{
viewPoint[0] = d.cameraModels()[0].localTransform().x();
viewPoint[1] = d.cameraModels()[0].localTransform().y();
viewPoint[2] = d.cameraModels()[0].localTransform().z();
}
else if(!d.stereoCameraModel().localTransform().isNull())
{
viewPoint[0] = d.stereoCameraModel().localTransform().x();
viewPoint[1] = d.stereoCameraModel().localTransform().y();
viewPoint[2] = d.stereoCameraModel().localTransform().z();
}
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), viewPoint);
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
if(_ui->groupBox_subtraction->isChecked() &&
@@ -1117,15 +1157,15 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
UERROR("Cloud %d not found in cache!", iter->first);
}
}
else if(uContains(createdClouds, iter->first))
else if(uContains(cachedClouds, iter->first))
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudWithoutNormals;
if(!_ui->groupBox_meshing->isChecked() &&
_ui->doubleSpinBox_voxelSize_assembled->value() > 0.0)
{
cloudWithoutNormals = util3d::voxelize(
createdClouds.at(iter->first).first,
createdClouds.at(iter->first).second,
cachedClouds.at(iter->first).first,
cachedClouds.at(iter->first).second,
_ui->doubleSpinBox_voxelSize_assembled->value());
//generate indices for all points (they are all valid)
@@ -1137,12 +1177,41 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
}
else
{
cloudWithoutNormals = createdClouds.at(iter->first).first;
indices = createdClouds.at(iter->first).second;
cloudWithoutNormals = cachedClouds.at(iter->first).first;
indices = cachedClouds.at(iter->first).second;
}
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value());
// view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
if(cachedSignatures.contains(iter->first))
{
const Signature & s = cachedSignatures.find(iter->first).value();
SensorData d = s.sensorData();
if(d.cameraModels().size() && !d.cameraModels()[0].localTransform().isNull())
{
viewPoint[0] = d.cameraModels()[0].localTransform().x();
viewPoint[1] = d.cameraModels()[0].localTransform().y();
viewPoint[2] = d.cameraModels()[0].localTransform().z();
}
else if(!d.stereoCameraModel().localTransform().isNull())
{
viewPoint[0] = d.stereoCameraModel().localTransform().x();
viewPoint[1] = d.stereoCameraModel().localTransform().y();
viewPoint[2] = d.stereoCameraModel().localTransform().z();
}
}
else
{
_progressDialog->appendText(tr("Cached cloud %1 is not found in cached data, the view point for normal computation will not be set (%2/%3).").arg(iter->first).arg(++i).arg(poses.size()));
}
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), viewPoint);
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
}
else
{
_progressDialog->appendText(tr("Cached cloud %1 not found. You may want to regenerate the clouds (%2/%3).").arg(iter->first).arg(++i).arg(poses.size()));
}
if(indices->size())
{
@@ -1165,8 +1234,16 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
if(points>0)
{
_progressDialog->appendText(tr("Generated cloud %1 with %2 points and %3 indices (%4/%5).")
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size()));
if(_ui->groupBox_regenerate->isChecked())
{
_progressDialog->appendText(tr("Generated cloud %1 with %2 points and %3 indices (%4/%5).")
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size()));
}
else
{
_progressDialog->appendText(tr("Copied cloud %1 from cache with %2 points and %3 indices (%4/%5).")
.arg(iter->first).arg(points).arg(totalIndices).arg(++i).arg(poses.size()));
}
}
else
{
+4 -4
View File
@@ -63,7 +63,7 @@ public:
const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory,
const ParametersMap & parameters);
@@ -71,7 +71,7 @@ public:
const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory,
const ParametersMap & parameters);
@@ -89,13 +89,13 @@ private:
std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::IndicesPtr> > getClouds(
const std::map<int, Transform> & poses,
const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const ParametersMap & parameters) const;
bool getExportedClouds(
const std::map<int, Transform> & poses,
const std::map<int, int> & mapIds,
const QMap<int, Signature> & cachedSignatures,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & createdClouds,
const std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::IndicesPtr> > & cachedClouds,
const QString & workingDirectory,
const ParametersMap & parameters,
std::map<int, pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr> & clouds,
+71 -45
View File
@@ -145,6 +145,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_odomImageDepthShow(false),
_savedMaximized(false),
_waypointsIndex(0),
_cachedMemoryUsage(0),
_createdCloudsMemoryUsage(0),
_odometryCorrection(Transform::getIdentity()),
_processingOdometry(false),
_oneSecondTimer(0),
@@ -552,6 +554,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_ui->statsToolBox->updateStat("GUI/RGB-D cloud/ms", 0.0f);
_ui->statsToolBox->updateStat("GUI/RGB-D closure_view/ms", 0.0f);
_ui->statsToolBox->updateStat("GUI/Refresh stats/ms", 0.0f);
_ui->statsToolBox->updateStat("GUI/Cache Data Size/MB", 0.0f);
_ui->statsToolBox->updateStat("GUI/Cache Clouds Size/MB", 0.0f);
this->loadFigures();
connect(_ui->statsToolBox, SIGNAL(figuresSetupChanged()), this, SLOT(configGUIModified()));
@@ -1307,13 +1311,26 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
UDEBUG("");
bool highestHypothesisIsSaved = (bool)uValue(stat.data(), Statistics::kLoopHypothesis_reactivated(), 0.0f);
bool smallMovement = (bool)uValue(stat.data(), Statistics::kMemorySmall_movement(), 0.0f);
// update cache
Signature signature;
if(uContains(stat.getSignatures(), stat.refImageId()))
{
signature = stat.getSignatures().at(stat.refImageId());
signature.sensorData().uncompressData(); // make sure data are uncompressed
_cachedSignatures.insert(signature.id(), signature);
if(!smallMovement)
{
// keep in cache only compressed data
Signature signatureWithoutRawData = signature;
signatureWithoutRawData.sensorData().setImageRaw(cv::Mat());
signatureWithoutRawData.sensorData().setDepthOrRightRaw(cv::Mat());
signatureWithoutRawData.sensorData().setUserDataRaw(cv::Mat());
signatureWithoutRawData.sensorData().setLaserScanRaw(cv::Mat(), 0, 0);
_cachedSignatures.insert(signature.id(), signatureWithoutRawData);
_cachedMemoryUsage += signatureWithoutRawData.sensorData().getMemoryUsed();
}
}
// For intermediate empty nodes, keep latest image shown
@@ -1332,7 +1349,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
bool rehearsedSimilarity = (float)uValue(stat.data(), Statistics::kMemoryRehearsal_id(), 0.0f) != 0.0f;
int proximityTimeDetections = (int)uValue(stat.data(), Statistics::kProximityTime_detections(), 0.0f);
bool scanMatchingSuccess = (bool)uValue(stat.data(), Statistics::kNeighborLinkRefiningAccepted(), 0.0f);
bool smallMovement = (bool)uValue(stat.data(), Statistics::kMemorySmall_movement(), 0.0f);
_ui->label_stats_imageNumber->setText(QString("%1 [%2]").arg(stat.refImageId()).arg(refMapId));
if(rehearsalMerged > 0)
@@ -1437,8 +1453,9 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
QMap<int, Signature>::iterator iter = _cachedSignatures.find(shownLoopId);
if(iter != _cachedSignatures.end())
{
iter.value().sensorData().uncompressData();
// uncompress after copy to avoid keeping uncompressed data in memory
loopSignature = iter.value();
loopSignature.sensorData().uncompressData();
}
}
}
@@ -1764,7 +1781,11 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
if(!_preferencesDialog->isImagesKept())
{
_cachedSignatures.clear();
_cachedMemoryUsage = 0;
}
_ui->statsToolBox->updateStat("GUI/Cache Data Size/MB", stat.refImageId(), _cachedMemoryUsage/(1024*1024));
_ui->statsToolBox->updateStat("GUI/Cache Clouds Size/MB", stat.refImageId(), _createdCloudsMemoryUsage/(1024*1024));
if(_state != kMonitoring && _state != kDetecting)
{
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
@@ -1889,13 +1910,13 @@ void MainWindow::updateMapCloud(
_cloudViewer->setCloudOpacity(cloudName, _preferencesDialog->getCloudOpacity(0));
_cloudViewer->setCloudPointSize(cloudName, _preferencesDialog->getCloudPointSize(0));
}
else if(_createdClouds.find(iter->first) == _createdClouds.end() && _cachedSignatures.contains(iter->first))
else if(_cachedClouds.find(iter->first) == _cachedClouds.end() && _cachedSignatures.contains(iter->first))
{
if((_cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0)) ||
_projectionLocalMaps.find(iter->first) == _projectionLocalMaps.end())
{
this->createAndAddCloudToMap(iter->first, iter->second, uValue(mapIds, iter->first, -1));
if(_createdClouds.find(iter->first) != _createdClouds.end())
if(viewerClouds.contains(cloudName))
{
_cloudViewer->setCloudVisibility(cloudName.c_str(), _cloudViewer->isVisible() && _preferencesDialog->isCloudsShown(0));
}
@@ -1992,8 +2013,8 @@ void MainWindow::updateMapCloud(
// activate actions
if(_state != kMonitoring && _state != kDetecting)
{
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty());
@@ -2223,11 +2244,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
return;
}
if(_createdClouds.find(nodeId) != _createdClouds.end())
{
UDEBUG("Cloud %d already created.");
return;
}
UASSERT(_cachedClouds.find(nodeId) == _cachedClouds.end());
if((!iter->sensorData().imageCompressed().empty() || !iter->sensorData().imageRaw().empty()) &&
(!iter->sensorData().depthOrRightCompressed().empty() || !iter->sensorData().depthOrRightRaw().empty()))
@@ -2259,6 +2276,21 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
indices.get(),
_preferencesDialog->getAllParameters());
// view point
Eigen::Vector3f viewPoint(0.0f,0.0f,0.0f);
if(data.cameraModels().size() && !data.cameraModels()[0].localTransform().isNull())
{
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();
}
// filtering pipeline
if(indices->size() && _preferencesDialog->getMapVoxel() > 0.0)
{
@@ -2353,7 +2385,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
//normals required
if(_preferencesDialog->getNormalKSearch() > 0)
{
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch());
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch(), viewPoint);
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
}
else
@@ -2411,25 +2443,12 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
pcl::PointCloud<pcl::PointXYZRGB>::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())
{
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<pcl::Vertices> polygons = util3d::organizedFastMesh(
output,
_preferencesDialog->getCloudMeshingAngle(),
_preferencesDialog->isCloudMeshingQuad(),
_preferencesDialog->getCloudMeshingTriangleSize(),
viewpoint);
viewPoint);
if(polygons.size())
{
// remove unused vertices to save memory
@@ -2440,9 +2459,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
{
UERROR("Adding mesh cloud %d to viewer failed!", nodeId);
}
else
else if(_preferencesDialog->isCloudsKept())
{
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
}
}
}
@@ -2457,7 +2477,7 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
if(_preferencesDialog->getNormalKSearch() > 0 && cloudWithNormals->size() == 0)
{
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch());
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloud, indices, _preferencesDialog->getNormalKSearch(), viewPoint);
pcl::concatenateFields(*cloud, *normals, *cloudWithNormals);
}
@@ -2479,9 +2499,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
{
UERROR("Adding cloud %d to viewer failed!", nodeId);
}
else
else if(_preferencesDialog->isCloudsKept())
{
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
}
}
else
@@ -2491,9 +2512,10 @@ void MainWindow::createAndAddCloudToMap(int nodeId, const Transform & pose, int
{
UERROR("Adding cloud %d to viewer failed!", nodeId);
}
else
else if(_preferencesDialog->isCloudsKept())
{
_createdClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_cachedClouds.insert(std::make_pair(nodeId, std::make_pair(output, indices)));
_createdCloudsMemoryUsage += output->size() * sizeof(pcl::PointXYZRGB) + indices->size()*sizeof(int);
}
}
}
@@ -2965,6 +2987,7 @@ void MainWindow::processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap & eve
(_cachedSignatures.value(iter->first).sensorData().imageCompressed().empty() && !iter->second.sensorData().imageCompressed().empty()))
{
_cachedSignatures.insert(iter->first, iter->second);
_cachedMemoryUsage += iter->second.sensorData().getMemoryUsed();
++addedSignatures;
}
_initProgressDialog->incrementStep();
@@ -2997,6 +3020,7 @@ void MainWindow::processRtabmapEvent3DMap(const rtabmap::RtabmapEvent3DMap & eve
if(!_preferencesDialog->isImagesKept())
{
_cachedSignatures.clear();
_cachedMemoryUsage = 0;
}
if(_state != kMonitoring && _state != kDetecting)
{
@@ -4842,7 +4866,9 @@ void MainWindow::anchorCloudsToGroundTruth()
void MainWindow::clearTheCache()
{
_cachedSignatures.clear();
_createdClouds.clear();
_cachedMemoryUsage = 0;
_cachedClouds.clear();
_createdCloudsMemoryUsage = 0;
_previousCloud.first = 0;
_previousCloud.second.first.first.reset();
_previousCloud.second.first.second.reset();
@@ -5250,7 +5276,7 @@ void MainWindow::exportClouds()
_ui->widget_mapVisibility->getVisiblePoses(),
_currentMapIds,
_cachedSignatures,
_createdClouds,
_cachedClouds,
_preferencesDialog->getWorkingDirectory(),
_preferencesDialog->getAllParameters());
}
@@ -5266,7 +5292,7 @@ void MainWindow::viewClouds()
_currentPosesMap,
_currentMapIds,
_cachedSignatures,
_createdClouds,
_cachedClouds,
_preferencesDialog->getWorkingDirectory(),
_preferencesDialog->getAllParameters());
@@ -5713,8 +5739,8 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
_ui->actionGenerate_map->setEnabled(false);
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty());
@@ -5769,8 +5795,8 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
_ui->actionGenerate_map->setEnabled(true);
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty());
@@ -5895,8 +5921,8 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
_ui->actionGenerate_map->setEnabled(true);
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty());
@@ -5959,8 +5985,8 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionPost_processing->setEnabled(_cachedSignatures.size() >= 2 && _currentPosesMap.size() >= 2 && _currentLinksMap.size() >= 1);
_ui->actionExport_images_RGB_jpg_Depth_png->setEnabled(!_cachedSignatures.empty() && !_currentPosesMap.empty());
_ui->menuExport_poses->setEnabled(!_currentPosesMap.empty());
_ui->actionSave_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_createdClouds.empty());
_ui->actionSave_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionView_high_res_point_cloud->setEnabled(!_cachedSignatures.empty() || !_cachedClouds.empty());
_ui->actionExport_2D_scans_ply_pcd->setEnabled(!_createdScans.empty());
_ui->actionExport_2D_Grid_map_bmp_png->setEnabled(!_gridLocalMaps.empty() || !_projectionLocalMaps.empty());
_ui->actionView_scans->setEnabled(!_createdScans.empty());
+12 -2
View File
@@ -270,6 +270,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
// General panel
connect(_ui->general_checkBox_imagesKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
connect(_ui->general_checkBox_cloudsKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
connect(_ui->checkBox_verticalLayoutUsed, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
connect(_ui->checkBox_imageRejectedShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
connect(_ui->checkBox_imageHighestHypShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
@@ -1150,6 +1151,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
if(groupBox->objectName() == _ui->groupBox_generalSettingsGui0->objectName())
{
_ui->general_checkBox_imagesKept->setChecked(true);
_ui->general_checkBox_cloudsKept->setChecked(true);
_ui->checkBox_beep->setChecked(false);
_ui->checkBox_notifyWhenNewGlobalPathIsReceived->setChecked(false);
_ui->checkBox_verticalLayoutUsed->setChecked(true);
@@ -1448,7 +1450,9 @@ void PreferencesDialog::loadConfigFrom()
QString path = QFileDialog::getOpenFileName(this, tr("Load settings..."), this->getWorkingDirectory(), "*.ini");
if(!path.isEmpty())
{
_ui->checkBox_useOdomFeatures->blockSignals(true);
this->readSettings(path);
_ui->checkBox_useOdomFeatures->blockSignals(false);
}
}
@@ -1501,6 +1505,7 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
settings.beginGroup("Gui");
settings.beginGroup("General");
_ui->general_checkBox_imagesKept->setChecked(settings.value("imagesKept", _ui->general_checkBox_imagesKept->isChecked()).toBool());
_ui->general_checkBox_cloudsKept->setChecked(settings.value("cloudsKept", _ui->general_checkBox_cloudsKept->isChecked()).toBool());
_ui->comboBox_loggerLevel->setCurrentIndex(settings.value("loggerLevel", _ui->comboBox_loggerLevel->currentIndex()).toInt());
_ui->comboBox_loggerEventLevel->setCurrentIndex(settings.value("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex()).toInt());
_ui->comboBox_loggerPauseLevel->setCurrentIndex(settings.value("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex()).toInt());
@@ -1904,6 +1909,7 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
settings.beginGroup("General");
settings.remove("");
settings.setValue("imagesKept", _ui->general_checkBox_imagesKept->isChecked());
settings.setValue("cloudsKept", _ui->general_checkBox_cloudsKept->isChecked());
settings.setValue("loggerLevel", _ui->comboBox_loggerLevel->currentIndex());
settings.setValue("loggerEventLevel", _ui->comboBox_loggerEventLevel->currentIndex());
settings.setValue("loggerPauseLevel", _ui->comboBox_loggerPauseLevel->currentIndex());
@@ -3440,8 +3446,8 @@ void PreferencesDialog::useOdomFeatures()
if(this->isVisible() && _ui->checkBox_useOdomFeatures->isChecked())
{
int r = QMessageBox::question(this, tr("Using odometry features for vocabulary..."),
tr("Do you want to match feature parameters "
"below with corresponding ones used for odometry?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
tr("Do you want to match vocabulary feature parameters "
"with corresponding ones used for odometry?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if(r == QMessageBox::Yes)
{
@@ -4270,6 +4276,10 @@ bool PreferencesDialog::isImagesKept() const
{
return _ui->general_checkBox_imagesKept->isChecked();
}
bool PreferencesDialog::isCloudsKept() const
{
return _ui->general_checkBox_cloudsKept->isChecked();
}
float PreferencesDialog::getTimeLimit() const
{
return _ui->general_doubleSpinBox_timeThr->value();
+29 -6
View File
@@ -63,7 +63,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-847</y>
<y>0</y>
<width>686</width>
<height>2023</height>
</rect>
@@ -86,7 +86,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
@@ -121,14 +121,14 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_beep">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<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>
@@ -141,7 +141,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QLabel" name="label_102">
<property name="text">
<string>Notify when a new global path is received.</string>
@@ -154,7 +154,7 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QCheckBox" name="checkBox_notifyWhenNewGlobalPathIsReceived">
<property name="text">
<string/>
@@ -164,6 +164,29 @@
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_313">
<property name="text">
<string>Insert created clouds in the GUI cache to avoid regenerating clouds on export.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="general_checkBox_cloudsKept">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>