30 #include <QGraphicsView> 31 #include <QVBoxLayout> 32 #include <QGraphicsScene> 33 #include <QGraphicsEllipseItem> 34 #include <QtGui/QWheelEvent> 35 #include <QGraphicsSceneHoverEvent> 37 #include <QtGui/QDesktopServices> 38 #include <QtGui/QContextMenuEvent> 39 #include <QColorDialog> 41 #include <QFileDialog> 43 #include <QtSvg/QSvgGenerator> 45 #include <QInputDialog> 46 #include <QMessageBox> 48 #include <QtCore/QDir> 49 #include <QtCore/QDateTime> 50 #include <QtCore/QUrl> 60 #if QT_VERSION >= 0x050000 61 #include <QStandardPaths> 71 QGraphicsEllipseItem(QRectF(-radius*100.0
f,-radius*100.0
f,radius*100.0
f*2.0
f,radius*100.0
f*2.0
f)),
78 this->setPos(-pose.
y()*100.0f,-pose.
x()*100.0f);
79 this->setBrush(pen().color());
80 this->setAcceptHoverEvents(
true);
84 _line =
new QGraphicsLineItem(0,0,-radius*
sin(yaw),-radius*
cos(yaw),
this);
93 QBrush b = this->brush();
97 _line->setPen(QPen(QColor(255-color.red(), 255-color.green(), 255-color.blue())));
105 this->setRect(-radius, -radius, radius*2.0
f, radius*2.0f);
106 _line->setLine(0,0,-radius*
sin(yaw),-radius*
cos(yaw));
126 QGraphicsEllipseItem::hoverEnterEvent(event);
132 QGraphicsEllipseItem::hoverEnterEvent(event);
155 this->setToolTip(QString(
"%1 [%2] %3\n" 156 "longitude=%4 latitude=%5 altitude=%6m error=%7m bearing=%8deg")
157 .arg(
id()).arg(
mapId()).arg(
pose().prettyPrint().c_str())
158 .arg(_gps.longitude()).arg(_gps.latitude()).arg(_gps.altitude()).arg(_gps.error()).arg(_gps.bearing()));
160 QGraphicsEllipseItem::hoverEnterEvent(event);
171 QGraphicsLineItem(-poseA.y()*100.0
f, -poseA.x()*100.0
f, -poseB.y()*100.0
f, -poseB.x()*100.0
f),
177 _interSession(interSessionClosure)
179 this->setAcceptHoverEvents(
true);
185 QPen p = this->pen();
192 this->setLine(-poseA.
y()*100.0f, -poseA.
x()*100.0f, -poseB.
y()*100.0f, -poseB.
x()*100.0f);
208 int from()
const {
return _from;}
209 int to()
const {
return _to;}
214 QString str = QString(
"%1->%2 (%3 m)").arg(_from).arg(_to).arg(_poseA.getDistance(_poseB));
215 if(!_link.transform().isNull())
217 str.append(QString(
"\n%1\n%2 %3").arg(_link.transform().prettyPrint().c_str()).arg(_link.transVariance()).arg(_link.rotVariance()));
219 this->setToolTip(str);
220 QPen pen = this->pen();
221 pen.setWidthF(pen.widthF()+2);
223 QGraphicsLineItem::hoverEnterEvent(event);
228 QPen pen = this->pen();
229 pen.setWidthF(pen.widthF()-2);
231 QGraphicsLineItem::hoverEnterEvent(event);
244 QGraphicsView(parent),
245 _nodeColor(Qt::blue),
246 _currentGoalColor(Qt::darkMagenta),
247 _neighborColor(Qt::blue),
248 _loopClosureColor(Qt::red),
249 _loopClosureLocalColor(Qt::yellow),
250 _loopClosureUserColor(Qt::red),
251 _loopClosureVirtualColor(Qt::magenta),
252 _neighborMergedColor(QColor(255,170,0)),
253 _landmarkColor(Qt::darkGreen),
254 _loopClosureRejectedColor(Qt::black),
255 _localPathColor(Qt::cyan),
256 _globalPathColor(Qt::darkMagenta),
257 _gtPathColor(Qt::gray),
258 _gpsPathColor(Qt::darkCyan),
259 _loopIntraSessionColor(Qt::red),
260 _loopInterSessionColor(Qt::green),
261 _intraInterSessionColors(
false),
262 _worldMapRotation(0.0
f),
272 _originReferential(0),
275 _loopClosureOutlierThr(0),
276 _maxLinkLength(0.02
f),
277 _orientationENU(
false)
279 this->setScene(
new QGraphicsScene(
this));
280 this->setDragMode(QGraphicsView::ScrollHandDrag);
283 this->scene()->clear();
284 _world = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
285 _root = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
291 QGraphicsLineItem * item = this->scene()->addLine(0,0,0,-100, QPen(QBrush(Qt::red),
_linkWidth));
293 item->setParentItem(
_root);
295 item = this->scene()->addLine(0,0,-100,0, QPen(QBrush(Qt::green),
_linkWidth));
297 item->setParentItem(
_root);
305 item = this->scene()->addLine(0,0,0,-50, QPen(QBrush(Qt::red),
_linkWidth));
306 item->setZValue(100);
307 item->setParentItem(
_root);
309 item = this->scene()->addLine(0,0,-50,0, QPen(QBrush(Qt::green),
_linkWidth));
310 item->setZValue(100);
311 item->setParentItem(
_root);
316 _localRadius = this->scene()->addEllipse(-0.0001,-0.0001,0.0001,0.0001);
322 _gridMap = this->scene()->addPixmap(QPixmap());
326 _graphRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
330 _globalPathRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
334 _localPathRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
338 _gtGraphRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
342 _gpsGraphRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
348 this->fitInView(this->sceneRect(), Qt::KeepAspectRatio);
362 const std::multimap<int, Link> & constraints,
363 const std::map<int, int> & mapIds,
364 const std::map<int, int> & weights)
371 UDEBUG(
"poses=%d constraints=%d", (
int)poses.size(), (int)constraints.size());
375 iter.value()->hide();
377 iter.value()->setZValue(iter.key()<0?21:20);
379 for(QMultiMap<int, LinkItem*>::iterator iter =
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
381 iter.value()->hide();
384 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
386 if(!iter->second.isNull())
388 QMap<int, NodeItem*>::iterator itemIter =
_nodeItems.find(iter->first);
391 itemIter.value()->setPose(iter->second);
392 itemIter.value()->show();
399 this->scene()->addItem(item);
400 item->setZValue(iter->first<0?21:20);
409 for(std::multimap<int, Link>::const_iterator iter=constraints.begin(); iter!=constraints.end(); ++iter)
412 int idFrom = iter->first<iter->second.to()?iter->first:iter->second.to();
413 int idTo = iter->first<iter->second.to()?iter->second.to():iter->first;
415 std::map<int, Transform>::const_iterator jterA = poses.find(idFrom);
416 std::map<int, Transform>::const_iterator jterB = poses.find(idTo);
418 if(jterA != poses.end() && jterB != poses.end() &&
424 QMultiMap<int, LinkItem*>::iterator itemIter =
_linkItems.end();
428 while(itemIter.key() == idFrom && itemIter !=
_linkItems.end())
430 if(itemIter.value()->to() == idTo)
432 itemIter.value()->setPoses(poseA, poseB);
433 itemIter.value()->show();
434 linkItem = itemIter.value();
441 bool interSessionClosure =
false;
444 interSessionClosure = mapIds.at(jterA->first) != mapIds.at(jterB->first);
452 linkItem =
new LinkItem(idFrom, idTo, poseA, poseB, iter->second, interSessionClosure);
453 QPen p = linkItem->pen();
456 linkItem->setZValue(10);
457 this->scene()->addItem(linkItem);
462 else if(linkItem && itemIter !=
_linkItems.end())
498 linkItem->setZValue(interSessionClosure?6:7);
503 linkItem->setZValue(7);
511 linkItem->setZValue(interSessionClosure?8:9);
516 linkItem->setZValue(9);
524 if(iter->second.to() != idTo)
531 float linearError = fabs(iter->second.transform().getNorm() - t.
getNorm());
545 if(!iter.value()->isVisible())
557 if(!iter.value()->isVisible())
570 (--
_nodeItems.end()).value()->setColor(Qt::green);
573 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
577 QRectF rect = this->scene()->itemsBoundingRect();
578 this->fitInView(rect.adjusted(-rect.width()/2.0f, -rect.height()/2.0f, rect.width()/2.0f, rect.height()/2.0f), Qt::KeepAspectRatio);
592 UDEBUG(
"poses=%d", (
int)poses.size());
596 iter.value()->hide();
601 iter.value()->hide();
604 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
606 if(!iter->second.isNull())
608 QMap<int, NodeItem*>::iterator itemIter =
_gtNodeItems.find(iter->first);
611 itemIter.value()->setPose(iter->second);
612 itemIter.value()->show();
619 this->scene()->addItem(item);
627 if(iter!=poses.begin())
629 std::map<int, Transform>::const_iterator iterPrevious = iter;
631 Transform previousPose = iterPrevious->second;
635 QMultiMap<int, LinkItem*>::iterator linkIter =
_gtLinkItems.end();
639 while(linkIter.key() == iterPrevious->first && linkIter !=
_gtLinkItems.end())
641 if(linkIter.value()->to() == iter->first)
643 linkIter.value()->setPoses(previousPose, currentPose);
644 linkIter.value()->show();
645 linkItem = linkIter.value();
654 linkItem =
new LinkItem(iterPrevious->first, iter->first, previousPose, currentPose,
Link(), 1);
655 QPen p = linkItem->pen();
658 linkItem->setZValue(10);
659 this->scene()->addItem(linkItem);
674 if(!iter.value()->isVisible())
686 if(!iter.value()->isVisible())
699 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
703 QRectF rect = this->scene()->itemsBoundingRect();
704 this->fitInView(rect.adjusted(-rect.width()/2.0f, -rect.height()/2.0f, rect.width()/2.0f, rect.height()/2.0f), Qt::KeepAspectRatio);
714 const std::map<int, Transform> & poses,
715 const std::map<int, GPS> & gpsValues)
721 UDEBUG(
"poses=%d", (
int)poses.size());
725 iter.value()->hide();
730 iter.value()->hide();
733 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
735 if(!iter->second.isNull())
737 QMap<int, NodeItem*>::iterator itemIter =
_gpsNodeItems.find(iter->first);
740 itemIter.value()->setPose(iter->second);
741 itemIter.value()->show();
747 UASSERT(gpsValues.find(iter->first) != gpsValues.end());
749 this->scene()->addItem(item);
757 if(iter!=poses.begin())
759 std::map<int, Transform>::const_iterator iterPrevious = iter;
761 Transform previousPose = iterPrevious->second;
765 QMultiMap<int, LinkItem*>::iterator linkIter =
_gpsLinkItems.end();
769 while(linkIter.key() == iterPrevious->first && linkIter !=
_gpsLinkItems.end())
771 if(linkIter.value()->to() == iter->first)
773 linkIter.value()->setPoses(previousPose, currentPose);
774 linkIter.value()->show();
775 linkItem = linkIter.value();
784 linkItem =
new LinkItem(iterPrevious->first, iter->first, previousPose, currentPose,
Link(), 1);
785 QPen p = linkItem->pen();
788 linkItem->setZValue(10);
789 this->scene()->addItem(linkItem);
804 if(!iter.value()->isVisible())
816 if(!iter.value()->isVisible())
829 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
833 QRectF rect = this->scene()->itemsBoundingRect();
834 this->fitInView(rect.adjusted(-rect.width()/2.0f, -rect.height()/2.0f, rect.width()/2.0f, rect.height()/2.0f), Qt::KeepAspectRatio);
846 qt.translate(-t.
o24()*100.0f, -t.
o14()*100.0f);
847 qt.rotateRadians(-t.
theta());
861 UASSERT(map8U.empty() || (!map8U.empty() && resolution > 0.0f));
867 _gridMap->setTransform(QTransform::fromScale(resolution*100.0
f, -resolution*100.0f),
true);
869 _gridMap->setPixmap(QPixmap::fromImage(image));
870 _gridMap->setPos(-yMin*100.0f, -xMin*100.0f);
871 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
884 for(std::map<int, float>::const_iterator iter = posterior.begin(); iter!=posterior.end(); ++iter)
886 if(iter->first > 0 && iter->second>max)
896 std::map<int,float>::const_iterator jter = posterior.find(iter.key());
897 if(jter != posterior.end())
899 float v = jter->second>max?max:jter->second;
900 iter.value()->setColor(QColor::fromHsvF((1-v/max)*240.0
f/360.0
f, 1, 1, 1));
901 iter.value()->setZValue(iter.value()->zValue()+zValueOffset);
903 else if(iter.key() > 0)
905 iter.value()->setColor(QColor::fromHsvF(240.0
f/360.0
f, 1, 1, 1));
913 UDEBUG(
"Set global path size=%d", (
int)globalPath.size());
917 if(globalPath.size() >= 2)
919 for(
unsigned int i=0; i<globalPath.size()-1; ++i)
922 int idFrom = globalPath[i].first;
923 int idTo = globalPath[i+1].first;
924 LinkItem * item =
new LinkItem(idFrom, idTo, globalPath[i].second, globalPath[i+1].second,
Link(),
false);
925 QPen p = item->pen();
929 this->scene()->addItem(item);
946 UWARN(
"Current goal %d not found in the graph",
id);
956 iter.value()->setPoses(t*iter.value()->getPoseA(), t*iter.value()->getPoseB());
963 _localRadius->setRect(-radius*100, -radius*100, radius*200, radius*200);
973 iter.value()->hide();
976 if(localPath.size() > 1)
978 for(
unsigned int i=0; i<localPath.size()-1; ++i)
980 int idFrom = localPath[i]<localPath[i+1]?localPath[i]:localPath[i+1];
981 int idTo = localPath[i]<localPath[i+1]?localPath[i+1]:localPath[i];
984 bool updated =
false;
990 if(itemIter.value()->to() == idTo)
993 itemIter.value()->show();
1004 QPen p = item->pen();
1008 this->scene()->addItem(item);
1009 item->setZValue(16);
1020 if(!iter.value()->isVisible())
1022 delete iter.value();
1052 _root->resetTransform();
1056 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1063 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1070 iter.value()->setColor(Qt::blue);
1082 if(!group.isEmpty())
1084 settings.beginGroup(group);
1086 settings.setValue(
"node_radius", (
double)this->
getNodeRadius());
1087 settings.setValue(
"link_width", (
double)this->
getLinkWidth());
1099 settings.setValue(
"gt_color", this->
getGTColor());
1100 settings.setValue(
"gps_color", this->
getGPSColor());
1116 if(!group.isEmpty())
1118 settings.endGroup();
1124 if(!group.isEmpty())
1126 settings.beginGroup(group);
1128 this->
setNodeRadius(settings.value(
"node_radius", this->getNodeRadius()).toDouble());
1129 this->
setLinkWidth(settings.value(
"link_width", this->getLinkWidth()).toDouble());
1130 this->
setNodeColor(settings.value(
"node_color", this->getNodeColor()).value<QColor>());
1131 this->
setCurrentGoalColor(settings.value(
"current_goal_color", this->getCurrentGoalColor()).value<QColor>());
1132 this->
setNeighborColor(settings.value(
"neighbor_color", this->getNeighborColor()).value<QColor>());
1137 this->
setNeighborMergedColor(settings.value(
"neighbor_merged_color", this->getNeighborMergedColor()).value<QColor>());
1139 this->
setLocalPathColor(settings.value(
"local_path_color", this->getLocalPathColor()).value<QColor>());
1140 this->
setGlobalPathColor(settings.value(
"global_path_color", this->getGlobalPathColor()).value<QColor>());
1141 this->
setGTColor(settings.value(
"gt_color", this->getGTColor()).value<QColor>());
1142 this->
setGPSColor(settings.value(
"gps_color", this->getGPSColor()).value<QColor>());
1143 this->
setIntraSessionLoopColor(settings.value(
"intra_session_color", this->getIntraSessionLoopColor()).value<QColor>());
1144 this->
setInterSessionLoopColor(settings.value(
"inter_session_color", this->getInterSessionLoopColor()).value<QColor>());
1145 this->
setGridMapVisible(settings.value(
"grid_visible", this->isGridMapVisible()).toBool());
1146 this->
setOriginVisible(settings.value(
"origin_visible", this->isOriginVisible()).toBool());
1147 this->
setReferentialVisible(settings.value(
"referential_visible", this->isReferentialVisible()).toBool());
1148 this->
setLocalRadiusVisible(settings.value(
"local_radius_visible", this->isLocalRadiusVisible()).toBool());
1150 this->
setLoopClosureOutlierThr(settings.value(
"loop_closure_outlier_thr", this->getLoopClosureOutlierThr()).toDouble());
1151 this->
setMaxLinkLength(settings.value(
"max_link_length", this->getMaxLinkLength()).toDouble());
1152 this->
setGraphVisible(settings.value(
"graph_visible", this->isGraphVisible()).toBool());
1153 this->
setGlobalPathVisible(settings.value(
"global_path_visible", this->isGlobalPathVisible()).toBool());
1154 this->
setLocalPathVisible(settings.value(
"local_path_visible", this->isLocalPathVisible()).toBool());
1155 this->
setGtGraphVisible(settings.value(
"gt_graph_visible", this->isGtGraphVisible()).toBool());
1156 this->
setGPSGraphVisible(settings.value(
"gps_graph_visible", this->isGPSGraphVisible()).toBool());
1157 this->
setOrientationENU(settings.value(
"orientation_ENU", this->isOrientationENU()).toBool());
1158 if(!group.isEmpty())
1160 settings.endGroup();
1244 QList<QGraphicsItem*> items = this->scene()->items();
1245 for(
int i=0; i<items.size(); ++i)
1247 QGraphicsLineItem * line = qgraphicsitem_cast<QGraphicsLineItem *>(items[i]);
1250 QPen pen = line->pen();
1271 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1284 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1289 iter.value()->setZValue(10);
1299 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1305 iter.value()->setZValue(10);
1313 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1324 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1335 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1346 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1395 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1400 !iter.value()->isInterSession())
1403 iter.value()->setZValue(9);
1413 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1418 iter.value()->isInterSession())
1421 iter.value()->setZValue(8);
1497 _root->setTransform(t);
1501 _root->resetTransform();
1505 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1530 if(event->delta() < 0)
1532 this->
scale(0.95, 0.95);
1536 this->
scale(1.05, 1.05);
1542 QPixmap pixmap(50, 50);
1544 return QIcon(pixmap);
1550 QAction * aScreenShot = menu.addAction(tr(
"Take a screenshot..."));
1551 menu.addSeparator();
1555 aChangeNodeColor->setIconVisibleInMenu(
true);
1556 aChangeCurrentGoalColor->setIconVisibleInMenu(
true);
1559 QMenu * menuLink = menu.addMenu(tr(
"Set link color..."));
1560 QAction * aChangeNeighborColor = menuLink->addAction(tr(
"Neighbor"));
1561 QAction * aChangeGlobalLoopColor = menuLink->addAction(tr(
"Global loop closure"));
1562 QAction * aChangeLocalLoopColor = menuLink->addAction(tr(
"Local loop closure"));
1563 QAction * aChangeUserLoopColor = menuLink->addAction(tr(
"User loop closure"));
1564 QAction * aChangeVirtualLoopColor = menuLink->addAction(tr(
"Virtual loop closure"));
1565 QAction * aChangeNeighborMergedColor = menuLink->addAction(tr(
"Neighbor merged"));
1566 QAction * aChangeLandmarkColor = menuLink->addAction(tr(
"Landmark"));
1567 QAction * aChangeRejectedLoopColor = menuLink->addAction(tr(
"Outlier loop closure"));
1568 QAction * aChangeRejectedLoopThr = menuLink->addAction(tr(
"Set outlier threshold..."));
1569 QAction * aChangeLocalPathColor = menuLink->addAction(tr(
"Local path"));
1570 QAction * aChangeGlobalPathColor = menuLink->addAction(tr(
"Global path"));
1571 QAction * aChangeGTColor = menuLink->addAction(tr(
"Ground truth"));
1572 QAction * aChangeGPSColor = menuLink->addAction(tr(
"GPS"));
1573 menuLink->addSeparator();
1574 QAction * aSetIntraInterSessionColors = menuLink->addAction(tr(
"Enable intra/inter-session colors"));
1575 QAction * aChangeIntraSessionLoopColor = menuLink->addAction(tr(
"Intra-session loop closure"));
1576 QAction * aChangeInterSessionLoopColor = menuLink->addAction(tr(
"Inter-session loop closure"));
1591 aChangeNeighborColor->setIconVisibleInMenu(
true);
1592 aChangeGlobalLoopColor->setIconVisibleInMenu(
true);
1593 aChangeLocalLoopColor->setIconVisibleInMenu(
true);
1594 aChangeUserLoopColor->setIconVisibleInMenu(
true);
1595 aChangeVirtualLoopColor->setIconVisibleInMenu(
true);
1596 aChangeNeighborMergedColor->setIconVisibleInMenu(
true);
1597 aChangeRejectedLoopColor->setIconVisibleInMenu(
true);
1598 aChangeLocalPathColor->setIconVisibleInMenu(
true);
1599 aChangeGlobalPathColor->setIconVisibleInMenu(
true);
1600 aChangeGTColor->setIconVisibleInMenu(
true);
1601 aChangeGPSColor->setIconVisibleInMenu(
true);
1602 aChangeIntraSessionLoopColor->setIconVisibleInMenu(
true);
1603 aChangeInterSessionLoopColor->setIconVisibleInMenu(
true);
1604 aSetIntraInterSessionColors->setCheckable(
true);
1607 menu.addSeparator();
1608 QAction * aSetNodeSize = menu.addAction(tr(
"Set node radius..."));
1609 QAction * aSetLinkSize = menu.addAction(tr(
"Set link width..."));
1610 QAction * aChangeMaxLinkLength = menu.addAction(tr(
"Set maximum link length..."));
1611 menu.addSeparator();
1612 QAction * aShowHideGridMap;
1613 QAction * aShowHideGraph;
1614 QAction * aShowHideGraphNodes;
1615 QAction * aShowHideOrigin;
1616 QAction * aShowHideReferential;
1617 QAction * aShowHideLocalRadius;
1618 QAction * aShowHideGlobalPath;
1619 QAction * aShowHideLocalPath;
1620 QAction * aShowHideGtGraph;
1621 QAction * aShowHideGPSGraph;
1622 QAction * aOrientationENU;
1625 aShowHideGridMap = menu.addAction(tr(
"Hide grid map"));
1629 aShowHideGridMap = menu.addAction(tr(
"Show grid map"));
1633 aShowHideOrigin = menu.addAction(tr(
"Hide origin referential"));
1637 aShowHideOrigin = menu.addAction(tr(
"Show origin referential"));
1641 aShowHideReferential = menu.addAction(tr(
"Hide current referential"));
1645 aShowHideReferential = menu.addAction(tr(
"Show current referential"));
1649 aShowHideLocalRadius = menu.addAction(tr(
"Hide local radius"));
1653 aShowHideLocalRadius = menu.addAction(tr(
"Show local radius"));
1657 aShowHideGraph = menu.addAction(tr(
"Hide graph"));
1661 aShowHideGraph = menu.addAction(tr(
"Show graph"));
1665 aShowHideGraphNodes = menu.addAction(tr(
"Hide graph nodes"));
1669 aShowHideGraphNodes = menu.addAction(tr(
"Show graph nodes"));
1673 aShowHideGlobalPath = menu.addAction(tr(
"Hide global path"));
1677 aShowHideGlobalPath = menu.addAction(tr(
"Show global path"));
1681 aShowHideLocalPath = menu.addAction(tr(
"Hide local path"));
1685 aShowHideLocalPath = menu.addAction(tr(
"Show local path"));
1689 aShowHideGtGraph = menu.addAction(tr(
"Hide ground truth graph"));
1693 aShowHideGtGraph = menu.addAction(tr(
"Show ground truth graph"));
1697 aShowHideGPSGraph = menu.addAction(tr(
"Hide GPS graph"));
1701 aShowHideGPSGraph = menu.addAction(tr(
"Show GPS graph"));
1703 aOrientationENU = menu.addAction(tr(
"ENU Orientation"));
1704 aOrientationENU->setCheckable(
true);
1706 aShowHideGraph->setEnabled(
_nodeItems.size());
1712 menu.addSeparator();
1713 QAction * aRestoreDefaults = menu.addAction(tr(
"Restore defaults"));
1715 QAction * r = menu.exec(event->globalPos());
1716 if(r == aScreenShot)
1721 #if QT_VERSION >= 0x050000 1722 filePath = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
1725 if(!dir.exists(filePath))
1727 filePath = QDir::homePath();
1729 filePath +=
"/graph.png";
1732 filePath = QFileDialog::getSaveFileName(
this, tr(
"Save figure to ..."), filePath,
"*.png *.xpm *.jpg *.pdf *.svg");
1734 filePath = QFileDialog::getSaveFileName(
this, tr(
"Save figure to ..."), filePath,
"*.png *.xpm *.jpg *.pdf");
1736 if(!filePath.isEmpty())
1738 if(QFileInfo(filePath).suffix() ==
"")
1750 _root->setScale(this->transform().m11());
1753 this->scene()->clearSelection();
1754 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1755 QSize sceneSize = this->scene()->sceneRect().size().toSize();
1757 if(QFileInfo(filePath).suffix().compare(
"pdf") == 0)
1759 QPrinter printer(QPrinter::HighResolution);
1760 printer.setOrientation(QPrinter::Portrait);
1761 printer.setOutputFileName( filePath );
1762 QPainter p(&printer);
1763 scene()->render(&p);
1766 else if(QFileInfo(filePath).suffix().compare(
"svg") == 0)
1769 QSvgGenerator svgGen;
1771 svgGen.setFileName( filePath );
1772 svgGen.setSize(sceneSize);
1774 int borderH = sceneSize.width()/100;
1775 int borderV = sceneSize.height()/100;
1776 svgGen.setViewBox(QRect(-borderH, -borderV, sceneSize.width()+borderH*2, sceneSize.height()+borderV*2));
1777 svgGen.setTitle(tr(
"RTAB-Map graph"));
1778 svgGen.setDescription(tr(
"RTAB-Map map and graph"));
1780 QPainter painter( &svgGen );
1782 this->scene()->render(&painter);
1784 UERROR(
"RTAB-MAp is not built with Qt's SVG library, cannot save picture in svg format.");
1789 QImage image(sceneSize, QImage::Format_ARGB32);
1790 image.fill(Qt::transparent);
1791 QPainter painter(&image);
1793 this->scene()->render(&painter);
1796 image.save(filePath);
1800 QMessageBox::warning(
this,
1802 tr(
"Could not export in PNG (the scene may be too large %1x%2), try saving in SVG.").arg(sceneSize.width()).arg(sceneSize.height()));
1808 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1811 QDesktopServices::openUrl(QUrl::fromLocalFile(filePath));
1816 else if(r == aSetIntraInterSessionColors)
1820 else if(r == aChangeRejectedLoopThr)
1823 double value = QInputDialog::getDouble(
this, tr(
"Loop closure outlier threshold"), tr(
"Value (m)"),
_loopClosureOutlierThr, 0.0, 1000.0, 2, &ok);
1829 else if(r == aChangeMaxLinkLength)
1832 double value = QInputDialog::getDouble(
this, tr(
"Maximum link length to be shown"), tr(
"Value (m)"),
_maxLinkLength, 0.0, 1000.0, 3, &ok);
1838 else if(r == aChangeNodeColor ||
1839 r == aChangeCurrentGoalColor ||
1840 r == aChangeNeighborColor ||
1841 r == aChangeGlobalLoopColor ||
1842 r == aChangeLocalLoopColor ||
1843 r == aChangeUserLoopColor ||
1844 r == aChangeVirtualLoopColor ||
1845 r == aChangeNeighborMergedColor ||
1846 r == aChangeRejectedLoopColor ||
1847 r == aChangeLocalPathColor ||
1848 r == aChangeGlobalPathColor ||
1849 r == aChangeGTColor ||
1850 r == aChangeGPSColor ||
1851 r == aChangeIntraSessionLoopColor ||
1852 r == aChangeInterSessionLoopColor)
1855 if(r == aChangeNodeColor)
1859 else if(r == aChangeCurrentGoalColor)
1863 else if(r == aChangeGlobalLoopColor)
1867 else if(r == aChangeLocalLoopColor)
1871 else if(r == aChangeUserLoopColor)
1875 else if(r == aChangeVirtualLoopColor)
1879 else if(r == aChangeNeighborMergedColor)
1883 else if(r == aChangeLandmarkColor)
1887 else if(r == aChangeRejectedLoopColor)
1891 else if(r == aChangeLocalPathColor)
1895 else if(r == aChangeGlobalPathColor)
1899 else if(r == aChangeGTColor)
1903 else if(r == aChangeGPSColor)
1907 else if(r == aChangeIntraSessionLoopColor)
1911 else if(r == aChangeInterSessionLoopColor)
1919 color = QColorDialog::getColor(color,
this);
1923 if(r == aChangeNodeColor)
1927 else if(r == aChangeCurrentGoalColor)
1931 else if(r == aChangeGlobalLoopColor)
1935 else if(r == aChangeLocalLoopColor)
1939 else if(r == aChangeUserLoopColor)
1943 else if(r == aChangeVirtualLoopColor)
1947 else if(r == aChangeNeighborMergedColor)
1951 else if(r == aChangeLandmarkColor)
1955 else if(r == aChangeRejectedLoopColor)
1959 else if(r == aChangeLocalPathColor)
1963 else if(r == aChangeGlobalPathColor)
1967 else if(r == aChangeGTColor)
1971 else if(r == aChangeGPSColor)
1975 else if(r == aChangeIntraSessionLoopColor)
1979 else if(r == aChangeInterSessionLoopColor)
1993 else if(r == aSetNodeSize)
1996 double value = QInputDialog::getDouble(
this, tr(
"Node radius"), tr(
"Radius (m)"),
_nodeRadius, 0.001, 100, 3, &ok);
2002 else if(r == aSetLinkSize)
2005 double value = QInputDialog::getDouble(
this, tr(
"Link width"), tr(
"Width (m)"),
_linkWidth, 0, 100, 2, &ok);
2011 else if(r == aShowHideGridMap)
2019 else if(r == aShowHideOrigin)
2023 else if(r == aShowHideReferential)
2027 else if(r == aShowHideLocalRadius)
2031 else if(r == aRestoreDefaults)
2035 else if(r == aShowHideGraph)
2039 else if(r == aShowHideGraphNodes)
2043 else if(r == aShowHideGlobalPath)
2047 else if(r == aShowHideLocalPath)
2051 else if(r == aShowHideGtGraph)
2055 else if(r == aShowHideGPSGraph)
2059 else if(r == aOrientationENU)
void setPoses(const Transform &poseA, const Transform &poseB)
void setLoopClosureOutlierThr(float value)
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
QGraphicsItem * _gpsGraphRoot
QColor _loopClosureLocalColor
QColor _loopClosureVirtualColor
void setGlobalPathColor(const QColor &color)
const QColor & getVirtualLoopClosureColor() const
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
float getLinkWidth() const
QGraphicsItem * _localPathRoot
void setCurrentGoalID(int id, const Transform &pose=Transform())
void setGridMapVisible(bool visible)
const QColor & getInterSessionLoopColor() const
QColor _neighborMergedColor
void setMaxLinkLength(float value)
QGraphicsEllipseItem * _localRadius
const Transform & pose() const
QGraphicsItemGroup * _referential
const Transform & getPoseA() const
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
void setRadius(float radius)
void setWorkingDirectory(const QString &path)
NodeGPSItem(int id, int mapId, const Transform &pose, float radius, const GPS &gps)
void setColor(const QColor &color)
void setIntraInterSessionColorsEnabled(bool enabled)
void saveSettings(QSettings &settings, const QString &group="") const
void updateReferentialPosition(const Transform &t)
void setGlobalPathVisible(bool visible)
void setNeighborColor(const QColor &color)
const QColor & getGPSColor() const
const QColor & getRejectedLoopClosureColor() const
float getNodeRadius() const
void setLandmarkColor(const QColor &color)
bool _intraInterSessionColors
bool isInterSession() const
bool isGlobalPathVisible() const
virtual void wheelEvent(QWheelEvent *event)
QGraphicsPixmapItem * _gridMap
void updateLocalPath(const std::vector< int > &localPath)
void setGPSGraphVisible(bool visible)
void setReferentialVisible(bool visible)
void setGPSColor(const QColor &color)
void setGlobalPath(const std::vector< std::pair< int, Transform > > &globalPath)
QMultiMap< int, LinkItem * > _gpsLinkItems
QGraphicsItem * _graphRoot
NodeItem(int id, int mapId, const Transform &pose, float radius, int weight=-1)
const QColor & getGlobalLoopClosureColor() const
bool isGPSGraphVisible() const
bool isGraphVisible() const
QColor _loopInterSessionColor
const QColor & getGlobalPathColor() const
#define UASSERT(condition)
GLM_FUNC_DECL genType cos(genType const &angle)
Wrappers of STL for convenient functions.
const QColor & getLocalPathColor() const
QColor _loopClosureRejectedColor
GLM_FUNC_DECL genType sin(genType const &angle)
void setGtGraphVisible(bool visible)
float getLoopClosureOutlierThr() const
void setColor(const QColor &color)
QColor _loopIntraSessionColor
QMultiMap< int, LinkItem * > _globalPathLinkItems
void setPose(const Transform &pose)
void setNeighborMergedColor(const QColor &color)
QImage uCvMat2QImage(const cv::Mat &image, bool isBgr=true, uCvQtDepthColorMap colorMap=uCvQtDepthWhiteToBlack)
QGraphicsItemGroup * _originReferential
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
const QColor & getNodeColor() const
float getMaxLinkLength() const
bool isOrientationENU() const
Link::Type linkType() const
void setLocalLoopClosureColor(const QColor &color)
QMultiMap< int, LinkItem * > _gtLinkItems
const QColor & getIntraSessionLoopColor() const
QGraphicsItem * _gtGraphRoot
GraphViewer(QWidget *parent=0)
bool isGtGraphVisible() const
void setInterSessionLoopColor(const QColor &color)
float _loopClosureOutlierThr
void setUserLoopClosureColor(const QColor &color)
void setOrientationENU(bool enabled)
void updateMap(const cv::Mat &map8U, float resolution, float xMin, float yMin)
bool uContains(const std::list< V > &list, const V &value)
void setGlobalLoopClosureColor(const QColor &color)
bool isLocalRadiusVisible() const
const QColor & getLocalLoopClosureColor() const
const QColor & getCurrentGoalColor() const
void setLocalPathColor(const QColor &color)
LinkItem(int from, int to, const Transform &poseA, const Transform &poseB, const Link &link, bool interSessionClosure)
bool isGridMapVisible() const
QMultiMap< int, LinkItem * > _localPathLinkItems
bool isIntraInterSessionColorsEnabled() const
bool isReferentialVisible() const
QGraphicsItem * _globalPathRoot
QMap< int, NodeItem * > _gpsNodeItems
void setVirtualLoopClosureColor(const QColor &color)
void setWorldMapRotation(const float &theta)
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
void setIntraSessionLoopColor(const QColor &color)
void setNodeRadius(float radius)
QIcon createIcon(const QColor &color)
QColor _loopClosureUserColor
void updateGTGraph(const std::map< int, Transform > &poses)
void setGTColor(const QColor &color)
bool isOriginVisible() const
void setGraphVisible(bool visible)
const Transform & getPoseB() const
void setNodeColor(const QColor &color)
const QColor & getUserLoopClosureColor() const
void setNodeVisible(bool visible)
ULogger class and convenient macros.
QString _workingDirectory
QMultiMap< int, LinkItem * > _linkItems
bool isLocalPathVisible() const
GLM_FUNC_DECL T yaw(detail::tquat< T, P > const &x)
const QColor & getNeighborMergedColor() const
void updateGPSGraph(const std::map< int, Transform > &gpsMapPoses, const std::map< int, GPS > &gpsValues)
void loadSettings(QSettings &settings, const QString &group="")
void updatePosterior(const std::map< int, float > &posterior, float fixedMax=0.0f, int zValueOffset=0)
void setLocalRadius(float radius)
void updateGraph(const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints, const std::map< int, int > &mapIds, const std::map< int, int > &weights=std::map< int, int >())
const QColor & getGTColor() const
virtual void contextMenuEvent(QContextMenuEvent *event)
QMap< int, NodeItem * > _nodeItems
QGraphicsLineItem * _line
QMap< int, NodeItem * > _gtNodeItems
const QColor & getNeighborColor() const
void setLocalPathVisible(bool visible)
void setOriginVisible(bool visible)
void setCurrentGoalColor(const QColor &color)
void setLocalRadiusVisible(bool visible)
void setRejectedLoopClosureColor(const QColor &color)
void setLinkWidth(float width)