Update 0.15.4.

Parameters:
-Added "GridGlobal/MaxNodes=0", "Rtabmap/PublishRAMUsage=false", "Mem/DepthAsMask=true", "Kp/FlannRebalancingFactor=2.0", "Vis/DepthAsMask=true".
-Modified "Kp/DetectorStrategy=6", "Kp/MaxFeatures=500",  "Mem/UseOdomFeatures=true", "GFTT/QualityLevel=0.001", "GFTT/MinDistance=3", "RGBD/OptimizeMaxError=1", "RGBD/ProximityPathFilteringRadius=1", "Odom/GuessMotion=true", "Odom/VisKeyFrameThr=150", "OdomF2M/BundleAdjustment=1", "Vis/Iterations=300" if built with g2o, "OdomF2M/BundleAdjustmentMaxFrames=10", "OdomFovis/MinFeaturesForEstimate=20", "OdomORBSLAM2/MapSize=3000", "Reg/RepeatOnce=true", "Vis/PnPRefineIterations=0" if built with g2o, "Vis/CorGuessMatchToProjection=true", "Vis/BundleAdjustment=1" if built with g2o, "Icp/MaxCorrespondenceDistance=0.1", "Icp/PointToPlaneK=5", "Icp/PointToPlaneRadius=1", "Icp/PM=true" if built with libpointmatcher, "Stereo/MaxLevel=5", "Stereo/MinDisparity=0.5".

BayesFilter: optimized prediction matrix update. Use of new argument "ignoreLocalSpaceLoopIds" of Memory::getNeighborsId() to ignore loop closure link by space in prediction update.
CameraThread: Added stereo exposure compensation option.
CameraRGB: Added forceGroundNormalsUp option and added support of ground truth from EuRoC dataset.
Statistics: Added "Memory/RAM_usage/MB".
Transform: Added clone() method to do deep copy.
Graph::importPoses(): EuRoC format support (9).
Rtabmap: Local visual loop closures are now identified as GlobalClosure link type.
OccupancyGrid/OctoMap: updated how cache is used (old node retrieved can be re-added to map without re-assembling the whole map).
OdometryF2F: when using ICP, increasing correspondence distance for first two frames. If Vis/CorType=1 and registration fails, second guess without motion is done with Vis/CorType=0.
OdometryF2M/RegVis: updated how features are removed from the map, using new projectedIDs filled in RegistrationInfo by RegistrationVis.
OdometryORBSLAM2: Maximum size of the feature map can be set with "OdomORBSLAM2/MapSize" parameter.
CloudViewer: fixed opengl camera drifting in follow mode.
DatabaseViewer: Added optimization scale option. ConstraintsView: hide loop closure links if type is ignored in gui parameters.
MainWindow: Support of "GridGlobal/MaxNodes" parameters when updating the maps.
UPlot: don't show ellipses when not in graphics view mode, updated how "random" colors are attributed to curves
Added rtabmap-euroc_dataset tool. Updated rtabmap-kitti_dataset and rtabmap-rgbd_dataset tools.
Added rtabmap-reprocess tool.
This commit is contained in:
matlabbe
2018-02-01 22:17:46 -05:00
parent 9f80f4ac42
commit 977d21eed5
76 changed files with 3844 additions and 1307 deletions

View File

@@ -1857,6 +1857,8 @@ void CloudViewer::updateCameraTargetPosition(const Transform & pose)
yAxis[0], yAxis[1], yAxis[2],0,
zAxis[0], zAxis[1], zAxis[2],0);
PR.normalizeRotation();
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]);

View File

@@ -141,9 +141,9 @@ void CreateSimpleCalibrationDialog::updateSaveStatus()
(!ui_->checkBox_stereo->isChecked() || !ui_->lineEdit_RT->text().isEmpty()))
{
//advanced
QStringList distorsionsStrListL = ui_->lineEdit_D_l->text().remove('[').remove(']').replace(',',' ').replace(';',' ').trimmed().split(' ');
QStringList distorsionsStrListR = ui_->lineEdit_D_r->text().remove('[').remove(']').replace(',',' ').replace(';',' ').trimmed().split(' ');
std::string RT = ui_->lineEdit_RT->text().remove('[').remove(']').replace(',',' ').replace(';',' ').trimmed().toStdString();
QStringList distorsionsStrListL = ui_->lineEdit_D_l->text().remove('[').remove(']').replace(',',' ').replace(';',' ').simplified().trimmed().split(' ');
QStringList distorsionsStrListR = ui_->lineEdit_D_r->text().remove('[').remove(']').replace(',',' ').replace(';',' ').simplified().trimmed().split(' ');
std::string RT = ui_->lineEdit_RT->text().remove('[').remove(']').replace(',',' ').replace(';',' ').simplified().trimmed().toStdString();
if((distorsionsStrListL.size() == 4 || distorsionsStrListL.size() == 5 || distorsionsStrListL.size() == 8) &&
(!ui_->checkBox_stereo->isChecked() || (distorsionsStrListR.size() == 4 || distorsionsStrListR.size() == 5 || distorsionsStrListR.size() == 8)) &&
@@ -192,7 +192,7 @@ void CreateSimpleCalibrationDialog::saveCalibration()
cv::Mat P = cv::Mat::zeros(3, 4, CV_64FC1);
K.copyTo(cv::Mat(P, cv::Range(0,3), cv::Range(0,3)));
QStringList distorsionCoeffs = ui_->lineEdit_D_l->text().remove('[').remove(']').replace(',',' ').replace(';',' ').trimmed().split(' ');
QStringList distorsionCoeffs = ui_->lineEdit_D_l->text().remove('[').remove(']').replace(',',' ').replace(';',' ').simplified().trimmed().split(' ');
UASSERT(distorsionCoeffs.size() == 4 || distorsionCoeffs.size() == 5 || distorsionCoeffs.size() == 8);
cv::Mat D = cv::Mat::zeros(1, distorsionCoeffs.size(), CV_64FC1);
bool ok;
@@ -240,7 +240,7 @@ void CreateSimpleCalibrationDialog::saveCalibration()
cv::Mat P = cv::Mat::zeros(3, 4, CV_64FC1);
K.copyTo(cv::Mat(P, cv::Range(0,3), cv::Range(0,3)));
QStringList distorsionCoeffs = ui_->lineEdit_D_r->text().remove('[').remove(']').replace(',',' ').replace(';',' ').trimmed().split(' ');
QStringList distorsionCoeffs = ui_->lineEdit_D_r->text().remove('[').remove(']').replace(',',' ').replace(';',' ').simplified().trimmed().split(' ');
UASSERT(distorsionCoeffs.size() == 4 || distorsionCoeffs.size() == 5 || distorsionCoeffs.size() == 8);
cv::Mat D = cv::Mat::zeros(1, distorsionCoeffs.size(), CV_64FC1);
bool ok;
@@ -257,8 +257,13 @@ void CreateSimpleCalibrationDialog::saveCalibration()
modelRight = CameraModel(name.toStdString(), cv::Size(width,height), K, D, R, P);
UASSERT(modelRight.isValidForRectification());
UASSERT(Transform::canParseString(ui_->lineEdit_RT->text().remove('[').remove(']').replace(',',' ').replace(';',' ').trimmed().toStdString()));
UASSERT(Transform::canParseString(ui_->lineEdit_RT->text().remove('[').remove(']').replace(',',' ').replace(';',' ').simplified().trimmed().toStdString()));
stereoModel = StereoCameraModel(name.toStdString(), modelLeft, modelRight, Transform::fromString(ui_->lineEdit_RT->text().remove('[').remove(']').replace(',',' ').replace(';',' ').trimmed().toStdString()));
if(stereoModel.baseline() < 0)
{
QMessageBox::warning(this, tr("Save"), tr("Error parsing the extrinsics \"%1\", resulting baseline (%f) is negative!").arg(ui_->lineEdit_RT->text()).arg(stereoModel.baseline()));
return;
}
UASSERT(stereoModel.isValidForRectification());
}

View File

@@ -320,6 +320,7 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
connect(ui_->checkBox_ignoreLocalLoopTime, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->checkBox_ignoreUserLoop, SIGNAL(stateChanged(int)), this, SLOT(updateGraphView()));
connect(ui_->spinBox_optimizationDepth, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
connect(ui_->doubleSpinBox_optimizationScale, SIGNAL(editingFinished()), this, SLOT(updateGraphView()));
connect(ui_->checkBox_gridErode, SIGNAL(stateChanged(int)), this, SLOT(updateGrid()));
connect(ui_->checkBox_octomap, SIGNAL(stateChanged(int)), this, SLOT(updateGrid()));
connect(ui_->checkBox_grid_2d, SIGNAL(stateChanged(int)), this, SLOT(updateGrid()));
@@ -354,15 +355,7 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
connect(ui_->checkBox_timeStats, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_timeStats, SIGNAL(stateChanged(int)), this, SLOT(updateStatistics()));
// Graph view
connect(ui_->checkBox_spanAllMaps, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignorePoseCorrection, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreGlobalLoop, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreLocalLoopSpace, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreLocalLoopTime, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_ignoreUserLoop, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->spinBox_optimizationDepth, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_gridErode, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_octomap, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_gainCompensationRadius, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_voxelSize, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_gridCellSize, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
@@ -484,13 +477,6 @@ void DatabaseViewer::readSettings()
ui_->graphViewer->loadSettings(settings, "GraphView");
settings.beginGroup("optimization");
ui_->checkBox_spanAllMaps->setChecked(settings.value("spanToAllMaps", ui_->checkBox_spanAllMaps->isChecked()).toBool());
ui_->checkBox_ignorePoseCorrection->setChecked(settings.value("ignorePoseCorrection", ui_->checkBox_ignorePoseCorrection->isChecked()).toBool());
ui_->checkBox_ignoreGlobalLoop->setChecked(settings.value("ignoreGlobalLoop", ui_->checkBox_ignoreGlobalLoop->isChecked()).toBool());
ui_->checkBox_ignoreLocalLoopSpace->setChecked(settings.value("ignoreLocalLoopSpace", ui_->checkBox_ignoreLocalLoopSpace->isChecked()).toBool());
ui_->checkBox_ignoreLocalLoopTime->setChecked(settings.value("ignoreLocalLoopTime", ui_->checkBox_ignoreLocalLoopTime->isChecked()).toBool());
ui_->checkBox_ignoreUserLoop->setChecked(settings.value("ignoreUserLoop", ui_->checkBox_ignoreUserLoop->isChecked()).toBool());
ui_->spinBox_optimizationDepth->setValue(settings.value("depth", ui_->spinBox_optimizationDepth->value()).toInt());
ui_->doubleSpinBox_gainCompensationRadius->setValue(settings.value("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value()).toDouble());
ui_->doubleSpinBox_voxelSize->setValue(settings.value("voxelSize", ui_->doubleSpinBox_voxelSize->value()).toDouble());
@@ -502,10 +488,6 @@ void DatabaseViewer::readSettings()
ui_->doubleSpinBox_posefilteringRadius->setValue(settings.value("poseFilteringRadius", ui_->doubleSpinBox_posefilteringRadius->value()).toDouble());
ui_->doubleSpinBox_posefilteringAngle->setValue(settings.value("poseFilteringAngle", ui_->doubleSpinBox_posefilteringAngle->value()).toDouble());
ui_->checkBox_gridErode->setChecked(settings.value("erode", ui_->checkBox_gridErode->isChecked()).toBool());
if(ui_->checkBox_octomap->isEnabled())
{
ui_->checkBox_octomap->setChecked(settings.value("octomap", ui_->checkBox_octomap->isChecked()).toBool());
}
settings.endGroup();
settings.beginGroup("mesh");
@@ -576,17 +558,6 @@ void DatabaseViewer::writeSettings()
// save optimization settings
settings.beginGroup("optimization");
//settings.setValue("iterations", ui_->spinBox_iterations->value());
settings.setValue("spanToAllMaps", ui_->checkBox_spanAllMaps->isChecked());
//settings.setValue("robust", ui_->checkBox_robust->isChecked());
settings.setValue("ignorePoseCorrection", ui_->checkBox_ignorePoseCorrection->isChecked());
settings.setValue("ignoreGlobalLoop", ui_->checkBox_ignoreGlobalLoop->isChecked());
settings.setValue("ignoreLocalLoopSpace", ui_->checkBox_ignoreLocalLoopSpace->isChecked());
settings.setValue("ignoreLocalLoopTime", ui_->checkBox_ignoreLocalLoopTime->isChecked());
settings.setValue("ignoreUserLoop", ui_->checkBox_ignoreUserLoop->isChecked());
//settings.setValue("strategy", ui_->comboBox_graphOptimizer->currentIndex());
//settings.setValue("slam2d", ui_->checkBox_2dslam->isChecked());
settings.setValue("depth", ui_->spinBox_optimizationDepth->value());
settings.setValue("gainCompensationRadius", ui_->doubleSpinBox_gainCompensationRadius->value());
settings.setValue("voxelSize", ui_->doubleSpinBox_voxelSize->value());
settings.endGroup();
@@ -598,7 +569,6 @@ void DatabaseViewer::writeSettings()
settings.setValue("poseFilteringRadius", ui_->doubleSpinBox_posefilteringRadius->value());
settings.setValue("poseFilteringAngle", ui_->doubleSpinBox_posefilteringAngle->value());
settings.setValue("erode", ui_->checkBox_gridErode->isChecked());
settings.setValue("octomap", ui_->checkBox_octomap->isChecked());
settings.endGroup();
settings.beginGroup("mesh");
@@ -666,6 +636,7 @@ void DatabaseViewer::restoreDefaultSettings()
ui_->checkBox_ignoreLocalLoopTime->setChecked(false);
ui_->checkBox_ignoreUserLoop->setChecked(false);
ui_->spinBox_optimizationDepth->setValue(0);
ui_->doubleSpinBox_optimizationScale->setValue(1.0);
ui_->doubleSpinBox_gainCompensationRadius->setValue(0.0);
ui_->doubleSpinBox_voxelSize->setValue(0.0);
@@ -925,6 +896,10 @@ bool DatabaseViewer::closeDatabase()
ui_->toolBox_statistics->clear();
databaseFileName_.clear();
ui_->checkBox_alignPosesWithGroundTruth->setVisible(false);
ui_->doubleSpinBox_optimizationScale->setVisible(false);
ui_->label_scale_title->setVisible(false);
ui_->label_rmse->setVisible(false);
ui_->label_rmse_title->setVisible(false);
ui_->checkBox_ignoreIntermediateNodes->setVisible(false);
ui_->label_alignPosesWithGroundTruth->setVisible(false);
ui_->label_optimizeFrom->setText(tr("Optimize from"));
@@ -968,6 +943,7 @@ bool DatabaseViewer::closeDatabase()
ui_->label_timeOptimization->clear();
ui_->label_pathLength->clear();
ui_->label_poses->clear();
ui_->label_rmse->clear();
ui_->spinBox_optimizationsFrom->setEnabled(false);
ui_->graphicsView_A->clear();
@@ -1435,6 +1411,10 @@ void DatabaseViewer::updateIds()
gpsPoses_.clear();
gpsValues_.clear();
ui_->checkBox_alignPosesWithGroundTruth->setVisible(false);
ui_->doubleSpinBox_optimizationScale->setVisible(false);
ui_->label_scale_title->setVisible(false);
ui_->label_rmse->setVisible(false);
ui_->label_rmse_title->setVisible(false);
ui_->checkBox_ignoreIntermediateNodes->setVisible(false);
ui_->label_alignPosesWithGroundTruth->setVisible(false);
ui_->menuExport_GPS->setEnabled(false);
@@ -1569,6 +1549,10 @@ void DatabaseViewer::updateIds()
if(!groundTruthPoses_.empty() || !gpsPoses_.empty())
{
ui_->checkBox_alignPosesWithGroundTruth->setVisible(true);
ui_->doubleSpinBox_optimizationScale->setVisible(true);
ui_->label_scale_title->setVisible(true);
ui_->label_rmse->setVisible(true);
ui_->label_rmse_title->setVisible(true);
ui_->label_alignPosesWithGroundTruth->setVisible(true);
if(!groundTruthPoses_.empty())
{
@@ -1595,6 +1579,7 @@ void DatabaseViewer::updateIds()
UINFO("Update database info...");
ui_->textEdit_info->clear();
ui_->textEdit_info->append(tr("Path:\t\t%1").arg(dbDriver_->getUrl().c_str()));
ui_->textEdit_info->append(tr("Version:\t\t%1").arg(dbDriver_->getDatabaseVersion().c_str()));
ui_->textEdit_info->append(tr("Sessions:\t\t%1").arg(sessions));
if(hasReducedGraph)
@@ -1720,7 +1705,7 @@ void DatabaseViewer::updateIds()
{
neighborLinks_.append(iter->second);
}
else
else if(iter->second.type()!=rtabmap::Link::kPosePrior)
{
loopLinks_.append(iter->second);
}
@@ -1784,6 +1769,7 @@ void DatabaseViewer::updateStatistics()
std::map<int, std::pair<std::map<std::string, float>, double> > allStats = dbDriver_->getAllStatistics();
std::map<std::string, std::pair<std::vector<float>, std::vector<float> > > allData;
std::map<std::string, int > allDataOi;
for(int i=0; i<ids_.size(); ++i)
{
@@ -1804,15 +1790,21 @@ void DatabaseViewer::updateStatistics()
{
//initialize data vectors
allData.insert(std::make_pair(iter->first, std::make_pair(std::vector<float>(ids_.size(), 0.0f), std::vector<float>(ids_.size(), 0.0f) )));
allDataOi.insert(std::make_pair(iter->first, 0));
}
allData.at(iter->first).first[i] = ui_->checkBox_timeStats->isChecked()?float(stamp-firstStamp):ids_[i];
allData.at(iter->first).second[i] = iter->second;
int & oi = allDataOi.at(iter->first);
allData.at(iter->first).first[oi] = ui_->checkBox_timeStats->isChecked()?float(stamp-firstStamp):ids_[i];
allData.at(iter->first).second[oi] = iter->second;
++oi;
}
}
for(std::map<std::string, std::pair<std::vector<float>, std::vector<float> > >::iterator iter=allData.begin(); iter!=allData.end(); ++iter)
{
int oi = allDataOi.at(iter->first);
iter->second.first.resize(oi);
iter->second.second.resize(oi);
ui_->toolBox_statistics->updateStat(iter->first.c_str(), iter->second.first, iter->second.second, true);
}
}
@@ -3420,16 +3412,7 @@ void DatabaseViewer::updateStereo(const SensorData * data)
UTimer timer;
ParametersMap parameters = ui_->parameters_toolbox->getParameters();
bool opticalFlow = uStr2Bool(parameters.at(Parameters::kStereoOpticalFlow()));
Stereo * stereo = 0;
if(opticalFlow)
{
stereo = new StereoOpticalFlow(parameters);
}
else
{
stereo = new Stereo(parameters);
}
Stereo * stereo = Stereo::create(parameters);
// generate kpts
std::vector<cv::KeyPoint> kpts;
@@ -3576,7 +3559,7 @@ void DatabaseViewer::updateStereo(const SensorData * data)
rightKpts[i].pt.x,
rightKpts[i].pt.y,
c,
QString("%1: (%2,%3) -> (%4,%5)").arg(i).arg(kpts[i].pt.x).arg(kpts[i].pt.y).arg(rightKpts[i].pt.x).arg(rightKpts[i].pt.y));
QString("%1: (%2,%3) -> (%4,%5) d=%6").arg(i).arg(kpts[i].pt.x).arg(kpts[i].pt.y).arg(rightKpts[i].pt.x).arg(rightKpts[i].pt.y).arg(kpts[i].pt.x - rightKpts[i].pt.x));
}
}
ui_->graphicsView_stereo->update();
@@ -4329,6 +4312,7 @@ void DatabaseViewer::sliderIterationsValueChanged(int value)
rotational_max);
// ground truth live statistics
ui_->label_rmse->setNum(translational_rmse);
UINFO("translational_rmse=%f", translational_rmse);
UINFO("translational_mean=%f", translational_mean);
UINFO("translational_median=%f", translational_median);
@@ -4611,6 +4595,7 @@ void DatabaseViewer::updateGraphView()
{
ui_->label_loopClosures->clear();
ui_->label_poses->clear();
ui_->label_rmse->clear();
if(odomPoses_.size())
{
@@ -4649,6 +4634,7 @@ void DatabaseViewer::updateGraphView()
ui_->menuExport_poses->setEnabled(true);
std::multimap<int, rtabmap::Link> links = links_;
loopLinks_.clear();
// filter current map if not spanning to all maps
if(!ui_->checkBox_spanAllMaps->isChecked() && uContains(mapIds_, fromId) && mapIds_.at(fromId) >= 0)
@@ -4718,6 +4704,7 @@ void DatabaseViewer::updateGraphView()
links.erase(iter++);
continue;
}
loopLinks_.push_back(iter->second);
++totalGlobal;
}
else if(iter->second.type() == Link::kLocalSpaceClosure)
@@ -4727,6 +4714,7 @@ void DatabaseViewer::updateGraphView()
links.erase(iter++);
continue;
}
loopLinks_.push_back(iter->second);
++totalLocalSpace;
}
else if(iter->second.type() == Link::kLocalTimeClosure)
@@ -4736,6 +4724,7 @@ void DatabaseViewer::updateGraphView()
links.erase(iter++);
continue;
}
loopLinks_.push_back(iter->second);
++totalLocalTime;
}
else if(iter->second.type() == Link::kUserClosure)
@@ -4745,14 +4734,37 @@ void DatabaseViewer::updateGraphView()
links.erase(iter++);
continue;
}
loopLinks_.push_back(iter->second);
++totalUser;
}
else if(iter->second.type() == Link::kPosePrior)
{
++totalPriors;
}
else
{
loopLinks_.push_back(iter->second);
}
Transform t = iter->second.transform().clone();
t.x() *= ui_->doubleSpinBox_optimizationScale->value();
t.y() *= ui_->doubleSpinBox_optimizationScale->value();
t.z() *= ui_->doubleSpinBox_optimizationScale->value();
iter->second.setTransform(t);
++iter;
}
ui_->horizontalSlider_loops->blockSignals(true);
if(loopLinks_.size() == 0)
{
ui_->horizontalSlider_loops->setEnabled(false);
}
else
{
ui_->horizontalSlider_loops->setEnabled(true);
ui_->horizontalSlider_loops->setMaximum(loopLinks_.size()-1);
}
ui_->horizontalSlider_loops->setValue(0);
ui_->horizontalSlider_loops->blockSignals(false);
ui_->label_loopClosures->setText(tr("(%1, %2, %3, %4, %5, %6, %7)")
.arg(totalNeighbor)
.arg(totalNeighborMerged)
@@ -5447,9 +5459,7 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent)
std::multimap<int, Link> linksIn = updateLinksWithModifications(links_);
linksIn.insert(std::make_pair(newLink.from(), newLink));
const Link * maxLinearLink = 0;
const Link * maxAngularLink = 0;
float maxLinearError = 0.0f;
float maxAngularError = 0.0f;
float maxLinearErrorRatio = 0.0f;
Optimizer * optimizer = Optimizer::create(ui_->parameters_toolbox->getParameters());
std::map<int, Transform> poses;
std::multimap<int, Link> links;
@@ -5480,43 +5490,31 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent)
fabs(iter->second.transform().x() - t.x()),
fabs(iter->second.transform().y() - t.y()),
fabs(iter->second.transform().z() - t.z()));
Eigen::Vector3f vA = t1.toEigen3f().linear()*Eigen::Vector3f(1,0,0);
Eigen::Vector3f vB = t2.toEigen3f().linear()*Eigen::Vector3f(1,0,0);
float angularError = pcl::getAngle3D(Eigen::Vector4f(vA[0], vA[1], vA[2], 0), Eigen::Vector4f(vB[0], vB[1], vB[2], 0));
if(linearError > maxLinearError)
float stddev = sqrt(iter->second.transVariance());
float linearErrorRatio = linearError/stddev;
if(linearErrorRatio > maxLinearErrorRatio)
{
maxLinearError = linearError;
maxLinearErrorRatio = linearErrorRatio;
maxLinearLink = &iter->second;
}
if(angularError > maxAngularError)
{
maxAngularError = angularError;
maxAngularLink = &iter->second;
}
}
}
if(maxLinearLink)
{
UINFO("Max optimization linear error = %f m (link %d->%d)", maxLinearError, maxLinearLink->from(), maxLinearLink->to());
}
if(maxAngularLink)
{
UINFO("Max optimization angular error = %f deg (link %d->%d)", maxAngularError*180.0f/M_PI, maxAngularLink->from(), maxAngularLink->to());
UINFO("Max optimization linear error ratio = %f (link %d->%d)", maxLinearErrorRatio, maxLinearLink->from(), maxLinearLink->to());
}
if(maxLinearError > maxOptimizationError)
if(maxLinearErrorRatio > maxOptimizationError)
{
msg = uFormat("Rejecting edge %d->%d because "
"graph error is too large after optimization (%f m for edge %d->%d, %f deg for edge %d->%d). "
"\"%s\" is %f m.",
"graph error is too large after optimization (ratio %f for edge %d->%d, stddev=%f). "
"\"%s\" is %f.",
newLink.from(),
newLink.to(),
maxLinearError,
maxLinearErrorRatio,
maxLinearLink->from(),
maxLinearLink->to(),
maxAngularError*180.0f/M_PI,
maxAngularLink?maxAngularLink->from():0,
maxAngularLink?maxAngularLink->to():0,
sqrt(maxLinearLink->transVariance()),
Parameters::kRGBDOptimizeMaxError().c_str(),
maxOptimizationError);
}

View File

@@ -932,6 +932,7 @@ void MainWindow::processCameraInfo(const rtabmap::CameraInfo & info)
_ui->statsToolBox->updateStat("Camera/Time decimation/ms", _preferencesDialog->isTimeUsedInFigures()?info.stamp-_firstStamp:(float)info.id, info.timeImageDecimation*1000.0f, _preferencesDialog->isCacheSavedInFigures());
_ui->statsToolBox->updateStat("Camera/Time disparity/ms", _preferencesDialog->isTimeUsedInFigures()?info.stamp-_firstStamp:(float)info.id, info.timeDisparity*1000.0f, _preferencesDialog->isCacheSavedInFigures());
_ui->statsToolBox->updateStat("Camera/Time mirroring/ms", _preferencesDialog->isTimeUsedInFigures()?info.stamp-_firstStamp:(float)info.id, info.timeMirroring*1000.0f, _preferencesDialog->isCacheSavedInFigures());
_ui->statsToolBox->updateStat("Camera/Time exposure compensation/ms", _preferencesDialog->isTimeUsedInFigures()?info.stamp-_firstStamp:(float)info.id, info.timeStereoExposureCompensation*1000.0f, _preferencesDialog->isCacheSavedInFigures());
_ui->statsToolBox->updateStat("Camera/Time scan from depth/ms", _preferencesDialog->isTimeUsedInFigures()?info.stamp-_firstStamp:(float)info.id, info.timeScanFromDepth*1000.0f, _preferencesDialog->isCacheSavedInFigures());
emit(cameraInfoProcessed());
@@ -2105,6 +2106,32 @@ void MainWindow::updateMapCloud(
_ui->actionAnchor_clouds_to_ground_truth->setChecked(false);
}
int maxNodes = uStr2Int(_preferencesDialog->getParameter(Parameters::kGridGlobalMaxNodes()));
if(maxNodes > 0 && poses.size()>1)
{
std::vector<int> nodes = graph::findNearestNodes(poses, poses.rbegin()->second, maxNodes);
std::map<int, Transform> nearestPoses;
nearestPoses.insert(*poses.rbegin());
for(std::vector<int>::iterator iter=nodes.begin(); iter!=nodes.end(); ++iter)
{
std::map<int, Transform>::iterator pter = poses.find(*iter);
if(pter != poses.end())
{
nearestPoses.insert(*pter);
}
}
//add negative...
for(std::map<int, Transform>::iterator iter=poses.begin(); iter!=poses.end(); ++iter)
{
if(iter->first > 0)
{
break;
}
nearestPoses.insert(*iter);
}
poses=nearestPoses;
}
// Map updated! regenerate the assembled cloud, last pose is the new one
UDEBUG("Update map with %d locations", poses.size());
QMap<std::string, Transform> viewerClouds = _cloudViewer->getAddedClouds();
@@ -4650,6 +4677,14 @@ void MainWindow::startDetection()
{
uInsert(odomParameters, ParametersPair(Parameters::kRegStrategy(), uNumber2Str(_preferencesDialog->getOdomRegistrationApproach())));
}
odomParameters.erase(Parameters::kRtabmapPublishRAMUsage()); // as odometry is in the same process than rtabmap, don't get RAM usage in odometry.
int odomStrategy = Parameters::defaultOdomStrategy();
Parameters::parse(odomParameters, Parameters::kOdomStrategy(), odomStrategy);
if(odomStrategy == 1)
{
// Only Frame To Frame supports all VisCorType
odomParameters.insert(ParametersPair(Parameters::kVisCorType(), _preferencesDialog->getParameter(Parameters::kVisCorType())));
}
Odometry * odom = Odometry::create(odomParameters);
_odomThread = new OdometryThread(odom, _preferencesDialog->getOdomBufferSize());

View File

@@ -451,7 +451,6 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
connect(_ui->groupBox_octomap, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_ui->spinBox_octomap_treeDepth, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_ui->checkBox_octomap_fullUpdate, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_ui->checkBox_octomap_2dgrid, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_ui->checkBox_octomap_show3dMap, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
connect(_ui->checkBox_octomap_cubeRendering, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteCloudRenderingPanel()));
@@ -612,6 +611,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
connect(_ui->doubleSpinBox_cameraImages_scanVoxelSize, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->spinBox_cameraImages_scanNormalsK, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->doubleSpinBox_cameraImages_scanNormalsRadius, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->checkBox_cameraImages_scanForceGroundNormalsUp, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
//Rtabmap basic
connect(_ui->general_doubleSpinBox_timeThr, SIGNAL(valueChanged(double)), _ui->general_doubleSpinBox_timeThr_2, SLOT(setValue(double)));
@@ -641,6 +642,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->general_checkBox_publishPdf->setObjectName(Parameters::kRtabmapPublishPdf().c_str());
_ui->general_checkBox_publishLikelihood->setObjectName(Parameters::kRtabmapPublishLikelihood().c_str());
_ui->general_checkBox_publishRMSE->setObjectName(Parameters::kRtabmapComputeRMSE().c_str());
_ui->general_checkBox_publishRAM->setObjectName(Parameters::kRtabmapPublishRAMUsage().c_str());
_ui->general_checkBox_statisticLogsBufferedInRAM->setObjectName(Parameters::kRtabmapStatisticLogsBufferedInRAM().c_str());
_ui->groupBox_statistics->setObjectName(Parameters::kRtabmapStatisticLogged().c_str());
_ui->general_checkBox_statisticLoggedHeaders->setObjectName(Parameters::kRtabmapStatisticLoggedHeaders().c_str());
@@ -703,10 +705,12 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->comboBox_dictionary_strategy->setObjectName(Parameters::kKpNNStrategy().c_str());
_ui->checkBox_dictionary_incremental->setObjectName(Parameters::kKpIncrementalDictionary().c_str());
_ui->checkBox_kp_incrementalFlann->setObjectName(Parameters::kKpIncrementalFlann().c_str());
_ui->surf_doubleSpinBox_rebalancingFactor->setObjectName(Parameters::kKpFlannRebalancingFactor().c_str());
_ui->comboBox_detector_strategy->setObjectName(Parameters::kKpDetectorStrategy().c_str());
_ui->surf_doubleSpinBox_nndrRatio->setObjectName(Parameters::kKpNndrRatio().c_str());
_ui->surf_doubleSpinBox_maxDepth->setObjectName(Parameters::kKpMaxDepth().c_str());
_ui->surf_doubleSpinBox_minDepth->setObjectName(Parameters::kKpMinDepth().c_str());
_ui->checkBox_memDepthAsMask->setObjectName(Parameters::kMemDepthAsMask().c_str());
_ui->surf_spinBox_wordsPerImageTarget->setObjectName(Parameters::kKpMaxFeatures().c_str());
_ui->spinBox_KPGridRows->setObjectName(Parameters::kKpGridRows().c_str());
_ui->spinBox_KPGridCols->setObjectName(Parameters::kKpGridCols().c_str());
@@ -861,9 +865,6 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->loopClosure_pnpReprojError->setObjectName(Parameters::kVisPnPReprojError().c_str());
_ui->loopClosure_pnpFlags->setObjectName(Parameters::kVisPnPFlags().c_str());
_ui->loopClosure_pnpRefineIterations->setObjectName(Parameters::kVisPnPRefineIterations().c_str());
_ui->loopClosure_correspondencesType->setObjectName(Parameters::kVisCorType().c_str());
connect(_ui->loopClosure_correspondencesType, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_loopClosureCorrespondences, SLOT(setCurrentIndex(int)));
_ui->stackedWidget_loopClosureCorrespondences->setCurrentIndex(Parameters::defaultVisCorType());
_ui->reextract_nn->setObjectName(Parameters::kVisCorNNType().c_str());
_ui->reextract_nndrRatio->setObjectName(Parameters::kVisCorNNDR().c_str());
_ui->spinBox_visCorGuessWinSize->setObjectName(Parameters::kVisCorGuessWinSize().c_str());
@@ -874,6 +875,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->reextract_gridcols->setObjectName(Parameters::kVisGridCols().c_str());
_ui->loopClosure_bowMaxDepth->setObjectName(Parameters::kVisMaxDepth().c_str());
_ui->loopClosure_bowMinDepth->setObjectName(Parameters::kVisMinDepth().c_str());
_ui->checkBox_visDepthAsMask->setObjectName(Parameters::kVisDepthAsMask().c_str());
_ui->loopClosure_roi->setObjectName(Parameters::kVisRoiRatios().c_str());
_ui->subpix_winSize->setObjectName(Parameters::kVisSubPixWinSize().c_str());
_ui->subpix_iterations->setObjectName(Parameters::kVisSubPixIterations().c_str());
@@ -937,6 +939,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->checkBox_grid_fullUpdate->setObjectName(Parameters::kGridGlobalFullUpdate().c_str());
_ui->doubleSpinBox_grid_minMapSize->setObjectName(Parameters::kGridGlobalMinSize().c_str());
_ui->spinBox_grid_maxNodes->setObjectName(Parameters::kGridGlobalMaxNodes().c_str());
_ui->doubleSpinBox_grid_footprintRadius->setObjectName(Parameters::kGridGlobalFootprintRadius().c_str());
_ui->checkBox_grid_erode->setObjectName(Parameters::kGridGlobalEroded().c_str());
@@ -965,6 +968,9 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->odom_f2m_bundleStrategy->setObjectName(Parameters::kOdomF2MBundleAdjustment().c_str());
_ui->odom_f2m_bundleMaxFrames->setObjectName(Parameters::kOdomF2MBundleAdjustmentMaxFrames().c_str());
//Odometry Frame To Frame
_ui->comboBox_odomf2f_corType->setObjectName(Parameters::kVisCorType().c_str());
//Odometry Mono
_ui->doubleSpinBox_minFlow->setObjectName(Parameters::kOdomMonoInitMinFlow().c_str());
_ui->doubleSpinBox_minInitTranslation->setObjectName(Parameters::kOdomMonoInitMinTranslation().c_str());
@@ -1041,6 +1047,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->doubleSpinBox_OdomORBSLAM2ThDepth->setObjectName(Parameters::kOdomORBSLAM2ThDepth().c_str());
_ui->doubleSpinBox_OdomORBSLAM2Fps->setObjectName(Parameters::kOdomORBSLAM2Fps().c_str());
_ui->spinBox_OdomORBSLAM2MaxFeatures->setObjectName(Parameters::kOdomORBSLAM2MaxFeatures().c_str());
_ui->spinBox_OdomORBSLAM2MapSize->setObjectName(Parameters::kOdomORBSLAM2MapSize().c_str());
//Stereo
_ui->stereo_winWidth->setObjectName(Parameters::kStereoWinWidth().c_str());
@@ -1457,7 +1464,6 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_ui->groupBox_octomap->setChecked(false);
_ui->spinBox_octomap_treeDepth->setValue(16);
_ui->checkBox_octomap_fullUpdate->setChecked(false);
_ui->checkBox_octomap_2dgrid->setChecked(true);
_ui->checkBox_octomap_show3dMap->setChecked(true);
_ui->checkBox_octomap_cubeRendering->setChecked(false);
@@ -1595,6 +1601,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_ui->doubleSpinBox_cameraImages_scanVoxelSize->setValue(0.025f);
_ui->spinBox_cameraImages_scanNormalsK->setValue(20);
_ui->doubleSpinBox_cameraImages_scanNormalsRadius->setValue(0.0);
_ui->checkBox_cameraImages_scanForceGroundNormalsUp->setChecked(false);
_ui->groupBox_depthFromScan->setChecked(false);
_ui->groupBox_depthFromScan_fillHoles->setChecked(true);
@@ -1845,7 +1852,6 @@ void PreferencesDialog::readGuiSettings(const QString & filePath)
_ui->groupBox_octomap->setChecked(settings.value("octomap", _ui->groupBox_octomap->isChecked()).toBool());
_ui->spinBox_octomap_treeDepth->setValue(settings.value("octomap_depth", _ui->spinBox_octomap_treeDepth->value()).toInt());
_ui->checkBox_octomap_fullUpdate->setChecked(settings.value("octomap_full_update", _ui->checkBox_octomap_fullUpdate->isChecked()).toBool());
_ui->checkBox_octomap_2dgrid->setChecked(settings.value("octomap_2dgrid", _ui->checkBox_octomap_2dgrid->isChecked()).toBool());
_ui->checkBox_octomap_show3dMap->setChecked(settings.value("octomap_3dmap", _ui->checkBox_octomap_show3dMap->isChecked()).toBool());
_ui->checkBox_octomap_cubeRendering->setChecked(settings.value("octomap_cube", _ui->checkBox_octomap_cubeRendering->isChecked()).toBool());
@@ -1997,6 +2003,8 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
_ui->doubleSpinBox_cameraImages_scanVoxelSize->setValue(settings.value("voxelSize", _ui->doubleSpinBox_cameraImages_scanVoxelSize->value()).toDouble());
_ui->spinBox_cameraImages_scanNormalsK->setValue(settings.value("normalsK", _ui->spinBox_cameraImages_scanNormalsK->value()).toInt());
_ui->doubleSpinBox_cameraImages_scanNormalsRadius->setValue(settings.value("normalsRadius", _ui->doubleSpinBox_cameraImages_scanNormalsRadius->value()).toDouble());
_ui->checkBox_cameraImages_scanForceGroundNormalsUp->setChecked(settings.value("normalsUp", _ui->checkBox_cameraImages_scanForceGroundNormalsUp->isChecked()).toBool());
settings.endGroup();//ScanFromDepth
settings.beginGroup("DepthFromScan");
@@ -2247,7 +2255,6 @@ void PreferencesDialog::writeGuiSettings(const QString & filePath) const
settings.setValue("octomap", _ui->groupBox_octomap->isChecked());
settings.setValue("octomap_depth", _ui->spinBox_octomap_treeDepth->value());
settings.setValue("octomap_full_update", _ui->checkBox_octomap_fullUpdate->isChecked());
settings.setValue("octomap_2dgrid", _ui->checkBox_octomap_2dgrid->isChecked());
settings.setValue("octomap_3dmap", _ui->checkBox_octomap_show3dMap->isChecked());
settings.setValue("octomap_cube", _ui->checkBox_octomap_cubeRendering->isChecked());
@@ -2401,6 +2408,7 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath) const
settings.setValue("voxelSize", _ui->doubleSpinBox_cameraImages_scanVoxelSize->value());
settings.setValue("normalsK", _ui->spinBox_cameraImages_scanNormalsK->value());
settings.setValue("normalsRadius", _ui->doubleSpinBox_cameraImages_scanNormalsRadius->value());
settings.setValue("normalsUp", _ui->checkBox_cameraImages_scanForceGroundNormalsUp->isChecked());
settings.endGroup();
settings.beginGroup("DepthFromScan");
@@ -2584,15 +2592,6 @@ bool PreferencesDialog::validateForm()
"with cvsba. Bundle adjustment is disabled."));
_ui->odom_f2m_bundleStrategy->setCurrentIndex(0);
}
if(_ui->odom_strategy->currentIndex() == 0 && // F2M
_ui->odom_f2m_bundleStrategy->currentIndex() > 0 &&
_ui->loopClosure_correspondencesType->currentIndex() == 1)
{
QMessageBox::warning(this, tr("Parameter warning"),
tr("Odometry local bundle adjustment optimization cannot be used at the same time than Optical Flow correspondences "
"strategy (see Visual Registration panel). Bundle adjustment is disabled."));
_ui->odom_f2m_bundleStrategy->setCurrentIndex(0);
}
// verify that Robust and Reject threshold are not set at the same time
if(_ui->graphOptimization_robust->isChecked() && _ui->graphOptimization_maxError->value()>0.0)
@@ -3066,6 +3065,9 @@ rtabmap::ParametersMap PreferencesDialog::getAllParameters() const
ParametersMap parameters = _parameters;
uInsert(parameters, _modifiedParameters);
// It will be added manually for odometry
parameters.erase(Parameters::kVisCorType());
return parameters;
}
@@ -3328,7 +3330,7 @@ void PreferencesDialog::selectSourceImagesPathOdom()
{
dir = getWorkingDirectory();
}
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Odometry (*.txt *.log *.toro *.g2o)"));
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Odometry (*.txt *.log *.toro *.g2o *.csv)"));
if(path.size())
{
QStringList list;
@@ -3352,7 +3354,7 @@ void PreferencesDialog::selectSourceImagesPathGt()
{
dir = getWorkingDirectory();
}
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Ground Truth (*.txt *.log *.toro *.g2o)"));
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Ground Truth (*.txt *.log *.toro *.g2o *.csv)"));
if(path.size())
{
QStringList list;
@@ -4334,7 +4336,7 @@ int PreferencesDialog::getOctomapTreeDepth() const
}
bool PreferencesDialog::isOctomapFullUpdate() const
{
return _ui->checkBox_octomap_fullUpdate->isChecked();
return uStr2Bool(this->getParameter(Parameters::kGridGlobalFullUpdate()));
}
double PreferencesDialog::getOctomapOccupancyThr() const
{
@@ -4851,7 +4853,8 @@ Camera * PreferencesDialog::createCamera(bool useRawImages, bool useColor)
_ui->doubleSpinBox_cameraImages_scanVoxelSize->value(),
_ui->spinBox_cameraImages_scanNormalsK->value(),
_ui->doubleSpinBox_cameraImages_scanNormalsRadius->value(),
this->getLaserLocalTransform());
this->getLaserLocalTransform(),
_ui->checkBox_cameraImages_scanForceGroundNormalsUp->isChecked());
((CameraRGBDImages*)camera)->setTimestamps(
_ui->checkBox_cameraImages_timestamps->isChecked(),
_ui->lineEdit_cameraImages_timestamps->text().toStdString(),
@@ -4899,7 +4902,8 @@ Camera * PreferencesDialog::createCamera(bool useRawImages, bool useColor)
_ui->doubleSpinBox_cameraImages_scanVoxelSize->value(),
_ui->spinBox_cameraImages_scanNormalsK->value(),
_ui->doubleSpinBox_cameraImages_scanNormalsRadius->value(),
this->getLaserLocalTransform());
this->getLaserLocalTransform(),
_ui->checkBox_cameraImages_scanForceGroundNormalsUp->isChecked());
((CameraStereoImages*)camera)->setTimestamps(
_ui->checkBox_cameraImages_timestamps->isChecked(),
_ui->lineEdit_cameraImages_timestamps->text().toStdString(),
@@ -5005,7 +5009,8 @@ Camera * PreferencesDialog::createCamera(bool useRawImages, bool useColor)
_ui->doubleSpinBox_cameraImages_scanVoxelSize->value(),
_ui->spinBox_cameraImages_scanNormalsK->value(),
_ui->doubleSpinBox_cameraImages_scanNormalsRadius->value(),
this->getLaserLocalTransform());
this->getLaserLocalTransform(),
_ui->checkBox_cameraImages_scanForceGroundNormalsUp->isChecked());
((CameraImages*)camera)->setDepthFromScan(
_ui->groupBox_depthFromScan->isChecked(),
!_ui->groupBox_depthFromScan_fillHoles->isChecked()?0:_ui->radioButton_depthFromScan_vertical->isChecked()?1:-1,
@@ -5220,6 +5225,15 @@ void PreferencesDialog::testOdometry()
{
uInsert(parameters, ParametersPair(Parameters::kRegStrategy(), uNumber2Str(getOdomRegistrationApproach())));
}
int odomStrategy = Parameters::defaultOdomStrategy();
Parameters::parse(parameters, Parameters::kOdomStrategy(), odomStrategy);
if(odomStrategy == 1)
{
// Only Frame To Frame supports all VisCorType
parameters.insert(ParametersPair(Parameters::kVisCorType(), this->getParameter(Parameters::kVisCorType())));
}
Odometry * odometry = Odometry::create(parameters);
OdometryThread odomThread(

View File

@@ -61,7 +61,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>407</width>
<width>395</width>
<height>242</height>
</rect>
</property>
@@ -253,7 +253,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>406</width>
<width>394</width>
<height>242</height>
</rect>
</property>
@@ -921,7 +921,7 @@
</item>
<item>
<layout class="QGridLayout" name="gridLayout_5" columnstretch="0,1">
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="label_loopClosures">
<property name="text">
<string/>
@@ -954,7 +954,7 @@
<item row="0" column="0">
<widget class="QSpinBox" name="spinBox_optimizationsFrom"/>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QLabel" name="label_52">
<property name="text">
<string>Poses</string>
@@ -968,7 +968,7 @@
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QLabel" name="label_41">
<property name="text">
<string>Links (N, NM, G, LS, LT, U, P)</string>
@@ -1020,7 +1020,7 @@
</item>
</layout>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="label_poses">
<property name="text">
<string/>
@@ -1050,6 +1050,16 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_ignoreIntermediateNodes">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_alignPosesWithGroundTruth_2">
<property name="text">
@@ -1060,13 +1070,20 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_ignoreIntermediateNodes">
<item row="6" column="1">
<widget class="QLabel" name="label_rmse_title">
<property name="text">
<string>RMSE (m)</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_rmse">
<property name="text">
<string/>
</property>
<property name="checked">
<bool>false</bool>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
@@ -1146,22 +1163,36 @@
<item>
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="page_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>340</width>
<height>228</height>
<width>318</width>
<height>219</height>
</rect>
</property>
<attribute name="label">
<string>Graph optimization</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_7" columnstretch="0,0,0">
<item row="3" column="0">
<layout class="QGridLayout" name="gridLayout_7" columnstretch="0,0,1">
<item row="0" column="2">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Depth (0=inf)</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_49">
<property name="text">
<string>Ignore local loop closures (time)</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkBox_ignoreLocalLoopSpace">
<property name="text">
<string/>
@@ -1171,37 +1202,21 @@
</property>
</widget>
</item>
<item row="2" column="2">
<item row="3" column="2">
<widget class="QLabel" name="label_48">
<property name="text">
<string>Ignore global loop closures</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox_optimizationDepth">
<property name="suffix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="1" column="2">
<item row="2" column="2">
<widget class="QLabel" name="label_35">
<property name="text">
<string>Ignore pose correction</string>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QCheckBox" name="checkBox_ignorePoseCorrection">
<property name="text">
<string/>
@@ -1211,7 +1226,7 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QCheckBox" name="checkBox_ignoreLocalLoopTime">
<property name="text">
<string/>
@@ -1221,7 +1236,7 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -1234,28 +1249,7 @@
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Depth (0=inf)</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_50">
<property name="text">
<string>Ignore user loop closures</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_47">
<property name="text">
<string>Ignore local loop closures (space)</string>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_ignoreUserLoop">
<property name="text">
<string/>
@@ -1265,7 +1259,14 @@
</property>
</widget>
</item>
<item row="2" column="0">
<item row="6" column="2">
<widget class="QLabel" name="label_50">
<property name="text">
<string>Ignore user loop closures</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="checkBox_ignoreGlobalLoop">
<property name="text">
<string/>
@@ -1276,9 +1277,51 @@
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_49">
<widget class="QLabel" name="label_47">
<property name="text">
<string>Ignore local loop closures (time)</string>
<string>Ignore local loop closures (space)</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_scale_title">
<property name="text">
<string>Scale</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_optimizationScale">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="maximum">
<double>9.900000000000000</double>
</property>
<property name="singleStep">
<double>0.001000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QSpinBox" name="spinBox_optimizationDepth">
<property name="suffix">
<string/>
</property>
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
@@ -1709,8 +1752,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>298</width>
<height>228</height>
<width>205</width>
<height>117</height>
</rect>
</property>
<attribute name="label">
@@ -1809,8 +1852,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>446</width>
<height>228</height>
<width>185</width>
<height>487</height>
</rect>
</property>
<attribute name="label">

File diff suppressed because it is too large Load Diff

View File

@@ -823,13 +823,13 @@ void UPlotCurve::draw(QPainter * painter, const QRect & limits)
}
}
if(limits.contains(item->pos().toPoint()) && limits.contains((item->pos() + QPointF(item->rect().width(), item->rect().height())).toPoint()))
/*if(limits.contains(item->pos().toPoint()) && limits.contains((item->pos() + QPointF(item->rect().width(), item->rect().height())).toPoint()))
{
painter->save();
painter->setPen(QPen(_itemsColor));
painter->drawEllipse(item->pos()+QPointF(item->rect().width()/2, item->rect().height()/2), (int)item->rect().width()/2, (int)item->rect().height()/2);
painter->restore();
}
}*/
}
}
}
@@ -1833,7 +1833,7 @@ UPlot::UPlot(QWidget *parent) :
_lowestRefreshRate = 99;
_refreshStartTime.start();
_penStyleCount = rand() % 10 + 1; // rand 1->10
_penStyleCount = 0;
_workingDirectory = QDir::homePath();
}
@@ -2081,6 +2081,28 @@ bool UPlot::contains(const QString & curveName)
QPen UPlot::getRandomPenColored()
{
int penStyle = 0;
bool colorNotUsed = false;
for(int i=0; i<12; ++i)
{
QColor tmp((Qt::GlobalColor)((penStyle+i) % 12 + 7 ));
bool colorAlreadyUsed = false;
for(QList<UPlotCurve*>::const_iterator iter = _curves.constBegin(); iter!=_curves.constEnd() && !colorAlreadyUsed; ++iter)
{
colorAlreadyUsed = (*iter)->pen().color() == tmp;
}
if(!colorAlreadyUsed)
{
colorNotUsed = true;
penStyle+=i;
break;
}
}
if(colorNotUsed)
{
_penStyleCount = penStyle;
}
return QPen((Qt::GlobalColor)(_penStyleCount++ % 12 + 7 ));
}