mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-01 17:10:26 +08:00
MERGE branch STM 325:449 into trunk
git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@450 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
#define MAINWINDOW_H_
|
||||
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QSlider>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtCore/QTimer>
|
||||
#include "Plot.h"
|
||||
|
||||
@@ -13,10 +15,11 @@ class MainWindow : public QMainWindow
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainWindow() {
|
||||
//Plot
|
||||
Plot * plot = new Plot(this);
|
||||
plot->setObjectName("Figure 1");
|
||||
plot->setMaxVisibleItems(25);
|
||||
this->setCentralWidget(plot); // ownership transferred
|
||||
plot->setMaxVisibleItems(50);
|
||||
plot->showRefreshRate(true);
|
||||
PlotCurve * curveA = new PlotCurve("Curve A", this);
|
||||
PlotCurve * curveB = new PlotCurve("Curve B", this);
|
||||
curveA->setPen(QPen(Qt::red));
|
||||
@@ -25,8 +28,23 @@ public:
|
||||
plot->addCurve(curveB); // ownership transferred
|
||||
connect(this, SIGNAL(valueUpdatedA(float)), curveA, SLOT(addValue(float)));
|
||||
connect(this, SIGNAL(valueUpdatedB(float)), curveB, SLOT(addValue(float)));
|
||||
|
||||
//Control
|
||||
QSlider * slider = new QSlider(Qt::Vertical, this);
|
||||
slider->setMinimum(1); // Hz
|
||||
slider->setMaximum(100); // Hz
|
||||
slider->setValue(10);
|
||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setRate(int)));
|
||||
|
||||
// layout
|
||||
QWidget * placeHolder = new QWidget(this);
|
||||
this->setCentralWidget(placeHolder);
|
||||
QHBoxLayout * hlayout = new QHBoxLayout(placeHolder);
|
||||
hlayout->addWidget(plot, 1);
|
||||
hlayout->addWidget(slider);
|
||||
|
||||
connect(&timer_, SIGNAL(timeout()), this, SLOT(updateCounter()));
|
||||
timer_.start(100);
|
||||
setRate(slider->value());
|
||||
qsrand(1);
|
||||
}
|
||||
~MainWindow() {}
|
||||
@@ -35,6 +53,9 @@ public slots:
|
||||
emit valueUpdatedA(qrand() % 100);
|
||||
emit valueUpdatedB(qrand() % 50);
|
||||
}
|
||||
void setRate(int rate) {
|
||||
timer_.start(1000/rate);
|
||||
}
|
||||
signals:
|
||||
void valueUpdatedA(float);
|
||||
void valueUpdatedB(float);
|
||||
|
||||
@@ -44,6 +44,7 @@ class Plot;
|
||||
class PdfPlotCurve;
|
||||
class StatsToolBox;
|
||||
class DetailedProgressDialog;
|
||||
class TwistGridWidget;
|
||||
|
||||
class RTABMAP_EXP MainWindow : public QMainWindow, public UEventsHandler
|
||||
{
|
||||
@@ -71,7 +72,7 @@ public:
|
||||
* dialog is automatically destroyed with the MainWindow.
|
||||
*/
|
||||
MainWindow(PreferencesDialog * prefDialog = 0, QWidget * parent = 0);
|
||||
~MainWindow();
|
||||
virtual ~MainWindow();
|
||||
|
||||
QString getWorkingDirectory() const;
|
||||
|
||||
@@ -118,10 +119,11 @@ signals:
|
||||
void stateChanged(MainWindow::State);
|
||||
void rtabmapEventInitReceived(int status, const QString & info);
|
||||
void imgRateChanged(double);
|
||||
void timeLimitChanged(double);
|
||||
void timeLimitChanged(float);
|
||||
void noMoreImagesReceived();
|
||||
void loopClosureThrChanged(float);
|
||||
void retrievalThrChanged(float);
|
||||
void twistReceived(float x, float y, float z, float roll, float pitch, float yaw, int row, int col);
|
||||
|
||||
private:
|
||||
void drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords, const std::multimap<int, cv::KeyPoint> & loopWords);
|
||||
@@ -143,6 +145,7 @@ private:
|
||||
|
||||
QSet<int> _lastIds;
|
||||
int _lastId;
|
||||
bool _processingStatistics;
|
||||
|
||||
QMap<int, QByteArray> _imagesMap;
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ public:
|
||||
// source panel
|
||||
double getGeneralImageRate() const;
|
||||
bool getGeneralAutoRestart() const;
|
||||
bool getGeneralCameraKeypoints() const;
|
||||
int getSourceType() const;
|
||||
QString getSourceTypeStr() const;
|
||||
int getSourceWidth() const;
|
||||
@@ -117,10 +118,11 @@ public:
|
||||
int getSourceUsbDeviceId() const; //UsbDevice group
|
||||
QString getSourceDatabasePath() const; //Database group
|
||||
bool getSourceDatabaseIgnoreChildren() const; //Database group
|
||||
bool getSourceDatabaseLoadActions() const; //Database group
|
||||
|
||||
//
|
||||
bool isImagesKept() const;
|
||||
double getTimeLimit() const;
|
||||
float getTimeLimit() const;
|
||||
|
||||
//specific
|
||||
double getLoopThr() const;
|
||||
@@ -137,7 +139,7 @@ public slots:
|
||||
void setRetrievalThr(int value);
|
||||
void setImgRate(double value);
|
||||
void setAutoRestart(bool value);
|
||||
void setTimeLimit(double value);
|
||||
void setTimeLimit(float value);
|
||||
void selectSource(Src src = kSrcUndef);
|
||||
|
||||
private slots:
|
||||
@@ -152,12 +154,12 @@ private slots:
|
||||
void addParameter(int value);
|
||||
void addParameter(double value);
|
||||
void addParameter(const QString & value);
|
||||
void updatePredictionLCSliders();
|
||||
void updatePredictionLC();
|
||||
void updatePredictionPlot();
|
||||
void updateKpROI();
|
||||
void changeWorkingDirectory();
|
||||
void changeDictionaryPath();
|
||||
void readSettingsEnd();
|
||||
void setupTreeView();
|
||||
|
||||
protected:
|
||||
virtual void showEvent ( QShowEvent * event );
|
||||
@@ -178,9 +180,7 @@ protected:
|
||||
|
||||
private:
|
||||
bool validateForm();
|
||||
void setupTreeView();
|
||||
void setupSignals();
|
||||
void setupPredictionPanel();
|
||||
void setupKpRoiPanel();
|
||||
bool parseModel(QList<QGroupBox*> & boxes, QStandardItem * parentItem, int currentLevel, int & absoluteIndex);
|
||||
void addParameter(const QObject * object, int value);
|
||||
@@ -199,10 +199,6 @@ private:
|
||||
QStandardItemModel * _indexModel;
|
||||
bool _initialized;
|
||||
|
||||
//For Bayes filter prediction parameters
|
||||
QList<QSlider*> _predictionLCSliders; // Sliders used to setup the prediction
|
||||
bool _predictionPanelInitialized;
|
||||
|
||||
QProgressDialog * _progressDialog;
|
||||
};
|
||||
|
||||
|
||||
@@ -19,14 +19,21 @@
|
||||
|
||||
#include "AboutDialog.h"
|
||||
#include "rtabmap/core/Rtabmap.h"
|
||||
#include "ui_aboutDialog.h"
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
AboutDialog::AboutDialog(QWidget * parent) :
|
||||
QDialog(parent)
|
||||
{
|
||||
_ui.setupUi(this);
|
||||
_ui.label_version->setText(Rtabmap::getVersion().c_str());
|
||||
_ui = new Ui_aboutDialog();
|
||||
_ui->setupUi(this);
|
||||
_ui->label_version->setText(Rtabmap::getVersion().c_str());
|
||||
}
|
||||
|
||||
AboutDialog::~AboutDialog()
|
||||
{
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
#include <QtGui/QDialog>
|
||||
#include <QtCore/QUrl>
|
||||
#include "ui_aboutDialog.h"
|
||||
|
||||
class Ui_aboutDialog;
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
@@ -33,10 +34,10 @@ class AboutDialog : public QDialog
|
||||
public:
|
||||
AboutDialog(QWidget * parent = 0);
|
||||
|
||||
virtual ~AboutDialog() {}
|
||||
virtual ~AboutDialog();
|
||||
|
||||
private:
|
||||
Ui_aboutDialog _ui;
|
||||
Ui_aboutDialog * _ui;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ SET(headers_ui
|
||||
./PdfPlot.h
|
||||
./StatsToolBox.h
|
||||
./DetailedProgressDialog.h
|
||||
./TwistWidget.h
|
||||
)
|
||||
|
||||
SET(uis
|
||||
@@ -49,6 +50,7 @@ SET(SRC_FILES
|
||||
./DetailedProgressDialog.cpp
|
||||
./AboutDialog.cpp
|
||||
./ConsoleWidget.cpp
|
||||
./TwistWidget.cpp
|
||||
${moc_srcs}
|
||||
${moc_uis}
|
||||
${srcs_qrc}
|
||||
@@ -57,7 +59,7 @@ SET(SRC_FILES
|
||||
SET(INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${UTILITE_INCLUDE_DIR}
|
||||
${UTILITE_INCLUDE_DIRS}
|
||||
${OpenCV_INCLUDE_DIRS}
|
||||
${CMAKE_CURRENT_BINARY_DIR} # for qt ui generated in binary dir
|
||||
)
|
||||
@@ -65,7 +67,7 @@ SET(INCLUDE_DIRS
|
||||
INCLUDE(${QT_USE_FILE})
|
||||
|
||||
SET(LIBRARIES
|
||||
${UTILITE_LIBRARY}
|
||||
${UTILITE_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
${OpenCV_LIBS}
|
||||
)
|
||||
|
||||
@@ -18,24 +18,42 @@
|
||||
*/
|
||||
|
||||
#include "ConsoleWidget.h"
|
||||
#include "ui_consoleWidget.h"
|
||||
#include <utilite/ULogger.h>
|
||||
#include <utilite/UEventsManager.h>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QTextCursor>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#define OLD_TIME 1000 //ms
|
||||
#define MAXIMUM_ITEMS 100
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
ConsoleWidget::ConsoleWidget(QWidget * parent) :
|
||||
QWidget(parent)
|
||||
{
|
||||
_ui.setupUi(this);
|
||||
_ui = new Ui_consoleWidget();
|
||||
_ui->setupUi(this);
|
||||
UEventsManager::addHandler(this);
|
||||
_ui->textEdit->document()->setMaximumBlockCount(MAXIMUM_ITEMS);
|
||||
_textCursor = new QTextCursor(_ui->textEdit->document());
|
||||
_ui->textEdit->setFontPointSize(10);
|
||||
QPalette p(_ui->textEdit->palette());
|
||||
p.setColor(QPalette::Base, Qt::black);
|
||||
_ui->textEdit->setPalette(p);
|
||||
_errorMessage = new QMessageBox(QMessageBox::Critical, tr("Fatal error occurred"), "", QMessageBox::Ok, this);
|
||||
_errorMessageMutex.lock();
|
||||
_time.start();
|
||||
_timer.setSingleShot(true);
|
||||
connect(_ui->pushButton_clear, SIGNAL(clicked()), _ui->textEdit, SLOT(clear()));
|
||||
connect(this, SIGNAL(msgReceived(const QString &, int)), this, SLOT(appendMsg(const QString &, int)));
|
||||
_ui.textEdit->document()->setMaximumBlockCount(100);
|
||||
_ui.textEdit->setFontPointSize(10);
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(flushConsole()));
|
||||
}
|
||||
|
||||
ConsoleWidget::~ConsoleWidget()
|
||||
{
|
||||
delete _ui;
|
||||
}
|
||||
|
||||
void ConsoleWidget::handleEvent(UEvent * anEvent)
|
||||
@@ -44,12 +62,37 @@ void ConsoleWidget::handleEvent(UEvent * anEvent)
|
||||
if(anEvent->getClassName().compare("ULogEvent") == 0)
|
||||
{
|
||||
ULogEvent * logEvent = (ULogEvent*)anEvent;
|
||||
emit msgReceived(logEvent->getMsg().c_str(), logEvent->getCode());
|
||||
_msgListMutex.lock();
|
||||
_msgList.append(QPair<QString, int>(logEvent->getMsg().c_str(), logEvent->getCode()));
|
||||
if(_msgList.size()>MAXIMUM_ITEMS)
|
||||
{
|
||||
_msgList.pop_front();
|
||||
}
|
||||
_msgListMutex.unlock();
|
||||
|
||||
if(_time.restart() < OLD_TIME)
|
||||
{
|
||||
if(logEvent->getCode() == ULogger::kFatal)
|
||||
{
|
||||
_timer.start(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_timer.start(OLD_TIME);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_timer.start(0);
|
||||
}
|
||||
|
||||
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);
|
||||
//This thread will wait until the message box is closed...
|
||||
// Assuming that error messages come from a different thread.
|
||||
_errorMessageMutex.lock();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,20 +101,48 @@ void ConsoleWidget::appendMsg(const QString & msg, int level)
|
||||
switch(level)
|
||||
{
|
||||
case 0:
|
||||
_ui.textEdit->setTextColor(Qt::darkGreen);
|
||||
_ui->textEdit->setTextColor(Qt::darkGreen);
|
||||
break;
|
||||
case 2:
|
||||
_ui.textEdit->setTextColor(Qt::darkYellow);
|
||||
_ui->textEdit->setTextColor(Qt::yellow);
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
_ui.textEdit->setTextColor(Qt::darkRed);
|
||||
_ui->textEdit->setTextColor(Qt::red);
|
||||
break;
|
||||
default:
|
||||
_ui.textEdit->setTextColor(Qt::black);
|
||||
_ui->textEdit->setTextColor(Qt::white);
|
||||
break;
|
||||
}
|
||||
_ui.textEdit->append(msg);
|
||||
_ui->textEdit->append(msg);
|
||||
|
||||
if(level == ULogger::kFatal)
|
||||
{
|
||||
_textCursor->endEditBlock();
|
||||
QTextCursor cursor = _ui->textEdit->textCursor();
|
||||
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
||||
_ui->textEdit->setTextCursor(cursor);
|
||||
//The application will exit, so warn the user.
|
||||
_errorMessage->setText(tr("Description:\n\n%1\n\nThe application will now exit...").arg(msg));
|
||||
_errorMessage->exec();
|
||||
_errorMessageMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleWidget::flushConsole()
|
||||
{
|
||||
_msgListMutex.lock();
|
||||
_textCursor->beginEditBlock();
|
||||
for(int i=0; i<_msgList.size(); ++i)
|
||||
{
|
||||
appendMsg(_msgList[i].first, _msgList[i].second);
|
||||
}
|
||||
_textCursor->endEditBlock();
|
||||
_msgList.clear();
|
||||
_msgListMutex.unlock();
|
||||
QTextCursor cursor = _ui->textEdit->textCursor();
|
||||
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
|
||||
_ui->textEdit->setTextCursor(cursor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,15 @@
|
||||
#ifndef CONSOLEWIDGET_H_
|
||||
#define CONSOLEWIDGET_H_
|
||||
|
||||
#include "ui_consoleWidget.h"
|
||||
#include <utilite/UEventsHandler.h>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QTime>
|
||||
|
||||
class Ui_consoleWidget;
|
||||
class QMessageBox;
|
||||
class QTextCursor;
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
@@ -39,12 +46,21 @@ public slots:
|
||||
signals:
|
||||
void msgReceived(const QString &, int);
|
||||
|
||||
private slots:
|
||||
void flushConsole();
|
||||
|
||||
protected:
|
||||
virtual void handleEvent(UEvent * anEvent);
|
||||
|
||||
private:
|
||||
Ui_consoleWidget _ui;
|
||||
|
||||
Ui_consoleWidget * _ui;
|
||||
QMessageBox * _errorMessage;
|
||||
QMutex _errorMessageMutex;
|
||||
QMutex _msgListMutex;
|
||||
QTimer _timer;
|
||||
QTime _time;
|
||||
QTextCursor * _textCursor;
|
||||
QList<QPair<QString, int> > _msgList;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,5 @@
|
||||
<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>
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "PdfPlot.h"
|
||||
#include "StatsToolBox.h"
|
||||
#include "DetailedProgressDialog.h"
|
||||
#include "TwistWidget.h"
|
||||
#include "rtabmap/core/SMState.h"
|
||||
|
||||
|
||||
#include <QtGui/QCloseEvent>
|
||||
@@ -73,6 +75,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
||||
_preferencesDialog(0),
|
||||
_aboutDialog(0),
|
||||
_lastId(0),
|
||||
_processingStatistics(false),
|
||||
_oneSecondTimer(0),
|
||||
_elapsedTime(0),
|
||||
_posteriorCurve(0),
|
||||
@@ -105,6 +108,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
||||
_ui->dockWidget_likelihood->setVisible(false);
|
||||
_ui->dockWidget_statsV2->setVisible(false);
|
||||
_ui->dockWidget_console->setVisible(false);
|
||||
_ui->dockWidget_twist->setVisible(false);
|
||||
}
|
||||
|
||||
if(prefDialog)
|
||||
@@ -143,7 +147,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
||||
tc = _ui->posteriorPlot->addThreshold("Loop closure thr", float(_preferencesDialog->getLoopThr()));
|
||||
connect(this, SIGNAL(loopClosureThrChanged(float)), tc, SLOT(setThreshold(float)));
|
||||
tc = _ui->posteriorPlot->addThreshold("Retrieval thr", float(_preferencesDialog->getRetrievalThr()));
|
||||
connect(this, SIGNAL(loopClosureThrChanged(float)), tc, SLOT(setThreshold(float)));
|
||||
connect(this, SIGNAL(retrievalThrChanged(float)), tc, SLOT(setThreshold(float)));
|
||||
|
||||
_likelihoodCurve = new PdfPlotCurve("Likelihood", &_imagesMap, this);
|
||||
_ui->likelihoodPlot->addCurve(_likelihoodCurve);
|
||||
@@ -168,13 +172,13 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
||||
_ui->menuShow_view->addAction(_ui->dockWidget_likelihood->toggleViewAction());
|
||||
_ui->menuShow_view->addAction(_ui->dockWidget_statsV2->toggleViewAction());
|
||||
_ui->menuShow_view->addAction(_ui->dockWidget_console->toggleViewAction());
|
||||
_ui->menuShow_view->addAction(_ui->dockWidget_twist->toggleViewAction());
|
||||
_ui->menuShow_view->addAction(_ui->toolBar->toggleViewAction());
|
||||
_ui->toolBar->setWindowTitle(tr("Control toolbar"));
|
||||
QAction * a = _ui->menuShow_view->addAction("Status");
|
||||
a->setCheckable(false);
|
||||
connect(a, SIGNAL(triggered(bool)), _initProgressDialog, SLOT(show()));
|
||||
|
||||
|
||||
// connect actions with custom slots
|
||||
connect(_ui->actionStart, SIGNAL(triggered()), this, SLOT(startDetection()));
|
||||
connect(_ui->actionPause, SIGNAL(triggered()), this, SLOT(pauseDetection()));
|
||||
@@ -189,6 +193,8 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
||||
connect(_ui->menuEdit, SIGNAL(aboutToShow()), this, SLOT(updateEditMenu()));
|
||||
connect(_ui->actionAuto_screen_capture, SIGNAL(triggered(bool)), this, SLOT(selectScreenCaptureFormat(bool)));
|
||||
|
||||
_ui->actionPause->setShortcut(Qt::Key_Space);
|
||||
|
||||
#if defined(Q_WS_MAC) or defined(Q_WS_WIN)
|
||||
connect(_ui->actionOpen_working_directory, SIGNAL(triggered()), SLOT(openWorkingDirectory()));
|
||||
#else
|
||||
@@ -223,7 +229,9 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
|
||||
connect(_ui->doubleSpinBox_stats_imgRate, SIGNAL(editingFinished()), this, SLOT(changeImgRateSetting()));
|
||||
connect(_ui->doubleSpinBox_stats_timeLimit, SIGNAL(editingFinished()), this, SLOT(changeTimeLimitSetting()));
|
||||
connect(this, SIGNAL(imgRateChanged(double)), _preferencesDialog, SLOT(setImgRate(double)));
|
||||
connect(this, SIGNAL(timeLimitChanged(double)), _preferencesDialog, SLOT(setTimeLimit(double)));
|
||||
connect(this, SIGNAL(timeLimitChanged(float)), _preferencesDialog, SLOT(setTimeLimit(float)));
|
||||
|
||||
connect(this, SIGNAL(twistReceived(float, float, float, float, float, float, int, int)), _ui->twistWidget, SLOT(addTwist(float, float, float, float, float, float, int, int)));
|
||||
|
||||
// Statistics from the detector
|
||||
qRegisterMetaType<rtabmap::Statistics>("rtabmap::Statistics");
|
||||
@@ -313,7 +321,7 @@ void MainWindow::handleEvent(UEvent* anEvent)
|
||||
if(anEvent->getClassName().compare("RtabmapEvent") == 0)
|
||||
{
|
||||
RtabmapEvent * rtabmapEvent = (RtabmapEvent*)anEvent;
|
||||
const Statistics & stats = rtabmapEvent->getStats();
|
||||
Statistics stats = rtabmapEvent->getStats();
|
||||
int highestHypothesisId = int(uValue(stats.data(), Statistics::kLoopHighest_hypothesis_id(), 0.0f));
|
||||
bool rejectedHyp = bool(uValue(stats.data(), Statistics::kLoopRejectedHypothesis(), 0.0f));
|
||||
if((stats.loopClosureId() > 0 && _ui->actionPause_on_match->isChecked()) ||
|
||||
@@ -328,8 +336,23 @@ void MainWindow::handleEvent(UEvent* anEvent)
|
||||
this->pauseDetection();
|
||||
}
|
||||
}
|
||||
Statistics statsCp = stats;
|
||||
emit statsReceived(statsCp);
|
||||
|
||||
// Performance issue: don't process the pdf and likelihood if the last event is
|
||||
// not yet completely processed, to avoid an unresponsive GUI when events accumulate.
|
||||
if(_processingStatistics || !_ui->dockWidget_posterior->isVisible())
|
||||
{
|
||||
stats.setPosterior(std::map<int, float>());
|
||||
}
|
||||
if(_processingStatistics || !_ui->dockWidget_likelihood->isVisible())
|
||||
{
|
||||
stats.setLikelihood(std::map<int, float>());
|
||||
}
|
||||
if(_processingStatistics || (!_ui->dockWidget_posterior->isVisible() && !_ui->dockWidget_likelihood->isVisible()))
|
||||
{
|
||||
stats.setWeights(std::map<int,int>());
|
||||
}
|
||||
|
||||
emit statsReceived(stats);
|
||||
}
|
||||
else if(anEvent->getClassName().compare("RtabmapEventInit") == 0)
|
||||
{
|
||||
@@ -368,10 +391,45 @@ void MainWindow::handleEvent(UEvent* anEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(anEvent->getClassName().compare("SMStateEvent") == 0)
|
||||
{
|
||||
SMStateEvent * smEvent = (SMStateEvent*)anEvent;
|
||||
if(smEvent->getSMState() != 0)
|
||||
{
|
||||
const SMState * sm = smEvent->getSMState();
|
||||
if(sm->getActuators().size())
|
||||
{
|
||||
const std::list<std::vector<float> > & actions = sm->getActuators();
|
||||
int col = 0;
|
||||
for(std::list<std::vector<float> >::const_iterator iter=actions.begin(); iter!=actions.end(); ++iter)
|
||||
{
|
||||
const std::vector<float> & a = *iter;
|
||||
if(a.size() == 6)
|
||||
{
|
||||
//Assume its a twist
|
||||
emit twistReceived(a[0], a[1], a[2], a[3], a[4], a[5], 0, col++);
|
||||
}
|
||||
}
|
||||
if(col != 2)
|
||||
{
|
||||
UWARN("col (%d) != 2", col);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UDEBUG("Actions null");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UDEBUG("SMState is null...");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::processStats(const rtabmap::Statistics & stat)
|
||||
{
|
||||
_processingStatistics = true;
|
||||
ULOGGER_DEBUG("");
|
||||
QTime time;
|
||||
time.start();
|
||||
@@ -414,6 +472,23 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
||||
_ui->imageView_source->scene()->addPixmap(refPixmap)->setVisible(this->_ui->imageView_source->isImageShown());
|
||||
_ui->imageView_source->setSceneRect(sceneRect);
|
||||
_ui->imageView_loopClosure->setSceneRect(sceneRect);
|
||||
|
||||
UDEBUG("Adding mask = %d", stat.refMotionMask().size());
|
||||
if(stat.refMotionMask().size() == (unsigned int)img.width()*img.height())
|
||||
{
|
||||
UDEBUG("Adding mask");
|
||||
const std::vector<unsigned char> & maskData = stat.refMotionMask();
|
||||
QImage mask(img.size(), QImage::Format_ARGB32);
|
||||
int i=0;
|
||||
for(int y=0; y<mask.height(); ++y)
|
||||
{
|
||||
for(int x=0; x<mask.width(); ++x)
|
||||
{
|
||||
mask.setPixel(x,y,qRgba(255,0,255,!maskData[i++]*_preferencesDialog->getKeypointsOpacity()));
|
||||
}
|
||||
}
|
||||
_ui->imageView_source->scene()->addPixmap(QPixmap::fromImage(mask));
|
||||
}
|
||||
}
|
||||
ULOGGER_DEBUG("");
|
||||
QImage lcImg;
|
||||
@@ -463,9 +538,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
||||
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(color));
|
||||
_ui->label_stats_loopClosuresRejected->setText(QString::number(_ui->label_stats_loopClosuresRejected->text().toInt() + 1));
|
||||
_ui->label_matchId->setText(QString("Loop hypothesis (%1) rejected!").arg(highestHypothesisId));
|
||||
QGraphicsTextItem * textItem = _ui->imageView_loopClosure->scene()->addText(tr("Rejected hypothesis"));
|
||||
textItem->setDefaultTextColor(QColor(255-color.red(), 255-color.green(), 255-color.blue())); // color inverted
|
||||
textItem->setZValue(2);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -496,10 +568,22 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
||||
if(!lcImg.isNull())
|
||||
{
|
||||
_ui->imageView_loopClosure->scene()->addPixmap(QPixmap::fromImage(lcImg))->setVisible(this->_ui->imageView_loopClosure->isImageShown());
|
||||
}
|
||||
if(highestHypothesisIsSaved)
|
||||
{
|
||||
_ui->label_matchId->setText(QString("[Retrieved!] ").append(_ui->label_matchId->text()));
|
||||
UDEBUG("Adding mask = %d", stat.loopMotionMask().size());
|
||||
if(stat.loopMotionMask().size() == (unsigned int)lcImg.width()*lcImg.height())
|
||||
{
|
||||
UDEBUG("Adding mask");
|
||||
const std::vector<unsigned char> & maskData = stat.loopMotionMask();
|
||||
QImage mask(lcImg.size(), QImage::Format_ARGB32);
|
||||
int i=0;
|
||||
for(int y=0; y<mask.height(); ++y)
|
||||
{
|
||||
for(int x=0; x<mask.width(); ++x)
|
||||
{
|
||||
mask.setPixel(x,y,qRgba(255,0,255,!maskData[i++]*_preferencesDialog->getKeypointsOpacity()));
|
||||
}
|
||||
}
|
||||
_ui->imageView_loopClosure->scene()->addPixmap(QPixmap::fromImage(mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -534,6 +618,8 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
||||
_ui->statsToolBox->updateStat("Keypoint/Keypoints count in the last signature/", stat.refImageId(), stat.refWords().size());
|
||||
_ui->statsToolBox->updateStat("Keypoint/Keypoints count in the loop signature/", stat.refImageId(), stat.loopWords().size());
|
||||
ULOGGER_DEBUG("");
|
||||
|
||||
// PDF AND LIKELIHOOD
|
||||
if(!stat.posterior().empty() && _ui->dockWidget_posterior->isVisible())
|
||||
{
|
||||
ULOGGER_DEBUG("");
|
||||
@@ -570,6 +656,30 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
||||
ULOGGER_DEBUG("");
|
||||
}
|
||||
|
||||
// ACTIONS
|
||||
if(stat.getActions().size())
|
||||
{
|
||||
const std::list<std::vector<float> > & actions = stat.getActions();
|
||||
int col = 0;
|
||||
for(std::list<std::vector<float> >::const_iterator iter=actions.begin(); iter!=actions.end(); ++iter)
|
||||
{
|
||||
const std::vector<float> & a = *iter;
|
||||
if(a.size() == 6)
|
||||
{
|
||||
//Assume its a twist
|
||||
emit twistReceived(a[0], a[1], a[2], a[3], a[4], a[5], 1, col++);
|
||||
}
|
||||
}
|
||||
if(col != 2)
|
||||
{
|
||||
UERROR("col (%d) != 2", col);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UDEBUG("Actions are empty...");
|
||||
}
|
||||
|
||||
ULOGGER_DEBUG("");
|
||||
// Update statistics tool box
|
||||
const std::map<std::string, float> & statistics = stat.data();
|
||||
@@ -591,6 +701,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
||||
_ui->statsToolBox->updateStat("/Gui refresh stats/ms", stat.refImageId(), elapsedTime);
|
||||
|
||||
this->captureScreen();
|
||||
_processingStatistics = false;
|
||||
}
|
||||
|
||||
void MainWindow::processRtabmapEventInit(int status, const QString & info)
|
||||
@@ -607,10 +718,6 @@ void MainWindow::processRtabmapEventInit(int status, const QString & info)
|
||||
else if((RtabmapEventInit::Status)status == RtabmapEventInit::kInitialized)
|
||||
{
|
||||
_initProgressDialog->setValue(_initProgressDialog->maximumSteps());
|
||||
if(_state == kPaused)
|
||||
{
|
||||
this->pauseDetection();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -653,7 +760,11 @@ void MainWindow::applyPrefSettings(PreferencesDialog::PANEL_FLAGS flags)
|
||||
this->updateSelectSourceMenu(_preferencesDialog->getSourceType());
|
||||
_ui->label_stats_source->setText(_selectSourceGrp->checkedAction()->text().replace('.', ""));
|
||||
|
||||
this->post(new CameraEvent(CameraEvent::kCmdChangeParam, _preferencesDialog->getGeneralImageRate(), _preferencesDialog->getGeneralAutoRestart()));
|
||||
if(_camera)
|
||||
{
|
||||
_camera->setImageRate(_preferencesDialog->getGeneralImageRate());
|
||||
_camera->setAutoRestart(_preferencesDialog->getGeneralAutoRestart());
|
||||
}
|
||||
}
|
||||
|
||||
if(flags & PreferencesDialog::kPanelGeneral)
|
||||
@@ -676,6 +787,7 @@ void MainWindow::applyPrefSettings(const rtabmap::ParametersMap & parameters)
|
||||
rtabmap::ParametersMap parametersModified = parameters;
|
||||
if(parametersModified.erase(Parameters::kRtabmapWorkingDirectory()))
|
||||
{
|
||||
_ui->statsToolBox->setWorkingDirectory(_preferencesDialog->getWorkingDirectory());
|
||||
if(_state == kMonitoring)
|
||||
{
|
||||
QMessageBox::information(this, tr("Working memory changed"), tr("The remote working directory can't be changed while the interface is in monitoring mode."));
|
||||
@@ -843,7 +955,7 @@ void MainWindow::changeImgRateSetting()
|
||||
|
||||
void MainWindow::changeTimeLimitSetting()
|
||||
{
|
||||
emit timeLimitChanged(_ui->doubleSpinBox_stats_timeLimit->value());
|
||||
emit timeLimitChanged((float)_ui->doubleSpinBox_stats_timeLimit->value());
|
||||
}
|
||||
|
||||
void MainWindow::captureScreen()
|
||||
@@ -916,7 +1028,7 @@ void MainWindow::startDetection()
|
||||
{
|
||||
_camera = new CameraDatabase(
|
||||
_preferencesDialog->getSourceDatabasePath().toStdString(),
|
||||
_preferencesDialog->getSourceDatabaseIgnoreChildren(),
|
||||
_preferencesDialog->getSourceDatabaseLoadActions(),
|
||||
_preferencesDialog->getGeneralImageRate(),
|
||||
_preferencesDialog->getGeneralAutoRestart(),
|
||||
_preferencesDialog->getSourceWidth(),
|
||||
@@ -941,7 +1053,10 @@ void MainWindow::startDetection()
|
||||
return;
|
||||
}
|
||||
|
||||
_camera->setPostThreatement(new CamKeypointTreatment(_preferencesDialog->getAllParameters()));
|
||||
if(_preferencesDialog->getGeneralCameraKeypoints())
|
||||
{
|
||||
_camera->setPostThreatement(new CamKeypointTreatment(_preferencesDialog->getAllParameters()));
|
||||
}
|
||||
|
||||
if(!_camera->init())
|
||||
{
|
||||
@@ -966,14 +1081,23 @@ void MainWindow::startDetection()
|
||||
|
||||
void MainWindow::pauseDetection()
|
||||
{
|
||||
ULOGGER_DEBUG("");
|
||||
this->post(new CameraEvent(CameraEvent::kCmdPause));
|
||||
emit stateChanged(kPaused);
|
||||
if(_camera)
|
||||
{
|
||||
if(_state == kPaused)
|
||||
{
|
||||
// On Ctrl-click, start the camera and pause it automatically
|
||||
if(QApplication::keyboardModifiers() & Qt::ShiftModifier)
|
||||
{
|
||||
emit stateChanged(kPaused);
|
||||
}
|
||||
}
|
||||
emit stateChanged(kPaused);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::stopDetection()
|
||||
{
|
||||
if(_state == kIdle)
|
||||
if(_state == kIdle || !_camera)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -991,8 +1115,7 @@ void MainWindow::stopDetection()
|
||||
if(_camera)
|
||||
{
|
||||
UEventsManager::removeHandler(_camera);
|
||||
//_camera->killSafely();
|
||||
|
||||
_camera->join(true);
|
||||
delete _camera;
|
||||
_camera = 0;
|
||||
emit stateChanged(kIdle);
|
||||
@@ -1268,6 +1391,7 @@ void MainWindow::changeState(MainWindow::State newState)
|
||||
_ui->actionOpen_working_directory->setEnabled(true);
|
||||
_ui->actionApply_settings_to_the_detector->setEnabled(true);
|
||||
_ui->menuSelect_source->setEnabled(true);
|
||||
_ui->doubleSpinBox_stats_imgRate->setEnabled(true);
|
||||
_ui->statusbar->clearMessage();
|
||||
_state = newState;
|
||||
_oneSecondTimer->stop();
|
||||
@@ -1313,6 +1437,10 @@ void MainWindow::changeState(MainWindow::State newState)
|
||||
_state = kDetecting;
|
||||
_elapsedTime->start();
|
||||
_oneSecondTimer->start();
|
||||
if(_camera)
|
||||
{
|
||||
_camera->start();
|
||||
}
|
||||
}
|
||||
else if(_state == kDetecting)
|
||||
{
|
||||
@@ -1325,6 +1453,10 @@ void MainWindow::changeState(MainWindow::State newState)
|
||||
_ui->actionGenerate_map->setEnabled(true);
|
||||
_state = kPaused;
|
||||
_oneSecondTimer->stop();
|
||||
if(_camera)
|
||||
{
|
||||
_camera->join(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kMonitoring:
|
||||
@@ -1342,6 +1474,7 @@ void MainWindow::changeState(MainWindow::State newState)
|
||||
_ui->actionOpen_working_directory->setEnabled(false);
|
||||
_ui->actionApply_settings_to_the_detector->setEnabled(false);
|
||||
_ui->menuSelect_source->setEnabled(false);
|
||||
_ui->doubleSpinBox_stats_imgRate->setEnabled(false);
|
||||
_ui->statusbar->showMessage(tr("Monitoring..."));
|
||||
_state = newState;
|
||||
_ui->label_elapsedTime->setText("00:00:00");
|
||||
|
||||
@@ -119,7 +119,7 @@ void PdfPlotCurve::setData(const QMap<int, float> & dataMap, const QMap<int, int
|
||||
UDEBUG("margin=%d", margin);
|
||||
while(margin < 0)
|
||||
{
|
||||
PdfPlotItem * newItem = new PdfPlotItem(0, 0, -1);
|
||||
PdfPlotItem * newItem = new PdfPlotItem(0, 0, 2, 0);
|
||||
newItem->setImagesRef(_imagesMapRef);
|
||||
this->_addValue(newItem);
|
||||
++margin;
|
||||
|
||||
@@ -138,7 +138,6 @@ void PlotItem::setPreviousItem(PlotItem * previousItem)
|
||||
|
||||
void PlotItem::showDescription(bool shown)
|
||||
{
|
||||
ULOGGER_DEBUG("");
|
||||
if(shown)
|
||||
{
|
||||
this->setPen(QPen(Qt::black, 2));
|
||||
@@ -313,7 +312,7 @@ void PlotCurve::attach(Plot * plot)
|
||||
_plot = plot;
|
||||
for(int i=0; i<_items.size(); ++i)
|
||||
{
|
||||
_plot->scene()->addItem(_items.at(i));
|
||||
_plot->addItem(_items.at(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,14 +384,13 @@ void PlotCurve::_addValue(PlotItem * data)
|
||||
{
|
||||
data->setPreviousItem((PlotItem *)_items.last());
|
||||
|
||||
//apply scale
|
||||
QGraphicsLineItem * line = new QGraphicsLineItem();
|
||||
line->setPen(_pen);
|
||||
line->setVisible(false);
|
||||
_items.append(line);
|
||||
if(_plot)
|
||||
{
|
||||
_plot->scene()->addItem(line);
|
||||
_plot->addItem(line);
|
||||
}
|
||||
|
||||
//Update min/max
|
||||
@@ -413,7 +411,7 @@ void PlotCurve::_addValue(PlotItem * data)
|
||||
//data->showDescription(_valuesShown);
|
||||
if(_plot)
|
||||
{
|
||||
_plot->scene()->addItem(_items.last());
|
||||
_plot->addItem(_items.last());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -604,7 +602,7 @@ void PlotCurve::setBrush(const QBrush & brush)
|
||||
ULOGGER_WARN("Not used...");
|
||||
}
|
||||
|
||||
void PlotCurve::update(float scaleX, float scaleY, float offsetX, float offsetY, int xDir, int yDir, bool allDataKept)
|
||||
void PlotCurve::update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, bool allDataKept)
|
||||
{
|
||||
//ULOGGER_DEBUG("scaleX=%f, scaleY=%f, offsetX=%f, offsetY=%f, xDir=%d, yDir=%d, _plot->scene()->width()=%f, _plot->scene()->height=%f", scaleX, scaleY, offsetX, offsetY, xDir, yDir,_plot->scene()->width(),_plot->scene()->height());
|
||||
//make sure direction values are 1 or -1
|
||||
@@ -636,14 +634,14 @@ void PlotCurve::update(float scaleX, float scaleY, float offsetX, float offsetY,
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setPos(((xDir*item->data().x()+offsetX)*scaleX-item->rect().width()/2),
|
||||
((yDir*item->data().y()+offsetY)*scaleY-item->rect().width()/2));
|
||||
QPointF newPos(((xDir*item->data().x()+offsetX)*scaleX-item->rect().width()/2.0f),
|
||||
((yDir*item->data().y()+offsetY)*scaleY-item->rect().width()/2.0f));
|
||||
if(!item->isVisible())
|
||||
{
|
||||
item->setVisible(true);
|
||||
}
|
||||
item->setPos(newPos);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -679,7 +677,44 @@ void PlotCurve::update(float scaleX, float scaleY, float offsetX, float offsetY,
|
||||
|
||||
}
|
||||
|
||||
int PlotCurve::itemsSize()
|
||||
void PlotCurve::draw(QPainter * painter)
|
||||
{
|
||||
if(painter)
|
||||
{
|
||||
for(int i=_items.size()-1; i>=0 && _items.at(i)->isVisible(); i-=2)
|
||||
{
|
||||
//plotItem
|
||||
const PlotItem * item = (const PlotItem *)_items.at(i);
|
||||
int x = (int)item->x();
|
||||
if(x<0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// draw line in first
|
||||
if(i-1>=0)
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen(this->pen());
|
||||
painter->setBrush(this->brush());
|
||||
//lineItem
|
||||
const QGraphicsLineItem * item = (const QGraphicsLineItem *)_items.at(i-1);
|
||||
QLineF line = item->line();
|
||||
int x = (int)line.p1().x();
|
||||
if(x<0)
|
||||
{
|
||||
line.setP1(QPoint(0, line.p1().y()));
|
||||
}
|
||||
painter->drawLine(line);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
painter->drawEllipse(item->pos()+QPointF(item->rect().width()/2, item->rect().height()/2), (int)item->rect().width()/2, (int)item->rect().height()/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int PlotCurve::itemsSize() const
|
||||
{
|
||||
return _items.size();
|
||||
}
|
||||
@@ -822,7 +857,7 @@ void ThresholdCurve::setOrientation(Qt::Orientation orientation)
|
||||
}
|
||||
}
|
||||
|
||||
void ThresholdCurve::update(float scaleX, float scaleY, float offsetX, float offsetY, int xDir, int yDir, bool allDataKept)
|
||||
void ThresholdCurve::update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, bool allDataKept)
|
||||
{
|
||||
if(_items.size() == 3)
|
||||
{
|
||||
@@ -835,14 +870,14 @@ void ThresholdCurve::update(float scaleX, float scaleY, float offsetX, float off
|
||||
item = (PlotItem*)_items.at(0);
|
||||
item->setData(QPointF(-offsetX/xDir, item->data().y()));
|
||||
item = (PlotItem*)_items.at(2);
|
||||
item->setData(QPointF( (_plot->scene()->width()/scaleX-offsetX)/xDir, item->data().y()));
|
||||
item->setData(QPointF( (_plot->sceneRect().width()/scaleX-offsetX)/xDir, item->data().y()));
|
||||
}
|
||||
else
|
||||
{
|
||||
item = (PlotItem*)_items.at(0);
|
||||
item->setData(QPointF(item->data().x(), -offsetY/yDir));
|
||||
item = (PlotItem*)_items.at(2);
|
||||
item->setData(QPointF(item->data().x(), (_plot->scene()->height()/scaleY-offsetY)/yDir));
|
||||
item->setData(QPointF(item->data().x(), (_plot->sceneRect().height()/scaleY-offsetY)/yDir));
|
||||
}
|
||||
this->updateMinMax();
|
||||
}
|
||||
@@ -954,23 +989,23 @@ void PlotAxis::setAxis(float & min, float & max)
|
||||
if(min != max)
|
||||
{
|
||||
float mul = 1;
|
||||
float rangef = fabsf(max - min);
|
||||
float rangef = max - min;
|
||||
int countStep = _count/5;
|
||||
float val;
|
||||
for(int i=0; i<6; ++i)
|
||||
{
|
||||
val = (rangef/countStep) * mul;
|
||||
if( val >= 1 && val < 10)
|
||||
val = (rangef/float(countStep)) * mul;
|
||||
if( val >= 1.0f && val < 10.0f)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if(val<1)
|
||||
{
|
||||
mul *= 10;
|
||||
mul *= 10.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
mul /= 10;
|
||||
mul /= 10.0f;
|
||||
}
|
||||
}
|
||||
//ULOGGER_DEBUG("min=%f, max=%f", min, max);
|
||||
@@ -1187,6 +1222,7 @@ void PlotLegend::addItem(const PlotCurve * curve)
|
||||
if(curve)
|
||||
{
|
||||
PlotLegendItem * legendItem = new PlotLegendItem(curve, this);
|
||||
legendItem->setAutoDefault(false);
|
||||
legendItem->setFlat(_flat);
|
||||
legendItem->setCheckable(true);
|
||||
legendItem->setChecked(false);
|
||||
@@ -1194,7 +1230,7 @@ void PlotLegend::addItem(const PlotCurve * curve)
|
||||
legendItem->setIconSize(QSize(25,20));
|
||||
connect(legendItem, SIGNAL(toggled(bool)), this, SLOT(redirectToggled(bool)));
|
||||
connect(legendItem, SIGNAL(legendItemRemoved(const PlotCurve *)), this, SLOT(removeLegendItem(const PlotCurve *)));
|
||||
|
||||
|
||||
// layout
|
||||
QHBoxLayout * hLayout = new QHBoxLayout();
|
||||
hLayout->addWidget(legendItem);
|
||||
@@ -1218,7 +1254,7 @@ QPixmap PlotLegend::createSymbol(const QPen & pen, const QBrush & brush)
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
void PlotLegend::removeLegendItem(const PlotCurve * curve)
|
||||
bool PlotLegend::remove(const PlotCurve * curve)
|
||||
{
|
||||
QList<PlotLegendItem *> items = this->findChildren<PlotLegendItem*>();
|
||||
for(int i=0; i<items.size(); ++i)
|
||||
@@ -1226,9 +1262,18 @@ void PlotLegend::removeLegendItem(const PlotCurve * curve)
|
||||
if(items.at(i)->curve() == curve)
|
||||
{
|
||||
delete items.at(i);
|
||||
emit legendItemRemoved(curve);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PlotLegend::removeLegendItem(const PlotCurve * curve)
|
||||
{
|
||||
if(this->remove(curve))
|
||||
{
|
||||
emit legendItemRemoved(curve);
|
||||
}
|
||||
}
|
||||
|
||||
void PlotLegend::contextMenuEvent(QContextMenuEvent * event)
|
||||
@@ -1342,6 +1387,7 @@ Plot::Plot(QWidget *parent) :
|
||||
|
||||
// This will update actions
|
||||
this->showLegend(true);
|
||||
this->setGraphicsView(false);
|
||||
this->setMaxVisibleItems(0);
|
||||
this->showGrid(false);
|
||||
this->showRefreshRate(false);
|
||||
@@ -1367,12 +1413,9 @@ Plot::Plot(QWidget *parent) :
|
||||
|
||||
Plot::~Plot()
|
||||
{
|
||||
_aAutoScreenCapture->setChecked(false);
|
||||
ULOGGER_DEBUG("%s", this->title().toStdString().c_str());
|
||||
QList<PlotCurve*> curves = _curves.values();
|
||||
for(int i=0; i<curves.size(); ++i)
|
||||
{
|
||||
this->removeCurve(curves.at(i));
|
||||
}
|
||||
this->removeCurves();
|
||||
}
|
||||
|
||||
void Plot::setupUi()
|
||||
@@ -1382,6 +1425,11 @@ void Plot::setupUi()
|
||||
_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
_view->setScene(new QGraphicsScene(0,0,0,0,this));
|
||||
_view->setStyleSheet( "QGraphicsView { border-style: none; }" );
|
||||
_sceneRoot = _view->scene()->addText("");
|
||||
_sceneRoot->translate(0,0);
|
||||
_graphicsViewHolder = new QWidget(this);
|
||||
_graphicsViewHolder->setMinimumSize(100,100);
|
||||
_verticalAxis = new PlotAxis(Qt::Vertical, 0, 1, this);
|
||||
_horizontalAxis = new PlotAxis(Qt::Horizontal, 0, 1, this);
|
||||
_title = new QLabel("");
|
||||
@@ -1402,18 +1450,23 @@ void Plot::setupUi()
|
||||
_refreshRate->setVisible(false);
|
||||
|
||||
//layouts
|
||||
QGridLayout * grid = new QGridLayout();
|
||||
QVBoxLayout * vLayout = new QVBoxLayout(_graphicsViewHolder);
|
||||
vLayout->setContentsMargins(0,0,0,0);
|
||||
vLayout->addWidget(_view);
|
||||
|
||||
QGridLayout * grid = new QGridLayout(this);
|
||||
grid->setContentsMargins(0,0,0,0);
|
||||
this->setLayout(grid);
|
||||
grid->addWidget(_title, 0, 2);
|
||||
grid->addWidget(_yLabel, 1, 0);
|
||||
grid->addWidget(_verticalAxis, 1, 1);
|
||||
grid->addWidget(_refreshRate, 2, 1);
|
||||
grid->addWidget(_view, 1, 2);
|
||||
grid->addWidget(_graphicsViewHolder, 1, 2);
|
||||
grid->setColumnStretch(2, 1);
|
||||
grid->setRowStretch(1, 1);
|
||||
grid->addWidget(_horizontalAxis, 2, 2);
|
||||
grid->addWidget(_xLabel, 3, 2);
|
||||
grid->addWidget(_legend, 1, 3);
|
||||
|
||||
connect(_legend, SIGNAL(legendItemToggled(const PlotCurve *, bool)), this, SLOT(showCurve(const PlotCurve *, bool)));
|
||||
connect(_legend, SIGNAL(legendItemRemoved(const PlotCurve *)), this, SLOT(removeCurve(const PlotCurve *)));
|
||||
}
|
||||
@@ -1426,6 +1479,8 @@ void Plot::createActions()
|
||||
_aShowGrid->setCheckable(true);
|
||||
_aShowRefreshRate = new QAction(tr("Show refresh rate"), this);
|
||||
_aShowRefreshRate->setCheckable(true);
|
||||
_aGraphicsView = new QAction(tr("Graphics view"), this);
|
||||
_aGraphicsView->setCheckable(true);
|
||||
_aKeepAllData = new QAction(tr("Keep all data"), this);
|
||||
_aKeepAllData->setCheckable(true);
|
||||
_aLimit0 = new QAction(tr("No maximum items shown"), this);
|
||||
@@ -1473,6 +1528,7 @@ void Plot::createMenus()
|
||||
_menu->addAction(_aShowLegend);
|
||||
_menu->addAction(_aShowGrid);
|
||||
_menu->addAction(_aShowRefreshRate);
|
||||
_menu->addAction(_aGraphicsView);
|
||||
_menu->addAction(_aKeepAllData);
|
||||
_menu->addSeparator()->setStatusTip(tr("Maximum items shown"));
|
||||
_menu->addAction(_aLimit0);
|
||||
@@ -1516,18 +1572,31 @@ bool Plot::addCurve(PlotCurve * curve)
|
||||
{
|
||||
if(curve)
|
||||
{
|
||||
// only last curve can trigger an update, so disable previous connections
|
||||
if(!qobject_cast<ThresholdCurve*>(curve))
|
||||
{
|
||||
for(int i=_curves.size()-1; i>=0; --i)
|
||||
{
|
||||
if(!qobject_cast<ThresholdCurve*>(_curves.at(i)))
|
||||
{
|
||||
disconnect(_curves.at(i), SIGNAL(dataChanged(const PlotCurve *)), this, SLOT(updateAxis()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add curve
|
||||
_curves.insert(curve, curve);
|
||||
_curves.append(curve);
|
||||
curve->attach(this); // ownership is transferred
|
||||
this->updateAxis(curve);
|
||||
curve->setStartX(_axisMaximums[1]);
|
||||
|
||||
connect(curve, SIGNAL(dataChanged(const PlotCurve *)), this, SLOT(updateAxis()));
|
||||
|
||||
_legend->addItem(curve);
|
||||
|
||||
ULOGGER_DEBUG("Curve \"%s\" added to plot \"%s\"", curve->name().toStdString().c_str(), this->title().toStdString().c_str());
|
||||
|
||||
this->update();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -1540,7 +1609,7 @@ bool Plot::addCurve(PlotCurve * curve)
|
||||
QStringList Plot::curveNames()
|
||||
{
|
||||
QStringList names;
|
||||
for(QMap<const PlotCurve*, PlotCurve*>::iterator iter = _curves.begin(); iter!=_curves.end(); ++iter)
|
||||
for(QList<PlotCurve*>::iterator iter = _curves.begin(); iter!=_curves.end(); ++iter)
|
||||
{
|
||||
if(*iter)
|
||||
{
|
||||
@@ -1552,7 +1621,7 @@ QStringList Plot::curveNames()
|
||||
|
||||
bool Plot::contains(const QString & curveName)
|
||||
{
|
||||
for(QMap<const PlotCurve*, PlotCurve*>::iterator iter = _curves.begin(); iter!=_curves.end(); ++iter)
|
||||
for(QList<PlotCurve*>::iterator iter = _curves.begin(); iter!=_curves.end(); ++iter)
|
||||
{
|
||||
if(*iter && (*iter)->name().compare(curveName) == 0)
|
||||
{
|
||||
@@ -1567,15 +1636,14 @@ QPen Plot::getRandomPenColored()
|
||||
return QPen((Qt::GlobalColor)(_penStyleCount++ % 12 + 7 ));
|
||||
}
|
||||
|
||||
void Plot::replot()
|
||||
void Plot::replot(QPainter * painter)
|
||||
{
|
||||
QList<PlotCurve *> curves = _curves.values();
|
||||
if(_maxVisibleItems>0)
|
||||
{
|
||||
PlotCurve * c = 0;
|
||||
int maxItem = 0;
|
||||
// find the curve with the most items
|
||||
for(QList<PlotCurve *>::iterator i=curves.begin(); i!=curves.end(); ++i)
|
||||
for(QList<PlotCurve *>::iterator i=_curves.begin(); i!=_curves.end(); ++i)
|
||||
{
|
||||
if((*i)->isVisible() && ((PlotCurve *)(*i))->itemsSize() > maxItem)
|
||||
{
|
||||
@@ -1597,43 +1665,18 @@ void Plot::replot()
|
||||
|
||||
_verticalAxis->setAxis(axis[2], axis[3]);
|
||||
_horizontalAxis->setAxis(axis[0], axis[1]);
|
||||
if(_aGraphicsView->isChecked() && !painter)
|
||||
{
|
||||
_verticalAxis->update();
|
||||
_horizontalAxis->update();
|
||||
}
|
||||
|
||||
//ULOGGER_DEBUG("x1=%f, x2=%f, y1=%f, y2=%f", _axisMaximums[0], _axisMaximums[1], _axisMaximums[2], _axisMaximums[3]);
|
||||
|
||||
QRectF newRect(0,0, _view->size().width(), _view->size().height());
|
||||
QRectF newRect(0,0, _graphicsViewHolder->size().width(), _graphicsViewHolder->size().height());
|
||||
_view->scene()->setSceneRect(newRect);
|
||||
int borderHor = _horizontalAxis->border();
|
||||
int borderVer = _verticalAxis->border();
|
||||
|
||||
float scaleX = 1;
|
||||
float scaleY = 1;
|
||||
float den = 0;
|
||||
den = axis[1] - axis[0];
|
||||
if(den != 0)
|
||||
{
|
||||
scaleX = (_view->sceneRect().width()-(borderHor*2)) / den;
|
||||
}
|
||||
den = axis[3] - axis[2];
|
||||
if(den != 0)
|
||||
{
|
||||
scaleY = (_view->sceneRect().height()-(borderVer*2)) / den;
|
||||
}
|
||||
|
||||
for(QList<PlotCurve *>::iterator i=curves.begin(); i!=curves.end(); ++i)
|
||||
{
|
||||
if((*i)->isVisible())
|
||||
{
|
||||
int xDir = 1;
|
||||
int yDir = -1;
|
||||
(*i)->update(scaleX,
|
||||
scaleY,
|
||||
xDir<0?axis[1]+float(borderHor-2)/scaleX:-(axis[0]-float(borderHor-2)/scaleX),
|
||||
yDir<0?axis[3]+float(borderVer-2)/scaleY:-(axis[2]-float(borderVer-2)/scaleY),
|
||||
xDir,
|
||||
yDir,
|
||||
_aKeepAllData->isChecked());
|
||||
}
|
||||
}
|
||||
float borderHor = (float)_horizontalAxis->border();
|
||||
float borderVer = (float)_verticalAxis->border();
|
||||
|
||||
//grid
|
||||
qDeleteAll(hGridLines);
|
||||
@@ -1642,27 +1685,91 @@ void Plot::replot()
|
||||
vGridLines.clear();
|
||||
if(_aShowGrid->isChecked())
|
||||
{
|
||||
borderHor-=2;
|
||||
borderVer-=2;
|
||||
// TODO make a PlotGrid class ?
|
||||
int w = _view->sceneRect().width()-(borderHor*2);
|
||||
int h = _view->sceneRect().height()-(borderVer*2);
|
||||
float stepH = w / _horizontalAxis->count();
|
||||
float stepV = h / _verticalAxis->count();
|
||||
float w = newRect.width()-(borderHor*2);
|
||||
float h = newRect.height()-(borderVer*2);
|
||||
float stepH = w / float(_horizontalAxis->count());
|
||||
float stepV = h / float(_verticalAxis->count());
|
||||
QPen pen(Qt::DashLine);
|
||||
for(int i=0; i*stepV < h+stepV; i+=5)
|
||||
for(float i=0.0f; i*stepV <= h+stepV; i+=5.0f)
|
||||
{
|
||||
//horizontal lines
|
||||
hGridLines.append(_view->scene()->addLine(0, stepV*i+borderVer, borderHor, stepV*i+borderVer));
|
||||
hGridLines.append(_view->scene()->addLine(borderHor, stepV*i+borderVer, w+borderHor, stepV*i+borderVer, pen));
|
||||
hGridLines.append(_view->scene()->addLine(w+borderHor, stepV*i+borderVer, w+borderHor*2, stepV*i+borderVer));
|
||||
if(!_aGraphicsView->isChecked())
|
||||
{
|
||||
if(painter)
|
||||
{
|
||||
painter->drawLine(0, stepV*i+borderVer+0.5f, borderHor, stepV*i+borderVer+0.5f);
|
||||
painter->save();
|
||||
painter->setPen(pen);
|
||||
painter->drawLine(borderHor, stepV*i+borderVer+0.5f, w+borderHor, stepV*i+borderVer+0.5f);
|
||||
painter->restore();
|
||||
painter->drawLine(w+borderHor, stepV*i+borderVer+0.5f, w+borderHor*2, stepV*i+borderVer+0.5f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hGridLines.append(new QGraphicsLineItem(0, stepV*i+borderVer, borderHor, stepV*i+borderVer, _sceneRoot));
|
||||
hGridLines.append(new QGraphicsLineItem(borderHor, stepV*i+borderVer, w+borderHor, stepV*i+borderVer, _sceneRoot));
|
||||
hGridLines.last()->setPen(pen);
|
||||
hGridLines.append(new QGraphicsLineItem(w+borderHor, stepV*i+borderVer, w+borderHor*2, stepV*i+borderVer, _sceneRoot));
|
||||
}
|
||||
}
|
||||
for(int i=0; i*stepH < w+stepH; i+=5)
|
||||
for(float i=0; i*stepH < w+stepH; i+=5.0f)
|
||||
{
|
||||
//vertical lines
|
||||
vGridLines.append(_view->scene()->addLine(stepH*i+borderHor, 0, stepH*i+borderHor, borderVer));
|
||||
vGridLines.append(_view->scene()->addLine(stepH*i+borderHor, borderVer, stepH*i+borderHor, h+borderVer, pen));
|
||||
vGridLines.append(_view->scene()->addLine(stepH*i+borderHor, h+borderVer, stepH*i+borderHor, h+borderVer*2));
|
||||
if(!_aGraphicsView->isChecked())
|
||||
{
|
||||
if(painter)
|
||||
{
|
||||
painter->drawLine(stepH*i+borderHor+0.5f, 0, stepH*i+borderHor+0.5f, borderVer);
|
||||
painter->save();
|
||||
painter->setPen(pen);
|
||||
painter->drawLine(stepH*i+borderHor+0.5f, borderVer, stepH*i+borderHor+0.5f, h+borderVer);
|
||||
painter->restore();
|
||||
painter->drawLine(stepH*i+borderHor+0.5f, h+borderVer, stepH*i+borderHor+0.5f, h+borderVer*2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vGridLines.append(new QGraphicsLineItem(stepH*i+borderHor, 0, stepH*i+borderHor, borderVer, _sceneRoot));
|
||||
vGridLines.append(new QGraphicsLineItem(stepH*i+borderHor, borderVer, stepH*i+borderHor, h+borderVer, _sceneRoot));
|
||||
vGridLines.last()->setPen(pen);
|
||||
vGridLines.append(new QGraphicsLineItem(stepH*i+borderHor, h+borderVer, stepH*i+borderHor, h+borderVer*2, _sceneRoot));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// curves
|
||||
float scaleX = 1;
|
||||
float scaleY = 1;
|
||||
float den = 0;
|
||||
den = axis[1] - axis[0];
|
||||
if(den != 0)
|
||||
{
|
||||
scaleX = (newRect.width()-(borderHor*2)) / den;
|
||||
}
|
||||
den = axis[3] - axis[2];
|
||||
if(den != 0)
|
||||
{
|
||||
scaleY = (newRect.height()-(borderVer*2)) / den;
|
||||
}
|
||||
for(QList<PlotCurve *>::iterator i=_curves.begin(); i!=_curves.end(); ++i)
|
||||
{
|
||||
if((*i)->isVisible())
|
||||
{
|
||||
float xDir = 1.0f;
|
||||
float yDir = -1.0f;
|
||||
(*i)->update(scaleX,
|
||||
scaleY,
|
||||
xDir<0?axis[1]+borderHor/scaleX:-(axis[0]-borderHor/scaleX),
|
||||
yDir<0?axis[3]+borderVer/scaleY:-(axis[2]-borderVer/scaleY),
|
||||
xDir,
|
||||
yDir,
|
||||
_aKeepAllData->isChecked());
|
||||
if(painter)
|
||||
{
|
||||
(*i)->draw(painter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1674,8 +1781,8 @@ void Plot::replot()
|
||||
{
|
||||
_lowestRefreshRate = refreshRate;
|
||||
}
|
||||
// Refresh the label only after each 100 ms
|
||||
if(_refreshStartTime.elapsed() > 100)
|
||||
// Refresh the label only after each 1000 ms
|
||||
if(_refreshStartTime.elapsed() > 1000)
|
||||
{
|
||||
_refreshRate->setText(QString::number(_lowestRefreshRate));
|
||||
_lowestRefreshRate = 99;
|
||||
@@ -1700,10 +1807,9 @@ void Plot::setFixedYAxis(float y1, float y2)
|
||||
|
||||
void Plot::updateAxis(const PlotCurve * curve)
|
||||
{
|
||||
PlotCurve * value = _curves.value(curve, 0);
|
||||
if(value && value->isVisible() && value->itemsSize() && value->isMinMaxValid())
|
||||
if(curve && curve->isVisible() && curve->itemsSize() && curve->isMinMaxValid())
|
||||
{
|
||||
const QVector<float> & minMax = value->getMinMax();
|
||||
const QVector<float> & minMax = curve->getMinMax();
|
||||
//ULOGGER_DEBUG("x1=%f, x2=%f, y1=%f, y2=%f", minMax[0], minMax[1], minMax[2], minMax[3]);
|
||||
if(minMax.size() != 4)
|
||||
{
|
||||
@@ -1711,7 +1817,7 @@ void Plot::updateAxis(const PlotCurve * curve)
|
||||
return;
|
||||
}
|
||||
this->updateAxis(minMax[0], minMax[1], minMax[2], minMax[3]);
|
||||
this->update();
|
||||
_aGraphicsView->isChecked()?this->replot(0):this->update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1777,25 +1883,48 @@ void Plot::updateAxis()
|
||||
}
|
||||
}
|
||||
|
||||
QList<PlotCurve*> curves = _curves.values();
|
||||
for(int i=0; i<curves.size(); ++i)
|
||||
for(int i=0; i<_curves.size(); ++i)
|
||||
{
|
||||
if(curves.at(i)->isVisible() && curves.at(i)->isMinMaxValid())
|
||||
if(_curves.at(i)->isVisible() && _curves.at(i)->isMinMaxValid())
|
||||
{
|
||||
const QVector<float> & minMax = curves.at(i)->getMinMax();
|
||||
const QVector<float> & minMax = _curves.at(i)->getMinMax();
|
||||
this->updateAxis(minMax[0], minMax[1], minMax[2], minMax[3]);
|
||||
}
|
||||
}
|
||||
|
||||
this->update();
|
||||
_aGraphicsView->isChecked()?this->replot(0):this->update();
|
||||
|
||||
this->captureScreen();
|
||||
}
|
||||
|
||||
void Plot::paintEvent(QPaintEvent * event)
|
||||
{
|
||||
this->replot();
|
||||
QWidget::paintEvent(event);
|
||||
UDEBUG("");
|
||||
if(!_aGraphicsView->isChecked())
|
||||
{
|
||||
QPainter painter(this);
|
||||
painter.translate(_graphicsViewHolder->pos());
|
||||
painter.save();
|
||||
painter.setBrush(Qt::white);
|
||||
painter.setPen(QPen(Qt::NoPen));
|
||||
painter.drawRect(_graphicsViewHolder->rect());
|
||||
painter.restore();
|
||||
|
||||
this->replot(&painter);
|
||||
}
|
||||
else
|
||||
{
|
||||
QWidget::paintEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::resizeEvent(QResizeEvent * event)
|
||||
{
|
||||
if(_aGraphicsView->isChecked())
|
||||
{
|
||||
this->replot(0);
|
||||
}
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
void Plot::contextMenuEvent(QContextMenuEvent * event)
|
||||
@@ -1818,6 +1947,10 @@ void Plot::contextMenuEvent(QContextMenuEvent * event)
|
||||
{
|
||||
this->showRefreshRate(_aShowRefreshRate->isChecked());
|
||||
}
|
||||
else if(action == _aGraphicsView)
|
||||
{
|
||||
this->setGraphicsView(_aGraphicsView->isChecked());
|
||||
}
|
||||
else if(action == _aKeepAllData)
|
||||
{
|
||||
this->keepAllData(_aKeepAllData->isChecked());
|
||||
@@ -1831,7 +1964,6 @@ void Plot::contextMenuEvent(QContextMenuEvent * event)
|
||||
action == _aLimitCustom)
|
||||
{
|
||||
this->setMaxVisibleItems(action->text().toInt());
|
||||
this->updateAxis();
|
||||
}
|
||||
else if(action == _aAddVerticalLine || action == _aAddHorizontalLine)
|
||||
{
|
||||
@@ -1982,16 +2114,7 @@ void Plot::contextMenuEvent(QContextMenuEvent * event)
|
||||
}
|
||||
else if(action == _aClearData)
|
||||
{
|
||||
QList<PlotCurve *> curves = _curves.values();
|
||||
for(int i=0; i<curves.size(); ++i)
|
||||
{
|
||||
// Don't clear threshold curves
|
||||
if(qobject_cast<ThresholdCurve*>(curves.at(i)) == 0)
|
||||
{
|
||||
curves.at(i)->clear();
|
||||
}
|
||||
}
|
||||
this->update();
|
||||
this->clearData();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2048,6 +2171,19 @@ void Plot::selectScreenCaptureFormat()
|
||||
this->captureScreen();
|
||||
}
|
||||
|
||||
void Plot::clearData()
|
||||
{
|
||||
for(int i=0; i<_curves.size(); ++i)
|
||||
{
|
||||
// Don't clear threshold curves
|
||||
if(qobject_cast<ThresholdCurve*>(_curves.at(i)) == 0)
|
||||
{
|
||||
_curves.at(i)->clear();
|
||||
}
|
||||
}
|
||||
_aGraphicsView->isChecked()?this->replot(0):this->update();
|
||||
}
|
||||
|
||||
// for convenience...
|
||||
ThresholdCurve * Plot::addThreshold(const QString & name, float value, Qt::Orientation orientation)
|
||||
{
|
||||
@@ -2064,7 +2200,7 @@ ThresholdCurve * Plot::addThreshold(const QString & name, float value, Qt::Orien
|
||||
}
|
||||
else
|
||||
{
|
||||
this->update();
|
||||
_aGraphicsView->isChecked()?this->replot(0):this->update();
|
||||
}
|
||||
return curve;
|
||||
}
|
||||
@@ -2074,6 +2210,10 @@ void Plot::setTitle(const QString & text)
|
||||
_title->setText(text);
|
||||
_title->setVisible(!text.isEmpty());
|
||||
this->update();
|
||||
if(_aGraphicsView->isChecked())
|
||||
{
|
||||
QTimer::singleShot(10, this, SLOT(updateAxis()));
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::setXLabel(const QString & text)
|
||||
@@ -2081,6 +2221,10 @@ void Plot::setXLabel(const QString & text)
|
||||
_xLabel->setText(text);
|
||||
_xLabel->setVisible(!text.isEmpty());
|
||||
this->update();
|
||||
if(_aGraphicsView->isChecked())
|
||||
{
|
||||
QTimer::singleShot(10, this, SLOT(updateAxis()));
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::setYLabel(const QString & text, Qt::Orientation orientation)
|
||||
@@ -2090,11 +2234,15 @@ void Plot::setYLabel(const QString & text, Qt::Orientation orientation)
|
||||
_yLabel->setVisible(!text.isEmpty());
|
||||
_aYLabelVertical->setChecked(orientation==Qt::Vertical);
|
||||
this->update();
|
||||
if(_aGraphicsView->isChecked())
|
||||
{
|
||||
QTimer::singleShot(10, this, SLOT(updateAxis()));
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsScene * Plot::scene() const
|
||||
void Plot::addItem(QGraphicsItem * item)
|
||||
{
|
||||
return _view->scene();
|
||||
item->setParentItem(_sceneRoot);
|
||||
}
|
||||
|
||||
void Plot::showLegend(bool shown)
|
||||
@@ -2102,12 +2250,16 @@ void Plot::showLegend(bool shown)
|
||||
_legend->setVisible(shown);
|
||||
_aShowLegend->setChecked(shown);
|
||||
this->update();
|
||||
if(_aGraphicsView->isChecked())
|
||||
{
|
||||
QTimer::singleShot(10, this, SLOT(updateAxis()));
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::showGrid(bool shown)
|
||||
{
|
||||
_aShowGrid->setChecked(shown);
|
||||
this->update();
|
||||
_aGraphicsView->isChecked()?this->replot(0):this->update();
|
||||
}
|
||||
|
||||
void Plot::showRefreshRate(bool shown)
|
||||
@@ -2115,6 +2267,17 @@ void Plot::showRefreshRate(bool shown)
|
||||
_aShowRefreshRate->setChecked(shown);
|
||||
_refreshRate->setVisible(shown);
|
||||
this->update();
|
||||
if(_aGraphicsView->isChecked())
|
||||
{
|
||||
QTimer::singleShot(10, this, SLOT(updateAxis()));
|
||||
}
|
||||
}
|
||||
|
||||
void Plot::setGraphicsView(bool on)
|
||||
{
|
||||
_aGraphicsView->setChecked(on);
|
||||
_view->setVisible(on);
|
||||
_aGraphicsView->isChecked()?this->replot(0):this->update();
|
||||
}
|
||||
|
||||
void Plot::keepAllData(bool kept)
|
||||
@@ -2155,11 +2318,17 @@ void Plot::setMaxVisibleItems(int maxVisibleItems)
|
||||
_aLimitCustom->setText(QString::number(maxVisibleItems));
|
||||
}
|
||||
_maxVisibleItems = maxVisibleItems;
|
||||
updateAxis();
|
||||
}
|
||||
|
||||
QRectF Plot::sceneRect() const
|
||||
{
|
||||
return _view->sceneRect();
|
||||
}
|
||||
|
||||
void Plot::removeCurves()
|
||||
{
|
||||
QList<PlotCurve*> tmp = _curves.values();
|
||||
QList<PlotCurve*> tmp = _curves;
|
||||
for(QList<PlotCurve*>::iterator iter=tmp.begin(); iter!=tmp.end(); ++iter)
|
||||
{
|
||||
this->removeCurve(*iter);
|
||||
@@ -2169,13 +2338,27 @@ void Plot::removeCurves()
|
||||
|
||||
void Plot::removeCurve(const PlotCurve * curve)
|
||||
{
|
||||
PlotCurve * c = _curves.value(curve, 0);
|
||||
QList<PlotCurve *>::iterator iter = qFind(_curves.begin(), _curves.end(), curve);
|
||||
ULOGGER_DEBUG("Plot=\"%s\" removing curve=\"%s\"", this->objectName().toStdString().c_str(), curve?curve->name().toStdString().c_str():"");
|
||||
if(c)
|
||||
if(iter!=_curves.end())
|
||||
{
|
||||
PlotCurve * c = *iter;
|
||||
c->detach(this);
|
||||
_curves.remove(c);
|
||||
_legend->removeLegendItem(c);
|
||||
_curves.erase(iter);
|
||||
_legend->remove(c);
|
||||
if(!qobject_cast<ThresholdCurve*>(c))
|
||||
{
|
||||
// transfer update connection to next curve
|
||||
for(int i=_curves.size()-1; i>=0; --i)
|
||||
{
|
||||
if(!qobject_cast<ThresholdCurve*>(_curves.at(i)))
|
||||
{
|
||||
connect(_curves.at(i), SIGNAL(dataChanged(const PlotCurve *)), this, SLOT(updateAxis()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(c->parent() == this)
|
||||
{
|
||||
delete c;
|
||||
@@ -2187,9 +2370,10 @@ void Plot::removeCurve(const PlotCurve * curve)
|
||||
|
||||
void Plot::showCurve(const PlotCurve * curve, bool shown)
|
||||
{
|
||||
PlotCurve * value = _curves.value(curve, 0);
|
||||
if(value)
|
||||
QList<PlotCurve *>::iterator iter = qFind(_curves.begin(), _curves.end(), curve);
|
||||
if(iter!=_curves.end())
|
||||
{
|
||||
PlotCurve * value = *iter;
|
||||
if(value->isVisible() != shown)
|
||||
{
|
||||
value->setVisible(shown);
|
||||
|
||||
@@ -94,13 +94,14 @@ public:
|
||||
|
||||
void setDefaultStepX(float stepX) {_defaultStepX = stepX;}
|
||||
QString name() const {return _name;}
|
||||
int itemsSize();
|
||||
int itemsSize() const;
|
||||
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
|
||||
void draw(QPainter * painter);
|
||||
|
||||
public slots:
|
||||
virtual void clear();
|
||||
@@ -125,7 +126,7 @@ protected:
|
||||
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);
|
||||
virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, bool allDataKept);
|
||||
QList<QGraphicsItem *> _items;
|
||||
Plot * _plot;
|
||||
|
||||
@@ -150,7 +151,7 @@ class ThresholdCurve : public PlotCurve
|
||||
|
||||
public:
|
||||
ThresholdCurve(const QString & name, float thesholdValue, Qt::Orientation orientation = Qt::Horizontal, QObject * parent = 0);
|
||||
~ThresholdCurve();
|
||||
virtual ~ThresholdCurve();
|
||||
|
||||
public slots:
|
||||
void setThreshold(float threshold);
|
||||
@@ -158,7 +159,7 @@ public slots:
|
||||
|
||||
protected:
|
||||
friend class Plot;
|
||||
virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, int xDir, int yDir, bool allDataKept);
|
||||
virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, bool allDataKept);
|
||||
virtual bool isMinMaxValid() const {return false;}
|
||||
|
||||
private:
|
||||
@@ -231,6 +232,7 @@ public:
|
||||
bool isFlat() const {return _flat;}
|
||||
void addItem(const PlotCurve * curve);
|
||||
QPixmap createSymbol(const QPen & pen, const QBrush & brush);
|
||||
bool remove(const PlotCurve * curve);
|
||||
|
||||
public slots:
|
||||
void removeLegendItem(const PlotCurve * curve);
|
||||
@@ -282,7 +284,7 @@ public:
|
||||
virtual ~Plot();
|
||||
|
||||
PlotCurve * addCurve(const QString & curveName);
|
||||
bool addCurve(PlotCurve * curve);
|
||||
bool addCurve(PlotCurve * curves);
|
||||
QStringList curveNames();
|
||||
bool contains(const QString & curveName);
|
||||
void removeCurves();
|
||||
@@ -303,24 +305,31 @@ public:
|
||||
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);
|
||||
void setGraphicsView(bool on);
|
||||
QRectF sceneRect() const;
|
||||
|
||||
public slots:
|
||||
void removeCurve(const PlotCurve * curve);
|
||||
void showCurve(const PlotCurve * curve, bool shown);
|
||||
void updateAxis(); //reset axis and recompute it with all curves minMax
|
||||
void clearData();
|
||||
|
||||
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);
|
||||
virtual void resizeEvent(QResizeEvent * event);
|
||||
|
||||
private:
|
||||
void replot();
|
||||
friend class PlotCurve;
|
||||
void addItem(QGraphicsItem * item);
|
||||
|
||||
private:
|
||||
void replot(QPainter * painter);
|
||||
bool updateAxis(float x, float y);
|
||||
bool updateAxis(float x1, float x2, float y1, float y2);
|
||||
void setupUi();
|
||||
@@ -331,6 +340,8 @@ private:
|
||||
private:
|
||||
PlotLegend * _legend;
|
||||
QGraphicsView * _view;
|
||||
QGraphicsItem * _sceneRoot;
|
||||
QWidget * _graphicsViewHolder;
|
||||
float _axisMaximums[4]; // {x1->x2, y1->y2}
|
||||
bool _axisMaximumsSet[4]; // {x1->x2, y1->y2}
|
||||
bool _fixedAxis[2];
|
||||
@@ -340,7 +351,7 @@ private:
|
||||
int _maxVisibleItems;
|
||||
QList<QGraphicsLineItem *> hGridLines;
|
||||
QList<QGraphicsLineItem *> vGridLines;
|
||||
QMap<const PlotCurve*, PlotCurve*> _curves;
|
||||
QList<PlotCurve*> _curves;
|
||||
QLabel * _title;
|
||||
QLabel * _xLabel;
|
||||
OrientableLabel * _yLabel;
|
||||
@@ -372,6 +383,7 @@ private:
|
||||
QAction * _aSaveFigure;
|
||||
QAction * _aAutoScreenCapture;
|
||||
QAction * _aClearData;
|
||||
QAction * _aGraphicsView;
|
||||
};
|
||||
|
||||
#ifndef PLOT_WIDGET_OUT_OF_LIB
|
||||
|
||||
@@ -49,8 +49,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_obsoletePanels(kPanelDummy),
|
||||
_ui(0),
|
||||
_indexModel(0),
|
||||
_initialized(false),
|
||||
_predictionPanelInitialized(false)
|
||||
_initialized(false)
|
||||
{
|
||||
ULOGGER_DEBUG("");
|
||||
|
||||
@@ -64,6 +63,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->buttonBox_local, SIGNAL(clicked(QAbstractButton *)), this, SLOT(resetApply(QAbstractButton *)));
|
||||
connect(_ui->pushButton_loadConfig, SIGNAL(clicked()), this, SLOT(loadConfigFrom()));
|
||||
connect(_ui->pushButton_saveConfig, SIGNAL(clicked()), this, SLOT(saveConfigTo()));
|
||||
connect(_ui->radioButton_basic, SIGNAL(toggled(bool)), this, SLOT(setupTreeView()));
|
||||
|
||||
// General panel
|
||||
connect(_ui->general_checkBox_imagesKept, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||
@@ -75,6 +75,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->checkBox_imageFlipped, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||
connect(_ui->comboBox_loggerType, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||
connect(_ui->checkBox_imageRejectedShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||
connect(_ui->checkBox_imageHighestHypShown, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||
connect(_ui->checkBox_beep, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||
connect(_ui->horizontalSlider_keypointsOpacity, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteGeneralPanel()));
|
||||
|
||||
@@ -84,6 +85,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->source_comboBox_type, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->general_doubleSpinBox_imgRate, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->general_checkBox_autoRestart, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->general_checkBox_cameraKeypoints, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
//usbDevice group
|
||||
connect(_ui->source_usbDevice_spinBox_id, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_spinBox_imgWidth, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
@@ -99,18 +101,38 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
//database group
|
||||
connect(_ui->source_database_toolButton_selectSource, SIGNAL(clicked()), this, SLOT(selectSource()));
|
||||
connect(_ui->source_database_lineEdit_path, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_database_checkBox_ignoreChildren, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->source_database_checkBox_loadActions, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
|
||||
//Rtabmap basic
|
||||
connect(_ui->general_doubleSpinBox_timeThr, SIGNAL(valueChanged(double)), _ui->general_doubleSpinBox_timeThr_2, SLOT(setValue(double)));
|
||||
connect(_ui->general_doubleSpinBox_hardThr, SIGNAL(valueChanged(double)), _ui->general_doubleSpinBox_hardThr_2, SLOT(setValue(double)));
|
||||
connect(_ui->surf_doubleSpinBox_hessianThr, SIGNAL(valueChanged(double)), _ui->surf_doubleSpinBox_hessianThr_2, SLOT(setValue(double)));
|
||||
connect(_ui->general_spinBox_imagesBufferSize, SIGNAL(valueChanged(int)), _ui->general_spinBox_imagesBufferSize_2, SLOT(setValue(int)));
|
||||
connect(_ui->general_checkBox_publishStats, SIGNAL(clicked(bool)), _ui->general_checkBox_publishStats_2, SLOT(setChecked(bool)));
|
||||
connect(_ui->lineEdit_workingDirectory, SIGNAL(textChanged(const QString &)), _ui->lineEdit_workingDirectory_2, SLOT(setText(const QString &)));
|
||||
|
||||
connect(_ui->general_doubleSpinBox_timeThr_2, SIGNAL(valueChanged(double)), _ui->general_doubleSpinBox_timeThr, SLOT(setValue(double)));
|
||||
connect(_ui->general_doubleSpinBox_hardThr_2, SIGNAL(valueChanged(double)), _ui->general_doubleSpinBox_hardThr, SLOT(setValue(double)));
|
||||
connect(_ui->surf_doubleSpinBox_hessianThr_2, SIGNAL(valueChanged(double)), _ui->surf_doubleSpinBox_hessianThr, SLOT(setValue(double)));
|
||||
connect(_ui->general_spinBox_imagesBufferSize_2, SIGNAL(valueChanged(int)), _ui->general_spinBox_imagesBufferSize, SLOT(setValue(int)));
|
||||
connect(_ui->general_checkBox_publishStats_2, SIGNAL(clicked(bool)), _ui->general_checkBox_publishStats, SLOT(setChecked(bool)));
|
||||
connect(_ui->lineEdit_workingDirectory_2, SIGNAL(textChanged(const QString &)), _ui->lineEdit_workingDirectory, SLOT(setText(const QString &)));
|
||||
connect(_ui->toolButton_workingDirectory_2, SIGNAL(clicked()), this, SLOT(changeWorkingDirectory()));
|
||||
|
||||
// Map objects name with the corresponding parameter key, needed for the addParameter() slots
|
||||
//Rtabmap
|
||||
_ui->general_doubleSpinBox_retrievalThr->setObjectName(Parameters::kRtabmapRetrievalThr().c_str());
|
||||
_ui->general_checkBox_publishStats->setObjectName(Parameters::kRtabmapPublishStats().c_str());
|
||||
_ui->general_checkBox_publishImages->setObjectName(Parameters::kRtabmapPublishImages().c_str());
|
||||
_ui->general_checkBox_publishPdf->setObjectName(Parameters::kRtabmapPublishPdf().c_str());
|
||||
_ui->general_checkBox_publishLikelihood->setObjectName(Parameters::kRtabmapPublishLikelihood().c_str());
|
||||
_ui->general_doubleSpinBox_timeThr->setObjectName(Parameters::kRtabmapTimeThr().c_str());
|
||||
_ui->general_spinBox_memoryThr->setObjectName(Parameters::kRtabmapMemoryThr().c_str());
|
||||
_ui->general_spinBox_imagesBufferSize->setObjectName(Parameters::kRtabmapSMStateBufferSize().c_str());
|
||||
_ui->general_spinBox_minMemorySizeForLoopDetection->setObjectName(Parameters::kRtabmapMinMemorySizeForLoopDetection().c_str());
|
||||
_ui->general_spinBox_maxRetrieved->setObjectName(Parameters::kRtabmapMaxRetrieved().c_str());
|
||||
_ui->general_checkBox_actionsByTime->setObjectName(Parameters::kRtabmapActionsByTime().c_str());
|
||||
_ui->general_checkBox_neighborhoodSummation->setObjectName(Parameters::kRtabmapSelectionNeighborhoodSummationUsed().c_str());
|
||||
_ui->general_checkBox_likelihoodUsed->setObjectName(Parameters::kRtabmapSelectionLikelihoodUsed().c_str());
|
||||
_ui->general_checkBox_likelihoodStdDevRemoved->setObjectName(Parameters::kRtabmapLikelihoodStdDevRemoved().c_str());
|
||||
_ui->general_checkBox_actionsSentRejectHyp->setObjectName(Parameters::kRtabmapActionsSentRejectHyp().c_str());
|
||||
_ui->general_doubleSpinBox_confidenceThr->setObjectName(Parameters::kRtabmapConfidenceThr().c_str());
|
||||
_ui->lineEdit_workingDirectory->setObjectName(Parameters::kRtabmapWorkingDirectory().c_str());
|
||||
@@ -123,17 +145,19 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->general_doubleSpinBox_similarityThr->setObjectName(Parameters::kMemSimilarityThr().c_str());
|
||||
_ui->general_checkBox_incrementalMemory->setObjectName(Parameters::kMemIncrementalMemory().c_str());
|
||||
_ui->general_checkBox_commonSignatureUsed->setObjectName(Parameters::kMemCommonSignatureUsed().c_str());
|
||||
_ui->general_checkBox_databaseCleaned->setObjectName(Parameters::kMemDatabaseCleaned().c_str());
|
||||
_ui->mem_spinBox_delayRequired->setObjectName(Parameters::kMemDelayRequired().c_str());
|
||||
_ui->general_checkBox_localGraphCleaned->setObjectName(Parameters::kRtabmapLocalGraphCleaned().c_str());
|
||||
_ui->general_doubleSpinBox_recentWmRatio->setObjectName(Parameters::kMemRecentWmRatio().c_str());
|
||||
_ui->general_checkBox_dataMergedOnRehearsal->setObjectName(Parameters::kMemDataMergedOnRehearsal().c_str());
|
||||
_ui->comboBox_signatureType->setObjectName(Parameters::kMemSignatureType().c_str());
|
||||
|
||||
// Database
|
||||
_ui->spinBox_dbMinSignToSave->setObjectName(Parameters::kDbMinSignaturesToSave().c_str());
|
||||
_ui->spinBox_dbMinWordsToSave->setObjectName(Parameters::kDbMinWordsToSave().c_str());
|
||||
_ui->general_checkBox_imagesCompressed->setObjectName(Parameters::kDbImagesCompressed().c_str());
|
||||
_ui->checkBox_dbInMemory->setObjectName(Parameters::kDbSqlite3InMemory().c_str());
|
||||
_ui->spinBox_dbCacheSize->setObjectName(Parameters::kDbSqlite3CacheSize().c_str());
|
||||
_ui->comboBox_dbJournalMode->setObjectName(Parameters::kDbSqlite3JournalMode().c_str());
|
||||
_ui->comboBox_dbSynchronous->setObjectName(Parameters::kDbSqlite3Synchronous().c_str());
|
||||
_ui->comboBox_dbTempStore->setObjectName(Parameters::kDbSqlite3TempStore().c_str());
|
||||
|
||||
// Create hypotheses
|
||||
_ui->general_doubleSpinBox_hardThr->setObjectName(Parameters::kRtabmapLoopThr().c_str());
|
||||
@@ -142,8 +166,11 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
//Bayes
|
||||
_ui->general_doubleSpinBox_vp->setObjectName(Parameters::kBayesVirtualPlacePriorThr().c_str());
|
||||
_ui->lineEdit_bayes_predictionLC->setObjectName(Parameters::kBayesPredictionLC().c_str());
|
||||
_ui->checkBox_bayes_predictionNonNullActionsOnly->setObjectName(Parameters::kBayesPredictionOnNonNullActionsOnly().c_str());
|
||||
connect(_ui->lineEdit_bayes_predictionLC, SIGNAL(textChanged(const QString &)), this, SLOT(updatePredictionPlot()));
|
||||
|
||||
//Keypoint-based
|
||||
_ui->checkBox_kp_publishKeypoints->setObjectName(Parameters::kKpPublishKeypoints().c_str());
|
||||
_ui->comboBox_dictionary_strategy->setObjectName(Parameters::kKpNNStrategy().c_str());
|
||||
_ui->checkBox_dictionary_incremental->setObjectName(Parameters::kKpIncrementalDictionary().c_str());
|
||||
_ui->comboBox_detector_strategy->setObjectName(Parameters::kKpDetectorStrategy().c_str());
|
||||
@@ -160,7 +187,6 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->checkBox_kp_tfIdfLikelihoodUsed->setObjectName(Parameters::kKpTfIdfLikelihoodUsed().c_str());
|
||||
_ui->checkBox_kp_tfIdfNormalized->setObjectName(Parameters::kKpTfIdfNormalized().c_str());
|
||||
_ui->checkBox_kp_parallelized->setObjectName(Parameters::kKpParallelized().c_str());
|
||||
_ui->checkBox_kp_sensorStateOnly->setObjectName(Parameters::kKpSensorStateOnly().c_str());
|
||||
_ui->lineEdit_kp_roi->setObjectName(Parameters::kKpRoiRatios().c_str());
|
||||
_ui->lineEdit_dictionaryPath->setObjectName(Parameters::kKpDictionaryPath().c_str());
|
||||
connect(_ui->toolButton_dictionaryPath, SIGNAL(clicked()), this, SLOT(changeDictionaryPath()));
|
||||
@@ -184,6 +210,20 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->sift_doubleSpinBox_Thr->setObjectName(Parameters::kSIFTThreshold().c_str());
|
||||
_ui->sift_doubleSpinBox_edgeThr->setObjectName(Parameters::kSIFTEdgeThreshold().c_str());
|
||||
|
||||
//FAST detector
|
||||
_ui->fast_spinBox_Threshold->setObjectName(Parameters::kFASTThreshold().c_str());
|
||||
_ui->fast_checkBox_nonmaxSuppression->setObjectName(Parameters::kFASTNonmaxSuppression().c_str());
|
||||
|
||||
//BRIEF descriptor
|
||||
_ui->brief_spinBox_size->setObjectName(Parameters::kBRIEFSize().c_str());
|
||||
|
||||
// Sensorimotor
|
||||
_ui->checkBox_publishMasks->setObjectName(Parameters::kSMPublishMasks().c_str());
|
||||
_ui->checkBox_motionMaskUsed->setObjectName(Parameters::kSMMotionMaskUsed().c_str());
|
||||
_ui->checkBox_logpolar->setObjectName(Parameters::kSMLogPolarUsed().c_str());
|
||||
_ui->checkBox_votingScheme->setObjectName(Parameters::kSMVotingSchemeUsed().c_str());
|
||||
_ui->sm_colorTable_comboBox->setObjectName(Parameters::kSMColorTable().c_str());
|
||||
|
||||
// verifyHypotheses
|
||||
_ui->comboBox_vh_strategy->setObjectName(Parameters::kRtabmapVhStrategy().c_str());
|
||||
_ui->vh_doubleSpinBox_similarity->setObjectName(Parameters::kVhSimilarity().c_str());
|
||||
@@ -203,7 +243,6 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->stackedWidget->setCurrentIndex(0);
|
||||
this->setupTreeView();
|
||||
connect(_ui->treeView, SIGNAL(clicked(QModelIndex)), this, SLOT(clicked(QModelIndex)));
|
||||
_ui->treeView->expandToDepth(1);
|
||||
|
||||
_obsoletePanels = kPanelAll;
|
||||
|
||||
@@ -230,25 +269,50 @@ void PreferencesDialog::init()
|
||||
|
||||
void PreferencesDialog::setupTreeView()
|
||||
{
|
||||
QFile modelFile(":/resources/PreferencesModel.txt");
|
||||
if(modelFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
int currentIndex = 0;
|
||||
if(_indexModel)
|
||||
{
|
||||
_indexModel = new QStandardItemModel(this);
|
||||
// Parse the model
|
||||
QList<QGroupBox*> boxes = this->getGroupBoxes();
|
||||
QStandardItem * parentItem = _indexModel->invisibleRootItem();
|
||||
int index = 0;
|
||||
this->parseModel(boxes, parentItem, 0, index); // recursive method
|
||||
if(index != _ui->stackedWidget->count())
|
||||
currentIndex = _indexModel->itemFromIndex(_ui->treeView->currentIndex())->data().toInt();
|
||||
_ui->treeView->setModel(0);
|
||||
delete _indexModel;
|
||||
}
|
||||
_indexModel = new QStandardItemModel(this);
|
||||
// Parse the model
|
||||
QList<QGroupBox*> boxes = this->getGroupBoxes();
|
||||
if(_ui->radioButton_basic->isChecked())
|
||||
{
|
||||
boxes = boxes.mid(0,3);
|
||||
}
|
||||
else // Advanced
|
||||
{
|
||||
boxes.removeAt(2);
|
||||
}
|
||||
|
||||
QStandardItem * parentItem = _indexModel->invisibleRootItem();
|
||||
int index = 0;
|
||||
this->parseModel(boxes, parentItem, 0, index); // recursive method
|
||||
if(_ui->radioButton_advanced->isChecked() && index != _ui->stackedWidget->count()-1)
|
||||
{
|
||||
ULOGGER_ERROR("The tree model is not the same size of the stacked widgets...%d vs %d advanced stacks", index, _ui->stackedWidget->count()-1);
|
||||
}
|
||||
if(_ui->radioButton_basic->isChecked())
|
||||
{
|
||||
if(currentIndex >= 2)
|
||||
{
|
||||
ULOGGER_ERROR("The tree model is not the same size of the stacked widgets...%d vs %d stacks", index, _ui->stackedWidget->count());
|
||||
_ui->stackedWidget->setCurrentIndex(2);
|
||||
currentIndex = 2;
|
||||
}
|
||||
_ui->treeView->setModel(_indexModel);
|
||||
}
|
||||
else
|
||||
else // Advanced
|
||||
{
|
||||
ULOGGER_ERROR("Can't open resource file \"PreferencesModel.txt\"");
|
||||
if(currentIndex == 2)
|
||||
{
|
||||
_ui->stackedWidget->setCurrentIndex(3);
|
||||
}
|
||||
}
|
||||
_ui->treeView->setModel(_indexModel);
|
||||
_ui->treeView->setCurrentIndex(_indexModel->index(currentIndex, 0));
|
||||
_ui->treeView->expandToDepth(1);
|
||||
}
|
||||
|
||||
// recursive...
|
||||
@@ -263,20 +327,19 @@ bool PreferencesDialog::parseModel(QList<QGroupBox*> & boxes, QStandardItem * pa
|
||||
QStandardItem * currentItem = 0;
|
||||
while(absoluteIndex < boxes.size())
|
||||
{
|
||||
QString objectName = boxes.at(absoluteIndex)->objectName();
|
||||
QString title = boxes.at(absoluteIndex)->title();
|
||||
bool ok = false;
|
||||
int lvl = QString(title.at(0)).toInt(&ok);
|
||||
int lvl = QString(objectName.at(objectName.size()-1)).toInt(&ok);
|
||||
if(!ok)
|
||||
{
|
||||
ULOGGER_ERROR("Error while parsing the first number of the QGroupBox title, the first character must be the number in the hierarchy");
|
||||
ULOGGER_ERROR("Error while parsing the first number of the QGroupBox title (%s), the first character must be the number in the hierarchy", title.toStdString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(lvl == currentLevel)
|
||||
{
|
||||
title.remove(0, 1);
|
||||
boxes.at(absoluteIndex)->setTitle(title);
|
||||
QStandardItem * item = new QStandardItem(title);
|
||||
item->setData(absoluteIndex);
|
||||
currentItem = item;
|
||||
@@ -354,7 +417,12 @@ void PreferencesDialog::clicked(const QModelIndex &index)
|
||||
QStandardItem * item = _indexModel->itemFromIndex(index);
|
||||
if(item)
|
||||
{
|
||||
_ui->stackedWidget->setCurrentIndex(item->data().toInt());
|
||||
int index = item->data().toInt();
|
||||
if(_ui->radioButton_advanced->isChecked() && index >= 2)
|
||||
{
|
||||
++index;
|
||||
}
|
||||
_ui->stackedWidget->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -370,7 +438,7 @@ void PreferencesDialog::closeDialog ( QAbstractButton * button )
|
||||
break;
|
||||
|
||||
case QDialogButtonBox::AcceptRole:
|
||||
if(_obsoletePanels & kPanelAll || _parameters.size())
|
||||
if((_obsoletePanels & kPanelAll) || _parameters.size())
|
||||
{
|
||||
if(validateForm())
|
||||
{
|
||||
@@ -415,7 +483,7 @@ void PreferencesDialog::resetSettings(int panelNumber)
|
||||
QList<QGroupBox*> boxes = this->getGroupBoxes();
|
||||
if(panelNumber >= 0 && panelNumber < boxes.size())
|
||||
{
|
||||
if(boxes.at(panelNumber)->objectName() == "groupBox_generalSettingsGui")
|
||||
if(boxes.at(panelNumber)->objectName() == "groupBox_generalSettingsGui0")
|
||||
{
|
||||
_ui->general_checkBox_imagesKept->setChecked(DEFAULT_GUI_IMAGES_KEPT);
|
||||
_ui->comboBox_loggerLevel->setCurrentIndex(DEFAULT_LOGGER_LEVEL);
|
||||
@@ -423,12 +491,22 @@ void PreferencesDialog::resetSettings(int panelNumber)
|
||||
_ui->comboBox_loggerPauseLevel->setCurrentIndex(DEFAULT_LOGGER_PAUSE_LEVEL);
|
||||
_ui->checkBox_logger_printTime->setChecked(DEFAULT_LOGGER_PRINT_TIME);
|
||||
}
|
||||
else if(boxes.at(panelNumber)->objectName() == "groupBox_source")
|
||||
else if(boxes.at(panelNumber)->objectName() == "groupBox_source0")
|
||||
{
|
||||
_ui->general_doubleSpinBox_imgRate->setValue(1.0);
|
||||
_ui->source_spinBox_imgWidth->setValue(0);
|
||||
_ui->source_spinBox_imgheight->setValue(0);
|
||||
_ui->general_checkBox_autoRestart->setChecked(false);
|
||||
_ui->general_checkBox_cameraKeypoints->setChecked(false);
|
||||
}
|
||||
else if(boxes.at(panelNumber)->objectName() == "groupBox_rtabmap_basic0")
|
||||
{
|
||||
_ui->general_doubleSpinBox_timeThr_2->setValue(Parameters::defaultRtabmapTimeThr());
|
||||
_ui->general_doubleSpinBox_hardThr_2->setValue(Parameters::defaultRtabmapLoopThr());
|
||||
_ui->surf_doubleSpinBox_hessianThr_2->setValue(Parameters::defaultSURFHessianThreshold());
|
||||
_ui->general_spinBox_imagesBufferSize_2->setValue(Parameters::defaultRtabmapSMStateBufferSize());
|
||||
_ui->general_checkBox_publishStats_2->setChecked(Parameters::defaultRtabmapPublishStats());
|
||||
_ui->lineEdit_workingDirectory_2->setText(Parameters::defaultRtabmapWorkingDirectory().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -444,11 +522,6 @@ void PreferencesDialog::resetSettings(int panelNumber)
|
||||
}
|
||||
}
|
||||
|
||||
if(boxes.at(panelNumber)->findChild<QLineEdit*>(_ui->lineEdit_bayes_predictionLC->objectName()))
|
||||
{
|
||||
this->setupPredictionPanel();
|
||||
}
|
||||
|
||||
if(boxes.at(panelNumber)->findChild<QLineEdit*>(_ui->lineEdit_kp_roi->objectName()))
|
||||
{
|
||||
this->setupKpRoiPanel();
|
||||
@@ -529,6 +602,7 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
|
||||
settings.beginGroup("Camera");
|
||||
_ui->general_doubleSpinBox_imgRate->setValue(settings.value("imgRate", _ui->general_doubleSpinBox_imgRate->value()).toDouble());
|
||||
_ui->general_checkBox_autoRestart->setChecked(settings.value("autoRestart", _ui->general_checkBox_autoRestart->isChecked()).toBool());
|
||||
_ui->general_checkBox_cameraKeypoints->setChecked(settings.value("cameraKeypoints", _ui->general_checkBox_cameraKeypoints->isChecked()).toBool());
|
||||
_ui->source_comboBox_type->setCurrentIndex(settings.value("type", _ui->source_comboBox_type->currentIndex()).toInt());
|
||||
_ui->source_spinBox_imgWidth->setValue(settings.value("imgWidth",_ui->source_spinBox_imgWidth->value()).toInt());
|
||||
_ui->source_spinBox_imgheight->setValue(settings.value("imgHeight",_ui->source_spinBox_imgheight->value()).toInt());
|
||||
@@ -549,7 +623,7 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
|
||||
//database group
|
||||
settings.beginGroup("database");
|
||||
_ui->source_database_lineEdit_path->setText(settings.value("path",_ui->source_database_lineEdit_path->text()).toString());
|
||||
_ui->source_database_checkBox_ignoreChildren->setChecked(settings.value("ignoreChildren",_ui->source_database_checkBox_ignoreChildren->isChecked()).toBool());
|
||||
_ui->source_database_checkBox_loadActions->setChecked(settings.value("loadActions",_ui->source_database_checkBox_loadActions->isChecked()).toBool());
|
||||
settings.endGroup(); // usbDevice
|
||||
settings.endGroup(); // Camera
|
||||
}
|
||||
@@ -669,6 +743,7 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath)
|
||||
|
||||
settings.setValue("imgRate", _ui->general_doubleSpinBox_imgRate->value());
|
||||
settings.setValue("autoRestart", _ui->general_checkBox_autoRestart->isChecked());
|
||||
settings.setValue("cameraKeypoints", _ui->general_checkBox_cameraKeypoints->isChecked());
|
||||
settings.setValue("type", _ui->source_comboBox_type->currentIndex());
|
||||
settings.setValue("imgWidth", _ui->source_spinBox_imgWidth->value());
|
||||
settings.setValue("imgHeight", _ui->source_spinBox_imgheight->value());
|
||||
@@ -689,7 +764,7 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath)
|
||||
//database group
|
||||
settings.beginGroup("database");
|
||||
settings.setValue("path", _ui->source_database_lineEdit_path->text());
|
||||
settings.setValue("ignoreChildren", _ui->source_database_checkBox_ignoreChildren->isChecked());
|
||||
settings.setValue("loadActions", _ui->source_database_checkBox_loadActions->isChecked());
|
||||
settings.endGroup(); //usbDevice
|
||||
|
||||
settings.endGroup(); // Camera
|
||||
@@ -730,7 +805,7 @@ void PreferencesDialog::writeCoreSettings(const QString & filePath)
|
||||
}
|
||||
else if(check)
|
||||
{
|
||||
settings.setValue(obj->objectName(), uBool2str(check->isChecked()).c_str());
|
||||
settings.setValue(obj->objectName(), uBool2Str(check->isChecked()).c_str());
|
||||
}
|
||||
else if(lineEdit)
|
||||
{
|
||||
@@ -783,7 +858,7 @@ void PreferencesDialog::readSettingsEnd()
|
||||
_progressDialog->setValue(1);
|
||||
_progressDialog->setLabelText(tr("Reading GUI settings..."));
|
||||
|
||||
this->setupPredictionPanel();
|
||||
this->updatePredictionPlot();
|
||||
this->setupKpRoiPanel();
|
||||
|
||||
_progressDialog->setValue(2); // this will make closing...
|
||||
@@ -1038,53 +1113,95 @@ void PreferencesDialog::addParameter(const QObject * object, int value)
|
||||
{
|
||||
if(object)
|
||||
{
|
||||
const QComboBox * comboBox = qobject_cast<const QComboBox*>(object);
|
||||
if(comboBox)
|
||||
{
|
||||
// Add related panels to parameters
|
||||
if(comboBox == _ui->comboBox_vh_strategy)
|
||||
{
|
||||
if(value == 0) // 0 none
|
||||
{
|
||||
// No panel related...
|
||||
}
|
||||
else if(value == 1) // 1 similarity
|
||||
{
|
||||
this->addParameters(_ui->groupBox_vh_similarity);
|
||||
}
|
||||
else if(value == 2) // 2 epipolar
|
||||
{
|
||||
this->addParameters(_ui->groupBox_vh_epipolar);
|
||||
}
|
||||
}
|
||||
else if(comboBox == _ui->comboBox_detector_strategy)
|
||||
{
|
||||
if(value == 0) // 0 surf
|
||||
{
|
||||
this->addParameters(_ui->groupBox_detector_surf);
|
||||
}
|
||||
else if(value == 1) // 1 star
|
||||
{
|
||||
this->addParameters(_ui->groupBox_detector_star);
|
||||
}
|
||||
else if(value == 2) // 2 sift
|
||||
{
|
||||
this->addParameters(_ui->groupBox_detector_sift);
|
||||
}
|
||||
}
|
||||
else if(comboBox == _ui->comboBox_descriptor_strategy)
|
||||
{
|
||||
this->addParameters(_ui->groupBox_surfDescriptor);
|
||||
}
|
||||
}
|
||||
// Make sure the value is inserted, check if the same key already exists
|
||||
rtabmap::ParametersMap::iterator iter = _parameters.find(object->objectName().toStdString());
|
||||
if(iter != _parameters.end())
|
||||
{
|
||||
_parameters.erase(iter);
|
||||
}
|
||||
_parameters.insert(rtabmap::ParametersPair(object->objectName().toStdString(), QString::number(value).toStdString()));
|
||||
//ULOGGER_DEBUG("PreferencesDialog::addParameter(object, int) Added [\"%s\",\"%s\"]", object->objectName().toStdString().c_str(), QString::number(value).toStdString().c_str());
|
||||
|
||||
const QComboBox * comboBox = qobject_cast<const QComboBox*>(object);
|
||||
const QSpinBox * spinbox = qobject_cast<const QSpinBox*>(object);
|
||||
const QCheckBox * checkbox = qobject_cast<const QCheckBox*>(object);
|
||||
if(comboBox || spinbox)
|
||||
{
|
||||
if(comboBox)
|
||||
{
|
||||
// Add related panels to parameters
|
||||
if(comboBox == _ui->comboBox_vh_strategy)
|
||||
{
|
||||
if(value == 0) // 0 none
|
||||
{
|
||||
// No panel related...
|
||||
}
|
||||
else if(value == 1) // 1 similarity
|
||||
{
|
||||
this->addParameters(_ui->groupBox_vh_similarity2);
|
||||
}
|
||||
else if(value == 2) // 2 epipolar
|
||||
{
|
||||
this->addParameters(_ui->groupBox_vh_epipolar2);
|
||||
}
|
||||
}
|
||||
else if(comboBox == _ui->comboBox_detector_strategy)
|
||||
{
|
||||
if(value == 0) // 0 surf
|
||||
{
|
||||
this->addParameters(_ui->groupBox_detector_surf2);
|
||||
}
|
||||
else if(value == 1) // 1 star
|
||||
{
|
||||
this->addParameters(_ui->groupBox_detector_star2);
|
||||
}
|
||||
else if(value == 2) // 2 sift
|
||||
{
|
||||
this->addParameters(_ui->groupBox_detector_sift2);
|
||||
}
|
||||
else if(value == 3) // 3 fast
|
||||
{
|
||||
this->addParameters(_ui->groupBox_detector_fast2);
|
||||
}
|
||||
}
|
||||
else if(comboBox == _ui->comboBox_descriptor_strategy)
|
||||
{
|
||||
if(value == 0) // 0 surf
|
||||
{
|
||||
this->addParameters(_ui->groupBox_descriptor_surf2);
|
||||
}
|
||||
else if(value == 3) // 1 sift
|
||||
{
|
||||
// no panel
|
||||
}
|
||||
else if(value == 5) // 2 brief
|
||||
{
|
||||
this->addParameters(_ui->groupBox_descriptor_brief2);
|
||||
}
|
||||
}
|
||||
else if(comboBox == _ui->comboBox_signatureType)
|
||||
{
|
||||
if(value == 0) // 0 keypoint
|
||||
{
|
||||
this->addParameters(_ui->groupBox_signature_keypoint1);
|
||||
}
|
||||
else if(value == 1) // 1 sensorimotor
|
||||
{
|
||||
this->addParameters(_ui->groupBox_signature_sensorimotor1);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add parameter
|
||||
_parameters.insert(rtabmap::ParametersPair(object->objectName().toStdString(), QString::number(value).toStdString()));
|
||||
}
|
||||
else if(checkbox)
|
||||
{
|
||||
// Add parameter
|
||||
_parameters.insert(rtabmap::ParametersPair(object->objectName().toStdString(), uBool2Str(value)));
|
||||
}
|
||||
else
|
||||
{
|
||||
UWARN("Undefined object \"%s\"", object->objectName().toStdString().c_str());
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1214,7 +1331,6 @@ QList<QGroupBox*> PreferencesDialog::getGroupBoxes()
|
||||
if(gb)
|
||||
{
|
||||
boxes.append(gb);
|
||||
this->addParameters(gb);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1224,133 +1340,26 @@ QList<QGroupBox*> PreferencesDialog::getGroupBoxes()
|
||||
return boxes;
|
||||
}
|
||||
|
||||
void PreferencesDialog::setupPredictionPanel()
|
||||
void PreferencesDialog::updatePredictionPlot()
|
||||
{
|
||||
QString prediction = _ui->lineEdit_bayes_predictionLC->text();
|
||||
QStringList values = prediction.split(' ');
|
||||
if(values.size() < 2)
|
||||
{
|
||||
ULOGGER_ERROR("The prediction string is not valid (prediction=\"%s\",size=%d)", prediction.toStdString().c_str(), values.size());
|
||||
return;
|
||||
}
|
||||
QStringList values = _ui->lineEdit_bayes_predictionLC->text().split(' ');
|
||||
|
||||
//Signals
|
||||
connect(_ui->spinBox_bayes_neighbors, SIGNAL(valueChanged(int)), this, SLOT(updatePredictionLCSliders()));
|
||||
|
||||
//Set values
|
||||
_ui->spinBox_bayes_neighbors->setValue(values.size()-2);
|
||||
this->updatePredictionLCSliders();
|
||||
if(_predictionLCSliders.size() != values.size())
|
||||
QVector<float> dataX((values.size()-2)*2 + 1);
|
||||
QVector<float> dataY((values.size()-2)*2 + 1);
|
||||
double value;
|
||||
double sum = 0;
|
||||
int lvl = 1;
|
||||
bool ok = false;
|
||||
bool error = false;
|
||||
int loopClosureIndex = (dataX.size()-1)/2;
|
||||
for(int i=0; i<values.size(); ++i)
|
||||
{
|
||||
ULOGGER_ERROR("The sliders list were not updated");
|
||||
return;
|
||||
}
|
||||
for(int i=0; i<_predictionLCSliders.size(); ++i)
|
||||
{
|
||||
bool ok;
|
||||
_predictionLCSliders.at(i)->setValue(int(QString(values.at(i)).toFloat(&ok) * 100));
|
||||
value = values.at(i).toDouble(&ok);
|
||||
if(!ok)
|
||||
{
|
||||
ULOGGER_WARN("conversion failed to float with string \"%s\"", values.at(i).toStdString().c_str());
|
||||
UERROR("Error parsing prediction : %s", values.at(i).toStdString().c_str());
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
_predictionPanelInitialized = true;
|
||||
this->updatePredictionLC();
|
||||
}
|
||||
|
||||
void PreferencesDialog::updatePredictionLCSliders()
|
||||
{
|
||||
int neighborsCount = _ui->spinBox_bayes_neighbors->value();
|
||||
if(neighborsCount < 0 || neighborsCount>9)
|
||||
{
|
||||
ULOGGER_ERROR("neighborsCount not valid (=%d)", neighborsCount);
|
||||
return;
|
||||
}
|
||||
|
||||
if(_predictionLCSliders.size() == 1)
|
||||
{
|
||||
_predictionLCSliders.clear(); // must be pair...
|
||||
ULOGGER_WARN("The list of sliders is supposed to be pair");
|
||||
}
|
||||
|
||||
if(_predictionLCSliders.size() == 0)
|
||||
{
|
||||
_predictionLCSliders.append(_ui->verticalSlider_prediction_vp);
|
||||
_predictionLCSliders.append(_ui->verticalSlider_prediction_lp);
|
||||
connect(_ui->verticalSlider_prediction_vp, SIGNAL(valueChanged(int)), this, SLOT(updatePredictionLC()));
|
||||
connect(_ui->verticalSlider_prediction_lp, SIGNAL(valueChanged(int)), this, SLOT(updatePredictionLC()));
|
||||
}
|
||||
|
||||
// If we don't have enough sliders
|
||||
while((_predictionLCSliders.size()-2) < neighborsCount)
|
||||
{
|
||||
int neighbor = _predictionLCSliders.size();
|
||||
QVBoxLayout * vLayout = 0;
|
||||
QHBoxLayout * hLayout = 0;
|
||||
QSlider * slider = 0;
|
||||
QLabel * value = 0;
|
||||
QLabel * title = 0;
|
||||
|
||||
slider = new QSlider(Qt::Vertical, this);
|
||||
|
||||
title = new QLabel(QString("l%1").arg(neighbor-1), slider);
|
||||
|
||||
title->setAlignment(Qt::AlignCenter);
|
||||
value = new QLabel(slider);
|
||||
value->setAlignment(Qt::AlignCenter);
|
||||
//layout
|
||||
vLayout = new QVBoxLayout();
|
||||
vLayout->addWidget(title);
|
||||
hLayout = new QHBoxLayout();
|
||||
hLayout->addWidget(slider);
|
||||
vLayout->addLayout(hLayout);
|
||||
vLayout->addWidget(value);
|
||||
|
||||
_ui->horizontalLayout_prior_NP->insertLayout(-1, vLayout);
|
||||
|
||||
_predictionLCSliders.push_back(slider);
|
||||
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(updatePredictionLC()));
|
||||
connect(slider, SIGNAL(valueChanged(int)), value, SLOT(setNum(int)));
|
||||
}
|
||||
|
||||
// If we have too much sliders
|
||||
while((_predictionLCSliders.size()-2) > neighborsCount)
|
||||
{
|
||||
// delete layouts and items
|
||||
delete _ui->horizontalLayout_prior_NP->itemAt(_ui->horizontalLayout_prior_NP->count()-1)->layout()->takeAt(0)->widget(); //label
|
||||
delete _ui->horizontalLayout_prior_NP->itemAt(_ui->horizontalLayout_prior_NP->count()-1)->layout()->itemAt(0)->layout()->takeAt(0)->widget(); //slider
|
||||
delete _ui->horizontalLayout_prior_NP->itemAt(_ui->horizontalLayout_prior_NP->count()-1)->layout()->takeAt(0)->layout(); //slider hlayout
|
||||
delete _ui->horizontalLayout_prior_NP->itemAt(_ui->horizontalLayout_prior_NP->count()-1)->layout()->takeAt(0)->widget(); //spinbox
|
||||
delete _ui->horizontalLayout_prior_NP->takeAt(_ui->horizontalLayout_prior_NP->count()-1);
|
||||
// remove the last slider
|
||||
_predictionLCSliders.removeLast();
|
||||
}
|
||||
|
||||
this->updatePredictionLC();
|
||||
}
|
||||
|
||||
void PreferencesDialog::updatePredictionLC()
|
||||
{
|
||||
if(!_predictionPanelInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(_predictionLCSliders.size() < 2)
|
||||
{
|
||||
ULOGGER_ERROR("Not enough slider in the list (%d)", _predictionLCSliders.size());
|
||||
return;
|
||||
}
|
||||
|
||||
QString values;
|
||||
QVector<float> dataX((_predictionLCSliders.size()-2)*2 + 1);
|
||||
QVector<float> dataY((_predictionLCSliders.size()-2)*2 + 1);
|
||||
float value;
|
||||
float sum = 0;
|
||||
int lvl = 1;
|
||||
int loopClosureIndex = (dataX.size()-1)/2;
|
||||
for(int i=0; i<_predictionLCSliders.size(); ++i)
|
||||
{
|
||||
value = (float(_predictionLCSliders.at(i)->value()))/100;
|
||||
sum+=value;
|
||||
if(i==0)
|
||||
{
|
||||
@@ -1368,22 +1377,19 @@ void PreferencesDialog::updatePredictionLC()
|
||||
dataY[loopClosureIndex+lvl] = value;
|
||||
dataX[loopClosureIndex+lvl] = lvl;
|
||||
++lvl;
|
||||
sum+=value; // double sum
|
||||
}
|
||||
values.append(QString::number(value));
|
||||
if(i+1 < _predictionLCSliders.size())
|
||||
{
|
||||
values.append(' ');
|
||||
}
|
||||
}
|
||||
|
||||
_ui->label_prediction_sum->setNum(sum);
|
||||
if(sum<=0 || sum>1.001)
|
||||
if(error)
|
||||
{
|
||||
_ui->label_prediction_sum->setText(QString("<font color=#FF0000>") + _ui->label_prediction_sum->text() + "</font>");
|
||||
ULOGGER_WARN("The prediction is not valid (the sum must be between >0 && <=1) (sum=%f)", sum);
|
||||
}
|
||||
else if(sum == 1)
|
||||
else if(sum == 1.0)
|
||||
{
|
||||
_ui->label_prediction_sum->setText(QString("<font color=#00FF00>") + _ui->label_prediction_sum->text() + "</font>");
|
||||
}
|
||||
else if(sum > 1.0)
|
||||
{
|
||||
_ui->label_prediction_sum->setText(QString("<font color=#FFa500>") + _ui->label_prediction_sum->text() + "</font>");
|
||||
}
|
||||
@@ -1394,7 +1400,6 @@ void PreferencesDialog::updatePredictionLC()
|
||||
|
||||
_ui->predictionPlot->removeCurves();
|
||||
_ui->predictionPlot->addCurve(new PlotCurve("Prediction", dataX, dataY, _ui->predictionPlot));
|
||||
_ui->lineEdit_bayes_predictionLC->setText(values);
|
||||
}
|
||||
|
||||
void PreferencesDialog::setupKpRoiPanel()
|
||||
@@ -1504,6 +1509,10 @@ bool PreferencesDialog::getGeneralAutoRestart() const
|
||||
{
|
||||
return _ui->general_checkBox_autoRestart->isChecked();
|
||||
}
|
||||
bool PreferencesDialog::getGeneralCameraKeypoints() const
|
||||
{
|
||||
return _ui->general_checkBox_cameraKeypoints->isChecked();
|
||||
}
|
||||
int PreferencesDialog::getSourceType() const
|
||||
{
|
||||
return _ui->source_comboBox_type->currentIndex();
|
||||
@@ -1544,9 +1553,9 @@ QString PreferencesDialog::getSourceDatabasePath() const
|
||||
{
|
||||
return _ui->source_database_lineEdit_path->text();
|
||||
}
|
||||
bool PreferencesDialog::getSourceDatabaseIgnoreChildren() const
|
||||
bool PreferencesDialog::getSourceDatabaseLoadActions() const
|
||||
{
|
||||
return _ui->source_database_checkBox_ignoreChildren->isChecked();
|
||||
return _ui->source_database_checkBox_loadActions->isChecked();
|
||||
}
|
||||
|
||||
double PreferencesDialog::getLoopThr() const
|
||||
@@ -1566,7 +1575,7 @@ bool PreferencesDialog::isImagesKept() const
|
||||
{
|
||||
return _ui->general_checkBox_imagesKept->isChecked();
|
||||
}
|
||||
double PreferencesDialog::getTimeLimit() const
|
||||
float PreferencesDialog::getTimeLimit() const
|
||||
{
|
||||
return _ui->general_doubleSpinBox_timeThr->value();
|
||||
}
|
||||
@@ -1642,7 +1651,7 @@ void PreferencesDialog::setAutoRestart(bool value)
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesDialog::setTimeLimit(double value)
|
||||
void PreferencesDialog::setTimeLimit(float value)
|
||||
{
|
||||
ULOGGER_DEBUG("timeLimit=%fs", value);
|
||||
if(_ui->general_doubleSpinBox_timeThr->value() != value)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <QtCore/QDir>
|
||||
#include <QtGui/QContextMenuEvent>
|
||||
#include <QtGui/QToolBox>
|
||||
#include <QtGui/QDialog>
|
||||
|
||||
#include "Plot.h"
|
||||
#include "utilite/ULogger.h"
|
||||
@@ -281,19 +282,20 @@ void StatsToolBox::plot(const StatItem * stat, const QString & plotName)
|
||||
id.replace(tr("Figure "), "");
|
||||
QString newPlotName = QString(tr("Figure %1")).arg(id.toInt()+1);
|
||||
//Dock
|
||||
QWidget * figure = new QWidget(0, Qt::Window);
|
||||
QDialog * figure = new QDialog(0, Qt::Window);
|
||||
_figures.insert(newPlotName, figure);
|
||||
figure->setLayout(new QHBoxLayout());
|
||||
QHBoxLayout * hLayout = new QHBoxLayout(figure);
|
||||
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->setMaxVisibleItems(50);
|
||||
newPlot->setObjectName(newPlotName);
|
||||
figure->layout()->addWidget(newPlot);
|
||||
hLayout->addWidget(newPlot);
|
||||
_plotMenu->addAction(newPlotName);
|
||||
figure->setSizeGripEnabled(true);
|
||||
|
||||
//Add a new curve linked to the statBox
|
||||
PlotCurve * curve = new PlotCurve(stat->objectName(), newPlot);
|
||||
@@ -347,16 +349,36 @@ void StatsToolBox::contextMenuEvent(QContextMenuEvent * event)
|
||||
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 * aClearFigures = topMenu.addAction(tr("Clear all figures"));
|
||||
QAction * action = topMenu.exec(event->globalPos());
|
||||
QString plotName;
|
||||
if(action)
|
||||
{
|
||||
for(int i=0; i<actions.size(); ++i)
|
||||
if(action == aClearFigures)
|
||||
{
|
||||
if(actions.at(i) == action)
|
||||
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();
|
||||
plots[0]->clearData();
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i=0; i<actions.size(); ++i)
|
||||
{
|
||||
plotName = actions.at(i)->text();
|
||||
break;
|
||||
if(actions.at(i) == action)
|
||||
{
|
||||
plotName = actions.at(i)->text();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,9 +444,21 @@ void StatsToolBox::addCurve(const QString & name, bool newFigure)
|
||||
|
||||
void StatsToolBox::setWorkingDirectory(const QString & workingDirectory)
|
||||
{
|
||||
if(QDir(_workingDirectory).exists())
|
||||
if(QDir(workingDirectory).exists())
|
||||
{
|
||||
_workingDirectory = workingDirectory;
|
||||
for(QMap<QString, QWidget*>::iterator i=_figures.begin(); i!=_figures.end(); ++i)
|
||||
{
|
||||
QList<Plot *> plots = i.value()->findChildren<Plot *>();
|
||||
if(plots.size() == 1)
|
||||
{
|
||||
plots[0]->setWorkingDirectory(_workingDirectory);
|
||||
}
|
||||
else
|
||||
{
|
||||
UERROR("");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
110
guilib/src/TwistWidget.cpp
Normal file
110
guilib/src/TwistWidget.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* TwistWidget.cpp
|
||||
*
|
||||
* Created on: Dec 11, 2011
|
||||
* Author: MatLab
|
||||
*/
|
||||
|
||||
#include "TwistWidget.h"
|
||||
|
||||
#include <utilite/ULogger.h>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtCore/qmath.h>
|
||||
#include <QtGui/QGridLayout>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
#define SIZE 50
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
TwistGridWidget::TwistGridWidget(QWidget * parent, Qt::WindowFlags f) :
|
||||
QWidget(parent, f)
|
||||
{
|
||||
_grid = new QGridLayout(this);
|
||||
_grid->setContentsMargins(0,0,0,0);
|
||||
_grid->addWidget(new QLabel(tr("Current"), this), 0, 0);
|
||||
_grid->addWidget(new QLabel(tr("Prediction"), this), 1, 0);
|
||||
}
|
||||
|
||||
void TwistGridWidget::addTwist(float x, float y, float z, float roll, float pitch, float yaw, int row, int col)
|
||||
{
|
||||
if(_grid->itemAtPosition(row, col+1))
|
||||
{
|
||||
QLayoutItem * item = _grid->itemAtPosition(row, col+1);
|
||||
if(item)
|
||||
{
|
||||
QWidget * w = item->widget();
|
||||
if(w)
|
||||
{
|
||||
_grid->removeItem(item);
|
||||
w->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
_grid->addWidget(new TwistWidget(x, y, z, roll, pitch, yaw, this), row, col+1);
|
||||
}
|
||||
|
||||
TwistWidget::TwistWidget(float x, float y, float z, float roll, float pitch, float yaw, QWidget * parent, Qt::WindowFlags f) :
|
||||
QWidget(parent, f)
|
||||
{
|
||||
if(qAbs(z) > 0.00001)
|
||||
{
|
||||
UWARN("%f,%f,%f %f,%f,%f", x,y,z, roll,pitch,yaw);
|
||||
}
|
||||
//linear
|
||||
_x = x;
|
||||
_y = y;
|
||||
_z = z;
|
||||
|
||||
//angular
|
||||
_roll = roll;
|
||||
_pitch = pitch;
|
||||
_yaw = yaw;
|
||||
|
||||
this->setFixedSize(SIZE,SIZE);
|
||||
this->setMinimumSize(SIZE,SIZE);
|
||||
}
|
||||
|
||||
void TwistWidget::paintEvent(QPaintEvent * event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.setPen(QPen(QBrush(Qt::black), 1, Qt::DashLine));
|
||||
painter.drawEllipse(0,0,SIZE,SIZE);
|
||||
|
||||
painter.translate(SIZE/2,SIZE/2);
|
||||
painter.rotate(-90);
|
||||
const float pi = 3.14159f;
|
||||
|
||||
painter.save();
|
||||
if(qAbs(_x) < 0.0001 && qAbs(_y) < 0.0001)
|
||||
{
|
||||
painter.setBrush(Qt::red);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawEllipse(-5,-5,10,10);
|
||||
}
|
||||
else
|
||||
{
|
||||
painter.setPen(QPen(QBrush(Qt::red), 3));
|
||||
painter.rotate(-qAtan2(_y, _x)*180.0f/pi);
|
||||
painter.drawLine(0,0,SIZE/2,0);
|
||||
}
|
||||
painter.restore();
|
||||
|
||||
painter.save();
|
||||
if(qAbs(_yaw) < 0.0001)
|
||||
{
|
||||
painter.setBrush(Qt::green);
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawEllipse(-3,-3,6,6);
|
||||
}
|
||||
else
|
||||
{
|
||||
painter.setPen(QPen(QBrush(Qt::green), 3));
|
||||
painter.rotate(-_yaw*180.0f/pi);
|
||||
painter.drawLine(0,0,50,0);
|
||||
}
|
||||
painter.restore();
|
||||
}
|
||||
|
||||
}
|
||||
53
guilib/src/TwistWidget.h
Normal file
53
guilib/src/TwistWidget.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* TwistWidget.h
|
||||
*
|
||||
* Created on: Dec 11, 2011
|
||||
* Author: MatLab
|
||||
*/
|
||||
|
||||
#ifndef TWISTWIDGET_H_
|
||||
#define TWISTWIDGET_H_
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
class QGridLayout;
|
||||
|
||||
namespace rtabmap {
|
||||
|
||||
class TwistGridWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TwistGridWidget(QWidget * parent = 0, Qt::WindowFlags f = 0);
|
||||
virtual ~TwistGridWidget() {}
|
||||
|
||||
public slots:
|
||||
void addTwist(float x, float y, float z, float roll, float pitch, float yaw, int row=0, int col=0);
|
||||
|
||||
private:
|
||||
QGridLayout * _grid;
|
||||
};
|
||||
|
||||
class TwistWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TwistWidget(float x, float y, float z, float roll, float pitch, float yaw, QWidget * parent, Qt::WindowFlags f = 0);
|
||||
virtual ~TwistWidget() {}
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent * event);
|
||||
|
||||
private:
|
||||
float _x;
|
||||
float _y;
|
||||
float _z;
|
||||
float _roll;
|
||||
float _pitch;
|
||||
float _yaw;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* TWISTWIDGET_H_ */
|
||||
@@ -1,22 +0,0 @@
|
||||
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
|
||||
@@ -14,9 +14,6 @@
|
||||
<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">
|
||||
@@ -27,6 +24,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_clear">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>842</width>
|
||||
<height>25</height>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuFile">
|
||||
@@ -228,7 +228,7 @@
|
||||
<number>8</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="rtabmap::Plot" name="posteriorPlot" native="true"/>
|
||||
</item>
|
||||
@@ -268,7 +268,7 @@
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="10,0">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
@@ -297,6 +297,9 @@
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
@@ -407,13 +410,6 @@
|
||||
</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">
|
||||
@@ -424,26 +420,25 @@
|
||||
</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="suffix">
|
||||
<string> ms</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10.000000000000000</double>
|
||||
<double>99999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>50.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.450000000000000</double>
|
||||
<double>450.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -494,16 +489,9 @@
|
||||
<number>8</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="rtabmap::Plot" name="likelihoodPlot" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="rtabmap::Plot" name="likelihoodPlot" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@@ -523,6 +511,24 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="dockWidget_twist">
|
||||
<property name="floating">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Actions</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>1</number>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="dockWidgetContents_5">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="rtabmap::TwistGridWidget" name="twistWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<action name="actionExit">
|
||||
<property name="text">
|
||||
<string>Exit</string>
|
||||
@@ -735,6 +741,12 @@
|
||||
<header>ConsoleWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>rtabmap::TwistGridWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>TwistWidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../GuiLib.qrc"/>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user