Added ViewPlane XY, XZ and YZ options to GraphViewer

Parameter RGBD/SavedLocalizationIgnored now called RGBD/StartAtOrigin (updated description, used only in localization mode)
IcpReg: if Force4DoF, set lower covariance values for roll and pitch
DbViewer: updated detectMoreLoopClosures with new minRadius option and update optimized poses between each new accepted loop closures.
MainWindow: suppressed warning if depth image is not found in current node data (when rgb is).
3D Map view: changed default map point size to 1 (was 2)
This commit is contained in:
matlabbe
2021-03-12 17:47:36 -05:00
parent da2e2f810c
commit f6e17be2b4
13 changed files with 360 additions and 102 deletions

View File

@@ -428,6 +428,7 @@ DatabaseViewer::DatabaseViewer(const QString & ini, QWidget * parent) :
connect(ui_->checkBox_icp_from_depth, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_detectMore_radius, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_detectMore_radiusMin, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->doubleSpinBox_detectMore_angle, SIGNAL(valueChanged(double)), this, SLOT(configModified()));
connect(ui_->spinBox_detectMore_iterations, SIGNAL(valueChanged(int)), this, SLOT(configModified()));
connect(ui_->checkBox_detectMore_intraSession, SIGNAL(stateChanged(int)), this, SLOT(configModified()));
@@ -588,6 +589,7 @@ void DatabaseViewer::readSettings()
exportDialog_->loadSettings(settings, exportDialog_->objectName());
settings.beginGroup("PostProcessingDialog");
ui_->doubleSpinBox_detectMore_radius->setValue(settings.value("cluster_radius", ui_->doubleSpinBox_detectMore_radius->value()).toDouble());
ui_->doubleSpinBox_detectMore_radiusMin->setValue(settings.value("cluster_radius_min", ui_->doubleSpinBox_detectMore_radiusMin->value()).toDouble());
ui_->doubleSpinBox_detectMore_angle->setValue(settings.value("cluster_angle", ui_->doubleSpinBox_detectMore_angle->value()).toDouble());
ui_->spinBox_detectMore_iterations->setValue(settings.value("iterations", ui_->spinBox_detectMore_iterations->value()).toInt());
ui_->checkBox_detectMore_intraSession->setChecked(settings.value("intra_session", ui_->checkBox_detectMore_intraSession->isChecked()).toBool());
@@ -674,6 +676,7 @@ void DatabaseViewer::writeSettings()
exportDialog_->saveSettings(settings, exportDialog_->objectName());
settings.beginGroup("PostProcessingDialog");
settings.setValue("cluster_radius", ui_->doubleSpinBox_detectMore_radius->value());
settings.setValue("cluster_radius_min", ui_->doubleSpinBox_detectMore_radiusMin->value());
settings.setValue("cluster_angle", ui_->doubleSpinBox_detectMore_angle->value());
settings.setValue("iterations", ui_->spinBox_detectMore_iterations->value());
settings.setValue("intra_session", ui_->checkBox_detectMore_intraSession->isChecked());
@@ -745,6 +748,7 @@ void DatabaseViewer::restoreDefaultSettings()
ui_->checkBox_icp_from_depth->setChecked(false);
ui_->doubleSpinBox_detectMore_radius->setValue(1.0);
ui_->doubleSpinBox_detectMore_radiusMin->setValue(0.0);
ui_->doubleSpinBox_detectMore_angle->setValue(30.0);
ui_->spinBox_detectMore_iterations->setValue(5);
ui_->checkBox_detectMore_intraSession->setChecked(true);
@@ -3910,7 +3914,7 @@ void DatabaseViewer::detectMoreLoopClosures()
QMessageBox::warning(this, tr("Cannot generate a graph"), tr("No graph in database?!"));
return;
}
}
}
std::map<int, Transform> optimizedPoses = graphes_.back();
@@ -3939,6 +3943,7 @@ void DatabaseViewer::detectMoreLoopClosures()
if(!interSession && !intraSession)
{
QMessageBox::warning(this, tr("Cannot detect more loop closures"), tr("Intra and inter session parameters are disabled! Enable one or both."));
return;
}
for(int n=0; n<iterations; ++n)
@@ -3948,7 +3953,7 @@ void DatabaseViewer::detectMoreLoopClosures()
std::map<int, Transform>(optimizedPoses.upper_bound(0), optimizedPoses.end()),
ui_->doubleSpinBox_detectMore_radius->value(),
ui_->doubleSpinBox_detectMore_angle->value()*CV_PI/180.0);
progressDialog->setMaximumSteps(progressDialog->maximumSteps()+(int)clusters.size());
progressDialog->appendText(tr("Looking for more loop closures, %1 clusters found.").arg(clusters.size()));
QApplication::processEvents();
@@ -3980,18 +3985,26 @@ void DatabaseViewer::detectMoreLoopClosures()
{
if(!findActiveLink(from, to).isValid() && !containsLink(linksRemoved_, from, to) &&
addedLinks.find(from) == addedLinks.end() &&
addedLinks.find(to) == addedLinks.end())
{
addedLinks.find(to) == addedLinks.end())
{
// Reverify if in the bounds with the current optimized graph
Transform delta = optimizedPoses.at(from).inverse() * optimizedPoses.at(to);
if(delta.getNorm() < ui_->doubleSpinBox_detectMore_radius->value() &&
if(addConstraint(from, to, true))
{
UINFO("Added new loop closure between %d and %d.", from, to);
++added;
addedLinks.insert(from);
addedLinks.insert(to);
delta.getNorm() >= ui_->doubleSpinBox_detectMore_radiusMin->value())
{
checkedLoopClosures.insert(std::make_pair(from, to));
if(addConstraint(from, to, true))
{
UINFO("Added new loop closure between %d and %d.", from, to);
++added;
addedLinks.insert(from);
addedLinks.insert(to);
lastAdded.first = from;
lastAdded.second = to;
lastAdded.second = to;
progressDialog->appendText(tr("Detected loop closure %1->%2! (%3/%4)").arg(from).arg(to).arg(i+1).arg(clusters.size()));
QApplication::processEvents();
optimizedPoses = graphes_.back();
}
}
@@ -4008,6 +4021,12 @@ void DatabaseViewer::detectMoreLoopClosures()
progressDialog->appendText(tr("Iteration %1/%2: Detected %3 loop closures!").arg(n+1).arg(iterations).arg(addedLinks.size()/2));
if(addedLinks.size() == 0)
{
break;
}
if(n+1<iterations)
{
// Re-optimize the map before doing next iterations
this->updateGraphView();
optimizedPoses = graphes_.back();
}
}
@@ -7666,7 +7685,7 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent)
if(!reg->isImageRequired())
{
// make a fake guess using globally optimized poses
if(graphes_.size())
if(graphes_.size())
{
std::map<int, Transform> optimizedPoses = graphes_.back();
if(optimizedPoses.size() > 0)
@@ -7877,6 +7896,11 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent)
tr("%1").arg(msg.c_str()));
}
updateConstraints = false;
}
if(updateConstraints && silent && !graphes_.empty() && graphes_.back().size() == poses.size())
{
graphes_.back() = poses;
}
}

View File

@@ -67,7 +67,7 @@ class NodeItem: public QGraphicsEllipseItem
{
public:
// in meter
NodeItem(int id, int mapId, const Transform & pose, float radius, int weight=-1) :
NodeItem(int id, int mapId, const Transform & pose, float radius, int weight, GraphViewer::ViewPlane plane) :
QGraphicsEllipseItem(QRectF(-radius*100.0f,-radius*100.0f,radius*100.0f*2.0f,radius*100.0f*2.0f)),
_id(id),
_mapId(mapId),
@@ -75,7 +75,7 @@ public:
_pose(pose),
_line(0)
{
this->setPos(-pose.y()*100.0f,-pose.x()*100.0f);
this->setPose(pose, plane);
this->setBrush(pen().color());
this->setAcceptHoverEvents(true);
float r,p,yaw;
@@ -109,7 +109,21 @@ public:
int id() const {return _id;};
int mapId() const {return _mapId;}
const Transform & pose() const {return _pose;}
void setPose(const Transform & pose) {this->setPos(-pose.y()*100.0f,-pose.x()*100.0f); _pose=pose;}
void setPose(const Transform & pose, GraphViewer::ViewPlane plane) {
switch(plane)
{
case GraphViewer::XZ:
this->setPos(pose.x()*100.0f,-pose.z()*100.0f);
break;
case GraphViewer::YZ:
this->setPos(pose.y()*100.0f,-pose.z()*100.0f);
break;
default: // XY
this->setPos(-pose.y()*100.0f,-pose.x()*100.0f);
break;
}
_pose=pose;
}
protected:
virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event )
@@ -143,8 +157,8 @@ private:
class NodeGPSItem: public NodeItem
{
public:
NodeGPSItem(int id, int mapId, const Transform & pose, float radius, const GPS & gps) :
NodeItem(id, mapId, pose, radius),
NodeGPSItem(int id, int mapId, const Transform & pose, float radius, const GPS & gps, GraphViewer::ViewPlane plane) :
NodeItem(id, mapId, pose, radius, -1, plane),
_gps(gps)
{
}
@@ -167,8 +181,7 @@ class LinkItem: public QGraphicsLineItem
{
public:
// in meter
LinkItem(int from, int to, const Transform & poseA, const Transform & poseB, const Link & link, bool interSessionClosure) :
QGraphicsLineItem(-poseA.y()*100.0f, -poseA.x()*100.0f, -poseB.y()*100.0f, -poseB.x()*100.0f),
LinkItem(int from, int to, const Transform & poseA, const Transform & poseB, const Link & link, bool interSessionClosure, GraphViewer::ViewPlane plane) :
_from(from),
_to(to),
_poseA(poseA),
@@ -176,6 +189,7 @@ public:
_link(link),
_interSession(interSessionClosure)
{
this->setPoses(poseA, poseB, plane);
this->setAcceptHoverEvents(true);
}
virtual ~LinkItem() {}
@@ -187,9 +201,20 @@ public:
this->setPen(p);
}
void setPoses(const Transform & poseA, const Transform & poseB)
void setPoses(const Transform & poseA, const Transform & poseB, GraphViewer::ViewPlane plane)
{
this->setLine(-poseA.y()*100.0f, -poseA.x()*100.0f, -poseB.y()*100.0f, -poseB.x()*100.0f);
switch(plane)
{
case GraphViewer::XZ:
this->setLine(poseA.x()*100.0f, -poseA.z()*100.0f, poseB.x()*100.0f, -poseB.z()*100.0f);
break;
case GraphViewer::YZ:
this->setLine(poseA.y()*100.0f, -poseA.z()*100.0f, poseB.y()*100.0f, -poseB.z()*100.0f);
break;
default: // XY
this->setLine(-poseA.y()*100.0f, -poseA.x()*100.0f, -poseB.y()*100.0f, -poseB.x()*100.0f);
break;
}
_poseA = poseA;
_poseB = poseB;
}
@@ -274,7 +299,8 @@ GraphViewer::GraphViewer(QWidget * parent) :
_localRadius(0),
_loopClosureOutlierThr(0),
_maxLinkLength(0.02f),
_orientationENU(false)
_orientationENU(false),
_viewPlane(XY)
{
this->setScene(new QGraphicsScene(this));
this->setDragMode(QGraphicsView::ScrollHandDrag);
@@ -286,30 +312,99 @@ GraphViewer::GraphViewer(QWidget * parent) :
_root->setParentItem(_world);
// add referential
QGraphicsLineItem * item;
_originReferential = new QGraphicsItemGroup();
this->scene()->addItem(_originReferential); // ownership transfered
QGraphicsLineItem * item = this->scene()->addLine(0,0,0,-100, QPen(QBrush(Qt::red), _linkWidth));
// XY referential
_originReferentialXY = new QGraphicsItemGroup();
this->scene()->addItem(_originReferentialXY); // ownership transfered
item = this->scene()->addLine(0,0,0,-100, QPen(QBrush(Qt::red), _linkWidth));
item->setZValue(1);
item->setParentItem(_root);
_originReferential->addToGroup(item);
_originReferentialXY->addToGroup(item);
item = this->scene()->addLine(0,0,-100,0, QPen(QBrush(Qt::green), _linkWidth));
item->setZValue(1);
item->setParentItem(_root);
_originReferential->addToGroup(item);
_originReferentialXY->addToGroup(item);
_originReferential->addToGroup(_originReferentialXY);
// XZ referential
_originReferentialXZ = new QGraphicsItemGroup();
this->scene()->addItem(_originReferentialXZ); // ownership transfered
item = this->scene()->addLine(0,0,100,0, QPen(QBrush(Qt::red), _linkWidth));
item->setZValue(1);
item->setParentItem(_root);
_originReferentialXZ->addToGroup(item);
item = this->scene()->addLine(0,0,0,-100, QPen(QBrush(Qt::blue), _linkWidth));
item->setZValue(1);
item->setParentItem(_root);
_originReferentialXZ->addToGroup(item);
_originReferential->addToGroup(_originReferentialXZ);
_originReferentialXZ->setVisible(false);
// YZ referential
_originReferentialYZ = new QGraphicsItemGroup();
this->scene()->addItem(_originReferentialYZ); // ownership transfered
item = this->scene()->addLine(0,0,100,0, QPen(QBrush(Qt::green), _linkWidth));
item->setZValue(1);
item->setParentItem(_root);
_originReferentialYZ->addToGroup(item);
item = this->scene()->addLine(0,0,0,-100, QPen(QBrush(Qt::blue), _linkWidth));
item->setZValue(1);
item->setParentItem(_root);
_originReferentialYZ->addToGroup(item);
_originReferential->addToGroup(_originReferentialYZ);
_originReferentialYZ->setVisible(false);
_originReferential->setZValue(1);
_originReferential->setParentItem(_root);
// current pose
_referential = new QGraphicsItemGroup();
this->scene()->addItem(_referential); // ownership transfered
// XY
_referentialXY = new QGraphicsItemGroup();
this->scene()->addItem(_referentialXY); // ownership transfered
item = this->scene()->addLine(0,0,0,-50, QPen(QBrush(Qt::red), _linkWidth));
item->setZValue(100);
item->setParentItem(_root);
_referential->addToGroup(item);
_referentialXY->addToGroup(item);
item = this->scene()->addLine(0,0,-50,0, QPen(QBrush(Qt::green), _linkWidth));
item->setZValue(100);
item->setParentItem(_root);
_referential->addToGroup(item);
_referentialXY->addToGroup(item);
_referential->addToGroup(_referentialXY);
// XZ
_referentialXZ = new QGraphicsItemGroup();
this->scene()->addItem(_referentialXZ); // ownership transfered
item = this->scene()->addLine(0,0,50,0, QPen(QBrush(Qt::red), _linkWidth));
item->setZValue(100);
item->setParentItem(_root);
_referentialXZ->addToGroup(item);
item = this->scene()->addLine(0,0,0,-50, QPen(QBrush(Qt::blue), _linkWidth));
item->setZValue(100);
item->setParentItem(_root);
_referentialXZ->addToGroup(item);
_referential->addToGroup(_referentialXZ);
_referentialXZ->setVisible(false);
// XZ
_referentialYZ = new QGraphicsItemGroup();
this->scene()->addItem(_referentialYZ); // ownership transfered
item = this->scene()->addLine(0,0,50,0, QPen(QBrush(Qt::green), _linkWidth));
item->setZValue(100);
item->setParentItem(_root);
_referentialYZ->addToGroup(item);
item = this->scene()->addLine(0,0,0,-50, QPen(QBrush(Qt::blue), _linkWidth));
item->setZValue(100);
item->setParentItem(_root);
_referentialYZ->addToGroup(item);
_referential->addToGroup(_referentialYZ);
_referentialYZ->setVisible(false);
_referential->setZValue(100);
_referential->setParentItem(_root);
@@ -388,14 +483,14 @@ void GraphViewer::updateGraph(const std::map<int, Transform> & poses,
QMap<int, NodeItem*>::iterator itemIter = _nodeItems.find(iter->first);
if(itemIter != _nodeItems.end())
{
itemIter.value()->setPose(iter->second);
itemIter.value()->setPose(iter->second, _viewPlane);
itemIter.value()->show();
}
else
{
// create node item
const Transform & pose = iter->second;
NodeItem * item = new NodeItem(iter->first, uContains(mapIds, iter->first)?mapIds.at(iter->first):-1, pose, _nodeRadius, uContains(weights, iter->first)?weights.at(iter->first):-1);
NodeItem * item = new NodeItem(iter->first, uContains(mapIds, iter->first)?mapIds.at(iter->first):-1, pose, _nodeRadius, uContains(weights, iter->first)?weights.at(iter->first):-1, _viewPlane);
this->scene()->addItem(item);
item->setZValue(iter->first<0?21:20);
item->setColor(iter->first<0?QColor(255-_nodeColor.red(), 255-_nodeColor.green(), 255-_nodeColor.blue()):_nodeColor);
@@ -429,7 +524,7 @@ void GraphViewer::updateGraph(const std::map<int, Transform> & poses,
{
if(itemIter.value()->to() == idTo)
{
itemIter.value()->setPoses(poseA, poseB);
itemIter.value()->setPoses(poseA, poseB, _viewPlane);
itemIter.value()->show();
linkItem = itemIter.value();
break;
@@ -449,7 +544,7 @@ void GraphViewer::updateGraph(const std::map<int, Transform> & poses,
if(linkItem == 0)
{
//create a link item
linkItem = new LinkItem(idFrom, idTo, poseA, poseB, iter->second, interSessionClosure);
linkItem = new LinkItem(idFrom, idTo, poseA, poseB, iter->second, interSessionClosure, _viewPlane);
QPen p = linkItem->pen();
p.setWidthF(_linkWidth*100.0f);
linkItem->setPen(p);
@@ -608,14 +703,14 @@ void GraphViewer::updateGTGraph(const std::map<int, Transform> & poses)
QMap<int, NodeItem*>::iterator itemIter = _gtNodeItems.find(iter->first);
if(itemIter != _gtNodeItems.end())
{
itemIter.value()->setPose(iter->second);
itemIter.value()->setPose(iter->second, _viewPlane);
itemIter.value()->show();
}
else
{
// create node item
const Transform & pose = iter->second;
NodeItem * item = new NodeItem(iter->first, -1, pose, _nodeRadius);
NodeItem * item = new NodeItem(iter->first, -1, pose, _nodeRadius, -1, _viewPlane);
this->scene()->addItem(item);
item->setZValue(20);
item->setColor(_gtPathColor);
@@ -640,7 +735,7 @@ void GraphViewer::updateGTGraph(const std::map<int, Transform> & poses)
{
if(linkIter.value()->to() == iter->first)
{
linkIter.value()->setPoses(previousPose, currentPose);
linkIter.value()->setPoses(previousPose, currentPose, _viewPlane);
linkIter.value()->show();
linkItem = linkIter.value();
break;
@@ -651,7 +746,7 @@ void GraphViewer::updateGTGraph(const std::map<int, Transform> & poses)
if(linkItem == 0)
{
//create a link item
linkItem = new LinkItem(iterPrevious->first, iter->first, previousPose, currentPose, Link(), 1);
linkItem = new LinkItem(iterPrevious->first, iter->first, previousPose, currentPose, Link(), 1, _viewPlane);
QPen p = linkItem->pen();
p.setWidthF(_linkWidth*100.0f);
linkItem->setPen(p);
@@ -737,7 +832,7 @@ void GraphViewer::updateGPSGraph(
QMap<int, NodeItem*>::iterator itemIter = _gpsNodeItems.find(iter->first);
if(itemIter != _gpsNodeItems.end())
{
itemIter.value()->setPose(iter->second);
itemIter.value()->setPose(iter->second, _viewPlane);
itemIter.value()->show();
}
else
@@ -745,7 +840,7 @@ void GraphViewer::updateGPSGraph(
// create node item
const Transform & pose = iter->second;
UASSERT(gpsValues.find(iter->first) != gpsValues.end());
NodeItem * item = new NodeGPSItem(iter->first, -1, pose, _nodeRadius, gpsValues.at(iter->first));
NodeItem * item = new NodeGPSItem(iter->first, -1, pose, _nodeRadius, gpsValues.at(iter->first), _viewPlane);
this->scene()->addItem(item);
item->setZValue(20);
item->setColor(_gpsPathColor);
@@ -770,7 +865,7 @@ void GraphViewer::updateGPSGraph(
{
if(linkIter.value()->to() == iter->first)
{
linkIter.value()->setPoses(previousPose, currentPose);
linkIter.value()->setPoses(previousPose, currentPose, _viewPlane);
linkIter.value()->show();
linkItem = linkIter.value();
break;
@@ -781,7 +876,7 @@ void GraphViewer::updateGPSGraph(
if(linkItem == 0)
{
//create a link item
linkItem = new LinkItem(iterPrevious->first, iter->first, previousPose, currentPose, Link(), 1);
linkItem = new LinkItem(iterPrevious->first, iter->first, previousPose, currentPose, Link(), 1, _viewPlane);
QPen p = linkItem->pen();
p.setWidthF(_linkWidth*100.0f);
linkItem->setPen(p);
@@ -844,7 +939,8 @@ void GraphViewer::updateReferentialPosition(const Transform & t)
{
QTransform qt;
qt.translate(-t.o24()*100.0f, -t.o14()*100.0f);
qt.rotateRadians(-t.theta());
if(_viewPlane == XY)
qt.rotateRadians(-t.theta());
_referential->setTransform(qt);
_localRadius->setTransform(qt);
@@ -921,7 +1017,7 @@ void GraphViewer::setGlobalPath(const std::vector<std::pair<int, Transform> > &
//create a link item
int idFrom = globalPath[i].first;
int idTo = globalPath[i+1].first;
LinkItem * item = new LinkItem(idFrom, idTo, globalPath[i].second, globalPath[i+1].second, Link(), false);
LinkItem * item = new LinkItem(idFrom, idTo, globalPath[i].second, globalPath[i+1].second, Link(), false, _viewPlane);
QPen p = item->pen();
p.setWidthF(_linkWidth*100.0f);
item->setPen(p);
@@ -953,7 +1049,7 @@ void GraphViewer::setCurrentGoalID(int id, const Transform & pose)
Transform t = pose * oldPose->getPoseA().inverse();
for(QMultiMap<int, LinkItem*>::iterator iter=_globalPathLinkItems.begin(); iter!=_globalPathLinkItems.end(); ++iter)
{
iter.value()->setPoses(t*iter.value()->getPoseA(), t*iter.value()->getPoseB());
iter.value()->setPoses(t*iter.value()->getPoseA(), t*iter.value()->getPoseB(), _viewPlane);
}
}
}
@@ -989,7 +1085,7 @@ void GraphViewer::updateLocalPath(const std::vector<int> & localPath)
{
if(itemIter.value()->to() == idTo)
{
itemIter.value()->setPoses(_nodeItems.value(idFrom)->pose(), _nodeItems.value(idTo)->pose());
itemIter.value()->setPoses(_nodeItems.value(idFrom)->pose(), _nodeItems.value(idTo)->pose(), _viewPlane);
itemIter.value()->show();
updated = true;
break;
@@ -1000,7 +1096,7 @@ void GraphViewer::updateLocalPath(const std::vector<int> & localPath)
if(!updated)
{
//create a link item
LinkItem * item = new LinkItem(idFrom, idTo, _nodeItems.value(idFrom)->pose(), _nodeItems.value(idTo)->pose(), Link(), false);
LinkItem * item = new LinkItem(idFrom, idTo, _nodeItems.value(idFrom)->pose(), _nodeItems.value(idTo)->pose(), Link(), false, _viewPlane);
QPen p = item->pen();
p.setWidthF(_linkWidth*100.0f);
item->setPen(p);
@@ -1113,6 +1209,7 @@ void GraphViewer::saveSettings(QSettings & settings, const QString & group) cons
settings.setValue("gt_graph_visible", this->isGtGraphVisible());
settings.setValue("gps_graph_visible", this->isGPSGraphVisible());
settings.setValue("orientation_ENU", this->isOrientationENU());
settings.setValue("view_plane", (int)this->getViewPlane());
if(!group.isEmpty())
{
settings.endGroup();
@@ -1155,6 +1252,7 @@ void GraphViewer::loadSettings(QSettings & settings, const QString & group)
this->setGtGraphVisible(settings.value("gt_graph_visible", this->isGtGraphVisible()).toBool());
this->setGPSGraphVisible(settings.value("gps_graph_visible", this->isGPSGraphVisible()).toBool());
this->setOrientationENU(settings.value("orientation_ENU", this->isOrientationENU()).toBool());
this->setViewPlane((ViewPlane)settings.value("view_plane", (int)this->getViewPlane()).toInt());
if(!group.isEmpty())
{
settings.endGroup();
@@ -1201,6 +1299,10 @@ bool GraphViewer::isOrientationENU() const
{
return _orientationENU;
}
GraphViewer::ViewPlane GraphViewer::getViewPlane() const
{
return _viewPlane;
}
void GraphViewer::setWorkingDirectory(const QString & path)
{
@@ -1441,7 +1543,11 @@ void GraphViewer::setIntraInterSessionColorsEnabled(bool enabled)
void GraphViewer::setGridMapVisible(bool visible)
{
_gridMap->setVisible(visible);
if(visible && _viewPlane!=XY)
{
UWARN("Grid map can be shown only with view plane is XY.");
}
_gridMap->setVisible(_viewPlane==XY && visible);
}
void GraphViewer::setOriginVisible(bool visible)
{
@@ -1485,6 +1591,11 @@ void GraphViewer::setGPSGraphVisible(bool visible)
}
void GraphViewer::setOrientationENU(bool enabled)
{
if(enabled && _viewPlane!=XY)
{
UWARN("ENU orientation can be set only with view plane is XY.");
}
enabled = _viewPlane==XY && enabled;
if(_orientationENU!=enabled)
{
_orientationENU = enabled;
@@ -1506,6 +1617,37 @@ void GraphViewer::setOrientationENU(bool enabled)
}
}
void GraphViewer::setViewPlane(ViewPlane plane)
{
if(plane != XY)
{
setOrientationENU(false);
setGridMapVisible(false);
}
_viewPlane = plane;
for(QMap<int, NodeItem*>::iterator iter=_nodeItems.begin(); iter!=_nodeItems.end(); ++iter)
{
iter.value()->setPose(iter.value()->pose(), _viewPlane);
}
for(QMultiMap<int, LinkItem*>::iterator iter=_linkItems.begin(); iter!=_linkItems.end(); ++iter)
{
iter.value()->setPoses(iter.value()->getPoseA(), iter.value()->getPoseB(), _viewPlane);
}
_originReferentialXY->setVisible(plane==XY);
_originReferentialXZ->setVisible(plane==XZ);
_originReferentialYZ->setVisible(plane==YZ);
_referentialXY->setVisible(plane==XY);
_referentialXZ->setVisible(plane==XZ);
_referentialYZ->setVisible(plane==YZ);
if(_nodeItems.size() || _linkItems.size())
{
this->scene()->setSceneRect(this->scene()->itemsBoundingRect()); // Re-shrink the scene to it's bounding contents
}
}
void GraphViewer::restoreDefaults()
{
setNodeRadius(0.01f);
@@ -1620,6 +1762,9 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
QAction * aShowHideGtGraph;
QAction * aShowHideGPSGraph;
QAction * aOrientationENU;
QAction * aViewPlaneXY;
QAction * aViewPlaneXZ;
QAction * aViewPlaneYZ;
if(_gridMap->isVisible())
{
aShowHideGridMap = menu.addAction(tr("Hide grid map"));
@@ -1628,6 +1773,7 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
{
aShowHideGridMap = menu.addAction(tr("Show grid map"));
}
aShowHideGridMap->setEnabled(_viewPlane == XY);
if(_originReferential->isVisible())
{
aShowHideOrigin = menu.addAction(tr("Hide origin referential"));
@@ -1703,12 +1849,24 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
aOrientationENU = menu.addAction(tr("ENU Orientation"));
aOrientationENU->setCheckable(true);
aOrientationENU->setChecked(_orientationENU);
aShowHideGraph->setEnabled(_nodeItems.size());
aShowHideGraph->setEnabled(_nodeItems.size() && _viewPlane == XY);
aShowHideGraphNodes->setEnabled(_nodeItems.size() && _graphRoot->isVisible());
aShowHideGlobalPath->setEnabled(_globalPathLinkItems.size());
aShowHideLocalPath->setEnabled(_localPathLinkItems.size());
aShowHideGtGraph->setEnabled(_gtNodeItems.size());
aShowHideGPSGraph->setEnabled(_gpsNodeItems.size());
QMenu * viewPlaneMenu = menu.addMenu("View Plane...");
aViewPlaneXY = viewPlaneMenu->addAction("XY");
aViewPlaneXY->setCheckable(true);
aViewPlaneXY->setChecked(_viewPlane == XY);
aViewPlaneXZ = viewPlaneMenu->addAction("XZ");
aViewPlaneXZ->setCheckable(true);
aViewPlaneXZ->setChecked(_viewPlane == XZ);
aViewPlaneYZ = viewPlaneMenu->addAction("YZ");
aViewPlaneYZ->setCheckable(true);
aViewPlaneYZ->setChecked(_viewPlane == YZ);
menu.addSeparator();
QAction * aRestoreDefaults = menu.addAction(tr("Restore defaults"));
@@ -2060,6 +2218,18 @@ void GraphViewer::contextMenuEvent(QContextMenuEvent * event)
{
this->setOrientationENU(!this->isOrientationENU());
}
else if(r == aViewPlaneXY)
{
this->setViewPlane(XY);
}
else if(r == aViewPlaneXZ)
{
this->setViewPlane(XZ);
}
else if(r == aViewPlaneYZ)
{
this->setViewPlane(YZ);
}
if(r)
{

View File

@@ -1806,7 +1806,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
LaserScan tmpScan;
signature.sensorData().uncompressData(
uncompressImages?&tmpRgb:0,
uncompressImages?&tmpDepth:0,
uncompressImages && !signature.sensorData().depthOrRightCompressed().empty()?&tmpDepth:0,
uncompressScan?&tmpScan:0,
0, &tmpG, &tmpO, &tmpE);

View File

@@ -1056,7 +1056,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->rgdb_angularUpdate->setObjectName(Parameters::kRGBDAngularUpdate().c_str());
_ui->rgdb_linearSpeedUpdate->setObjectName(Parameters::kRGBDLinearSpeedUpdate().c_str());
_ui->rgdb_angularSpeedUpdate->setObjectName(Parameters::kRGBDAngularSpeedUpdate().c_str());
_ui->rgbd_savedLocalizationIgnored->setObjectName(Parameters::kRGBDSavedLocalizationIgnored().c_str());
_ui->rgbd_savedLocalizationIgnored->setObjectName(Parameters::kRGBDStartAtOrigin().c_str());
_ui->rgdb_rehearsalWeightIgnoredWhileMoving->setObjectName(Parameters::kMemRehearsalWeightIgnoredWhileMoving().c_str());
_ui->rgdb_newMapOdomChange->setObjectName(Parameters::kRGBDNewMapOdomChangeDistance().c_str());
_ui->odomScanHistory->setObjectName(Parameters::kRGBDNeighborLinkRefining().c_str());
@@ -1781,10 +1781,10 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
_3dRenderingVoxelSizeScan[i]->setValue(0.0);
_3dRenderingColorScheme[i]->setValue(0);
_3dRenderingOpacity[i]->setValue(i==0?1.0:0.75);
_3dRenderingPtSize[i]->setValue(2);
_3dRenderingPtSize[i]->setValue(i==0?1:2);
_3dRenderingColorSchemeScan[i]->setValue(0);
_3dRenderingOpacityScan[i]->setValue(i==0?1.0:0.5);
_3dRenderingPtSizeScan[i]->setValue(2);
_3dRenderingPtSizeScan[i]->setValue(i==0?1:2);
_3dRenderingPtSizeFeatures[i]->setValue(3);
_3dRenderingGravity[i]->setChecked(false);
_3dRenderingGravityLength[i]->setValue(1);

View File

@@ -61,7 +61,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>311</width>
<width>422</width>
<height>311</height>
</rect>
</property>
@@ -304,7 +304,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>311</width>
<width>421</width>
<height>311</height>
</rect>
</property>
@@ -1379,7 +1379,7 @@
<item>
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>1</number>
<number>2</number>
</property>
<widget class="QWidget" name="page_3">
<property name="geometry">
@@ -1541,7 +1541,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-330</y>
<y>0</y>
<width>519</width>
<height>871</height>
</rect>
@@ -2116,15 +2116,15 @@
<rect>
<x>0</x>
<y>0</y>
<width>226</width>
<height>160</height>
<width>312</width>
<height>243</height>
</rect>
</property>
<attribute name="label">
<string>Detect more loop closures</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_10" columnstretch="0,1">
<item row="3" column="1">
<item row="4" column="1">
<widget class="QLabel" name="label_32">
<property name="text">
<string>Intra-session</string>
@@ -2153,11 +2153,11 @@
<item row="0" column="1">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Radius</string>
<string>Radius Max</string>
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_detectMore_angle">
<property name="suffix">
<string> degrees</string>
@@ -2176,14 +2176,14 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Angle</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QSpinBox" name="spinBox_detectMore_iterations">
<property name="minimum">
<number>1</number>
@@ -2196,14 +2196,14 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QLabel" name="label_31">
<property name="text">
<string>Iterations</string>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -2216,27 +2216,53 @@
</property>
</spacer>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QLabel" name="label_34">
<property name="text">
<string>Inter-session</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QCheckBox" name="checkBox_detectMore_intraSession">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QCheckBox" name="checkBox_detectMore_interSession">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_36">
<property name="text">
<string>Radius Min</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_detectMore_radiusMin">
<property name="suffix">
<string> m</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">

View File

@@ -63,7 +63,7 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-2259</y>
<y>0</y>
<width>686</width>
<height>3414</height>
</rect>
@@ -95,7 +95,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>5</number>
<number>12</number>
</property>
<widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
@@ -11004,7 +11004,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<item row="4" column="1">
<widget class="QLabel" name="label_scanMatching_2">
<property name="text">
<string>Ignore last saved localization pose from previous session. If true, RTAB-Map won't assume it is restarting from the same place than where it shut down previously. In localization mode, the robot will assume that it is starting from the origin of the map.</string>
<string>If true, rtabmap will assume the robot is restarting from origin of the map. If false, rtabmap will assume the robot is restarting from the last saved localization pose from previous session (the place where it shut down previously). Used only in localization mode.</string>
</property>
<property name="wordWrap">
<bool>true</bool>