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 <QtSvg/QSvgGenerator> 43 #include <QInputDialog> 44 #include <QMessageBox> 46 #include <QtCore/QDir> 47 #include <QtCore/QDateTime> 48 #include <QtCore/QUrl> 64 QGraphicsEllipseItem(QRectF(-radius*100.0
f,-radius*100.0
f,radius*100.0
f*2.0
f,radius*100.0
f*2.0
f)),
70 this->setPos(-pose.
y()*100.0f,-pose.
x()*100.0f);
71 this->setBrush(pen().color());
72 this->setAcceptHoverEvents(
true);
76 _line =
new QGraphicsLineItem(0,0,-radius*
sin(yaw),-radius*
cos(yaw),
this);
85 QBrush b = this->brush();
89 _line->setPen(QPen(QColor(255-color.red(), 255-color.green(), 255-color.blue())));
97 this->setRect(-radius, -radius, radius*2.0
f, radius*2.0f);
98 _line->setLine(0,0,-radius*
sin(yaw),-radius*
cos(yaw));
111 QGraphicsEllipseItem::hoverEnterEvent(event);
117 QGraphicsEllipseItem::hoverEnterEvent(event);
139 this->setToolTip(QString(
"%1 [%2] %3\n" 140 "longitude=%4 latitude=%5 altitude=%6m error=%7m bearing=%8deg")
141 .arg(
id()).arg(
mapId()).arg(
pose().prettyPrint().c_str())
142 .arg(_gps.longitude()).arg(_gps.latitude()).arg(_gps.altitude()).arg(_gps.error()).arg(_gps.bearing()));
144 QGraphicsEllipseItem::hoverEnterEvent(event);
155 QGraphicsLineItem(-poseA.y()*100.0
f, -poseA.x()*100.0
f, -poseB.y()*100.0
f, -poseB.x()*100.0
f),
161 _interSession(interSessionClosure)
163 this->setAcceptHoverEvents(
true);
169 QPen p = this->pen();
176 this->setLine(-poseA.
y()*100.0f, -poseA.
x()*100.0f, -poseB.
y()*100.0f, -poseB.
x()*100.0f);
192 int from()
const {
return _from;}
193 int to()
const {
return _to;}
198 QString str = QString(
"%1->%2 (%3 m)").arg(_from).arg(_to).arg(_poseA.getDistance(_poseB));
199 if(!_link.transform().isNull())
201 str.append(QString(
"\n%1\n%2 %3").arg(_link.transform().prettyPrint().c_str()).arg(_link.transVariance()).arg(_link.rotVariance()));
203 this->setToolTip(str);
204 QPen pen = this->pen();
205 pen.setWidthF(pen.widthF()+2);
207 QGraphicsLineItem::hoverEnterEvent(event);
212 QPen pen = this->pen();
213 pen.setWidthF(pen.widthF()-2);
215 QGraphicsLineItem::hoverEnterEvent(event);
228 QGraphicsView(parent),
229 _nodeColor(Qt::blue),
230 _currentGoalColor(Qt::darkMagenta),
231 _neighborColor(Qt::blue),
232 _loopClosureColor(Qt::red),
233 _loopClosureLocalColor(Qt::yellow),
234 _loopClosureUserColor(Qt::red),
235 _loopClosureVirtualColor(Qt::magenta),
236 _neighborMergedColor(QColor(255,170,0)),
237 _loopClosureRejectedColor(Qt::black),
238 _localPathColor(Qt::cyan),
239 _globalPathColor(Qt::darkMagenta),
240 _gtPathColor(Qt::gray),
241 _gpsPathColor(Qt::darkCyan),
242 _loopIntraSessionColor(Qt::red),
243 _loopInterSessionColor(Qt::green),
244 _intraInterSessionColors(
false),
253 _originReferential(0),
256 _loopClosureOutlierThr(0),
257 _maxLinkLength(0.02
f),
258 _orientationENU(
false)
260 this->setScene(
new QGraphicsScene(
this));
261 this->setDragMode(QGraphicsView::ScrollHandDrag);
264 this->scene()->clear();
265 _root = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
270 QGraphicsLineItem * item = this->scene()->addLine(0,0,0,-100, QPen(QBrush(Qt::red),
_linkWidth));
271 item->setZValue(100);
272 item->setParentItem(
_root);
274 item = this->scene()->addLine(0,0,-100,0, QPen(QBrush(Qt::green),
_linkWidth));
275 item->setZValue(100);
276 item->setParentItem(
_root);
282 item = this->scene()->addLine(0,0,0,-50, QPen(QBrush(Qt::red),
_linkWidth));
283 item->setZValue(100);
284 item->setParentItem(
_root);
286 item = this->scene()->addLine(0,0,-50,0, QPen(QBrush(Qt::green),
_linkWidth));
287 item->setZValue(100);
288 item->setParentItem(
_root);
291 _localRadius = this->scene()->addEllipse(-0.0001,-0.0001,0.0001,0.0001);
297 _gridMap = this->scene()->addPixmap(QPixmap());
301 _graphRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
305 _globalPathRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
309 _localPathRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
313 _gtGraphRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
317 _gpsGraphRoot = (QGraphicsItem *)this->scene()->addEllipse(QRectF(-0.0001,-0.0001,0.0001,0.0001));
323 this->fitInView(this->sceneRect(), Qt::KeepAspectRatio);
331 const std::multimap<int, Link> & constraints,
332 const std::map<int, int> & mapIds)
339 UDEBUG(
"poses=%d constraints=%d", (
int)poses.size(), (int)constraints.size());
343 iter.value()->hide();
346 for(QMultiMap<int, LinkItem*>::iterator iter =
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
348 iter.value()->hide();
351 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
353 if(!iter->second.isNull())
355 QMap<int, NodeItem*>::iterator itemIter =
_nodeItems.find(iter->first);
358 itemIter.value()->setPose(iter->second);
359 itemIter.value()->show();
366 this->scene()->addItem(item);
376 for(std::multimap<int, Link>::const_iterator iter=constraints.begin(); iter!=constraints.end(); ++iter)
379 int idFrom = iter->first<iter->second.to()?iter->first:iter->second.to();
380 int idTo = iter->first<iter->second.to()?iter->second.to():iter->first;
382 std::map<int, Transform>::const_iterator jterA = poses.find(idFrom);
383 std::map<int, Transform>::const_iterator jterB = poses.find(idTo);
385 if(jterA != poses.end() && jterB != poses.end() &&
391 QMultiMap<int, LinkItem*>::iterator itemIter =
_linkItems.end();
395 while(itemIter.key() == idFrom && itemIter !=
_linkItems.end())
397 if(itemIter.value()->to() == idTo)
399 itemIter.value()->setPoses(poseA, poseB);
400 itemIter.value()->show();
401 linkItem = itemIter.value();
408 bool interSessionClosure =
false;
411 interSessionClosure = mapIds.at(jterA->first) != mapIds.at(jterB->first);
419 linkItem =
new LinkItem(idFrom, idTo, poseA, poseB, iter->second, interSessionClosure);
420 QPen p = linkItem->pen();
423 linkItem->setZValue(10);
424 this->scene()->addItem(linkItem);
429 else if(linkItem && itemIter !=
_linkItems.end())
461 linkItem->setZValue(interSessionClosure?6:7);
466 linkItem->setZValue(7);
474 linkItem->setZValue(interSessionClosure?8:9);
479 linkItem->setZValue(9);
487 if(iter->second.to() != idTo)
494 float linearError =
uMax3(
495 fabs(iter->second.transform().x() - t.
x()),
496 fabs(iter->second.transform().y() - t.
y()),
497 fabs(iter->second.transform().z() - t.
z()));
511 if(!iter.value()->isVisible())
523 if(!iter.value()->isVisible())
536 (--
_nodeItems.end()).value()->setColor(Qt::green);
539 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
543 QRectF rect = this->scene()->itemsBoundingRect();
544 this->fitInView(rect.adjusted(-rect.width()/2.0f, -rect.height()/2.0f, rect.width()/2.0f, rect.height()/2.0f), Qt::KeepAspectRatio);
558 UDEBUG(
"poses=%d", (
int)poses.size());
562 iter.value()->hide();
567 iter.value()->hide();
570 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
572 if(!iter->second.isNull())
574 QMap<int, NodeItem*>::iterator itemIter =
_gtNodeItems.find(iter->first);
577 itemIter.value()->setPose(iter->second);
578 itemIter.value()->show();
585 this->scene()->addItem(item);
593 if(iter!=poses.begin())
595 std::map<int, Transform>::const_iterator iterPrevious = iter;
597 Transform previousPose = iterPrevious->second;
601 QMultiMap<int, LinkItem*>::iterator linkIter =
_gtLinkItems.end();
605 while(linkIter.key() == iterPrevious->first && linkIter !=
_gtLinkItems.end())
607 if(linkIter.value()->to() == iter->first)
609 linkIter.value()->setPoses(previousPose, currentPose);
610 linkIter.value()->show();
611 linkItem = linkIter.value();
620 linkItem =
new LinkItem(iterPrevious->first, iter->first, previousPose, currentPose,
Link(), 1);
621 QPen p = linkItem->pen();
624 linkItem->setZValue(10);
625 this->scene()->addItem(linkItem);
640 if(!iter.value()->isVisible())
652 if(!iter.value()->isVisible())
665 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
669 QRectF rect = this->scene()->itemsBoundingRect();
670 this->fitInView(rect.adjusted(-rect.width()/2.0f, -rect.height()/2.0f, rect.width()/2.0f, rect.height()/2.0f), Qt::KeepAspectRatio);
680 const std::map<int, Transform> & poses,
681 const std::map<int, GPS> & gpsValues)
687 UDEBUG(
"poses=%d", (
int)poses.size());
691 iter.value()->hide();
696 iter.value()->hide();
699 for(std::map<int, Transform>::const_iterator iter=poses.begin(); iter!=poses.end(); ++iter)
701 if(!iter->second.isNull())
703 QMap<int, NodeItem*>::iterator itemIter =
_gpsNodeItems.find(iter->first);
706 itemIter.value()->setPose(iter->second);
707 itemIter.value()->show();
713 UASSERT(gpsValues.find(iter->first) != gpsValues.end());
715 this->scene()->addItem(item);
723 if(iter!=poses.begin())
725 std::map<int, Transform>::const_iterator iterPrevious = iter;
727 Transform previousPose = iterPrevious->second;
731 QMultiMap<int, LinkItem*>::iterator linkIter =
_gpsLinkItems.end();
735 while(linkIter.key() == iterPrevious->first && linkIter !=
_gpsLinkItems.end())
737 if(linkIter.value()->to() == iter->first)
739 linkIter.value()->setPoses(previousPose, currentPose);
740 linkIter.value()->show();
741 linkItem = linkIter.value();
750 linkItem =
new LinkItem(iterPrevious->first, iter->first, previousPose, currentPose,
Link(), 1);
751 QPen p = linkItem->pen();
754 linkItem->setZValue(10);
755 this->scene()->addItem(linkItem);
770 if(!iter.value()->isVisible())
782 if(!iter.value()->isVisible())
795 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
799 QRectF rect = this->scene()->itemsBoundingRect();
800 this->fitInView(rect.adjusted(-rect.width()/2.0f, -rect.height()/2.0f, rect.width()/2.0f, rect.height()/2.0f), Qt::KeepAspectRatio);
824 UASSERT(map8U.empty() || (!map8U.empty() && resolution > 0.0f));
830 _gridMap->setTransform(QTransform::fromScale(resolution*100.0
f, -resolution*100.0f),
true);
832 _gridMap->setPixmap(QPixmap::fromImage(image));
833 _gridMap->setPos(-yMin*100.0f, -xMin*100.0f);
834 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
847 for(std::map<int, float>::const_iterator iter = posterior.begin(); iter!=posterior.end(); ++iter)
849 if(iter->first > 0 && iter->second>max)
859 std::map<int,float>::const_iterator jter = posterior.find(iter.key());
860 if(jter != posterior.end())
862 float v = jter->second>max?max:jter->second;
863 iter.value()->setColor(QColor::fromHsvF((1-v/max)*240.0
f/360.0
f, 1, 1, 1));
867 iter.value()->setColor(QColor::fromHsvF(240.0
f/360.0
f, 1, 1, 1));
875 UDEBUG(
"Set global path size=%d", (
int)globalPath.size());
879 if(globalPath.size() >= 2)
881 for(
unsigned int i=0; i<globalPath.size()-1; ++i)
884 int idFrom = globalPath[i].first;
885 int idTo = globalPath[i+1].first;
886 LinkItem * item =
new LinkItem(idFrom, idTo, globalPath[i].second, globalPath[i+1].second,
Link(),
false);
887 QPen p = item->pen();
891 this->scene()->addItem(item);
908 UWARN(
"Current goal %d not found in the graph",
id);
918 iter.value()->setPoses(t*iter.value()->getPoseA(), t*iter.value()->getPoseB());
925 _localRadius->setRect(-radius, -radius, radius*2, radius*2);
935 iter.value()->hide();
938 if(localPath.size() > 1)
940 for(
unsigned int i=0; i<localPath.size()-1; ++i)
942 int idFrom = localPath[i]<localPath[i+1]?localPath[i]:localPath[i+1];
943 int idTo = localPath[i]<localPath[i+1]?localPath[i+1]:localPath[i];
946 bool updated =
false;
952 if(itemIter.value()->to() == idTo)
955 itemIter.value()->show();
966 QPen p = item->pen();
970 this->scene()->addItem(item);
982 if(!iter.value()->isVisible())
1016 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1023 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1030 iter.value()->setColor(Qt::blue);
1042 if(!group.isEmpty())
1044 settings.beginGroup(group);
1046 settings.setValue(
"node_radius", (
double)this->
getNodeRadius());
1047 settings.setValue(
"link_width", (
double)this->
getLinkWidth());
1059 settings.setValue(
"gt_color", this->
getGTColor());
1060 settings.setValue(
"gps_color", this->
getGPSColor());
1076 if(!group.isEmpty())
1078 settings.endGroup();
1084 if(!group.isEmpty())
1086 settings.beginGroup(group);
1088 this->
setNodeRadius(settings.value(
"node_radius", this->getNodeRadius()).toDouble());
1089 this->
setLinkWidth(settings.value(
"link_width", this->getLinkWidth()).toDouble());
1090 this->
setNodeColor(settings.value(
"node_color", this->getNodeColor()).value<QColor>());
1091 this->
setCurrentGoalColor(settings.value(
"current_goal_color", this->getCurrentGoalColor()).value<QColor>());
1092 this->
setNeighborColor(settings.value(
"neighbor_color", this->getNeighborColor()).value<QColor>());
1097 this->
setNeighborMergedColor(settings.value(
"neighbor_merged_color", this->getNeighborMergedColor()).value<QColor>());
1099 this->
setLocalPathColor(settings.value(
"local_path_color", this->getLocalPathColor()).value<QColor>());
1100 this->
setGlobalPathColor(settings.value(
"global_path_color", this->getGlobalPathColor()).value<QColor>());
1101 this->
setGTColor(settings.value(
"gt_color", this->getGTColor()).value<QColor>());
1102 this->
setGPSColor(settings.value(
"gps_color", this->getGPSColor()).value<QColor>());
1103 this->
setIntraSessionLoopColor(settings.value(
"intra_session_color", this->getIntraSessionLoopColor()).value<QColor>());
1104 this->
setInterSessionLoopColor(settings.value(
"inter_session_color", this->getInterSessionLoopColor()).value<QColor>());
1105 this->
setGridMapVisible(settings.value(
"grid_visible", this->isGridMapVisible()).toBool());
1106 this->
setOriginVisible(settings.value(
"origin_visible", this->isOriginVisible()).toBool());
1107 this->
setReferentialVisible(settings.value(
"referential_visible", this->isReferentialVisible()).toBool());
1108 this->
setLocalRadiusVisible(settings.value(
"local_radius_visible", this->isLocalRadiusVisible()).toBool());
1110 this->
setLoopClosureOutlierThr(settings.value(
"loop_closure_outlier_thr", this->getLoopClosureOutlierThr()).toDouble());
1111 this->
setMaxLinkLength(settings.value(
"max_link_length", this->getMaxLinkLength()).toDouble());
1112 this->
setGraphVisible(settings.value(
"graph_visible", this->isGraphVisible()).toBool());
1113 this->
setGlobalPathVisible(settings.value(
"global_path_visible", this->isGlobalPathVisible()).toBool());
1114 this->
setLocalPathVisible(settings.value(
"local_path_visible", this->isLocalPathVisible()).toBool());
1115 this->
setGtGraphVisible(settings.value(
"gt_graph_visible", this->isGtGraphVisible()).toBool());
1116 this->
setGPSGraphVisible(settings.value(
"gps_graph_visible", this->isGPSGraphVisible()).toBool());
1117 this->
setOrientationENU(settings.value(
"orientation_ENU", this->isOrientationENU()).toBool());
1118 if(!group.isEmpty())
1120 settings.endGroup();
1204 QList<QGraphicsItem*> items = this->scene()->items();
1205 for(
int i=0; i<items.size(); ++i)
1207 QGraphicsLineItem * line = qgraphicsitem_cast<QGraphicsLineItem *>(items[i]);
1210 QPen pen = line->pen();
1231 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1244 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1249 iter.value()->setZValue(10);
1259 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1265 iter.value()->setZValue(10);
1273 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)
1295 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1344 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1349 !iter.value()->isInterSession())
1352 iter.value()->setZValue(9);
1362 for(QMultiMap<int, LinkItem*>::iterator iter=
_linkItems.begin(); iter!=
_linkItems.end(); ++iter)
1367 iter.value()->isInterSession())
1370 iter.value()->setZValue(8);
1464 if(event->delta() < 0)
1466 this->
scale(0.95, 0.95);
1470 this->
scale(1.05, 1.05);
1476 QPixmap pixmap(50, 50);
1478 return QIcon(pixmap);
1484 QAction * aScreenShotPNG = menu.addAction(tr(
"Take a screenshot (PNG)"));
1485 QAction * aScreenShotSVG = menu.addAction(tr(
"Take a screenshot (SVG)"));
1487 aScreenShotSVG->setEnabled(
false);
1489 menu.addSeparator();
1493 aChangeNodeColor->setIconVisibleInMenu(
true);
1494 aChangeCurrentGoalColor->setIconVisibleInMenu(
true);
1497 QMenu * menuLink = menu.addMenu(tr(
"Set link color..."));
1498 QAction * aChangeNeighborColor = menuLink->addAction(tr(
"Neighbor"));
1499 QAction * aChangeGlobalLoopColor = menuLink->addAction(tr(
"Global loop closure"));
1500 QAction * aChangeLocalLoopColor = menuLink->addAction(tr(
"Local loop closure"));
1501 QAction * aChangeUserLoopColor = menuLink->addAction(tr(
"User loop closure"));
1502 QAction * aChangeVirtualLoopColor = menuLink->addAction(tr(
"Virtual loop closure"));
1503 QAction * aChangeNeighborMergedColor = menuLink->addAction(tr(
"Neighbor merged"));
1504 QAction * aChangeRejectedLoopColor = menuLink->addAction(tr(
"Outlier loop closure"));
1505 QAction * aChangeRejectedLoopThr = menuLink->addAction(tr(
"Set outlier threshold..."));
1506 QAction * aChangeLocalPathColor = menuLink->addAction(tr(
"Local path"));
1507 QAction * aChangeGlobalPathColor = menuLink->addAction(tr(
"Global path"));
1508 QAction * aChangeGTColor = menuLink->addAction(tr(
"Ground truth"));
1509 QAction * aChangeGPSColor = menuLink->addAction(tr(
"GPS"));
1510 menuLink->addSeparator();
1511 QAction * aSetIntraInterSessionColors = menuLink->addAction(tr(
"Enable intra/inter-session colors"));
1512 QAction * aChangeIntraSessionLoopColor = menuLink->addAction(tr(
"Intra-session loop closure"));
1513 QAction * aChangeInterSessionLoopColor = menuLink->addAction(tr(
"Inter-session loop closure"));
1527 aChangeNeighborColor->setIconVisibleInMenu(
true);
1528 aChangeGlobalLoopColor->setIconVisibleInMenu(
true);
1529 aChangeLocalLoopColor->setIconVisibleInMenu(
true);
1530 aChangeUserLoopColor->setIconVisibleInMenu(
true);
1531 aChangeVirtualLoopColor->setIconVisibleInMenu(
true);
1532 aChangeNeighborMergedColor->setIconVisibleInMenu(
true);
1533 aChangeRejectedLoopColor->setIconVisibleInMenu(
true);
1534 aChangeLocalPathColor->setIconVisibleInMenu(
true);
1535 aChangeGlobalPathColor->setIconVisibleInMenu(
true);
1536 aChangeGTColor->setIconVisibleInMenu(
true);
1537 aChangeGPSColor->setIconVisibleInMenu(
true);
1538 aChangeIntraSessionLoopColor->setIconVisibleInMenu(
true);
1539 aChangeInterSessionLoopColor->setIconVisibleInMenu(
true);
1540 aSetIntraInterSessionColors->setCheckable(
true);
1543 menu.addSeparator();
1544 QAction * aSetNodeSize = menu.addAction(tr(
"Set node radius..."));
1545 QAction * aSetLinkSize = menu.addAction(tr(
"Set link width..."));
1546 QAction * aChangeMaxLinkLength = menu.addAction(tr(
"Set maximum link length..."));
1547 menu.addSeparator();
1548 QAction * aShowHideGridMap;
1549 QAction * aShowHideGraph;
1550 QAction * aShowHideGraphNodes;
1551 QAction * aShowHideOrigin;
1552 QAction * aShowHideReferential;
1553 QAction * aShowHideLocalRadius;
1554 QAction * aShowHideGlobalPath;
1555 QAction * aShowHideLocalPath;
1556 QAction * aShowHideGtGraph;
1557 QAction * aShowHideGPSGraph;
1558 QAction * aOrientationENU;
1561 aShowHideGridMap = menu.addAction(tr(
"Hide grid map"));
1565 aShowHideGridMap = menu.addAction(tr(
"Show grid map"));
1569 aShowHideOrigin = menu.addAction(tr(
"Hide origin referential"));
1573 aShowHideOrigin = menu.addAction(tr(
"Show origin referential"));
1577 aShowHideReferential = menu.addAction(tr(
"Hide current referential"));
1581 aShowHideReferential = menu.addAction(tr(
"Show current referential"));
1585 aShowHideLocalRadius = menu.addAction(tr(
"Hide local radius"));
1589 aShowHideLocalRadius = menu.addAction(tr(
"Show local radius"));
1593 aShowHideGraph = menu.addAction(tr(
"Hide graph"));
1597 aShowHideGraph = menu.addAction(tr(
"Show graph"));
1601 aShowHideGraphNodes = menu.addAction(tr(
"Hide graph nodes"));
1605 aShowHideGraphNodes = menu.addAction(tr(
"Show graph nodes"));
1609 aShowHideGlobalPath = menu.addAction(tr(
"Hide global path"));
1613 aShowHideGlobalPath = menu.addAction(tr(
"Show global path"));
1617 aShowHideLocalPath = menu.addAction(tr(
"Hide local path"));
1621 aShowHideLocalPath = menu.addAction(tr(
"Show local path"));
1625 aShowHideGtGraph = menu.addAction(tr(
"Hide ground truth graph"));
1629 aShowHideGtGraph = menu.addAction(tr(
"Show ground truth graph"));
1633 aShowHideGPSGraph = menu.addAction(tr(
"Hide GPS graph"));
1637 aShowHideGPSGraph = menu.addAction(tr(
"Show GPS graph"));
1639 aOrientationENU = menu.addAction(tr(
"ENU Orientation"));
1640 aOrientationENU->setCheckable(
true);
1642 aShowHideGraph->setEnabled(
_nodeItems.size());
1648 menu.addSeparator();
1649 QAction * aRestoreDefaults = menu.addAction(tr(
"Restore defaults"));
1651 QAction * r = menu.exec(event->globalPos());
1652 if(r == aScreenShotPNG || r == aScreenShotSVG)
1658 if(!dir.exists(targetDir))
1660 dir.mkdir(targetDir);
1663 targetDir +=
"Graph_view";
1664 if(!dir.exists(targetDir))
1666 dir.mkdir(targetDir);
1669 bool isPNG = r == aScreenShotPNG;
1670 QString name = (QDateTime::currentDateTime().toString(
"yyMMddhhmmsszzz") + (isPNG?
".png":
".svg"));
1678 _root->setScale(this->transform().m11());
1681 this->scene()->clearSelection();
1682 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1683 QSize sceneSize = this->scene()->sceneRect().size().toSize();
1687 QImage image(sceneSize, QImage::Format_ARGB32);
1688 image.fill(Qt::transparent);
1689 QPainter painter(&image);
1691 this->scene()->render(&painter);
1694 image.save(targetDir + name);
1698 QMessageBox::warning(
this,
1700 tr(
"Could not export in PNG (the scene may be too large %1x%2), try saving in SVG.").arg(sceneSize.width()).arg(sceneSize.height()));
1706 QSvgGenerator svgGen;
1708 svgGen.setFileName( targetDir + name );
1709 svgGen.setSize(sceneSize);
1711 int borderH = sceneSize.width()/100;
1712 int borderV = sceneSize.height()/100;
1713 svgGen.setViewBox(QRect(-borderH, -borderV, sceneSize.width()+borderH*2, sceneSize.height()+borderV*2));
1714 svgGen.setTitle(tr(
"RTAB-Map graph"));
1715 svgGen.setDescription(tr(
"RTAB-Map map and graph"));
1717 QPainter painter( &svgGen );
1719 this->scene()->render(&painter);
1721 UERROR(
"RTAB-MAp is not built with Qt's SVG library, cannot save picture in svg format.");
1727 this->scene()->setSceneRect(this->scene()->itemsBoundingRect());
1730 QDesktopServices::openUrl(QUrl::fromLocalFile(targetDir + name));
1734 else if(r == aSetIntraInterSessionColors)
1738 else if(r == aChangeRejectedLoopThr)
1741 double value = QInputDialog::getDouble(
this, tr(
"Loop closure outlier threshold"), tr(
"Value (m)"),
_loopClosureOutlierThr, 0.0, 1000.0, 2, &ok);
1747 else if(r == aChangeMaxLinkLength)
1750 double value = QInputDialog::getDouble(
this, tr(
"Maximum link length to be shown"), tr(
"Value (m)"),
_maxLinkLength, 0.0, 1000.0, 3, &ok);
1756 else if(r == aChangeNodeColor ||
1757 r == aChangeCurrentGoalColor ||
1758 r == aChangeNeighborColor ||
1759 r == aChangeGlobalLoopColor ||
1760 r == aChangeLocalLoopColor ||
1761 r == aChangeUserLoopColor ||
1762 r == aChangeVirtualLoopColor ||
1763 r == aChangeNeighborMergedColor ||
1764 r == aChangeRejectedLoopColor ||
1765 r == aChangeLocalPathColor ||
1766 r == aChangeGlobalPathColor ||
1767 r == aChangeGTColor ||
1768 r == aChangeGPSColor ||
1769 r == aChangeIntraSessionLoopColor ||
1770 r == aChangeInterSessionLoopColor)
1773 if(r == aChangeNodeColor)
1777 else if(r == aChangeCurrentGoalColor)
1781 else if(r == aChangeGlobalLoopColor)
1785 else if(r == aChangeLocalLoopColor)
1789 else if(r == aChangeUserLoopColor)
1793 else if(r == aChangeVirtualLoopColor)
1797 else if(r == aChangeNeighborMergedColor)
1801 else if(r == aChangeRejectedLoopColor)
1805 else if(r == aChangeLocalPathColor)
1809 else if(r == aChangeGlobalPathColor)
1813 else if(r == aChangeGTColor)
1817 else if(r == aChangeGPSColor)
1821 else if(r == aChangeIntraSessionLoopColor)
1825 else if(r == aChangeInterSessionLoopColor)
1833 color = QColorDialog::getColor(color,
this);
1837 if(r == aChangeNodeColor)
1841 else if(r == aChangeCurrentGoalColor)
1845 else if(r == aChangeGlobalLoopColor)
1849 else if(r == aChangeLocalLoopColor)
1853 else if(r == aChangeUserLoopColor)
1857 else if(r == aChangeVirtualLoopColor)
1861 else if(r == aChangeNeighborMergedColor)
1865 else if(r == aChangeRejectedLoopColor)
1869 else if(r == aChangeLocalPathColor)
1873 else if(r == aChangeGlobalPathColor)
1877 else if(r == aChangeGTColor)
1881 else if(r == aChangeGPSColor)
1885 else if(r == aChangeIntraSessionLoopColor)
1889 else if(r == aChangeInterSessionLoopColor)
1903 else if(r == aSetNodeSize)
1906 double value = QInputDialog::getDouble(
this, tr(
"Node radius"), tr(
"Radius (m)"),
_nodeRadius, 0.001, 100, 3, &ok);
1912 else if(r == aSetLinkSize)
1915 double value = QInputDialog::getDouble(
this, tr(
"Link width"), tr(
"Width (m)"),
_linkWidth, 0, 100, 2, &ok);
1921 else if(r == aShowHideGridMap)
1929 else if(r == aShowHideOrigin)
1933 else if(r == aShowHideReferential)
1937 else if(r == aShowHideLocalRadius)
1941 else if(r == aRestoreDefaults)
1945 else if(r == aShowHideGraph)
1949 else if(r == aShowHideGraphNodes)
1953 else if(r == aShowHideGlobalPath)
1957 else if(r == aShowHideLocalPath)
1961 else if(r == aShowHideGtGraph)
1965 else if(r == aShowHideGPSGraph)
1969 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
void updatePosterior(const std::map< int, float > &posterior, float fixedMax=0.0f)
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
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
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
T uMax3(const T &a, const T &b, const T &c)
QMultiMap< int, LinkItem * > _globalPathLinkItems
void updateGraph(const std::map< int, Transform > &poses, const std::multimap< int, Link > &constraints, const std::map< int, int > &mapIds)
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)
NodeItem(int id, int mapId, const Transform &pose, float radius)
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)
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 setLocalRadius(float radius)
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)