moved rtabmap-ros-pkg project in this project

git-svn-id: http://rtabmap.googlecode.com/svn/branches/0.3/rtabmap@52 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2011-06-05 14:45:39 +00:00
commit 2d73090f3a
338 changed files with 56859 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AboutDialog.h"
#include "rtabmap/core/Rtabmap.h"
namespace rtabmap {
AboutDialog::AboutDialog(QWidget * parent) :
QDialog(parent)
{
_ui.setupUi(this);
_ui.label_version->setText(Rtabmap::getVersion().c_str());
}
}

44
guilib/src/AboutDialog.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ABOUTDIALOG_H_
#define ABOUTDIALOG_H_
#include <QtGui/QDialog>
#include <QtCore/QUrl>
#include "ui_aboutDialog.h"
namespace rtabmap {
class AboutDialog : public QDialog
{
Q_OBJECT
public:
AboutDialog(QWidget * parent = 0);
virtual ~AboutDialog() {}
private:
Ui_aboutDialog _ui;
};
}
#endif /* ABOUTDIALOG_H_ */

101
guilib/src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,101 @@
### Qt Gui stuff ###
SET(headers_ui
../include/${PROJECT_PREFIX}/gui/MainWindow.h
../include/${PROJECT_PREFIX}/gui/PreferencesDialog.h
./AboutDialog.h
./ConsoleWidget.h
./ImageView.h
./Plot.h
./PdfPlot.h
./StatsToolBox.h
./DetailedProgressDialog.h
)
SET(uis
./ui/mainWindow.ui
./ui/preferencesDialog.ui
./ui/aboutDialog.ui
./ui/consoleWidget.ui
)
SET(qrc
./GuiLib.qrc
)
# generate rules for building source files from the resources
QT4_ADD_RESOURCES(srcs_qrc ${qrc})
#Generate .h files from the .ui files
QT4_WRAP_UI(moc_uis ${uis})
#This will generate moc_* for Qt
QT4_WRAP_CPP(moc_srcs ${headers_ui})
### Qt Gui stuff end###
SET(SRC_FILES
./MainWindow.cpp
./PreferencesDialog.cpp
./KeypointItem.cpp
./qtipl.cpp
./ImageView.cpp
./Plot.cpp
./PdfPlot.cpp
./StatsToolBox.cpp
./DetailedProgressDialog.cpp
./AboutDialog.cpp
./ConsoleWidget.cpp
${moc_srcs}
${moc_uis}
${srcs_qrc}
)
SET(INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}
${UTILITE_INCLUDE_DIR}
${OpenCV_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR} # for qt ui generated in binary dir
)
INCLUDE(${QT_USE_FILE})
SET(LIBRARIES
${UTILITE_LIBRARY}
${QT_LIBRARIES}
${OpenCV_LIBS}
)
#include files
INCLUDE_DIRECTORIES(${INCLUDE_DIRS})
IF(WIN32)
IF(BUILD_SHARED_LIBS)
ADD_DEFINITIONS(-DRTABMAP_EXPORTS)
ELSE()
ADD_DEFINITIONS(-DRTABMAP_EXPORTS_STATIC)
ENDIF()
ENDIF(WIN32)
# create an executable file named "AvpdGui" from the source files
ADD_LIBRARY(guilib ${SRC_FILES})
# Linking with Qt libraries
TARGET_LINK_LIBRARIES(guilib corelib ${LIBRARIES})
SET_TARGET_PROPERTIES(
guilib
PROPERTIES
OUTPUT_NAME ${PROJECT_PREFIX}_gui
INSTALL_NAME_DIR ${CMAKE_INSTALL_PREFIX}/lib
)
INSTALL(TARGETS guilib
RUNTIME DESTINATION bin COMPONENT runtime
LIBRARY DESTINATION lib COMPONENT devel
ARCHIVE DESTINATION lib COMPONENT devel)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include/ DESTINATION include/ COMPONENT devel FILES_MATCHING PATTERN "*.h" PATTERN ".svn" EXCLUDE)

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ConsoleWidget.h"
#include <utilite/ULogger.h>
#include <utilite/UEventsManager.h>
#include <QtGui/QMessageBox>
namespace rtabmap {
ConsoleWidget::ConsoleWidget(QWidget * parent) :
QWidget(parent)
{
_ui.setupUi(this);
UEventsManager::addHandler(this);
connect(this, SIGNAL(msgReceived(const QString &, int)), this, SLOT(appendMsg(const QString &, int)));
_ui.textEdit->document()->setMaximumBlockCount(100);
_ui.textEdit->setFontPointSize(10);
}
ConsoleWidget::~ConsoleWidget()
{
}
void ConsoleWidget::handleEvent(UEvent * anEvent)
{
// WARNING, don't put a log message here! otherwise it could be recursively called.
if(anEvent->getClassName().compare("ULogEvent") == 0)
{
ULogEvent * logEvent = (ULogEvent*)anEvent;
emit msgReceived(logEvent->getMsg().c_str(), logEvent->getCode());
if(logEvent->getCode() == ULogger::kFatal)
{
//The application will exit, so warn the user.
QMessageBox::critical(this, tr("Fatal error occurred"), tr("Error! :\n \"%1\"\nThe application will now exit...").arg(logEvent->getMsg().c_str()), QMessageBox::Ok);
}
}
}
void ConsoleWidget::appendMsg(const QString & msg, int level)
{
switch(level)
{
case 0:
_ui.textEdit->setTextColor(Qt::darkGreen);
break;
case 2:
_ui.textEdit->setTextColor(Qt::darkYellow);
break;
case 3:
case 4:
_ui.textEdit->setTextColor(Qt::darkRed);
break;
default:
_ui.textEdit->setTextColor(Qt::black);
break;
}
_ui.textEdit->append(msg);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CONSOLEWIDGET_H_
#define CONSOLEWIDGET_H_
#include "ui_consoleWidget.h"
#include <utilite/UEventsHandler.h>
namespace rtabmap {
class ConsoleWidget : public QWidget, public UEventsHandler
{
Q_OBJECT;
public:
ConsoleWidget(QWidget * parent = 0);
virtual ~ConsoleWidget();
public slots:
void appendMsg(const QString & msg, int level);
signals:
void msgReceived(const QString &, int);
protected:
virtual void handleEvent(UEvent * anEvent);
private:
Ui_consoleWidget _ui;
};
}
#endif /* CONSOLEWIDGET_H_ */

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DetailedProgressDialog.h"
#include <QtGui/QLayout>
#include <QtGui/QProgressBar>
#include <QtGui/QPlainTextEdit>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QCloseEvent>
#include <QtGui/QCheckBox>
#include <QtCore/QTimer>
#include "utilite/ULogger.h"
namespace rtabmap {
DetailedProgressDialog::DetailedProgressDialog(QWidget *parent, Qt::WindowFlags flags) :
QDialog(parent, flags),
_autoClose(false),
_delayedClosingTime(0)
{
_text = new QLabel(this);
_text->setWordWrap(true);
_progressBar = new QProgressBar(this);
_progressBar->setMaximum(1);
_detailedText = new QPlainTextEdit(this);
_detailedText->setReadOnly(true);
_detailedText->setLineWrapMode(QPlainTextEdit::NoWrap);
_closeButton = new QPushButton(this);
_closeButton->setText("Close");
_closeWhenDoneCheckBox = new QCheckBox(this);
_closeWhenDoneCheckBox->setChecked(false);
_closeWhenDoneCheckBox->setText("Close when done.");
_endMessage = "Finished!";
this->clear();
connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
QVBoxLayout * layout = new QVBoxLayout(this);
layout->addWidget(_text);
layout->addWidget(_progressBar);
layout->addWidget(_detailedText);
QHBoxLayout * hLayout = new QHBoxLayout();
layout->addLayout(hLayout);
hLayout->addWidget(_closeWhenDoneCheckBox);
hLayout->addWidget(_closeButton);
this->setLayout(layout);
}
DetailedProgressDialog::~DetailedProgressDialog()
{
}
void DetailedProgressDialog::setAutoClose(bool on, int delayedClosingTimeSec)
{
_delayedClosingTime = delayedClosingTimeSec;
_closeWhenDoneCheckBox->setChecked(on);
}
void DetailedProgressDialog::appendText(const QString & text)
{
_text->setText(text);
_detailedText->appendPlainText(text);
}
void DetailedProgressDialog::setValue(int value)
{
_progressBar->setValue(value);
if(value == _progressBar->maximum())
{
_text->setText(_endMessage);
_closeButton->setEnabled(true);
if(_closeWhenDoneCheckBox->isChecked() && _delayedClosingTime == 0)
{
this->close();
}
else if(_closeWhenDoneCheckBox->isChecked())
{
QTimer::singleShot(_delayedClosingTime*1000, this, SLOT(close()));
}
}
}
int DetailedProgressDialog::maximumSteps() const
{
return _progressBar->maximum();
}
void DetailedProgressDialog::setMaximumSteps(int steps)
{
_progressBar->setMaximum(steps);
}
void DetailedProgressDialog::incrementStep()
{
//incremental progress bar (if we don't know how many items will be added)
if(_progressBar->value() == _progressBar->maximum()-1)
{
_progressBar->setMaximum(_progressBar->maximum()+1);
}
_progressBar->setValue(_progressBar->value()+1);
}
void DetailedProgressDialog::clear()
{
_text->clear();
_progressBar->reset();
_detailedText->clear();
_closeButton->setEnabled(false);
}
void DetailedProgressDialog::closeEvent(QCloseEvent *event)
{
if(_progressBar->value() == _progressBar->maximum())
{
event->accept();
}
else
{
event->ignore();
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DETAILEDPROGRESSDIALOG_H_
#define DETAILEDPROGRESSDIALOG_H_
#include <QtGui/QDialog>
class QLabel;
class QPlainTextEdit;
class QProgressBar;
class QPushButton;
class QCheckBox;
namespace rtabmap {
class DetailedProgressDialog : public QDialog
{
Q_OBJECT
public:
DetailedProgressDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
virtual ~DetailedProgressDialog();
void setEndMessage(const QString & message) {_endMessage = message;} // Message shown when the progress is finished
void setValue(int value);
int maximumSteps() const;
void setMaximumSteps(int steps);
void setAutoClose(bool on, int delayedClosingTimeMsec = 0);
protected:
virtual void closeEvent(QCloseEvent * event);
public slots:
void appendText(const QString & text);
void incrementStep();
void clear();
private:
QLabel * _text;
QPlainTextEdit * _detailedText;
QProgressBar * _progressBar;
QPushButton * _closeButton;
QCheckBox * _closeWhenDoneCheckBox;
QString _endMessage;
bool _autoClose;
int _delayedClosingTime; // sec
};
}
#endif /* DETAILEDPROGRESSDIALOG_H_ */

21
guilib/src/GuiLib.qrc Normal file
View File

@@ -0,0 +1,21 @@
<RCC>
<qresource>
<file>images/Stop1NormalYellow.png</file>
<file>images/PauseNormalRed.png</file>
<file>images/PauseNormal.png</file>
<file>images/Play1Normal.png</file>
<file>images/Pause.ico</file>
<file>images/PauseOnLoop.ico</file>
<file>images/PauseLoopRejected.ico</file>
<file>qss/default.qss</file>
<file>images/Plot16.png</file>
<file>images/Plot48.png</file>
<file>images/RTAB-Map.ico</file>
<file>images/RTAB-Map.png</file>
<file>images/IntRoLab.png</file>
<file>images/IntRoLabSmall.png</file>
<file>images/metal_7280826_512.jpg</file>
<file>images/crosshatch_metal_grille_9280154_150.JPG</file>
<file>resources/PreferencesModel.txt</file>
</qresource>
</RCC>

115
guilib/src/ImageView.cpp Normal file
View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ImageView.h"
#include <QtGui/QWheelEvent>
#include <QtCore/qmath.h>
#include <QtGui/QMenu>
#include <QtGui/QFileDialog>
#include <QtCore/QDir>
#include "utilite/ULogger.h"
namespace rtabmap {
ImageView::ImageView(QWidget * parent) :
QGraphicsView(parent),
_zoom(250),
_minZoom(250),
_savedFileName((QDir::homePath()+ "/") + "picture" + ".png")
{
this->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
this->setScene(new QGraphicsScene(this));
connect(this->scene(), SIGNAL(sceneRectChanged(const QRectF &)), this, SLOT(updateZoom()));
}
ImageView::~ImageView() {
}
void ImageView::resetZoom()
{
_zoom = _minZoom;
this->setDragMode(QGraphicsView::NoDrag);
}
void ImageView::contextMenuEvent(QContextMenuEvent * e)
{
QMenu menu(tr(""), this);
QAction * saveImage = menu.addAction(tr("Save picture..."));
if(menu.exec(e->globalPos()) == saveImage)
{
QString text;
#ifdef QT_SVG_LIB
text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), _savedFileName, "*.png *.xpm *.jpg *.pdf *.svg");
#else
text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), _savedFileName, "*.png *.xpm *.jpg *.pdf");
#endif
if(!text.isEmpty())
{
_savedFileName = text;
QImage img(this->sceneRect().width(), this->sceneRect().height(),QImage::Format_ARGB32_Premultiplied);
QPainter p(&img);
this->scene()->render(&p, this->sceneRect(), this->sceneRect());
img.save(text);
}
}
}
void ImageView::updateZoom()
{
qreal scaleRatio = 1;
if(this->scene())
{
scaleRatio = this->geometry().width()/this->sceneRect().width();
}
_minZoom = log(scaleRatio)/log(2)*50+250;
}
void ImageView::wheelEvent(QWheelEvent * e)
{
if(e->delta() > 0)
{
_zoom += 20;
this->setDragMode(QGraphicsView::ScrollHandDrag);
if(_zoom>=500)
{
_zoom = 500;
}
}
else
{
_zoom -= 20;
if(_zoom<=_minZoom)
{
this->setDragMode(QGraphicsView::NoDrag);
_zoom = _minZoom;
this->fitInView(this->sceneRect(), Qt::KeepAspectRatio);
return;
}
}
qreal scale = qPow(qreal(2), (_zoom - 250) / qreal(50));
QMatrix matrix;
matrix.scale(scale, scale);
this->setMatrix(matrix);
}
}

53
guilib/src/ImageView.h Normal file
View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef IMAGEVIEW_H_
#define IMAGEVIEW_H_
#include <QtGui/QGraphicsView>
#include <QtCore/QRectF>
namespace rtabmap {
class ImageView : public QGraphicsView {
Q_OBJECT
public:
ImageView(QWidget * parent = 0);
virtual ~ImageView();
void resetZoom();
protected:
virtual void contextMenuEvent(QContextMenuEvent * e);
virtual void wheelEvent(QWheelEvent * e);
private slots:
void updateZoom();
private:
int _zoom;
int _minZoom;
QString _savedFileName;
};
}
#endif /* IMAGEVIEW_H_ */

118
guilib/src/KeypointItem.cpp Normal file
View File

@@ -0,0 +1,118 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "KeypointItem.h"
#include <QtGui/QPen>
#include <QtGui/QBrush>
#include <QtGui/QGraphicsScene>
#include "utilite/ULogger.h"
namespace rtabmap {
KeypointItem::KeypointItem(qreal x, qreal y, int r, const QString & info, const QColor & color, QGraphicsItem * parent) :
QGraphicsEllipseItem(x, y, r, r, parent),
_info(info),
_placeHolder(0)
{
this->setPen(QPen(color));
this->setBrush(QBrush(color));
this->setAcceptsHoverEvents(true);
this->setFlag(QGraphicsItem::ItemIsFocusable, true);
_width = pen().width();
}
KeypointItem::~KeypointItem()
{
/*if(_placeHolder)
{
delete _placeHolder;
}*/
}
void KeypointItem::showDescription()
{
if(!_placeHolder)
{
_placeHolder = new QGraphicsRectItem (this);
_placeHolder->setVisible(false);
_placeHolder->setBrush(QBrush(QColor ( 0, 0, 0, 170 ))); // Black transparent background
QGraphicsTextItem * text = new QGraphicsTextItem(_placeHolder);
text->setDefaultTextColor(this->pen().color().rgb());
text->setPlainText(_info);
_placeHolder->setRect(text->boundingRect());
}
if(_placeHolder->parentItem())
{
_placeHolder->setParentItem(0); // Make it a to level item
}
QPen pen = this->pen();
this->setPen(QPen(pen.color(), _width+2));
_placeHolder->setZValue(this->zValue()+1);
_placeHolder->setPos(this->mapFromScene(0,0));
_placeHolder->setVisible(true);
}
void KeypointItem::hideDescription()
{
if(_placeHolder)
{
_placeHolder->setVisible(false);
}
this->setPen(QPen(pen().color(), _width));
}
void KeypointItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event )
{
QGraphicsScene * scene = this->scene();
if(scene && scene->focusItem() == 0)
{
this->showDescription();
}
else
{
this->setPen(QPen(pen().color(), _width+2));
}
QGraphicsEllipseItem::hoverEnterEvent(event);
}
void KeypointItem::hoverLeaveEvent ( QGraphicsSceneHoverEvent * event )
{
if(!this->hasFocus())
{
this->hideDescription();
}
QGraphicsEllipseItem::hoverEnterEvent(event);
}
void KeypointItem::focusInEvent ( QFocusEvent * event )
{
this->showDescription();
QGraphicsEllipseItem::focusInEvent(event);
}
void KeypointItem::focusOutEvent ( QFocusEvent * event )
{
this->hideDescription();
QGraphicsEllipseItem::focusOutEvent(event);
}
}

54
guilib/src/KeypointItem.h Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KEYPOINTITEM_H_
#define KEYPOINTITEM_H_
#include <QtGui/QGraphicsEllipseItem>
#include <QtGui/QGraphicsTextItem>
#include <QtGui/QPen>
#include <QtGui/QBrush>
namespace rtabmap {
class KeypointItem : public QGraphicsEllipseItem
{
public:
KeypointItem(qreal x, qreal y, int r, const QString & info, const QColor & color = Qt::green, QGraphicsItem * parent = 0);
virtual ~KeypointItem();
protected:
virtual void hoverEnterEvent ( QGraphicsSceneHoverEvent * event );
virtual void hoverLeaveEvent ( QGraphicsSceneHoverEvent * event );
virtual void focusInEvent ( QFocusEvent * event );
virtual void focusOutEvent ( QFocusEvent * event );
private:
void showDescription();
void hideDescription();
private:
QString _info;
QGraphicsRectItem * _placeHolder;
int _width;
};
}
#endif /* KEYPOINTITEM_H_ */

1394
guilib/src/MainWindow.cpp Normal file

File diff suppressed because it is too large Load Diff

148
guilib/src/PdfPlot.cpp Normal file
View File

@@ -0,0 +1,148 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "PdfPlot.h"
#include "utilite/ULogger.h"
namespace rtabmap {
PdfPlotItem::PdfPlotItem(float dataX, float dataY, float width, int childCount) :
PlotItem(dataX, dataY, width),
_img(0),
_imagesRef(0)
{
setLikelihood(dataX, dataY, childCount);
_text = new QGraphicsTextItem(this);
_text->setVisible(false);
}
PdfPlotItem::~PdfPlotItem()
{
}
void PdfPlotItem::setLikelihood(int id, float value, int childCount)
{
if(id != this->data().x())
{
delete _img;
_img = 0;
}
this->setData(QPointF(id, value));
_childCount = childCount;
}
void PdfPlotItem::showDescription(bool shown)
{
if(shown)
{
if(!_img && _imagesRef)
{
QImage img;
QMap<int, QByteArray>::const_iterator iter = _imagesRef->find(int(this->data().x()));
if(iter != _imagesRef->constEnd())
{
if(img.loadFromData(iter.value(), "JPEG"))
{
QPixmap scaled = QPixmap::fromImage(img).scaledToWidth(128);
_img = new QGraphicsPixmapItem(scaled, this);
_img->setVisible(false);
}
}
}
if(_img)
_text->setPos(this->mapFromScene(4+150,0));
else
_text->setPos(this->mapFromScene(4,0));
_text->setPlainText(QString("ID = %1\nValue = %2\nWeight = %3").arg(this->data().x()).arg(this->data().y()).arg(_childCount));
_text->setVisible(true);
if(_img)
{
_img->setPos(this->mapFromScene(4,0));
_img->setVisible(true);
}
}
else
{
_text->setVisible(false);
if(_img)
_img->setVisible(false);
}
PlotItem::showDescription(shown);
}
PdfPlotCurve::PdfPlotCurve(const QString & name, const QMap<int, QByteArray> * imagesMapRef = 0, QObject * parent) :
PlotCurve(name, parent),
_imagesMapRef(imagesMapRef)
{
}
PdfPlotCurve::~PdfPlotCurve()
{
}
void PdfPlotCurve::clear()
{
PlotCurve::clear();
}
void PdfPlotCurve::setData(const QMap<int, float> & dataMap, const QMap<int, int> & weightsMap, int lastId)
{
ULOGGER_DEBUG("dataSize=%d", dataMap.size());
if(dataMap.size() > 0)
{
//match the size of the current data
int margin = int((_items.size()+1)/2) - dataMap.size();
UDEBUG("margin=%d", margin);
while(margin < 0)
{
PdfPlotItem * newItem = new PdfPlotItem(0, 0, -1);
newItem->setImagesRef(_imagesMapRef);
this->_addValue(newItem);
++margin;
}
while(margin > 0)
{
this->removeItem(0);
--margin;
}
ULOGGER_DEBUG("itemsize=%d", _items.size());
// update values
int index = 0;
for(QMap<int, float>::const_iterator i=dataMap.begin(); i!=dataMap.end(); ++i, index+=2)
{
((PdfPlotItem*)_items[index])->setLikelihood(i.key(), i.value(), weightsMap.value(i.key(),-1));
}
//reset minMax, this will force the plot to update the axes
this->updateMinMax();
emit dataChanged(this);
}
}
}

67
guilib/src/PdfPlot.h Normal file
View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PDFPLOT_H_
#define PDFPLOT_H_
#include "Plot.h"
namespace rtabmap {
class PdfPlotItem : public PlotItem
{
public:
PdfPlotItem(float dataX, float dataY, float width, int childCount = -1);
virtual ~PdfPlotItem();
void setLikelihood(int id, float value, int childCount);
void setImagesRef(const QMap<int, QByteArray> * imagesRef) {_imagesRef = imagesRef;}
float value() const {return this->data().y();}
int id() const {return this->data().x();}
protected:
virtual void showDescription(bool shown);
private:
QGraphicsTextItem * _text;
QGraphicsPixmapItem * _img;
int _childCount;
const QMap<int, QByteArray> * _imagesRef;
};
class PdfPlotCurve : public PlotCurve
{
Q_OBJECT
public:
PdfPlotCurve(const QString & name, const QMap<int, QByteArray> * imagesMapRef, QObject * parent = 0);
virtual ~PdfPlotCurve();
virtual void clear();
void setData(const QMap<int, float> & dataMap, const QMap<int, int> & weightsMap, int lastId);
private:
const QMap<int, QByteArray> * _imagesMapRef;
};
}
#endif /* PDFPLOT_H_ */

2207
guilib/src/Plot.cpp Normal file

File diff suppressed because it is too large Load Diff

380
guilib/src/Plot.h Normal file
View File

@@ -0,0 +1,380 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PLOT_H_
#define PLOT_H_
// Uncomment this to disable all references to RTAB-Map and UtiLite dependencies
//#define PLOT_WIDGET_OUT_OF_LIB
#include <QtGui/QFrame>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtGui/QPen>
#include <QtGui/QBrush>
#include <QtGui/QGraphicsEllipseItem>
#include <QtCore/QMutex>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtCore/QTime>
class QGraphicsView;
class QGraphicsScene;
class QGraphicsItem;
class QFormLayout;
#ifndef PLOT_WIDGET_OUT_OF_LIB
namespace rtabmap {
#endif
class PlotItem : public QGraphicsEllipseItem
{
public:
PlotItem(qreal dataX, qreal dataY, qreal width=2);
PlotItem(const QPointF & data, qreal width=2);
virtual ~PlotItem();
public:
void setNextItem(PlotItem * nextItem);
void setPreviousItem(PlotItem * previousItem);
void setData(const QPointF & data);
PlotItem * nextItem() const {return _nextItem;}
PlotItem * previousItem() const {return _previousItem;};
const QPointF & data() const {return _data;}
protected:
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent * event);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent * event);
virtual void focusInEvent(QFocusEvent * event);
virtual void focusOutEvent(QFocusEvent * event);
virtual void keyReleaseEvent(QKeyEvent * keyEvent);
virtual void showDescription(bool shown);
private:
QPointF _data;
QGraphicsTextItem * _text;
PlotItem * _previousItem;
PlotItem * _nextItem;
};
class Plot;
class PlotCurve : public QObject
{
Q_OBJECT
public:
PlotCurve(const QString & name, QObject * parent = 0);
PlotCurve(const QString & name, const QVector<PlotItem *> data, QObject * parent = 0);
PlotCurve(const QString & name, const QVector<float> & x, const QVector<float> & y, QObject * parent = 0);
virtual ~PlotCurve();
const QPen & pen() const {return _pen;}
const QBrush & brush() const {return _brush;}
void setPen(const QPen & pen);
void setBrush(const QBrush & brush);
void setDefaultStepX(float stepX) {_defaultStepX = stepX;}
QString name() const {return _name;}
int itemsSize();
QPointF getItemData(int index);
void setStartX(float startX) {_startX = startX;}
bool isVisible() const {return _visible;}
void setData(QVector<PlotItem*> & data); // take the ownership
void setData(const QVector<float> & x, const QVector<float> & y);
void getData(QVector<float> & x, QVector<float> & y) const; // only call in Qt MainThread
public slots:
virtual void clear();
void setVisible(bool visible);
void addValue(PlotItem * data); // take the ownership
void addValue(float y);
void addValue(float x, float y);
void addValue(const QString & y);
void addValues(QVector<PlotItem *> & data); // take the ownership
void addValues(const QVector<float> & xs, const QVector<float> & ys);
void addValues(const QVector<float> & ys);
signals:
void dataChanged(const PlotCurve *);
protected:
friend class Plot;
void attach(Plot * plot);
void detach(Plot * plot);
void updateMinMax();
const QVector<float> & getMinMax() const {return _minMax;}
int removeItem(int index);
void _addValue(PlotItem * data);;
virtual bool isMinMaxValid() const {return _minMax.size();}
virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, int xDir, int yDir, bool allDataKept);
QList<QGraphicsItem *> _items;
Plot * _plot;
private:
void removeItem(PlotItem * item);
private:
QString _name;
QPen _pen;
QBrush _brush;
float _defaultStepX;
float _startX;
bool _visible;
bool _valuesShown;
QVector<float> _minMax; // minX, maxX, minY, maxY
};
class ThresholdCurve : public PlotCurve
{
Q_OBJECT
public:
ThresholdCurve(const QString & name, float thesholdValue, Qt::Orientation orientation = Qt::Horizontal, QObject * parent = 0);
~ThresholdCurve();
public slots:
void setThreshold(float threshold);
void setOrientation(Qt::Orientation orientation);
protected:
friend class Plot;
virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, int xDir, int yDir, bool allDataKept);
virtual bool isMinMaxValid() const {return false;}
private:
Qt::Orientation _orientation;
};
class PlotAxis : public QWidget
{
public:
PlotAxis(Qt::Orientation orientation = Qt::Horizontal, float min=0, float max=1, QWidget * parent = 0);
virtual ~PlotAxis();
public:
void setAxis(float & min, float & max);
int border() const {return _border;}
int step() const {return _step;}
int count() const {return _count;}
void setReversed(bool reversed); // Vertical :bottom->up, horizontal :right->left
protected:
virtual void paintEvent(QPaintEvent * event);
private:
Qt::Orientation _orientation;
float _min;
float _max;
int _count;
int _step;
bool _reversed;
int _gradMaxDigits;
int _border;
};
class PlotLegendItem : public QPushButton
{
Q_OBJECT
public:
PlotLegendItem(const PlotCurve * curve, QWidget * parent = 0);
virtual ~PlotLegendItem();
const PlotCurve * curve() const {return _curve;}
signals:
void legendItemRemoved(const PlotCurve *);
protected:
virtual void contextMenuEvent(QContextMenuEvent * event);
private:
const PlotCurve * _curve;
QMenu * _menu;
QAction * _aChangeText;
QAction * _aResetText;
QAction * _aRemoveCurve;
QAction * _aCopyToClipboard;
};
class PlotLegend : public QWidget
{
Q_OBJECT
public:
PlotLegend(QWidget * parent = 0);
virtual ~PlotLegend();
void setFlat(bool on);
bool isFlat() const {return _flat;}
void addItem(const PlotCurve * curve);
QPixmap createSymbol(const QPen & pen, const QBrush & brush);
public slots:
void removeLegendItem(const PlotCurve * curve);
signals:
void legendItemRemoved(const PlotCurve * curve);
void legendItemToggled(const PlotCurve * curve, bool toggled);
protected:
virtual void contextMenuEvent(QContextMenuEvent * event);
private slots:
void redirectToggled(bool);
private:
bool _flat;
QMenu * _menu;
QAction * _aUseFlatButtons;
};
class OrientableLabel : public QLabel
{
Q_OBJECT
public:
OrientableLabel(const QString & text, Qt::Orientation orientation = Qt::Horizontal, QWidget * parent = 0);
virtual ~OrientableLabel();
Qt::Orientation orientation() const {return _orientation;}
void setOrientation(Qt::Orientation orientation);
QSize sizeHint() const;
QSize minimumSizeHint() const;
protected:
virtual void paintEvent(QPaintEvent* event);
private:
Qt::Orientation _orientation;
};
/*
* TODO It could be cool to right-click on a dot in the
* plot to create a new plot to monitor the dot value changes.
*/
class Plot : public QWidget
{
Q_OBJECT
public:
Plot(QWidget * parent = 0);
virtual ~Plot();
PlotCurve * addCurve(const QString & curveName);
bool addCurve(PlotCurve * curve);
QStringList curveNames();
bool contains(const QString & curveName);
void removeCurves();
ThresholdCurve * addThreshold(const QString & name, float value, Qt::Orientation orientation = Qt::Horizontal);
QString title() const {return this->objectName();}
QPen getRandomPenColored();
void showLegend(bool shown);
void showGrid(bool shown);
void showRefreshRate(bool shown);
void keepAllData(bool kept);
void showXAxis(bool shown) {_horizontalAxis->setVisible(shown);}
void showYAxis(bool shown) {_verticalAxis->setVisible(shown);}
void setVariableXAxis() {_fixedAxis[0] = false;}
void setVariableYAxis() {_fixedAxis[1] = false;}
void setFixedXAxis(float x1, float x2);
void setFixedYAxis(float y1, float y2);
void setMaxVisibleItems(int maxVisibleItems);
void setTitle(const QString & text);
void setXLabel(const QString & text);
void setYLabel(const QString & text, Qt::Orientation orientation = Qt::Vertical);
QGraphicsScene * scene() const;
void setWorkingDirectory(const QString & workingDirectory);
public slots:
void removeCurve(const PlotCurve * curve);
void showCurve(const PlotCurve * curve, bool shown);
private slots:
void captureScreen();
void updateAxis(const PlotCurve * curve);
void updateAxis(); //reset axis and recompute it with all curves minMax
protected:
virtual void contextMenuEvent(QContextMenuEvent * event);
virtual void paintEvent(QPaintEvent * event);
private:
void replot();
bool updateAxis(float x, float y);
bool updateAxis(float x1, float x2, float y1, float y2);
void setupUi();
void createActions();
void createMenus();
private:
PlotLegend * _legend;
QGraphicsView * _view;
float _axisMaximums[4]; // {x1->x2, y1->y2}
bool _axisMaximumsSet[4]; // {x1->x2, y1->y2}
bool _fixedAxis[2];
PlotAxis * _verticalAxis;
PlotAxis * _horizontalAxis;
int _penStyleCount;
int _maxVisibleItems;
QList<QGraphicsLineItem *> hGridLines;
QList<QGraphicsLineItem *> vGridLines;
QMap<const PlotCurve*, PlotCurve*> _curves;
QLabel * _title;
QLabel * _xLabel;
OrientableLabel * _yLabel;
QLabel * _refreshRate;
QString _workingDirectory;
QTime _refreshIntervalTime;
int _lowestRefreshRate;
QTime _refreshStartTime;
QMenu * _menu;
QAction * _aShowLegend;
QAction * _aShowGrid;
QAction * _aKeepAllData;
QAction * _aLimit0;
QAction * _aLimit10;
QAction * _aLimit50;
QAction * _aLimit100;
QAction * _aLimit500;
QAction * _aLimit1000;
QAction * _aLimitCustom;
QAction * _aAddVerticalLine;
QAction * _aAddHorizontalLine;
QAction * _aChangeTitle;
QAction * _aChangeXLabel;
QAction * _aChangeYLabel;
QAction * _aYLabelVertical;
QAction * _aShowRefreshRate;
QAction * _aSaveFigure;
QAction * _aAutoScreenCapture;
QAction * _aClearData;
};
#ifndef PLOT_WIDGET_OUT_OF_LIB
}
#endif
#endif /* PLOT_H_ */

File diff suppressed because it is too large Load Diff

435
guilib/src/StatsToolBox.cpp Normal file
View File

@@ -0,0 +1,435 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "StatsToolBox.h"
#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QGridLayout>
#include <QtGui/QMenu>
#include <QtGui/QLabel>
#include <QtGui/QToolButton>
#include <QtCore/QChildEvent>
#include <QtCore/QDir>
#include <QtGui/QContextMenuEvent>
#include <QtGui/QToolBox>
#include "Plot.h"
#include "utilite/ULogger.h"
namespace rtabmap {
StatItem::StatItem(const QString & name, float x, float y, const QString & unit, const QMenu * menu, QGridLayout * grid, QWidget * parent) :
QWidget(parent),
_xValue(x)
{
this->setupUi(grid);
_name->setText(name);
_value->setNum(y);
_unit->setText(unit);
this->updateMenu(menu);
}
StatItem::~StatItem()
{
}
void StatItem::setValue(float x, float y)
{
_value->setText(QString::number(y, 'g', 4));
_xValue = x;
emit valueChanged(x,y);
}
void StatItem::setupUi(QGridLayout * grid)
{
_menu = new QMenu(this);
_menu->addMenu("Add to figure...");
_button = new QToolButton(this);
_button->setIcon(QIcon(":/images/Plot16.png"));
_button->setPopupMode(QToolButton::InstantPopup);
_button->setMenu(_menu);
_name = new QLabel(this);
_name->setWordWrap(true);
_value = new QLabel(this);
_unit = new QLabel(this);
if(grid)
{
int row = grid->rowCount();
//This fixes an issue where the
//button (used on col 0) of the first line in the
//toolbox couldn't be clicked
grid->addWidget(_button, row, 3);
grid->addWidget(_name, row, 0);
grid->addWidget(_value, row, 1);
grid->addWidget(_unit, row, 2);
}
else
{
QHBoxLayout * layout = new QHBoxLayout(this);
this->setLayout(layout);
layout->addWidget(_button);
layout->addWidget(_name);
layout->addWidget(_value);
layout->addWidget(_unit);
layout->addStretch();
layout->setMargin(0);
}
}
void StatItem::updateMenu(const QMenu * menu)
{
_menu->clear();
QAction * action;
QList<QAction *> actions = menu->actions();
QMenu * plotMenu = _menu->addMenu("Add to figure...");
for(int i=0; i<actions.size(); ++i)
{
action = plotMenu->addAction(actions.at(i)->text());
connect(action, SIGNAL(triggered()), this, SLOT(preparePlotRequest()));
}
}
void StatItem::preparePlotRequest()
{
QAction * action = qobject_cast<QAction*>(sender());
if(action)
{
emit plotRequested(this, action->text());
}
}
StatsToolBox::StatsToolBox(QWidget * parent) :
QWidget(parent)
{
ULOGGER_DEBUG("");
//Statistics in the GUI (for plotting)
_statBox = new QToolBox(this);
this->setLayout(new QVBoxLayout());
this->layout()->setMargin(0);
this->layout()->addWidget(_statBox);
_statBox->layout()->setSpacing(0);
_plotMenu = new QMenu(this);
_plotMenu->addAction(tr("<New figure>"));
_workingDirectory = QDir::homePath();
}
StatsToolBox::~StatsToolBox()
{
closeFigures();
}
void StatsToolBox::closeFigures()
{
QMap<QString, QWidget*> figuresTmp = _figures;
for(QMap<QString, QWidget*>::iterator iter = figuresTmp.begin(); iter!=figuresTmp.end(); ++iter)
{
iter.value()->close();
}
}
void StatsToolBox::updateStat(const QString & statFullName, float x, float y)
{
// round float to max 2 numbers after the dot
//x = (float(int(100*x)))/100;
//y = (float(int(100*y)))/100;
StatItem * item = _statBox->findChild<StatItem *>(statFullName);
if(item)
{
item->setValue(x, y);
}
else
{
// statFullName format : "Grp/Name/unit"
QStringList list = statFullName.split('/');
QString grp;
QString name;
QString unit;
if(list.size() >= 3)
{
grp = list.at(0);
name = list.at(1);
unit = list.at(2);
}
else if(list.size() == 2)
{
grp = list.at(0);
name = list.at(1);
}
else if(list.size() == 1)
{
name = list.at(0);
}
else
{
ULOGGER_WARN("A statistic has no name");
return;
}
if(grp.isEmpty())
{
grp = tr("Global");
}
int index = -1;
for(int i=0; i<_statBox->count(); ++i)
{
if(_statBox->itemText(i).compare(grp) == 0)
{
index = i;
break;
}
}
if(index<0)
{
QWidget * newWidget = new QWidget(_statBox);
index = _statBox->addItem(newWidget, grp);
QVBoxLayout * layout = new QVBoxLayout(newWidget);
newWidget->setLayout(layout);
QGridLayout * grid = new QGridLayout();
grid->setVerticalSpacing(2);
grid->setColumnStretch(0, 1);
layout->addLayout(grid);
layout->addStretch();
}
QVBoxLayout * layout = qobject_cast<QVBoxLayout *>(_statBox->widget(index)->layout());
if(!layout)
{
ULOGGER_ERROR("Layout is null ?!?");
return;
}
QGridLayout * grid = qobject_cast<QGridLayout *>(layout->itemAt(0)->layout());
if(!grid)
{
ULOGGER_ERROR("Layout is null ?!?");
return;
}
item = new StatItem(name, x, y, unit, _plotMenu, grid, _statBox->widget(index));
item->setObjectName(statFullName);
//layout->insertWidget(layout->count()-1, item);
connect(item, SIGNAL(plotRequested(const StatItem *, const QString &)), this, SLOT(plot(const StatItem *, const QString &)));
connect(this, SIGNAL(menuChanged(const QMenu *)), item, SLOT(updateMenu(const QMenu *)));
}
}
void StatsToolBox::plot(const StatItem * stat, const QString & plotName)
{
QWidget * fig = _figures.value(plotName, (QWidget*)0);
Plot * plot = 0;
if(fig)
{
plot = fig->findChild<Plot *>(plotName);
}
if(plot)
{
// if not already in the plot
if(!plot->contains(stat->objectName()))
{
PlotCurve * curve = new PlotCurve(stat->objectName(), plot);
curve->setPen(plot->getRandomPenColored());
connect(stat, SIGNAL(valueChanged(float, float)), curve, SLOT(addValue(float, float)));
if(!plot->addCurve(curve))
{
ULOGGER_WARN("Already added to the figure");
}
}
else
{
ULOGGER_WARN("Already added to the figure");
}
plot->activateWindow();
}
else
{
//Create a new plot
QString id = tr("Figure 0");
if(_plotMenu->actions().size())
{
id = _plotMenu->actions().last()->text();
}
id.replace(tr("Figure "), "");
QString newPlotName = QString(tr("Figure %1")).arg(id.toInt()+1);
//Dock
QWidget * figure = new QWidget(0, Qt::Window);
_figures.insert(newPlotName, figure);
figure->setLayout(new QHBoxLayout());
figure->setWindowTitle(newPlotName);
figure->setAttribute(Qt::WA_DeleteOnClose, true);
connect(figure, SIGNAL(destroyed(QObject*)), this, SLOT(figureDeleted(QObject*)));
//Plot
Plot * newPlot = new Plot(figure);
newPlot->setWorkingDirectory(_workingDirectory);
newPlot->setMaxVisibleItems(10);
newPlot->setObjectName(newPlotName);
figure->layout()->addWidget(newPlot);
_plotMenu->addAction(newPlotName);
//Add a new curve linked to the statBox
PlotCurve * curve = new PlotCurve(stat->objectName(), newPlot);
curve->setPen(newPlot->getRandomPenColored());
connect(stat, SIGNAL(valueChanged(float, float)), curve, SLOT(addValue(float, float)));
if(!newPlot->addCurve(curve))
{
ULOGGER_ERROR("Not supposed to be here !?!");
delete curve;
}
figure->show();
emit menuChanged(_plotMenu);
}
}
void StatsToolBox::figureDeleted(QObject * obj)
{
if(obj)
{
QWidget * plot = qobject_cast<QWidget*>(obj);
if(plot)
{
_figures.remove(plot->windowTitle());
QList<QAction*> actions = _plotMenu->actions();
for(int i=0; i<actions.size(); ++i)
{
if(actions.at(i)->text().compare(plot->windowTitle()) == 0)
{
_plotMenu->removeAction(actions.at(i));
delete actions[i];
emit menuChanged(_plotMenu);
break;
}
}
}
else
{
UERROR("");
}
}
else
{
UERROR("");
}
}
void StatsToolBox::contextMenuEvent(QContextMenuEvent * event)
{
QMenu topMenu(this);
QMenu * menu = topMenu.addMenu(tr("Add all statistics from tab \"%1\" to...").arg(_statBox->itemText(_statBox->currentIndex())));
QList<QAction* > actions = _plotMenu->actions();
menu->addActions(actions);
QAction * action = topMenu.exec(event->globalPos());
QString plotName;
if(action)
{
for(int i=0; i<actions.size(); ++i)
{
if(actions.at(i) == action)
{
plotName = actions.at(i)->text();
break;
}
}
}
if(!plotName.isEmpty())
{
QList<StatItem*> items = _statBox->currentWidget()->findChildren<StatItem*>();
for(int i=0; i<items.size(); ++i)
{
this->plot(items.at(i), plotName);
if(plotName.compare(tr("<New figure>")) == 0)
{
plotName = _plotMenu->actions().last()->text();
}
}
}
}
void StatsToolBox::getFiguresSetup(QList<int> & curvesPerFigure, QStringList & curveNames)
{
curvesPerFigure.clear();
curveNames.clear();
for(QMap<QString, QWidget*>::iterator i=_figures.begin(); i!=_figures.end(); ++i)
{
QList<Plot *> plots = i.value()->findChildren<Plot *>();
if(plots.size() == 1)
{
QStringList names = plots[0]->curveNames();
curvesPerFigure.append(names.size());
curveNames.append(names);
}
else
{
UERROR("");
}
}
}
void StatsToolBox::addCurve(const QString & name, bool newFigure)
{
StatItem * item = _statBox->findChild<StatItem *>(name);
if(!item)
{
this->updateStat(name, 0, 0);
item = _statBox->findChild<StatItem *>(name);
}
if(item)
{
if(newFigure)
{
this->plot(item, "");
}
else
{
this->plot(item, _plotMenu->actions().last()->text());
}
}
else
{
ULOGGER_ERROR("Not supposed to be here...");
}
}
void StatsToolBox::setWorkingDirectory(const QString & workingDirectory)
{
if(QDir(_workingDirectory).exists())
{
_workingDirectory = workingDirectory;
}
else
{
ULOGGER_ERROR("The directory \"%s\" doesn't exist", workingDirectory.toStdString().c_str());
}
}
}

103
guilib/src/StatsToolBox.h Normal file
View File

@@ -0,0 +1,103 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef STATSTOOLBOX_H_
#define STATSTOOLBOX_H_
#include <QtGui/QWidget>
#include <QtCore/QMap>
class QToolButton;
class QLabel;
class QMenu;
class QGridLayout;
class QToolBox;
namespace rtabmap {
class StatItem : public QWidget
{
Q_OBJECT;
public:
StatItem(const QString & name, float x, float y, const QString & unit = QString(), const QMenu * menu = 0, QGridLayout * grid = 0, QWidget * parent = 0);
virtual ~StatItem();
void setValue(float x, float y);
public slots:
void updateMenu(const QMenu * menu);
signals:
void valueChanged(float, float);
void plotRequested(const StatItem *, const QString &);
private slots:
void preparePlotRequest();
private:
void setupUi(QGridLayout * grid);
private:
QToolButton * _button;
QLabel * _name;
QLabel * _value;
QLabel * _unit;
QMenu * _menu;
float _xValue;
};
class StatsToolBox : public QWidget
{
Q_OBJECT;
public:
StatsToolBox(QWidget * parent);
virtual ~StatsToolBox();
void getFiguresSetup(QList<int> & curvesPerFigure, QStringList & curveNames);
void addCurve(const QString & name, bool newFigure = true);
void setWorkingDirectory(const QString & workingDirectory);
void closeFigures();
public slots:
void updateStat(const QString & statFullName, float x, float y);
signals:
void menuChanged(const QMenu *);
private slots:
void plot(const StatItem * stat, const QString & plotName = QString());
void figureDeleted(QObject * obj);
protected:
virtual void contextMenuEvent(QContextMenuEvent * event);
private:
QMenu * _plotMenu;
QToolBox * _statBox;
QString _workingDirectory;
QMap<QString, QWidget*> _figures;
};
}
#endif /* STATSTOOLBOX_H_ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
guilib/src/images/Pause.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
guilib/src/images/Plot.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -0,0 +1,17 @@
/*QGroupBox {
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #E0E0E0, stop: 1 #FFFFFF);
border: 2px solid gray;
border-radius: 5px;
margin-top: 1ex; /* leave space at the top for the title */
}
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top center;
padding: 0 3px;
background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #FFOECE, stop: 1 #FFFFFF);
}
*/

53
guilib/src/qtipl.cpp Normal file
View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "qtipl.h"
#include "utilite/ULogger.h"
#include <opencv2/core/core_c.h>
namespace rtabmap {
// TODO : support only from gray 8bits ?
QImage Ipl2QImage(const IplImage *newImage)
{
QImage qtemp;
if (newImage && newImage->depth == IPL_DEPTH_8U && cvGetSize(newImage).width>0)
{
int x;
int y;
char* data = newImage->imageData;
qtemp= QImage(newImage->width, newImage->height,QImage::Format_RGB32 );
for( y = 0; y < newImage->height; y++, data +=newImage->widthStep )
{
for( x = 0; x < newImage->width; x++)
{
uint *p = (uint*)qtemp.scanLine (y) + x;
*p = qRgb(data[x * newImage->nChannels+2], data[x * newImage->nChannels+1],data[x * newImage->nChannels]);
}
}
}
else
{
ULOGGER_ERROR("Wrong IplImage format");
}
return qtemp;
}
}

32
guilib/src/qtipl.h Normal file
View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QTIPL_H
#define QTIPL_H
#include <QtGui/QImage>
#include <opencv2/core/core.hpp>
namespace rtabmap {
QImage Ipl2QImage(const IplImage *newImage);
}
#endif

View File

@@ -0,0 +1,22 @@
0General
1Bayes filter
1Similarity
1Memory strategy
0Source
1Images
1Video
1Usb device
0Signature type
1Keypoint-based
2Detectors
3SURF detector
3Star detector
2Descriptor
2Dictionary
1FFT-based
0Hypotheses creation
1Simple
1Std dev
0Hypotheses verification
1Sequence
1Epipolar constraints

View File

@@ -0,0 +1,252 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>aboutDialog</class>
<widget class="QDialog" name="aboutDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>543</width>
<height>368</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>About RTAB-Map</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
<item>
<widget class="QLabel" name="label_10">
<property name="maximumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../GuiLib.qrc">:/images/RTAB-Map.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'MS Shell Dlg 2'; font-size:14pt; font-weight:600;&quot;&gt;RTAB-Map : Real-Time Appearance-Based Mapping&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>RTAB-Map is an appearance-based loop closure detector for autonomous robot. This interface is used to control or to monitor the core process. </string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Author :</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Links :</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Version :</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_HomePage_2">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://www.code.google.com/p/rtabmap&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Source page&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Mathieu Labbé, matlabbe@gmail.com</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_version">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_HomePage_3">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://introlab.gel.usherbrooke.ca/mediawiki-introlab/index.php/RTAB-Map&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Home page&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="../GuiLib.qrc">:/images/IntRoLabSmall.png</pixmap>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Copyright (C) 2011 IntRoLab - Université de Sherbrooke</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../GuiLib.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>aboutDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>aboutDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>consoleWidget</class>
<widget class="QWidget" name="consoleWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>consoleWidget</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QTextEdit" name="textEdit">
<property name="lineWrapMode">
<enum>QTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

877
guilib/src/ui/mainWindow.ui Normal file
View File

@@ -0,0 +1,877 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>mainWindow</class>
<widget class="QMainWindow" name="mainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>612</width>
<height>632</height>
</rect>
</property>
<property name="windowTitle">
<string>RTAB-Map : Real-Time Appearance-Based Mapping</string>
</property>
<property name="windowIcon">
<iconset resource="../GuiLib.qrc">
<normaloff>:/images/RTAB-Map.ico</normaloff>:/images/RTAB-Map.ico</iconset>
</property>
<property name="dockOptions">
<set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks|QMainWindow::VerticalTabs</set>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QLabel" name="label_19">
<property name="text">
<string>-Source-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLabel" name="label_refId">
<property name="minimumSize">
<size>
<width>0</width>
<height>18</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="rtabmap::ImageView" name="imageView_source">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QCheckBox" name="checkBox_showFeatures">
<property name="text">
<string>Show features</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_showImage">
<property name="text">
<string>Show image</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_18">
<property name="text">
<string>-Loop closure detection-</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_matchId">
<property name="minimumSize">
<size>
<width>0</width>
<height>18</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="rtabmap::ImageView" name="imageView_loopClosure">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QCheckBox" name="checkBox_showFeaturesLoop">
<property name="text">
<string>Show features</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="checkBox_showImageLoop">
<property name="text">
<string>Show image</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>612</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionExit"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
</property>
<addaction name="actionReset_the_memory"/>
<addaction name="actionDelete_memory"/>
<addaction name="separator"/>
<addaction name="actionOpen_working_directory"/>
<addaction name="actionDump_the_memory"/>
<addaction name="actionDump_the_prediction_matrix"/>
<addaction name="actionGenerate_map"/>
<addaction name="separator"/>
<addaction name="actionApply_settings_to_the_detector"/>
<addaction name="separator"/>
<addaction name="actionClear_cache"/>
<addaction name="actionAuto_screen_capture"/>
</widget>
<widget class="QMenu" name="menu6">
<property name="title">
<string>?</string>
</property>
<addaction name="actionHelp"/>
<addaction name="separator"/>
<addaction name="actionAbout"/>
</widget>
<widget class="QMenu" name="menuProcess">
<property name="title">
<string>Detection</string>
</property>
<widget class="QMenu" name="menuSelect_source">
<property name="title">
<string>Select source</string>
</property>
<addaction name="actionStream"/>
<addaction name="actionImages"/>
<addaction name="actionVideo"/>
<addaction name="actionDatabase"/>
</widget>
<addaction name="menuSelect_source"/>
<addaction name="separator"/>
<addaction name="actionStart"/>
<addaction name="actionPause"/>
<addaction name="actionStop"/>
<addaction name="separator"/>
<addaction name="actionPause_on_match"/>
<addaction name="actionPause_when_a_loop_hypothesis_is_rejected"/>
</widget>
<widget class="QMenu" name="menuWindow">
<property name="title">
<string>Window</string>
</property>
<widget class="QMenu" name="menuShow_view">
<property name="title">
<string>Show view</string>
</property>
<addaction name="separator"/>
</widget>
<widget class="QMenu" name="menuFigures">
<property name="title">
<string>Figures</string>
</property>
<addaction name="actionSave_state"/>
<addaction name="actionLoad_state"/>
</widget>
<addaction name="menuShow_view"/>
<addaction name="menuFigures"/>
<addaction name="separator"/>
<addaction name="actionPreferences"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
<addaction name="menuProcess"/>
<addaction name="menuWindow"/>
<addaction name="menu6"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="dockWidget_posterior">
<property name="features">
<set>QDockWidget::AllDockWidgetFeatures</set>
</property>
<property name="windowTitle">
<string>A posteriori PDF</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="rtabmap::Plot" name="posteriorPlot" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionStart"/>
<addaction name="actionPause"/>
<addaction name="actionStop"/>
<addaction name="separator"/>
<addaction name="actionPause_on_match"/>
<addaction name="actionPause_when_a_loop_hypothesis_is_rejected"/>
</widget>
<widget class="QDockWidget" name="dockWidget_statsV2">
<property name="floating">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>Statistics</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_3">
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="margin">
<number>2</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Source</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_stats_source">
<property name="text">
<string>Unknown</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_stats_imgRate">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Elapsed time (hh:mm:ss)</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_elapsedTime">
<property name="text">
<string>Unknown</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Current image id</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_stats_imageNumber">
<property name="text">
<string>Unknown</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Loop closures detected</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_stats_loopClosuresDetected">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_38">
<property name="text">
<string>Loop closures detected
(only reactivated ones)</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_stats_loopClosuresReactivatedDetected">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Loop closures rejected</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_stats_loopClosuresRejected">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Image rate</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Hz</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Time limit processing</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_21">
<property name="text">
<string>s</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_stats_timeLimit">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>10.000000000000000</double>
</property>
<property name="value">
<double>0.450000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="rtabmap::StatsToolBox" name="statsToolBox" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_likelihood">
<property name="floating">
<bool>true</bool>
</property>
<property name="windowTitle">
<string>Likelihood</string>
</property>
<attribute name="dockWidgetArea">
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="rtabmap::Plot" name="likelihoodPlot" native="true">
<property name="minimumSize">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_console">
<property name="windowTitle">
<string>Console</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="rtabmap::ConsoleWidget" name="widget" native="true"/>
</item>
</layout>
</widget>
</widget>
<action name="actionExit">
<property name="text">
<string>Exit</string>
</property>
</action>
<action name="actionStream">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Usb device</string>
</property>
</action>
<action name="actionVideo">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Video...</string>
</property>
</action>
<action name="actionImages">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Images...</string>
</property>
</action>
<action name="actionSURF">
<property name="text">
<string>SURF</string>
</property>
</action>
<action name="actionFourier">
<property name="text">
<string>Fourier</string>
</property>
</action>
<action name="actionSIFT">
<property name="text">
<string>SIFT</string>
</property>
</action>
<action name="actionCenSurE">
<property name="text">
<string>CenSurE</string>
</property>
</action>
<action name="actionHelp">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Help</string>
</property>
</action>
<action name="actionAbout">
<property name="text">
<string>About...</string>
</property>
</action>
<action name="actionPreferences">
<property name="text">
<string>Preferences...</string>
</property>
</action>
<action name="actionStart">
<property name="icon">
<iconset resource="../GuiLib.qrc">
<normaloff>:/images/Play1Normal.png</normaloff>:/images/Play1Normal.png</iconset>
</property>
<property name="text">
<string>Start</string>
</property>
</action>
<action name="actionPause">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../GuiLib.qrc">
<normaloff>:/images/PauseNormalRed.png</normaloff>:/images/PauseNormalRed.png</iconset>
</property>
<property name="text">
<string>Pause</string>
</property>
</action>
<action name="actionPause_on_match">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../GuiLib.qrc">
<normaloff>:/images/PauseOnLoop.ico</normaloff>:/images/PauseOnLoop.ico</iconset>
</property>
<property name="text">
<string>Pause on match</string>
</property>
</action>
<action name="actionStop">
<property name="icon">
<iconset resource="../GuiLib.qrc">
<normaloff>:/images/Stop1NormalYellow.png</normaloff>:/images/Stop1NormalYellow.png</iconset>
</property>
<property name="text">
<string>Stop</string>
</property>
</action>
<action name="actionReset_the_memory">
<property name="text">
<string>Save/reload the memory</string>
</property>
</action>
<action name="actionApply_settings_to_the_detector">
<property name="text">
<string>Apply settings to the detector</string>
</property>
</action>
<action name="actionDump_the_memory">
<property name="text">
<string>Dump the memory</string>
</property>
</action>
<action name="actionDatabase">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Database...</string>
</property>
</action>
<action name="actionPause_when_a_loop_hypothesis_is_rejected">
<property name="checkable">
<bool>true</bool>
</property>
<property name="icon">
<iconset resource="../GuiLib.qrc">
<normaloff>:/images/PauseLoopRejected.ico</normaloff>:/images/PauseLoopRejected.ico</iconset>
</property>
<property name="text">
<string>Pause when a loop hypothesis is rejected</string>
</property>
</action>
<action name="actionClear_cache">
<property name="text">
<string>Clear the cache</string>
</property>
</action>
<action name="actionSave_state">
<property name="text">
<string>Save state</string>
</property>
</action>
<action name="actionLoad_state">
<property name="text">
<string>Load state</string>
</property>
</action>
<action name="actionAuto_screen_capture">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Auto screen capture</string>
</property>
</action>
<action name="actionDump_the_prediction_matrix">
<property name="text">
<string>Dump the prediction matrix</string>
</property>
</action>
<action name="actionGenerate_map">
<property name="text">
<string>Generate map...</string>
</property>
</action>
<action name="actionDelete_memory">
<property name="text">
<string>Delete memory</string>
</property>
</action>
<action name="actionOpen_working_directory">
<property name="text">
<string>Show working directory in file browser</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>rtabmap::Plot</class>
<extends>QWidget</extends>
<header>Plot.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>rtabmap::ImageView</class>
<extends>QGraphicsView</extends>
<header>ImageView.h</header>
</customwidget>
<customwidget>
<class>rtabmap::StatsToolBox</class>
<extends>QWidget</extends>
<header>StatsToolBox.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>rtabmap::ConsoleWidget</class>
<extends>QWidget</extends>
<header>ConsoleWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../GuiLib.qrc"/>
</resources>
<connections/>
</ui>

File diff suppressed because it is too large Load Diff