merged attention branch to trunk

git-svn-id: http://rtabmap.googlecode.com/svn/trunk/rtabmap@657 f169173b-cf89-36c8-b27e-44dbe73f0c83
This commit is contained in:
matlabbe
2012-12-11 18:05:05 +00:00
parent f9033809a2
commit 2836d4c48c
216 changed files with 7983 additions and 94891 deletions

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DATABASEVIEWER_H_
#define DATABASEVIEWER_H_
#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
#include <QtGui/QMainWindow>
#include <QtCore/QByteArray>
#include <QtCore/QMap>
#include <QtCore/QSet>
#include <QtGui/QImage>
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <set>
class Ui_DatabaseViewer;
class QGraphicsScene;
class QGraphicsView;
class QLabel;
namespace rtabmap
{
class Memory;
}
class RTABMAP_EXP DatabaseViewer : public QMainWindow
{
Q_OBJECT
public:
DatabaseViewer(QWidget * parent = 0);
virtual ~DatabaseViewer();
bool openDatabase(const QString & path);
private slots:
void openDatabase();
void generateGraph();
void generateLocalGraph();
void sliderAValueChanged(int);
void sliderBValueChanged(int);
void sliderAMoved(int);
void sliderBMoved(int);
private:
void updateIds();
QImage ipl2QImage(const IplImage *newImage);
void drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords, QGraphicsScene * scene);
void update(int value,
QLabel * labelIndex,
QLabel * labelActions,
QLabel * labelParents,
QLabel * labelChildren,
QGraphicsView * view,
QLabel * labelId);
private:
Ui_DatabaseViewer * ui_;
QMap<int, QByteArray> imagesMap_;
QList<int> ids_;
rtabmap::Memory * memory_;
QString pathDatabase_;
};
#endif /* DATABASEVIEWER_H_ */

View File

@@ -30,8 +30,6 @@
namespace rtabmap {
class Camera;
class Micro;
class CameraMicro;
class DBReader;
}
@@ -93,14 +91,13 @@ private slots:
void pauseDetection();
void stopDetection();
void generateMap();
void generateLocalMap();
void deleteMemory();
void openWorkingDirectory();
void updateEditMenu();
void selectImages();
void selectVideo();
void selectStream();
void selectMic();
void selectAudioFile();
void selectDatabase();
void resetTheMemory();
void dumpTheMemory();
@@ -137,14 +134,12 @@ signals:
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);
void setupMainLayout(bool vertical);
void updateSelectSourceImageMenu(int type);
void updateSelectSourceAudioMenu(int type);
void updateSelectSourceDatabase(bool used);
private:
@@ -152,8 +147,6 @@ private:
State _state;
rtabmap::Camera * _camera;
rtabmap::Micro * _mic;
rtabmap::CameraMicro * _cameraMic;
rtabmap::DBReader * _dbReader;
SrcType _srcType;
@@ -175,14 +168,10 @@ private:
PdfPlotCurve * _posteriorCurve;
PdfPlotCurve * _likelihoodCurve;
UPlotCurve * _audioCurve;
UPlotCurve * _audioCurveLoop;
PdfPlotCurve * _rawLikelihoodCurve;
DetailedProgressDialog * _initProgressDialog;
QActionGroup * _selectSourceImageGrp;
QActionGroup * _selectSourceAudioGrp;
QString _graphSavingFileName;
QString _autoScreenCaptureFormat;

View File

@@ -24,6 +24,7 @@
#include <QtGui/QDialog>
#include <QtCore/QModelIndex>
#include <set>
#include "rtabmap/core/Parameters.h"
@@ -66,12 +67,6 @@ public:
kSrcVideo
};
enum SrcAudio {
kSrcAudioUndef,
kSrcAudioMicDevice,
kSrcAudioFile
};
public:
static QString getIniFilePath();
@@ -108,7 +103,6 @@ public:
// source panel
double getGeneralInputRate() const;
bool isSourceImageUsed() const;
bool isSourceAudioUsed() const;
bool isSourceDatabaseUsed() const;
bool getGeneralAutoRestart() const;
bool getGeneralCameraKeypoints() const;
@@ -124,29 +118,22 @@ public:
bool getSourceImagesRefreshDir() const; //Images group
QString getSourceVideoPath() const; //Video group
int getSourceUsbDeviceId() const; //UsbDevice group
int getSourceAudioType() const; //Audio group
QString getSourceAudioTypeStr() const; //Audio group
int getSourceMicDevice() const; //Audio group
int getSourceMicFs() const; //Audio group
int getSourceMicSampleSize() const; //Audio group
QString getSourceAudioPath() const; //Audio group
bool getSourceAudioPlayWhileRecording() const; //Audio group
QString getSourceDatabasePath() const; //Database group
int getSourceDatabaseStartPos() const; //Database group
int getIgnoredDCComponents() const;
//
bool isImagesKept() const;
float getTimeLimit() const;
int getMemoryType() const;
//specific
bool isStatisticsPublished() const;
double getLoopThr() const;
double getRetrievalThr() const;
double getVpThr() const;
double getExpThr() const;
//
void disableSourceAudio();
void disableGeneralCameraKeypoints();
signals:
@@ -156,11 +143,9 @@ signals:
public slots:
void setInputRate(double value);
void setHardThr(int value);
void setRetrievalThr(int value);
void setAutoRestart(bool value);
void setTimeLimit(float value);
void selectSourceImage(Src src = kSrcUndef);
void selectSourceAudio(SrcAudio = kSrcAudioUndef);
void selectSourceDatabase(bool user = false);
private slots:
@@ -182,6 +167,7 @@ private slots:
void readSettingsEnd();
void setupTreeView();
void updateBasicParameter();
void openDatabaseViewer();
protected:
virtual void showEvent ( QShowEvent * event );

View File

@@ -4,13 +4,13 @@
SET(headers_ui
../include/${PROJECT_PREFIX}/gui/MainWindow.h
../include/${PROJECT_PREFIX}/gui/PreferencesDialog.h
../include/${PROJECT_PREFIX}/gui/DatabaseViewer.h
./AboutDialog.h
./ConsoleWidget.h
../include/${PROJECT_PREFIX}/gui/ImageView.h
./PdfPlot.h
./StatsToolBox.h
./DetailedProgressDialog.h
./TwistWidget.h
)
SET(uis
@@ -18,6 +18,7 @@ SET(uis
./ui/preferencesDialog.ui
./ui/aboutDialog.ui
./ui/consoleWidget.ui
./ui/DatabaseViewer.ui
)
SET(qrc
@@ -48,7 +49,7 @@ SET(SRC_FILES
./DetailedProgressDialog.cpp
./AboutDialog.cpp
./ConsoleWidget.cpp
./TwistWidget.cpp
./DatabaseViewer.cpp
${moc_srcs}
${moc_uis}
${srcs_qrc}

View File

@@ -1,84 +0,0 @@
/*
* CameraMicro.h
*
* Created on: 2012-05-27
* Author: mathieu
*/
#ifndef CAMERAMICRO_H_
#define CAMERAMICRO_H_
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/Micro.h"
#include "rtabmap/core/SensorimotorEvent.h"
#include <utilite/UThreadNode.h>
#include <utilite/UEventsManager.h>
namespace rtabmap
{
class CameraMicro : public UThreadNode
{
public:
CameraMicro(Camera * camera, Micro * micro) :
camera_(camera),
micro_(micro)
{
}
protected:
void mainLoopBegin()
{
if(!camera_ || !micro_ )
{
UERROR("Camera and/or Micro are null");
this->kill();
return;
}
micro_->startRecorder();
}
void mainLoop()
{
cv::Mat frameFreq;
// frame rate should depend on micro and camera frame rate
// (getFrame() and takeImage() are blocking calls)
cv::Mat frame = micro_->getFrame(frameFreq, true);
if(frame.empty())
{
if(this->isRunning())
{
UEventsManager::post(new MicroEvent(MicroEvent::kTypeNoMoreFrames));
this->kill();
}
return;
}
cv::Mat image = camera_->takeImage();
if(image.empty())
{
UEventsManager::post(new CameraEvent(CameraEvent::kCodeNoMoreImages));
this->kill();
return;
}
std::list<Sensor> sensors;
sensors.push_back(Sensor(image, Sensor::kTypeImage));
sensors.push_back(Sensor(frameFreq, Sensor::kTypeAudioFreqSqrdMagn));
UEventsManager::post(new SensorimotorEvent(sensors, std::list<Actuator>()));
}
void mainLoopKill()
{
if(micro_)
{
micro_->stop();
}
}
private:
Camera * camera_;
Micro * micro_;
};
}
#endif /* CAMERAMICRO_H_ */

View File

@@ -0,0 +1,420 @@
/*
* Copyright (C) 2010-2011, Mathieu Labbe and IntRoLab - Universite de Sherbrooke
*
* This file is part of RTAB-Map.
*
* RTAB-Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RTAB-Map is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RTAB-Map. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rtabmap/gui/DatabaseViewer.h"
#include "ui_DatabaseViewer.h"
#include <QtGui/QMessageBox>
#include <QtGui/QFileDialog>
#include <QtGui/QInputDialog>
#include <QtCore/QBuffer>
#include <QtCore/QTextStream>
#include <utilite/ULogger.h>
#include <utilite/UDirectory.h>
#include <utilite/UConversion.h>
#include <opencv2/core/core_c.h>
#include <utilite/UTimer.h>
#include "rtabmap/core/Memory.h"
#include "rtabmap/core/DBDriver.h"
#include "rtabmap/gui/KeypointItem.h"
DatabaseViewer::DatabaseViewer(QWidget * parent) :
QMainWindow(parent),
memory_(0)
{
pathDatabase_ = QDir::homePath()+"/Documents/RTAB-Map"; //use home directory by default
if(!UDirectory::exists(pathDatabase_.toStdString()))
{
pathDatabase_ = QDir::homePath();
}
ui_ = new Ui_DatabaseViewer();
ui_->setupUi(this);
connect(ui_->actionQuit, SIGNAL(triggered()), this, SLOT(close()));
connect(ui_->buttonBox, SIGNAL(rejected()), this, SLOT(close()));
// connect actions with custom slots
connect(ui_->actionOpen_database, SIGNAL(triggered()), this, SLOT(openDatabase()));
connect(ui_->actionGenerate_graph_dot, SIGNAL(triggered()), this, SLOT(generateGraph()));
connect(ui_->actionGenerate_local_graph_dot, SIGNAL(triggered()), this, SLOT(generateLocalGraph()));
ui_->graphicsView_A->setScene(new QGraphicsScene(this));
ui_->graphicsView_B->setScene(new QGraphicsScene(this));
ui_->horizontalSlider_A->setTracking(false);
ui_->horizontalSlider_B->setTracking(false);
ui_->horizontalSlider_A->setEnabled(false);
ui_->horizontalSlider_B->setEnabled(false);
connect(ui_->horizontalSlider_A, SIGNAL(valueChanged(int)), this, SLOT(sliderAValueChanged(int)));
connect(ui_->horizontalSlider_B, SIGNAL(valueChanged(int)), this, SLOT(sliderBValueChanged(int)));
connect(ui_->horizontalSlider_A, SIGNAL(sliderMoved(int)), this, SLOT(sliderAMoved(int)));
connect(ui_->horizontalSlider_B, SIGNAL(sliderMoved(int)), this, SLOT(sliderBMoved(int)));
}
DatabaseViewer::~DatabaseViewer()
{
delete ui_;
if(memory_)
{
delete memory_;
}
}
void DatabaseViewer::openDatabase()
{
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), pathDatabase_, tr("Databases (*.db)"));
if(!path.isEmpty())
{
openDatabase(path);
}
}
bool DatabaseViewer::openDatabase(const QString & path)
{
UDEBUG("Open database \"%s\"", path.toStdString().c_str());
if(QFile::exists(path))
{
QStringList types;
types << "Keypoint" << "Sensorimotor";
if(memory_)
{
delete memory_;
memory_ = 0;
imagesMap_.clear();
ids_.clear();
}
std::string driverType = "sqlite3";
rtabmap::ParametersMap parameters;
parameters.insert(rtabmap::ParametersPair(rtabmap::Parameters::kDbSqlite3InMemory(), "false"));
memory_ = new rtabmap::Memory(parameters);
if(!memory_->init(path.toStdString()))
{
QMessageBox::warning(this, "Database error", tr("Can't open database \"%1\"").arg(path));
}
else
{
pathDatabase_ = UDirectory::getDir(path.toStdString()).c_str();
updateIds();
return true;
}
}
else
{
QMessageBox::warning(this, "Database error", tr("Database \"%1\" does not exist.").arg(path));
}
return false;
}
void DatabaseViewer::updateIds()
{
if(!memory_)
{
return;
}
std::set<int> ids = memory_->getAllSignatureIds();
ids_ = QList<int>::fromStdList(std::list<int>(ids.begin(), ids.end()));
ids_.prepend(0);
UDEBUG("Loaded %d ids", ids_.size());
if(ids_.size())
{
ui_->horizontalSlider_A->setMinimum(0);
ui_->horizontalSlider_B->setMinimum(0);
ui_->horizontalSlider_A->setMaximum(ids_.size()-1);
ui_->horizontalSlider_B->setMaximum(ids_.size()-1);
ui_->horizontalSlider_A->setSliderPosition(0);
ui_->horizontalSlider_B->setSliderPosition(0);
ui_->horizontalSlider_A->setEnabled(true);
ui_->horizontalSlider_B->setEnabled(true);
ui_->label_idA->setText("0");
ui_->label_idB->setText("0");
}
else
{
ui_->horizontalSlider_A->setEnabled(false);
ui_->horizontalSlider_B->setEnabled(false);
ui_->label_idA->setText("NaN");
ui_->label_idB->setText("NaN");
}
}
void DatabaseViewer::generateGraph()
{
if(!memory_)
{
QMessageBox::warning(this, tr("Cannot generate a graph"), tr("A database must must loaded first...\nUse File->Open database."));
return;
}
QString path = QFileDialog::getSaveFileName(this, tr("Save File"), pathDatabase_+"/Graph.dot", tr("Graphiz file (*.dot)"));
if(!path.isEmpty())
{
memory_->generateGraph(path.toStdString());
}
}
void DatabaseViewer::generateLocalGraph()
{
if(!ids_.size() || !memory_)
{
QMessageBox::warning(this, tr("Cannot generate a graph"), tr("The database is empty..."));
return;
}
bool ok = false;
int id = QInputDialog::getInt(this, tr("Around which location?"), tr("Location ID"), ids_.first(), ids_.first(), ids_.last(), 1, &ok);
if(ok)
{
int margin = QInputDialog::getInt(this, tr("Depth around the location?"), tr("Margin"), 4, 1, 100, 1, &ok);
if(ok)
{
QString path = QFileDialog::getSaveFileName(this, tr("Save File"), pathDatabase_+"/Graph" + QString::number(id) + ".dot", tr("Graphiz file (*.dot)"));
if(!path.isEmpty())
{
std::map<int, int> ids = memory_->getNeighborsId(id, margin, -1, false);
if(ids.size() > 0)
{
ids.insert(std::pair<int,int>(id, 0));
std::set<int> idsSet;
for(std::map<int, int>::iterator iter = ids.begin(); iter!=ids.end(); ++iter)
{
idsSet.insert(idsSet.end(), iter->first);
UINFO("Node %d", iter->first);
}
UINFO("idsSet=%d", idsSet.size());
memory_->generateGraph(path.toStdString(), idsSet);
}
else
{
QMessageBox::critical(this, tr("Error"), tr("No neighbors found for signature %1.").arg(id));
}
}
}
}
}
void DatabaseViewer::drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords, QGraphicsScene * scene)
{
if(!scene)
{
return;
}
rtabmap::KeypointItem * item = 0;
int alpha = 70;
for(std::multimap<int, cv::KeyPoint>::const_iterator i = refWords.begin(); i != refWords.end(); ++i )
{
const cv::KeyPoint & r = (*i).second;
int id = (*i).first;
QString info = QString( "WordRef = %1\n"
"Laplacian = %2\n"
"Dir = %3\n"
"Hessian = %4\n"
"X = %5\n"
"Y = %6\n"
"Size = %7").arg(id).arg(1).arg(r.angle).arg(r.response).arg(r.pt.x).arg(r.pt.y).arg(r.size);
float radius = r.size*1.2/9.*2;
item = new rtabmap::KeypointItem(r.pt.x-radius, r.pt.y-radius, radius*2, info, QColor(255, 255, 0, alpha));
scene->addItem(item);
item->setZValue(1);
}
}
void DatabaseViewer::sliderAValueChanged(int value)
{
this->update(value,
ui_->label_indexA,
ui_->label_actionsA,
ui_->label_parentsA,
ui_->label_childrenA,
ui_->graphicsView_A,
ui_->label_idA);
}
void DatabaseViewer::sliderBValueChanged(int value)
{
this->update(value,
ui_->label_indexB,
ui_->label_actionsB,
ui_->label_parentsB,
ui_->label_childrenB,
ui_->graphicsView_B,
ui_->label_idB);
}
void DatabaseViewer::update(int value,
QLabel * labelIndex,
QLabel * labelActions,
QLabel * labelParents,
QLabel * labelChildren,
QGraphicsView * view,
QLabel * labelId)
{
UTimer timer;
labelIndex->setText(QString::number(value));
labelActions->clear();
labelParents->clear();
labelChildren->clear();
if(value >= 0 && value < ids_.size())
{
view->scene()->clear();
int id = ids_.at(value);
labelId->setText(QString::number(id));
if(id>0)
{
//image
QImage img;
QMap<int, QByteArray>::iterator iter = imagesMap_.find(id);
if(iter == imagesMap_.end())
{
if(memory_)
{
cv::Mat image = memory_->getImage(id);
if(!image.empty())
{
IplImage iplImg = image;
img = ipl2QImage(&iplImg);
if(!img.isNull())
{
QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer, "BMP"); // writes image into ba in BMP format
imagesMap_.insert(id, ba);
}
}
}
}
else
{
img.loadFromData(iter.value(), "BMP");
}
if(memory_ && dynamic_cast<rtabmap::Memory*>(memory_))
{
std::multimap<int, cv::KeyPoint> words = dynamic_cast<rtabmap::Memory*>(memory_)->getWords(id);
if(words.size())
{
drawKeypoints(words, view->scene());
}
}
if(!img.isNull())
{
view->scene()->addPixmap(QPixmap::fromImage(img));
}
else
{
ULOGGER_DEBUG("Image is empty");
}
// loops
std::set<int> parents;
std::set<int> children;
memory_->getLoopClosureIds(id, parents, children, true);
if(parents.size())
{
QString str;
for(std::set<int>::iterator iter=parents.begin(); iter!=parents.end(); ++iter)
{
str.append(QString("%1 ").arg(*iter));
}
labelParents->setText(str);
}
if(children.size())
{
QString str;
for(std::set<int>::iterator iter=children.begin(); iter!=children.end(); ++iter)
{
str.append(QString("%1 ").arg(*iter));
}
labelChildren->setText(str);
}
}
labelId->setText(QString::number(id));
view->fitInView(view->scene()->itemsBoundingRect(), Qt::KeepAspectRatio);
}
else
{
ULOGGER_ERROR("Slider index out of range ?");
}
UINFO("Time = %fs", timer.ticks());
}
void DatabaseViewer::sliderAMoved(int value)
{
ui_->label_indexA->setText(QString::number(value));
if(value>=0 && value < ids_.size())
{
ui_->label_idA->setText(QString::number(ids_.at(value)));
}
else
{
ULOGGER_ERROR("Slider index out of range ?");
}
}
void DatabaseViewer::sliderBMoved(int value)
{
ui_->label_indexB->setText(QString::number(value));
if(value>=0 && value < ids_.size())
{
ui_->label_idB->setText(QString::number(ids_.at(value)));
}
else
{
ULOGGER_ERROR("Slider index out of range ?");
}
}
QImage DatabaseViewer::ipl2QImage(const IplImage *newImage)
{
QImage qtemp;
if (newImage && newImage->depth == IPL_DEPTH_8U && cvGetSize(newImage).width>0)
{
int x;
int y;
char* data = newImage->imageData;
qtemp= QImage(newImage->width, newImage->height,QImage::Format_RGB32 );
for( y = 0; y < newImage->height; y++, data +=newImage->widthStep )
{
for( x = 0; x < newImage->width; x++)
{
uint *p = (uint*)qtemp.scanLine (y) + x;
*p = qRgb(data[x * newImage->nChannels+2], data[x * newImage->nChannels+1],data[x * newImage->nChannels]);
}
}
}
else
{
ULOGGER_ERROR("Wrong IplImage format");
}
return qtemp;
}

View File

@@ -16,5 +16,6 @@
<file>images/IntRoLabSmall.png</file>
<file>images/metal_7280826_512.jpg</file>
<file>images/crosshatch_metal_grille_9280154_150.JPG</file>
<file>images/mag_glass.png</file>
</qresource>
</RCC>

View File

@@ -20,10 +20,7 @@
#include "rtabmap/gui/MainWindow.h"
#include "ui_mainWindow.h"
#include "rtabmap/core/Camera.h"
#include "rtabmap/core/Micro.h"
#include "rtabmap/core/DBReader.h"
#include "rtabmap/core/SensorimotorEvent.h"
#include "CameraMicro.h"
#include "rtabmap/gui/qtipl.h"
#include "rtabmap/gui/KeypointItem.h"
#include "AboutDialog.h"
@@ -34,9 +31,6 @@
#include "PdfPlot.h"
#include "StatsToolBox.h"
#include "DetailedProgressDialog.h"
#include "TwistWidget.h"
#include "rtabmap/core/Sensor.h"
#include <QtGui/QCloseEvent>
#include <QtGui/QPixmap>
@@ -74,8 +68,6 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_ui(0),
_state(kIdle),
_camera(0),
_mic(0),
_cameraMic(0),
_dbReader(0),
_srcType(kSrcUndefined),
_preferencesDialog(0),
@@ -86,6 +78,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_elapsedTime(0),
_posteriorCurve(0),
_likelihoodCurve(0),
_rawLikelihoodCurve(0),
_autoScreenCaptureFormat("png")
{
ULOGGER_DEBUG("");
@@ -112,11 +105,9 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
{
_ui->dockWidget_posterior->setVisible(false);
_ui->dockWidget_likelihood->setVisible(false);
_ui->dockWidget_rawlikelihood->setVisible(false);
_ui->dockWidget_statsV2->setVisible(false);
_ui->dockWidget_console->setVisible(false);
_ui->dockWidget_twist->setVisible(false);
_ui->dockWidget_audioLoopFrames->setVisible(false);
_ui->dockWidget_audioProcessedFrames->setVisible(false);
}
if(prefDialog)
@@ -148,23 +139,20 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(Qt::black));
_posteriorCurve = new PdfPlotCurve("Posterior", &_imagesMap, this);
_ui->posteriorPlot->addCurve(_posteriorCurve);
_ui->posteriorPlot->addCurve(_posteriorCurve, false);
_ui->posteriorPlot->showLegend(false);
_ui->posteriorPlot->setFixedYAxis(0,1);
UPlotCurveThreshold * tc;
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(retrievalThrChanged(float)), tc, SLOT(setThreshold(float)));
_likelihoodCurve = new PdfPlotCurve("Likelihood", &_imagesMap, this);
_ui->likelihoodPlot->addCurve(_likelihoodCurve);
_ui->likelihoodPlot->addCurve(_likelihoodCurve, false);
_ui->likelihoodPlot->showLegend(false);
_ui->widget_audioProcessedFrames->setScaled(true, true);
_ui->widget_audioProcessedFrames->setOnlyLastFramesDrawn(true);
_ui->widget_audioLoopFrames->setScaled(true, true);
_ui->widget_audioLoopFrames->setOnlyLastFramesDrawn(true);
_rawLikelihoodCurve = new PdfPlotCurve("Likelihood", &_imagesMap, this);
_ui->rawLikelihoodPlot->addCurve(_rawLikelihoodCurve, false);
_ui->rawLikelihoodPlot->showLegend(false);
_ui->doubleSpinBox_stats_imgRate->setValue(_preferencesDialog->getGeneralInputRate());
_ui->doubleSpinBox_stats_timeLimit->setValue(_preferencesDialog->getTimeLimit());
@@ -183,11 +171,9 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
// Dock Widget view actions (Menu->Window)
_ui->menuShow_view->addAction(_ui->dockWidget_posterior->toggleViewAction());
_ui->menuShow_view->addAction(_ui->dockWidget_likelihood->toggleViewAction());
_ui->menuShow_view->addAction(_ui->dockWidget_rawlikelihood->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->dockWidget_audioLoopFrames->toggleViewAction());
_ui->menuShow_view->addAction(_ui->dockWidget_audioProcessedFrames->toggleViewAction());
_ui->menuShow_view->addAction(_ui->toolBar->toggleViewAction());
_ui->toolBar->setWindowTitle(tr("Control toolbar"));
QAction * a = _ui->menuShow_view->addAction("Status");
@@ -204,6 +190,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
connect(_ui->actionClear_cache, SIGNAL(triggered()), this, SLOT(clearTheCache()));
connect(_ui->actionAbout, SIGNAL(triggered()), _aboutDialog , SLOT(exec()));
connect(_ui->actionGenerate_map, SIGNAL(triggered()), this , SLOT(generateMap()));
connect(_ui->actionGenerate_local_map, SIGNAL(triggered()), this, SLOT(generateLocalMap()));
connect(_ui->actionDelete_memory, SIGNAL(triggered()), this , SLOT(deleteMemory()));
connect(_ui->menuEdit, SIGNAL(aboutToShow()), this, SLOT(updateEditMenu()));
connect(_ui->actionAuto_screen_capture, SIGNAL(triggered(bool)), this, SLOT(selectScreenCaptureFormat(bool)));
@@ -233,12 +220,6 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
connect(_ui->actionImageFiles, SIGNAL(triggered()), this, SLOT(selectImages()));
connect(_ui->actionVideo, SIGNAL(triggered()), this, SLOT(selectVideo()));
connect(_ui->actionUsbCamera, SIGNAL(triggered()), this, SLOT(selectStream()));
_selectSourceAudioGrp = new QActionGroup(this);
_selectSourceAudioGrp->addAction(_ui->actionMic);
_selectSourceAudioGrp->addAction(_ui->actionAudioFile);
this->updateSelectSourceAudioMenu(_preferencesDialog->getSourceAudioType());
connect(_ui->actionMic, SIGNAL(triggered()), this, SLOT(selectMic()));
connect(_ui->actionAudioFile, SIGNAL(triggered()), this, SLOT(selectAudioFile()));
this->updateSelectSourceDatabase(_preferencesDialog->isSourceDatabaseUsed());
connect(_ui->actionDatabase, SIGNAL(triggered()), this, SLOT(selectDatabase()));
@@ -260,7 +241,6 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent) :
connect(this, SIGNAL(imgRateChanged(double)), _preferencesDialog, SLOT(setInputRate(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");
connect(this, SIGNAL(statsReceived(rtabmap::Statistics)), this, SLOT(processStats(rtabmap::Statistics)));
@@ -326,6 +306,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
_preferencesDialog->saveMainWindowState(this);
_ui->dockWidget_likelihood->close();
_ui->dockWidget_rawlikelihood->close();
_ui->dockWidget_posterior->close();
_ui->dockWidget_statsV2->close();
_ui->dockWidget_console->close();
@@ -336,18 +317,6 @@ void MainWindow::closeEvent(QCloseEvent* event)
delete _camera;
_camera = 0;
}
if(_mic)
{
UERROR("Mic must be already deleted here!");
delete _mic;
_mic = 0;
}
if(_cameraMic)
{
UERROR("CameraMic must be already deleted here!");
delete _mic;
_mic = 0;
}
if(_dbReader)
{
UERROR("DBReader must be already deleted here!");
@@ -382,7 +351,7 @@ void MainWindow::handleEvent(UEvent* anEvent)
this->pauseDetection();
}
}
UDEBUG("stat.rawLikelihood().size()=%d", stats.rawLikelihood().size());
// 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())
@@ -393,6 +362,10 @@ void MainWindow::handleEvent(UEvent* anEvent)
{
stats.setLikelihood(std::map<int, float>());
}
if(_processingStatistics || !_ui->dockWidget_rawlikelihood->isVisible())
{
stats.setRawLikelihood(std::map<int, float>());
}
if(_processingStatistics || (!_ui->dockWidget_posterior->isVisible() && !_ui->dockWidget_likelihood->isVisible()))
{
stats.setWeights(std::map<int,int>());
@@ -403,7 +376,7 @@ void MainWindow::handleEvent(UEvent* anEvent)
else if(anEvent->getClassName().compare("RtabmapEventInit") == 0)
{
RtabmapEventInit * rtabmapEventInit = (RtabmapEventInit*)anEvent;
emit rtabmapEventInitReceived(rtabmapEventInit->getStatus(), rtabmapEventInit->getInfo().c_str());
emit rtabmapEventInitReceived((int)rtabmapEventInit->getStatus(), rtabmapEventInit->getInfo().c_str());
}
else if(anEvent->getClassName().compare("CameraEvent") == 0)
@@ -418,18 +391,6 @@ void MainWindow::handleEvent(UEvent* anEvent)
emit noMoreImagesReceived();
}
}
else if(anEvent->getClassName().compare("MicroEvent") == 0)
{
MicroEvent * microEvent = (MicroEvent*)anEvent;
if(microEvent->getCode() == MicroEvent::kTypeNoMoreFrames)
{
if(_preferencesDialog->beepOnPause())
{
QMetaObject::invokeMethod(this, "beep");
}
emit noMoreImagesReceived();
}
}
else if(anEvent->getClassName().compare("ULogEvent") == 0)
{
ULogEvent * logEvent = (ULogEvent*)anEvent;
@@ -448,19 +409,6 @@ void MainWindow::handleEvent(UEvent* anEvent)
}
}
}
else if(anEvent->getClassName().compare("SensorimotorEvent") == 0)
{
SensorimotorEvent * e = (rtabmap::SensorimotorEvent*)anEvent;
if(e->getCode() == SensorimotorEvent::kTypeNoMoreData)
{
if(_preferencesDialog->beepOnPause())
{
QMetaObject::invokeMethod(this, "beep");
}
emit noMoreImagesReceived();
}
}
}
void MainWindow::processStats(const rtabmap::Statistics & stat)
@@ -472,10 +420,15 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
//Affichage des stats et images
if(stat.extended())
{
float totalTime = static_cast<float>(uValue(stat.data(), Statistics::kTimingTotal(), 0.0f));
if(totalTime/1000.0f > float(1.0/_preferencesDialog->getGeneralInputRate()))
{
UWARN("Processing time (%fs) is over acquisition time (%fs), real-time problem!", totalTime/1000.0f, 1.0/_preferencesDialog->getGeneralInputRate());
}
UDEBUG("");
_ui->label_refId->setText(QString("New ID = %1").arg(stat.refImageId()));
int highestHypothesisId = static_cast<float>(uValue(stat.data(), Statistics::kLoopHighest_hypothesis_id(), 0.0f));
bool refParentId = (int)uValue(stat.data(), Statistics::kParent_id(), 0.0f);
bool highestHypothesisIsSaved = (bool)uValue(stat.data(), Statistics::kHypothesis_reactivated(), 0.0f);
// Loop closure info
@@ -485,69 +438,9 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
_ui->imageView_loopClosure->resetTransform();
_ui->imageView_loopClosure->setBackgroundBrush(QBrush(Qt::black));
// extract some sensors
cv::Mat refImage;
cv::Mat refAudioFrame;
bool twistSet = false;
for(std::list<Sensor>::const_iterator iter = stat.refRawData().begin(); iter!=stat.refRawData().end(); ++iter)
{
if(refImage.empty() && iter->type() == Sensor::kTypeImage)
{
refImage = iter->data();
}
else if(refAudioFrame.empty() && iter->type() == Sensor::kTypeAudioFreqSqrdMagn)
{
refAudioFrame = iter->data();
}
else if(iter->type() == Sensor::kTypeTwist)
{
if(!twistSet)
{
const Sensor & a = *iter;
if(a.data().total() == 6 && (a.data().type() & CV_32F))
{
emit twistReceived(a.data().at<float>(0),
a.data().at<float>(1),
a.data().at<float>(2),
a.data().at<float>(3),
a.data().at<float>(4),
a.data().at<float>(5),
0,
0);
}
else
{
UERROR("Twist must be CV_32F and have 6 elements (%d)", a.data().total());
}
twistSet = true; // Show only the first
}
}
else if(iter->type() != Sensor::kTypeImageFeatures2d)
{
UWARN("Source type %d not handled", iter->type());
}
}
cv::Mat loopImage;
cv::Mat loopAudioFrame;
for(std::list<Sensor>::const_iterator iter = stat.loopClosureRawData().begin(); iter!=stat.loopClosureRawData().end(); ++iter)
{
if(loopImage.empty() && iter->type() == Sensor::kTypeImage)
{
loopImage = iter->data();
}
else if(loopAudioFrame.empty() && iter->type() == Sensor::kTypeAudioFreqSqrdMagn)
{
loopAudioFrame = iter->data();
}
else if(iter->type() == Sensor::kTypeTwist)
{
// do nothing
}
else if(iter->type() != Sensor::kTypeImageFeatures2d)
{
UWARN("Source type %d not handled", iter->type());
}
}
// get images
cv::Mat refImage = stat.refImage();
cv::Mat loopImage = stat.loopImage();
_ui->label_matchId->clear();
QPixmap refPixmap;
@@ -571,23 +464,6 @@ 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));
}
}
QImage lcImg;
@@ -668,22 +544,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
if(!lcImg.isNull())
{
_ui->imageView_loopClosure->scene()->addPixmap(QPixmap::fromImage(lcImg))->setVisible(this->_ui->imageView_loopClosure->isImageShown());
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));
}
}
}
}
@@ -722,102 +582,25 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
if(!stat.posterior().empty() && _ui->dockWidget_posterior->isVisible())
{
UDEBUG("");
if(!refParentId)
if(stat.weights().size() != stat.posterior().size())
{
_posteriorCurve->setData(QMap<int, float>(stat.posterior()), QMap<int, int>(stat.weights()), stat.refImageId());
}
else
{
// if the new signature has a parent, don't add it
_posteriorCurve->setData(QMap<int, float>(stat.posterior()), QMap<int, int>(stat.weights()), 0);
UWARN("%d %d", stat.weights().size(), stat.posterior().size());
}
_posteriorCurve->setData(QMap<int, float>(stat.posterior()), QMap<int, int>(stat.weights()));
ULOGGER_DEBUG("");
//Adjust thresholds
float value;
value = float(_preferencesDialog->getLoopThr());
emit(loopClosureThrChanged(value));
value = float(_preferencesDialog->getRetrievalThr());
emit(retrievalThrChanged(value));
}
if(!stat.likelihood().empty() && _ui->dockWidget_likelihood->isVisible())
{
UDEBUG("");
if(!refParentId)
{
_likelihoodCurve->setData(QMap<int, float>(stat.likelihood()), QMap<int, int>(stat.weights()), stat.refImageId());
}
else
{
// if the new signature has a parent, don't add it
_likelihoodCurve->setData(QMap<int, float>(stat.likelihood()), QMap<int, int>(stat.weights()), 0);
}
ULOGGER_DEBUG("");
_likelihoodCurve->setData(QMap<int, float>(stat.likelihood()), QMap<int, int>(stat.weights()));
}
// Audio frame
if(_ui->dockWidget_audioProcessedFrames->isVisible() && !refAudioFrame.empty())
if(!stat.rawLikelihood().empty() && _ui->dockWidget_rawlikelihood->isVisible())
{
if(_mic)
{
_ui->widget_audioProcessedFrames->setSamplingRate(_mic->fs());
}
std::vector<float> v((float*)refAudioFrame.data, ((float*)refAudioFrame.data) + refAudioFrame.cols);
_ui->widget_audioProcessedFrames->push(v);
}
if(_ui->dockWidget_audioLoopFrames->isVisible())
{
if(_mic)
{
_ui->widget_audioLoopFrames->setSamplingRate(_mic->fs());
}
std::vector<float> v;
if(!loopAudioFrame.empty())
{
v = std::vector<float>((float*)loopAudioFrame.data, ((float*)loopAudioFrame.data) + loopAudioFrame.cols);
}
else if(!refAudioFrame.empty())
{
v = std::vector<float>(refAudioFrame.cols, 0);
}
if(v.size())
{
_ui->widget_audioLoopFrames->push(v);
}
}
// ACTIONS
if(stat.getActuators().size())
{
const std::list<Actuator> & actuators = stat.getActuators();
for(std::list<Actuator>::const_iterator iter=actuators.begin(); iter!=actuators.end(); ++iter)
{
const Actuator & a = *iter;
if(a.type() == Actuator::kTypeTwist)
{
if(a.data().total() == 6 && (a.data().type() & CV_32F))
{
emit twistReceived(a.data().at<float>(0),
a.data().at<float>(1),
a.data().at<float>(2),
a.data().at<float>(3),
a.data().at<float>(4),
a.data().at<float>(5),
1,
0);
}
else
{
UERROR("Twist must be CV_32F and have 6 elements (%d)", a.data().total());
}
break; // Show only the first
}
}
}
else
{
UDEBUG("Actions are empty...");
_rawLikelihoodCurve->setData(QMap<int, float>(stat.rawLikelihood()), QMap<int, int>(stat.weights()));
}
// Update statistics tool box
@@ -827,6 +610,7 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
//ULOGGER_DEBUG("Updating stat \"%s\"", (*iter).first.c_str());
_ui->statsToolBox->updateStat(QString((*iter).first.c_str()).replace('_', ' '), stat.refImageId(), (*iter).second);
}
UDEBUG("");
}
else if(!stat.extended() && stat.loopClosureId()>0)
@@ -895,21 +679,12 @@ void MainWindow::applyPrefSettings(PreferencesDialog::PANEL_FLAGS flags)
// Camera settings...
_ui->doubleSpinBox_stats_imgRate->setValue(_preferencesDialog->getGeneralInputRate());
this->updateSelectSourceImageMenu(_preferencesDialog->getSourceImageType());
this->updateSelectSourceAudioMenu(_preferencesDialog->getSourceAudioType());
this->updateSelectSourceDatabase(_preferencesDialog->isSourceDatabaseUsed());
QString src;
if(_preferencesDialog->isSourceImageUsed() && _preferencesDialog->isSourceAudioUsed())
{
src = (_preferencesDialog->getSourceImageTypeStr() + "+") + _preferencesDialog->getSourceAudioTypeStr();
}
else if(_preferencesDialog->isSourceImageUsed())
if(_preferencesDialog->isSourceImageUsed())
{
src = _preferencesDialog->getSourceImageTypeStr();
}
else if(_preferencesDialog->isSourceAudioUsed())
{
src = _preferencesDialog->getSourceAudioTypeStr();
}
else if(_preferencesDialog->isSourceDatabaseUsed())
{
src = "Database";
@@ -973,8 +748,6 @@ void MainWindow::applyPrefSettings(const rtabmap::ParametersMap & parameters)
float value;
value = float(_preferencesDialog->getLoopThr());
emit(loopClosureThrChanged(value));
value = float(_preferencesDialog->getRetrievalThr());
emit(retrievalThrChanged(value));
}
void MainWindow::drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords, const std::multimap<int, cv::KeyPoint> & loopWords)
@@ -1085,7 +858,7 @@ void MainWindow::drawKeypoints(const std::multimap<int, cv::KeyPoint> & refWords
{
_lastId = (*refWords.rbegin()).first;
}
_lastIds = QSet<int>::fromList(QList<int>::fromStdList(uKeys(refWords)));
_lastIds = QSet<int>::fromList(QList<int>::fromStdList(uKeysList(refWords)));
}
// Draw lines between corresponding features...
@@ -1157,29 +930,6 @@ void MainWindow::updateSelectSourceImageMenu(int type)
}
}
void MainWindow::updateSelectSourceAudioMenu(int type)
{
if(_preferencesDialog->isSourceAudioUsed())
{
switch(type)
{
case 0:
_ui->actionMic->setChecked(true);
break;
case 1:
default:
_ui->actionAudioFile->setChecked(true);
break;
}
}
else
{
// they are exclusive actions, so check/uncheck one should disable all.
_ui->actionMic->setChecked(true);
_ui->actionMic->setChecked(false);
}
}
void MainWindow::updateSelectSourceDatabase(bool used)
{
_ui->actionDatabase->setChecked(used);
@@ -1241,15 +991,6 @@ void MainWindow::startDetection()
emit stateChanged(kIdle);
return;
}
if(_mic != 0)
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("A mic is running, stop it first."));
UWARN("_mic is not null... it must be stopped first");
emit stateChanged(kIdle);
return;
}
if(_dbReader != 0)
{
QMessageBox::warning(this,
@@ -1262,7 +1003,6 @@ void MainWindow::startDetection()
// Adjust pre-requirements
if( !_preferencesDialog->isSourceImageUsed() &&
!_preferencesDialog->isSourceAudioUsed() &&
!_preferencesDialog->isSourceDatabaseUsed())
{
QMessageBox::warning(this,
@@ -1272,54 +1012,13 @@ void MainWindow::startDetection()
emit stateChanged(kIdle);
return;
}
if(_preferencesDialog->getMemoryType() == 0)
{
//KeypointMemory
if(!_preferencesDialog->isSourceImageUsed() && !_preferencesDialog->isSourceDatabaseUsed())
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("Image source is not selected. See Preferences->Source panel. "
"Keypoint memory only works with images."));
UWARN("Image source is not selected. See Preferences->Source panel. "
"Keypoint memory only works with images.");
emit stateChanged(kIdle);
return;
}
else if(_preferencesDialog->isSourceAudioUsed())
{
QMessageBox::information(this,
tr("RTAB-Map"),
tr("Audio source is selected. Keypoint memory only works with images... "
"the audio source is now disabled."));
UDEBUG("Audio source is selected. Keypoint memory only works with images... "
"the audio source is now disabled.");
_preferencesDialog->disableSourceAudio();
}
}
else
{
//SM memory
if(_preferencesDialog->isSourceImageUsed() && _preferencesDialog->getGeneralCameraKeypoints())
{
QMessageBox::information(this,
tr("RTAB-Map"),
tr("Keypoint features extraction is selected for the camera. "
"Sensorimotor memory doesn't handle features (only raw images), "
"so it is overkill to extract them... keypoints extraction is now disabled."));
UDEBUG("Keypoint features extraction is selected for the camera. "
"Sensorimotor memory doesn't handle features (only raw images), "
"so it is overkill to extract them... keypoints extraction is now disabled.");
_preferencesDialog->disableGeneralCameraKeypoints();
}
}
if(_preferencesDialog->isSourceDatabaseUsed())
{
_dbReader = new DBReader(_preferencesDialog->getSourceDatabasePath().toStdString(),
_preferencesDialog->getGeneralInputRate());
if(!_dbReader->init())
if(!_dbReader->init(_preferencesDialog->getSourceDatabaseStartPos()))
{
ULOGGER_WARN("init DBReader failed... ");
QMessageBox::warning(this,
@@ -1401,51 +1100,6 @@ void MainWindow::startDetection()
UEventsManager::addHandler(_camera); //thread
}
if(_preferencesDialog->isSourceAudioUsed())
{
UDEBUG("");
int sourceAudioType = _preferencesDialog->getSourceAudioType();
if(sourceAudioType == 1) //Audio file
{
_mic = new Micro(MicroEvent::kTypeFrameFreqSqrdMagn,
_preferencesDialog->getSourceAudioPath().toStdString(),
true,
44100.0/_preferencesDialog->getGeneralInputRate(),
0,
_preferencesDialog->getSourceAudioPlayWhileRecording());
}
else // Mic
{
_mic = new Micro(MicroEvent::kTypeFrameFreqSqrdMagn,
_preferencesDialog->getSourceMicDevice(),
_preferencesDialog->getSourceMicFs(),
float(_preferencesDialog->getSourceMicFs())/_preferencesDialog->getGeneralInputRate(),
1,
_preferencesDialog->getSourceMicSampleSize());
}
if(!_mic->init())
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("Mic initialization failed..."));
ULOGGER_WARN("init mic failed... ");
emit stateChanged(kIdle);
delete _mic;
_mic = 0;
if(_camera)
{
delete _camera;
_camera = 0;
}
return;
}
}
if(_camera && _mic)
{
_cameraMic = new CameraMicro(_camera, _mic);
}
}
this->post(new RtabmapEventCmd(RtabmapEventCmd::kCmdCleanSensorsBuffer));
@@ -1464,32 +1118,19 @@ void MainWindow::startDetection()
void MainWindow::pauseDetection()
{
if(_camera || _mic || _dbReader)
if(_camera || _dbReader)
{
if(_state == kPaused && (QApplication::keyboardModifiers() & Qt::ShiftModifier))
{
// On Ctrl-click, start the camera and pause it automatically
if((_camera &&_camera->isRunning()) ||
(_mic &&_mic->isRunning()) ||
(_cameraMic && _cameraMic->isRunning()) ||
(_dbReader && _dbReader->isRunning()))
{
//Don't wait for GUI thread, kill now
if(_cameraMic)
if(_camera)
{
_cameraMic->kill();
}
else
{
if(_camera)
{
_camera->kill();
}
if(_mic)
{
_mic->kill();
}
_camera->kill();
}
if(_dbReader)
{
_dbReader->kill();
@@ -1514,15 +1155,13 @@ void MainWindow::pauseDetection()
void MainWindow::stopDetection()
{
if(_state == kIdle || (!_camera && !_mic && !_dbReader))
if(_state == kIdle || (!_camera && !_dbReader))
{
return;
}
if(_state == kDetecting &&
( (!_mic && _camera && _camera->isRunning()) ||
(!_camera && _mic && _mic->isRunning()) ||
(_cameraMic && _cameraMic->isRunning()) ||
( (_camera && _camera->isRunning()) ||
(_dbReader && _dbReader->isRunning())) )
{
QMessageBox::StandardButton button = QMessageBox::question(this, tr("Stopping process..."), tr("Are you sure you want to stop the process?"), QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
@@ -1535,41 +1174,22 @@ void MainWindow::stopDetection()
ULOGGER_DEBUG("");
// kill the processes
if(_cameraMic)
if(_camera)
{
_cameraMic->join(true);
}
else
{
if(_camera)
{
_camera->join(true);
}
if(_mic)
{
_mic->join(true);
}
_camera->join(true);
}
if(_dbReader)
{
_dbReader->join(true);
}
// delete the processes
if(_cameraMic)
{
delete _cameraMic;
_cameraMic = 0;
}
if(_camera)
{
delete _camera;
_camera = 0;
}
if(_mic)
{
delete _mic;
_mic = 0;
}
if(_dbReader)
{
delete _dbReader;
@@ -1618,6 +1238,47 @@ void MainWindow::generateMap()
}
}
void MainWindow::generateLocalMap()
{
if(_graphSavingFileName.isEmpty())
{
_graphSavingFileName = _preferencesDialog->getWorkingDirectory() + "/Graph.dot";
}
bool ok = false;
int loopId = 1;
if(_ui->label_matchId->text().size())
{
std::list<std::string> values = uSplitNumChar(_ui->label_matchId->text().toStdString());
if(values.size() > 1)
{
int val = QString((++values.begin())->c_str()).toInt(&ok);
if(ok)
{
loopId = val;
}
ok = false;
}
}
int id = QInputDialog::getInt(this, tr("Around which location?"), tr("Location ID"), loopId, 1, 999999, 1, &ok);
if(ok)
{
int margin = QInputDialog::getInt(this, tr("Depth around the location?"), tr("Margin"), 4, 1, 100, 1, &ok);
if(ok)
{
QString path = QFileDialog::getSaveFileName(this, tr("Save File"), _graphSavingFileName, tr("Graphiz file (*.dot)"));
if(!path.isEmpty())
{
_graphSavingFileName = path;
RtabmapEventCmd * event = new RtabmapEventCmd(RtabmapEventCmd::kCmdGenerateLocalGraph);
QString str = path + QString(";") + QString::number(id) + QString(";") + QString::number(margin);
event->setStr(str.toStdString());
this->post(event); // The event is automatically deleted by the EventsManager...
}
}
}
}
void MainWindow::deleteMemory()
{
QMessageBox::StandardButton button;
@@ -1701,16 +1362,6 @@ void MainWindow::selectStream()
_preferencesDialog->selectSourceImage(PreferencesDialog::kSrcUsbDevice);
}
void MainWindow::selectMic()
{
_preferencesDialog->selectSourceAudio(PreferencesDialog::kSrcAudioMicDevice);
}
void MainWindow::selectAudioFile()
{
_preferencesDialog->selectSourceAudio(PreferencesDialog::kSrcAudioFile);
}
void MainWindow::selectDatabase()
{
_preferencesDialog->selectSourceDatabase(true);
@@ -1737,6 +1388,7 @@ void MainWindow::clearTheCache()
{
_imagesMap.clear();
_likelihoodCurve->clear();
_rawLikelihoodCurve->clear();
_posteriorCurve->clear();
_lastId = 0;
_lastIds.clear();
@@ -1920,6 +1572,7 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionDump_the_memory->setEnabled(true);
_ui->actionDelete_memory->setEnabled(true);
_ui->actionGenerate_map->setEnabled(true);
_ui->actionGenerate_local_map->setEnabled(true);
_ui->actionOpen_working_directory->setEnabled(true);
_ui->actionApply_settings_to_the_detector->setEnabled(true);
_ui->menuSelect_source->setEnabled(true);
@@ -1945,6 +1598,7 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionDump_the_memory->setEnabled(false);
_ui->actionDelete_memory->setEnabled(false);
_ui->actionGenerate_map->setEnabled(false);
_ui->actionGenerate_local_map->setEnabled(false);
_ui->actionOpen_working_directory->setEnabled(true);
_ui->actionApply_settings_to_the_detector->setEnabled(false);
_ui->menuSelect_source->setEnabled(false);
@@ -1954,21 +1608,12 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->label_elapsedTime->setText("00:00:00");
_elapsedTime->start();
_oneSecondTimer->start();
if(_cameraMic)
if(_camera)
{
_cameraMic->start();
}
else
{
if(_camera)
{
_camera->start();
}
if(_mic)
{
_mic->start();
}
_camera->start();
}
if(_dbReader)
{
_dbReader->start();
@@ -1985,24 +1630,16 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionDump_the_memory->setEnabled(false);
_ui->actionDelete_memory->setEnabled(false);
_ui->actionGenerate_map->setEnabled(false);
_ui->actionGenerate_local_map->setEnabled(false);
_state = kDetecting;
_elapsedTime->start();
_oneSecondTimer->start();
if(_cameraMic)
if(_camera)
{
_cameraMic->start();
}
else
{
if(_camera)
{
_camera->start();
}
if(_mic)
{
_mic->start();
}
_camera->start();
}
if(_dbReader)
{
_dbReader->start();
@@ -2017,24 +1654,16 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionDump_the_memory->setEnabled(true);
_ui->actionDelete_memory->setEnabled(true);
_ui->actionGenerate_map->setEnabled(true);
_ui->actionGenerate_local_map->setEnabled(true);
_state = kPaused;
_oneSecondTimer->stop();
// kill sensors
if(_cameraMic)
if(_camera)
{
_cameraMic->join(true);
}
else
{
if(_camera)
{
_camera->join(true);
}
if(_mic)
{
_mic->join(true);
}
_camera->join(true);
}
if(_dbReader)
{
_dbReader->join(true);
@@ -2053,6 +1682,7 @@ void MainWindow::changeState(MainWindow::State newState)
_ui->actionDump_the_memory->setEnabled(true);
_ui->actionDelete_memory->setEnabled(true);
_ui->actionGenerate_map->setEnabled(false);
_ui->actionGenerate_local_map->setEnabled(false);
_ui->actionOpen_working_directory->setEnabled(false);
_ui->actionApply_settings_to_the_detector->setEnabled(false);
_ui->menuSelect_source->setEnabled(false);

View File

@@ -18,18 +18,17 @@
*/
#include "PdfPlot.h"
#include "utilite/ULogger.h"
#include <utilite/ULogger.h>
namespace rtabmap {
PdfPlotItem::PdfPlotItem(float dataX, float dataY, float width, int childCount) :
UPlotItem(dataX, dataY, width),
_img(0),
_imagesRef(0)
_imagesRef(0),
_text(0)
{
setLikelihood(dataX, dataY, childCount);
_text = new QGraphicsTextItem(this);
_text->setVisible(false);
}
PdfPlotItem::~PdfPlotItem()
@@ -39,7 +38,7 @@ PdfPlotItem::~PdfPlotItem()
void PdfPlotItem::setLikelihood(int id, float value, int childCount)
{
if(id != this->data().x())
if(_img && id != this->data().x())
{
delete _img;
_img = 0;
@@ -50,6 +49,11 @@ void PdfPlotItem::setLikelihood(int id, float value, int childCount)
void PdfPlotItem::showDescription(bool shown)
{
if(!_text)
{
_text = new QGraphicsTextItem(this);
_text->setVisible(false);
}
if(shown)
{
if(!_img && _imagesRef)
@@ -71,7 +75,14 @@ void PdfPlotItem::showDescription(bool shown)
_text->setPos(this->mapFromScene(4+150,0));
else
_text->setPos(this->mapFromScene(4,0));
_text->setPlainText(QString("ID = %1\nValue = %2\nWeight = %3").arg(this->data().x()).arg(this->data().y()).arg(_childCount));
if(_childCount >= 0)
{
_text->setPlainText(QString("ID = %1\nValue = %2\nWeight = %3").arg(this->data().x()).arg(this->data().y()).arg(_childCount));
}
else
{
_text->setPlainText(QString("ID = %1\nValue = %2").arg(this->data().x()).arg(this->data().y()));
}
_text->setVisible(true);
if(_img)
{
@@ -109,14 +120,14 @@ void PdfPlotCurve::clear()
UPlotCurve::clear();
}
void PdfPlotCurve::setData(const QMap<int, float> & dataMap, const QMap<int, int> & weightsMap, int lastId)
void PdfPlotCurve::setData(const QMap<int, float> & dataMap, const QMap<int, int> & weightsMap)
{
ULOGGER_DEBUG("dataSize=%d", dataMap.size());
ULOGGER_DEBUG("dataMap=%d, weightsMap=%d", dataMap.size(), weightsMap.size());
if(dataMap.size() > 0)
{
//match the size of the current data
int margin = int((_items.size()+1)/2) - dataMap.size();
UDEBUG("margin=%d", margin);
while(margin < 0)
{
PdfPlotItem * newItem = new PdfPlotItem(0, 0, 2, 0);
@@ -124,6 +135,7 @@ void PdfPlotCurve::setData(const QMap<int, float> & dataMap, const QMap<int, int
this->_addValue(newItem);
++margin;
}
while(margin > 0)
{
this->removeItem(0);
@@ -133,10 +145,14 @@ void PdfPlotCurve::setData(const QMap<int, float> & dataMap, const QMap<int, int
ULOGGER_DEBUG("itemsize=%d", _items.size());
// update values
int index = 0;
for(QMap<int, float>::const_iterator i=dataMap.begin(); i!=dataMap.end(); ++i, index+=2)
QList<QGraphicsItem*>::iterator iter = _items.begin();
QMap<int, int>::const_iterator j=weightsMap.begin();
for(QMap<int, float>::const_iterator i=dataMap.begin(); i!=dataMap.end(); ++i, ++j)
{
((PdfPlotItem*)_items[index])->setLikelihood(i.key(), i.value(), weightsMap.value(i.key(),-1));
((PdfPlotItem*)*iter)->setLikelihood(i.key(), i.value(), j!=weightsMap.end()?j.value():-1);
//2 times...
++iter;
++iter;
}
//reset minMax, this will force the plot to update the axes

View File

@@ -40,10 +40,10 @@ protected:
virtual void showDescription(bool shown);
private:
QGraphicsTextItem * _text;
QGraphicsPixmapItem * _img;
int _childCount;
const QMap<int, QByteArray> * _imagesRef;
QGraphicsTextItem * _text;
};
@@ -56,7 +56,7 @@ public:
virtual ~PdfPlotCurve();
virtual void clear();
void setData(const QMap<int, float> & dataMap, const QMap<int, int> & weightsMap, int lastId);
void setData(const QMap<int, float> & dataMap, const QMap<int, int> & weightsMap);
private:
const QMap<int, QByteArray> * _imagesMapRef;

View File

@@ -18,6 +18,7 @@
*/
#include "rtabmap/gui/PreferencesDialog.h"
#include "rtabmap/gui/DatabaseViewer.h"
#include <QtCore/QSettings>
#include <QtCore/QDir>
#include <QtGui/QFileDialog>
@@ -26,6 +27,7 @@
#include <QtGui/QMainWindow>
#include <QtCore/QTimer>
#include <QtGui/QProgressDialog>
#include <QtGui/QScrollBar>
#include "ui_preferencesDialog.h"
#include "rtabmap/core/Rtabmap.h"
#include "rtabmap/core/Parameters.h"
@@ -39,6 +41,7 @@
#define DEFAULT_LOGGER_EVENT_LEVEL 3
#define DEFAULT_LOGGER_PAUSE_LEVEL 4
#define DEFAULT_LOGGER_PRINT_TIME true
#define DEFAULT_LOGGER_TYPE 1
using namespace rtabmap;
@@ -101,80 +104,60 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
//video group
connect(_ui->source_video_toolButton_selectSource, SIGNAL(clicked()), this, SLOT(selectSourceImage()));
connect(_ui->source_video_lineEdit_path, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
//Audio source
connect(_ui->groupBox_sourceAudio, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
_ui->stackedWidget_audio->setCurrentIndex(_ui->source_comboBox_audio_type->currentIndex());
connect(_ui->source_comboBox_audio_type, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_audio, SLOT(setCurrentIndex(int)));
connect(_ui->source_comboBox_audio_type, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
//audioDevice group
connect(_ui->source_audio_toolButton_selectSource, SIGNAL(clicked()), this, SLOT(selectSourceAudio()));
connect(_ui->source_micDevice, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_micFs, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_micSampleSize, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_audio_lineEdit_path, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_checkBox_playWhileRecording, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
//database group
connect(_ui->source_database_toolButton_selectSource, SIGNAL(clicked()), this, SLOT(selectSourceDatabase()));
connect(_ui->toolButton_dbViewer, SIGNAL(clicked()), this, SLOT(openDatabaseViewer()));
connect(_ui->groupBox_sourceDatabase, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_database_lineEdit_path, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
connect(_ui->source_spinBox_databaseStartPos, SIGNAL(valueChanged(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_doubleSpinBox_similarityThr, SIGNAL(valueChanged(double)), _ui->general_doubleSpinBox_similarityThr_2, SLOT(setValue(double)));
connect(_ui->doubleSpinBox_similarityThreshold, SIGNAL(valueChanged(double)), _ui->doubleSpinBox_similarityThreshold_2, SLOT(setValue(double)));
connect(_ui->general_spinBox_imagesBufferSize, SIGNAL(valueChanged(int)), _ui->general_spinBox_imagesBufferSize_2, SLOT(setValue(int)));
connect(_ui->general_spinBox_maxStMemSize, SIGNAL(valueChanged(int)), _ui->general_spinBox_maxStMemSize_2, SLOT(setValue(int)));
connect(_ui->comboBox_signatureType, SIGNAL(currentIndexChanged(int)), _ui->comboBox_signatureType_2, SLOT(setCurrentIndex(int)));
connect(_ui->lineEdit_workingDirectory, SIGNAL(textChanged(const QString &)), _ui->lineEdit_workingDirectory_2, SLOT(setText(const QString &)));
connect(_ui->general_doubleSpinBox_timeThr_2, SIGNAL(editingFinished()), this, SLOT(updateBasicParameter()));
connect(_ui->general_doubleSpinBox_hardThr_2, SIGNAL(editingFinished()), this, SLOT(updateBasicParameter()));
connect(_ui->surf_doubleSpinBox_hessianThr_2, SIGNAL(editingFinished()), this, SLOT(updateBasicParameter()));
connect(_ui->general_doubleSpinBox_similarityThr_2, SIGNAL(editingFinished()), this, SLOT(updateBasicParameter()));
connect(_ui->doubleSpinBox_similarityThreshold_2, SIGNAL(editingFinished()), this, SLOT(updateBasicParameter()));
connect(_ui->general_spinBox_imagesBufferSize_2, SIGNAL(editingFinished()), this, SLOT(updateBasicParameter()));
connect(_ui->general_spinBox_maxStMemSize_2, SIGNAL(editingFinished()), this, SLOT(updateBasicParameter()));
connect(_ui->general_checkBox_publishStats, SIGNAL(stateChanged(int)), this, SLOT(updateBasicParameter()));
connect(_ui->general_checkBox_publishStats_2, SIGNAL(stateChanged(int)), this, SLOT(updateBasicParameter()));
connect(_ui->comboBox_signatureType_2, SIGNAL(currentIndexChanged(int)), _ui->comboBox_signatureType, SLOT(setCurrentIndex(int)));
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_publishRawData->setObjectName(Parameters::kRtabmapPublishRawData().c_str());
_ui->general_checkBox_publishRawData->setObjectName(Parameters::kRtabmapPublishImage().c_str());
_ui->general_checkBox_publishPdf->setObjectName(Parameters::kRtabmapPublishPdf().c_str());
_ui->general_checkBox_publishLikelihood->setObjectName(Parameters::kRtabmapPublishLikelihood().c_str());
_ui->general_checkBox_statisticLogsBufferedInRAM->setObjectName(Parameters::kRtabmapStatisticLogsBufferedInRAM().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_imagesBufferSize->setObjectName(Parameters::kRtabmapImageBufferSize().c_str());
_ui->general_spinBox_maxRetrieved->setObjectName(Parameters::kRtabmapMaxRetrieved().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_likelihoodNullValuesIgnored->setObjectName(Parameters::kRtabmapLikelihoodNullValuesIgnored().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());
connect(_ui->toolButton_workingDirectory, SIGNAL(clicked()), this, SLOT(changeWorkingDirectory()));
// Memory
_ui->general_checkBox_keepRawData->setObjectName(Parameters::kMemRawDataKept().c_str());
_ui->general_spinBox_maxStMemSize->setObjectName(Parameters::kMemMaxStMemSize().c_str());
_ui->general_checkBox_similarityOnlyLast->setObjectName(Parameters::kMemSimilarityOnlyLast().c_str());
_ui->general_doubleSpinBox_similarityThr->setObjectName(Parameters::kMemSimilarityThr().c_str());
_ui->general_checkBox_keepRawData->setObjectName(Parameters::kMemImageKept().c_str());
_ui->general_spinBox_maxStMemSize->setObjectName(Parameters::kMemSTMSize().c_str());
_ui->general_checkBox_similarityOnlyLast->setObjectName(Parameters::kMemRehearsalOnlyWithLast().c_str());
_ui->doubleSpinBox_similarityThreshold->setObjectName(Parameters::kMemRehearsalSimilarity().c_str());
_ui->general_checkBox_incrementalMemory->setObjectName(Parameters::kMemIncrementalMemory().c_str());
_ui->general_checkBox_commonSignatureUsed->setObjectName(Parameters::kMemCommonSignatureUsed().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());
@@ -189,7 +172,7 @@ 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());
_ui->checkBox_bayes_fullPredictionUpdate->setObjectName(Parameters::kBayesFullPredictionUpdate().c_str());
connect(_ui->lineEdit_bayes_predictionLC, SIGNAL(textChanged(const QString &)), this, SLOT(updatePredictionPlot()));
//Keypoint-based
@@ -207,7 +190,6 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->surf_doubleSpinBox_ratioBadSign->setObjectName(Parameters::kKpBadSignRatio().c_str());
_ui->general_checkBox_reactivatedWordsComparedToNewWords->setObjectName(Parameters::kKpReactivatedWordsComparedToNewWords().c_str());
_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->lineEdit_kp_roi->setObjectName(Parameters::kKpRoiRatios().c_str());
_ui->lineEdit_dictionaryPath->setObjectName(Parameters::kKpDictionaryPath().c_str());
@@ -221,13 +203,6 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->surf_checkBox_upright->setObjectName(Parameters::kSURFUpright().c_str());
_ui->surf_checkBox_gpuVersion->setObjectName(Parameters::kSURFGpuVersion().c_str());
//Star detector
_ui->star_spinBox_maxSize->setObjectName(Parameters::kStarMaxSize().c_str());
_ui->star_spinBox_responseThr->setObjectName(Parameters::kStarResponseThreshold().c_str());
_ui->star_spinBox_lineThrProj->setObjectName(Parameters::kStarLineThresholdProjected().c_str());
_ui->star_spinBox_lineThrBin->setObjectName(Parameters::kStarLineThresholdBinarized().c_str());
_ui->star_spinBox_suppressNonmaxSize->setObjectName(Parameters::kStarSuppressNonmaxSize().c_str());
//SIFT detector
_ui->sift_spinBox_nFeatures->setObjectName(Parameters::kSIFTNFeatures().c_str());
_ui->sift_spinBox_nOctaveLayers->setObjectName(Parameters::kSIFTNOctaveLayers().c_str());
@@ -235,25 +210,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->sift_doubleSpinBox_edgeThr->setObjectName(Parameters::kSIFTEdgeThreshold().c_str());
_ui->sift_doubleSpinBox_sigma->setObjectName(Parameters::kSIFTSigma().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->sm_colorTable_comboBox->setObjectName(Parameters::kSMColorTable().c_str());
_ui->sm_audioDBThreshold->setObjectName(Parameters::kSMAudioDBThreshold().c_str());
_ui->checkBox_dBIndexing->setObjectName(Parameters::kSMAudioDBIndexing().c_str());
_ui->checkBox_audioMagnitudeInvariant->setObjectName(Parameters::kSMMagnitudeInvariant().c_str());
// verifyHypotheses
_ui->comboBox_vh_strategy->setObjectName(Parameters::kRtabmapVhStrategy().c_str());
_ui->vh_doubleSpinBox_similarity->setObjectName(Parameters::kVhSimilarity().c_str());
_ui->surf_spinBox_matchCountMinAccepted->setObjectName(Parameters::kVhEpMatchCountMin().c_str());
_ui->surf_doubleSpinBox_ransacParam1->setObjectName(Parameters::kVhEpRansacParam1().c_str());
_ui->surf_doubleSpinBox_ransacParam2->setObjectName(Parameters::kVhEpRansacParam2().c_str());
@@ -339,7 +297,7 @@ void PreferencesDialog::setupTreeView()
}
_ui->treeView->setModel(_indexModel);
_ui->treeView->setCurrentIndex(_indexModel->index(currentIndex, 0));
_ui->treeView->expandToDepth(1);
_ui->treeView->expandToDepth(0);
}
// recursive...
@@ -450,6 +408,8 @@ void PreferencesDialog::clicked(const QModelIndex &index)
++index;
}
_ui->stackedWidget->setCurrentIndex(index);
_ui->scrollArea->horizontalScrollBar()->setValue(0);
_ui->scrollArea->verticalScrollBar()->setValue(0);
}
}
@@ -519,6 +479,7 @@ void PreferencesDialog::resetSettings(int panelNumber)
_ui->comboBox_loggerEventLevel->setCurrentIndex(DEFAULT_LOGGER_EVENT_LEVEL);
_ui->comboBox_loggerPauseLevel->setCurrentIndex(DEFAULT_LOGGER_PAUSE_LEVEL);
_ui->checkBox_logger_printTime->setChecked(DEFAULT_LOGGER_PRINT_TIME);
_ui->comboBox_loggerType->setCurrentIndex(DEFAULT_LOGGER_TYPE);
}
else if(boxes.at(panelNumber)->objectName() == "groupBox_source0")
{
@@ -529,31 +490,29 @@ void PreferencesDialog::resetSettings(int panelNumber)
_ui->source_spinBox_framesDropped->setValue(0);
_ui->general_checkBox_autoRestart->setChecked(false);
_ui->general_checkBox_cameraKeypoints->setChecked(false);
_ui->groupBox_sourceAudio->setChecked(false);
_ui->source_micDevice->setValue(0);
_ui->source_micFs->setValue(48000);
_ui->source_micSampleSize->setValue(2);
_ui->source_images_spinBox_startPos->setValue(1);
_ui->source_images_refreshDir->setChecked(false);
_ui->groupBox_sourceDatabase->setChecked(false);
_ui->source_spinBox_databaseStartPos->setValue(0);
}
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_doubleSpinBox_similarityThr_2->setValue(Parameters::defaultMemSimilarityThr());
_ui->general_spinBox_imagesBufferSize_2->setValue(Parameters::defaultRtabmapSMStateBufferSize());
_ui->general_spinBox_maxStMemSize_2->setValue(Parameters::defaultMemMaxStMemSize());
_ui->doubleSpinBox_similarityThreshold_2->setValue(Parameters::defaultMemRehearsalSimilarity());
_ui->general_spinBox_imagesBufferSize_2->setValue(Parameters::defaultRtabmapImageBufferSize());
_ui->general_spinBox_maxStMemSize_2->setValue(Parameters::defaultMemSTMSize());
_ui->general_checkBox_publishStats_2->setChecked(Parameters::defaultRtabmapPublishStats());
_ui->lineEdit_workingDirectory_2->setText(Parameters::defaultRtabmapWorkingDirectory().c_str());
// match the advanced (spin and doubleSpin boxes)
_ui->general_doubleSpinBox_timeThr->setValue(Parameters::defaultRtabmapTimeThr());
_ui->general_doubleSpinBox_hardThr->setValue(Parameters::defaultRtabmapLoopThr());
_ui->surf_doubleSpinBox_hessianThr->setValue(Parameters::defaultSURFHessianThreshold());
_ui->general_doubleSpinBox_similarityThr->setValue(Parameters::defaultMemSimilarityThr());
_ui->general_spinBox_imagesBufferSize->setValue(Parameters::defaultRtabmapSMStateBufferSize());
_ui->general_spinBox_maxStMemSize->setValue(Parameters::defaultMemMaxStMemSize());
_ui->doubleSpinBox_similarityThreshold->setValue(Parameters::defaultMemRehearsalSimilarity());
_ui->general_spinBox_imagesBufferSize->setValue(Parameters::defaultRtabmapImageBufferSize());
_ui->general_spinBox_maxStMemSize->setValue(Parameters::defaultMemSTMSize());
}
else
{
@@ -676,19 +635,10 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
settings.endGroup(); // video
settings.endGroup(); // Camera
settings.beginGroup("Audio");
_ui->groupBox_sourceAudio->setChecked(settings.value("audioUsed", _ui->groupBox_sourceAudio->isChecked()).toBool());
_ui->source_comboBox_audio_type->setCurrentIndex(settings.value("type", _ui->source_comboBox_audio_type->currentIndex()).toInt());
_ui->source_micDevice->setValue(settings.value("id",_ui->source_micDevice->value()).toInt());
_ui->source_micFs->setValue(settings.value("fs",_ui->source_micFs->value()).toInt());
_ui->source_micSampleSize->setValue(settings.value("sampleSize",_ui->source_micSampleSize->value()).toInt());
_ui->source_audio_lineEdit_path->setText(settings.value("path",_ui->source_audio_lineEdit_path->text()).toString());
_ui->source_checkBox_playWhileRecording->setChecked(settings.value("playWhileRecording",_ui->source_checkBox_playWhileRecording->isChecked()).toBool());
settings.endGroup(); // Audio
settings.beginGroup("Database");
_ui->groupBox_sourceDatabase->setChecked(settings.value("databaseUsed", _ui->groupBox_sourceDatabase->isChecked()).toBool());
_ui->source_database_lineEdit_path->setText(settings.value("path",_ui->source_database_lineEdit_path->text()).toString());
_ui->source_spinBox_databaseStartPos->setValue(settings.value("startPos", _ui->source_spinBox_databaseStartPos->value()).toInt());
settings.endGroup(); // Database
}
@@ -708,9 +658,11 @@ bool PreferencesDialog::readCoreSettings(const QString & filePath)
QSettings settings(path, QSettings::IniFormat);
const rtabmap::ParametersMap & parameters = Parameters::getDefaultParameters();
settings.beginGroup("Core");
QStringList keys = settings.allKeys();
// Get profile
const rtabmap::ParametersMap & parameters = Parameters::getDefaultParameters();
for(rtabmap::ParametersMap::const_iterator iter = parameters.begin(); iter!=parameters.end(); ++iter)
{
QString key((*iter).first.c_str());
@@ -836,20 +788,10 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath)
settings.endGroup(); // Camera
settings.beginGroup("Audio");
settings.setValue("audioUsed", _ui->groupBox_sourceAudio->isChecked());
settings.setValue("type", _ui->source_comboBox_audio_type->currentIndex());
settings.setValue("id", _ui->source_micDevice->value());
settings.setValue("fs", _ui->source_micFs->value());
settings.setValue("sampleSize", _ui->source_micSampleSize->value());
settings.setValue("path", _ui->source_audio_lineEdit_path->text());
settings.setValue("playWhileRecording", _ui->source_checkBox_playWhileRecording->isChecked());
settings.endGroup(); // Audio
settings.beginGroup("Database");
settings.setValue("databaseUsed", _ui->groupBox_sourceDatabase->isChecked());
settings.setValue("path", _ui->source_database_lineEdit_path->text());
settings.setValue("startPos", _ui->source_spinBox_databaseStartPos->value());
settings.endGroup();
}
@@ -1108,59 +1050,6 @@ void PreferencesDialog::selectSourceImage(Src src)
}
}
void PreferencesDialog::selectSourceAudio(SrcAudio src)
{
ULOGGER_DEBUG("");
bool fromPrefDialog = false;
//bool modified = false;
if(src == kSrcAudioUndef)
{
fromPrefDialog = true;
if(_ui->source_comboBox_audio_type->currentIndex() == 1)
{
src = kSrcAudioFile;
}
else
{
src = kSrcAudioMicDevice;
}
}
else
{
// from user
_ui->groupBox_sourceAudio->setChecked(true);
}
if(src == kSrcAudioFile)
{
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), _ui->source_audio_lineEdit_path->text(), tr("Audio files (*.wav *.mp3)"));
QFile file(path);
if(!path.isEmpty() && file.exists())
{
_ui->source_comboBox_audio_type->setCurrentIndex(1);
_ui->source_audio_lineEdit_path->setText(path);
}
}
else
{
_ui->source_comboBox_audio_type->setCurrentIndex(0);
}
if(!fromPrefDialog && _obsoletePanels)
{
_ui->groupBox_sourceDatabase->setChecked(false);
if(validateForm())
{
this->writeSettings();
}
else
{
this->readSettingsBegin();
}
}
}
void PreferencesDialog::selectSourceDatabase(bool user)
{
ULOGGER_DEBUG("");
@@ -1176,12 +1065,12 @@ void PreferencesDialog::selectSourceDatabase(bool user)
if(!path.isEmpty() && file.exists())
{
_ui->source_database_lineEdit_path->setText(path);
_ui->source_spinBox_databaseStartPos->setValue(0);
}
if(user && _obsoletePanels)
{
_ui->groupBox_sourceImage->setChecked(false);
_ui->groupBox_sourceAudio->setChecked(false);
if(validateForm())
{
this->writeSettings();
@@ -1193,6 +1082,21 @@ void PreferencesDialog::selectSourceDatabase(bool user)
}
}
void PreferencesDialog::openDatabaseViewer()
{
DatabaseViewer * viewer = new DatabaseViewer(this);
viewer->setAttribute(Qt::WA_DeleteOnClose, true);
viewer->setWindowModality(Qt::WindowModal);
if(viewer->openDatabase(_ui->source_database_lineEdit_path->text()))
{
viewer->show();
}
else
{
delete viewer;
}
}
void PreferencesDialog::setParameter(const std::string & key, const std::string & value)
{
UDEBUG("%s=%s", key.c_str(), value.c_str());
@@ -1204,17 +1108,30 @@ void PreferencesDialog::setParameter(const std::string & key, const std::string
QComboBox * combo = qobject_cast<QComboBox *>(obj);
QCheckBox * check = qobject_cast<QCheckBox *>(obj);
QLineEdit * lineEdit = qobject_cast<QLineEdit *>(obj);
bool ok;
if(spin)
{
spin->setValue(QString(value.c_str()).toInt());
spin->setValue(QString(value.c_str()).toInt(&ok));
if(!ok)
{
UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
}
}
else if(doubleSpin)
{
doubleSpin->setValue(QString(value.c_str()).toDouble());
doubleSpin->setValue(QString(value.c_str()).toDouble(&ok));
if(!ok)
{
UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
}
}
else if(combo)
{
combo->setCurrentIndex(QString(value.c_str()).toInt());
combo->setCurrentIndex(QString(value.c_str()).toInt(&ok));
if(!ok)
{
UERROR("Conversion failed from \"%s\" for parameter %s", value.c_str(), key.c_str());
}
}
else if(check)
{
@@ -1297,11 +1214,7 @@ void PreferencesDialog::addParameter(const QObject * object, int value)
{
// No panel related...
}
else if(value == 1) // 1 similarity
{
this->addParameters(_ui->groupBox_vh_similarity2);
}
else if(value == 2) // 2 epipolar
else if(value == 1) // 2 epipolar
{
this->addParameters(_ui->groupBox_vh_epipolar2);
}
@@ -1312,18 +1225,10 @@ void PreferencesDialog::addParameter(const QObject * object, int value)
{
this->addParameters(_ui->groupBox_detector_surf2);
}
else if(value == 1) // 1 star
{
this->addParameters(_ui->groupBox_detector_star2);
}
else if(value == 2) // 2 sift
else if(value == 1) // 1 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)
{
@@ -1335,21 +1240,6 @@ void PreferencesDialog::addParameter(const QObject * object, int value)
{
this->addParameters(_ui->groupBox_detector_sift2);
}
else if(value == 2) // 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
@@ -1464,10 +1354,6 @@ void PreferencesDialog::updateBasicParameter()
{
_ui->surf_doubleSpinBox_hessianThr->setValue(_ui->surf_doubleSpinBox_hessianThr_2->value());
}
else if(sender() == _ui->general_doubleSpinBox_similarityThr_2)
{
_ui->general_doubleSpinBox_similarityThr->setValue(_ui->general_doubleSpinBox_similarityThr_2->value());
}
else if(sender() == _ui->general_spinBox_imagesBufferSize_2)
{
_ui->general_spinBox_imagesBufferSize->setValue(_ui->general_spinBox_imagesBufferSize_2->value());
@@ -1484,15 +1370,19 @@ void PreferencesDialog::updateBasicParameter()
{
_ui->general_checkBox_publishStats->setChecked(_ui->general_checkBox_publishStats_2->isChecked());
}
else if(sender() == _ui->doubleSpinBox_similarityThreshold_2)
{
_ui->doubleSpinBox_similarityThreshold->setValue(_ui->doubleSpinBox_similarityThreshold_2->value());
}
else
{
//update all values (only those using editingFinished signal)
_ui->general_doubleSpinBox_timeThr->setValue(_ui->general_doubleSpinBox_timeThr_2->value());
_ui->general_doubleSpinBox_hardThr->setValue(_ui->general_doubleSpinBox_hardThr_2->value());
_ui->surf_doubleSpinBox_hessianThr->setValue(_ui->surf_doubleSpinBox_hessianThr_2->value());
_ui->general_doubleSpinBox_similarityThr->setValue(_ui->general_doubleSpinBox_similarityThr_2->value());
_ui->general_spinBox_imagesBufferSize->setValue(_ui->general_spinBox_imagesBufferSize_2->value());
_ui->general_spinBox_maxStMemSize->setValue(_ui->general_spinBox_maxStMemSize_2->value());
_ui->doubleSpinBox_similarityThreshold->setValue(_ui->doubleSpinBox_similarityThreshold_2->value());
}
}
@@ -1507,10 +1397,8 @@ void PreferencesDialog::makeObsoleteSourcePanel()
if(sender() == _ui->groupBox_sourceDatabase && _ui->groupBox_sourceDatabase->isChecked())
{
_ui->groupBox_sourceImage->setChecked(false);
_ui->groupBox_sourceAudio->setChecked(false);
}
else if((sender() == _ui->groupBox_sourceImage && _ui->groupBox_sourceImage->isChecked()) ||
(sender() == _ui->groupBox_sourceAudio && _ui->groupBox_sourceAudio->isChecked()))
else if(sender() == _ui->groupBox_sourceImage && _ui->groupBox_sourceImage->isChecked())
{
_ui->groupBox_sourceDatabase->setChecked(false);
}
@@ -1564,7 +1452,7 @@ QList<QGroupBox*> PreferencesDialog::getGroupBoxes()
void PreferencesDialog::updatePredictionPlot()
{
QStringList values = _ui->lineEdit_bayes_predictionLC->text().split(' ');
QStringList values = _ui->lineEdit_bayes_predictionLC->text().simplified().split(' ');
if(values.size() < 2)
{
UERROR("Error parsing prediction (must have at least 2 items) : %s",
@@ -1584,7 +1472,7 @@ void PreferencesDialog::updatePredictionPlot()
value = values.at(i).toDouble(&ok);
if(!ok)
{
UERROR("Error parsing prediction : %s", values.at(i).toStdString().c_str());
UERROR("Error parsing prediction : \"%s\"", values.at(i).toStdString().c_str());
error = true;
}
sum+=value;
@@ -1736,10 +1624,6 @@ bool PreferencesDialog::isSourceImageUsed() const
{
return _ui->groupBox_sourceImage->isChecked();
}
bool PreferencesDialog::isSourceAudioUsed() const
{
return _ui->groupBox_sourceAudio->isChecked();
}
bool PreferencesDialog::isSourceDatabaseUsed() const
{
return _ui->groupBox_sourceDatabase->isChecked();
@@ -1792,38 +1676,14 @@ int PreferencesDialog::getSourceUsbDeviceId() const
{
return _ui->source_usbDevice_spinBox_id->value();
}
int PreferencesDialog::getSourceAudioType() const
{
return _ui->source_comboBox_audio_type->currentIndex();
}
QString PreferencesDialog::getSourceAudioTypeStr() const
{
return _ui->source_comboBox_audio_type->currentText();
}
int PreferencesDialog::getSourceMicDevice() const
{
return _ui->source_micDevice->value();
}
int PreferencesDialog::getSourceMicFs() const
{
return _ui->source_micFs->value();
}
int PreferencesDialog::getSourceMicSampleSize() const
{
return _ui->source_micSampleSize->value();
}
QString PreferencesDialog::getSourceAudioPath() const
{
return _ui->source_audio_lineEdit_path->text();
}
bool PreferencesDialog::getSourceAudioPlayWhileRecording() const
{
return _ui->source_checkBox_playWhileRecording->isChecked();
}
QString PreferencesDialog::getSourceDatabasePath() const
{
return _ui->source_database_lineEdit_path->text();
}
int PreferencesDialog::getSourceDatabaseStartPos() const
{
return _ui->source_spinBox_databaseStartPos->value();
}
bool PreferencesDialog::isStatisticsPublished() const
{
@@ -1833,10 +1693,6 @@ double PreferencesDialog::getLoopThr() const
{
return _ui->general_doubleSpinBox_hardThr->value();
}
double PreferencesDialog::getRetrievalThr() const
{
return _ui->general_doubleSpinBox_retrievalThr->value();
}
double PreferencesDialog::getVpThr() const
{
return _ui->general_doubleSpinBox_vp->value();
@@ -1850,10 +1706,6 @@ float PreferencesDialog::getTimeLimit() const
{
return _ui->general_doubleSpinBox_timeThr->value();
}
int PreferencesDialog::getMemoryType() const
{
return _ui->comboBox_signatureType->currentIndex();
}
/*** SETTERS ***/
void PreferencesDialog::setHardThr(int value)
@@ -1874,24 +1726,6 @@ void PreferencesDialog::setHardThr(int value)
}
}
void PreferencesDialog::setRetrievalThr(int value)
{
double dValue = double(value)/100;
ULOGGER_DEBUG("reactivation thr=%f", dValue);
if(_ui->general_doubleSpinBox_retrievalThr->value() != dValue)
{
_ui->general_doubleSpinBox_retrievalThr->setValue(dValue);
if(validateForm())
{
this->writeSettings();
}
else
{
this->readSettingsBegin();
}
}
}
void PreferencesDialog::setInputRate(double value)
{
ULOGGER_DEBUG("imgRate=%2.2f", value);
@@ -1943,22 +1777,6 @@ void PreferencesDialog::setTimeLimit(float value)
}
}
void PreferencesDialog::disableSourceAudio()
{
if(_ui->groupBox_sourceAudio->isChecked())
{
_ui->groupBox_sourceAudio->setChecked(false);
if(validateForm())
{
this->writeSettings();
}
else
{
this->readSettingsBegin();
}
}
}
void PreferencesDialog::disableGeneralCameraKeypoints()
{
if(_ui->general_checkBox_cameraKeypoints->isChecked())

View File

@@ -36,13 +36,24 @@
namespace rtabmap {
StatItem::StatItem(const QString & name, float x, float y, const QString & unit, const QMenu * menu, QGridLayout * grid, QWidget * parent) :
StatItem::StatItem(const QString & name, const std::vector<float> & x, const std::vector<float> & y, const QString & unit, const QMenu * menu, QGridLayout * grid, QWidget * parent) :
QWidget(parent),
_xValue(x)
_button(0),
_name(0),
_value(0),
_unit(0),
_menu(0)
{
this->setupUi(grid);
_name->setText(name);
_value->setNum(y);
if(y.size() == 1)
{
_value->setNum(y[0]);
}
else if(y.size() > 1)
{
_value->setText("*");
}
_unit->setText(unit);
this->updateMenu(menu);
}
@@ -55,10 +66,20 @@ StatItem::~StatItem()
void StatItem::setValue(float x, float y)
{
_value->setText(QString::number(y, 'g', 3));
_xValue = x;
emit valueChanged(x,y);
}
void StatItem::setValues(const std::vector<float> & x, const std::vector<float> & y)
{
_value->setText("*");
emit valuesChanged(x,y);
}
QString StatItem::value() const
{
return _value->text();
}
void StatItem::setupUi(QGridLayout * grid)
{
_menu = new QMenu(this);
@@ -156,6 +177,14 @@ void StatsToolBox::closeFigures()
}
void StatsToolBox::updateStat(const QString & statFullName, float x, float y)
{
std::vector<float> vx(1),vy(1);
vx[0] = x;
vy[0] = y;
updateStat(statFullName, vx, vy);
}
void StatsToolBox::updateStat(const QString & statFullName, const std::vector<float> & x, const std::vector<float> & y)
{
// round float to max 2 numbers after the dot
//x = (float(int(100*x)))/100;
@@ -164,7 +193,14 @@ void StatsToolBox::updateStat(const QString & statFullName, float x, float y)
StatItem * item = _statBox->findChild<StatItem *>(statFullName);
if(item)
{
item->setValue(x, y);
if(y.size() == 1 && x.size() == 1)
{
item->setValue(x[0], y[0]);
}
else
{
item->setValues(x, y);
}
}
else
{
@@ -260,6 +296,11 @@ void StatsToolBox::plot(const StatItem * stat, const QString & plotName)
UPlotCurve * curve = new UPlotCurve(stat->objectName(), plot);
curve->setPen(plot->getRandomPenColored());
connect(stat, SIGNAL(valueChanged(float, float)), curve, SLOT(addValue(float, float)));
connect(stat, SIGNAL(valuesChanged(const std::vector<float> &, const std::vector<float> &)), curve, SLOT(setData(const std::vector<float> &, const std::vector<float> &)));
if(stat->value().compare("*") == 0)
{
plot->setMaxVisibleItems(0);
}
if(!plot->addCurve(curve))
{
ULOGGER_WARN("Already added to the figure");
@@ -285,6 +326,7 @@ void StatsToolBox::plot(const StatItem * stat, const QString & plotName)
QDialog * figure = new QDialog(0, Qt::Window);
_figures.insert(newPlotName, figure);
QHBoxLayout * hLayout = new QHBoxLayout(figure);
hLayout->setContentsMargins(0,0,0,0);
figure->setWindowTitle(newPlotName);
figure->setAttribute(Qt::WA_DeleteOnClose, true);
connect(figure, SIGNAL(destroyed(QObject*)), this, SLOT(figureDeleted(QObject*)));
@@ -301,6 +343,11 @@ void StatsToolBox::plot(const StatItem * stat, const QString & plotName)
UPlotCurve * curve = new UPlotCurve(stat->objectName(), newPlot);
curve->setPen(newPlot->getRandomPenColored());
connect(stat, SIGNAL(valueChanged(float, float)), curve, SLOT(addValue(float, float)));
connect(stat, SIGNAL(valuesChanged(const std::vector<float> &, const std::vector<float> &)), curve, SLOT(setData(const std::vector<float> &, const std::vector<float> &)));
if(stat->value().compare("*") == 0)
{
newPlot->setMaxVisibleItems(0);
}
if(!newPlot->addCurve(curve))
{
ULOGGER_ERROR("Not supposed to be here !?!");
@@ -357,7 +404,7 @@ void StatsToolBox::contextMenuEvent(QContextMenuEvent * event)
if(action == aClearFigures)
{
for(QMap<QString, QWidget*>::iterator i=_figures.begin(); i!=_figures.end(); ++i)
{
{
QList<UPlot *> plots = i.value()->findChildren<UPlot *>();
if(plots.size() == 1)
{

View File

@@ -36,15 +36,18 @@ class StatItem : public QWidget
Q_OBJECT;
public:
StatItem(const QString & name, float x, float y, const QString & unit = QString(), const QMenu * menu = 0, QGridLayout * grid = 0, QWidget * parent = 0);
StatItem(const QString & name, const std::vector<float> & x, const std::vector<float> & y, const QString & unit = QString(), const QMenu * menu = 0, QGridLayout * grid = 0, QWidget * parent = 0);
virtual ~StatItem();
void setValue(float x, float y);
void setValues(const std::vector<float> & x, const std::vector<float> & y);
QString value() const;
public slots:
void updateMenu(const QMenu * menu);
signals:
void valueChanged(float, float);
void valuesChanged(const std::vector<float> &, const std::vector<float> &);
void plotRequested(const StatItem *, const QString &);
private slots:
@@ -59,7 +62,6 @@ private:
QLabel * _value;
QLabel * _unit;
QMenu * _menu;
float _xValue;
};
@@ -80,6 +82,7 @@ public:
public slots:
void updateStat(const QString & statFullName, float x, float y);
void updateStat(const QString & statFullName, const std::vector<float> & x, const std::vector<float> & y);
signals:
void menuChanged(const QMenu *);

View File

@@ -1,111 +0,0 @@
/*
* 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))
{
TwistWidget * w = (TwistWidget*)_grid->itemAtPosition(row, col+1)->widget();
w->setData(x, y, z, roll, pitch, yaw);
this->update();
}
else
{
_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)
{
this->setData(x, y, z, roll, pitch, yaw);
this->setFixedSize(SIZE,SIZE);
this->setMinimumSize(SIZE,SIZE);
}
void TwistWidget::setData(float x, float y, float z, float roll, float pitch, float yaw)
{
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;
}
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();
}
}

View File

@@ -1,55 +0,0 @@
/*
* 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() {}
void setData(float x, float y, float z, float roll, float pitch, float yaw);
protected:
virtual void paintEvent(QPaintEvent * event);
private:
float _x;
float _y;
float _z;
float _roll;
float _pitch;
float _yaw;
};
}
#endif /* TWISTWIDGET_H_ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,360 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DatabaseViewer</class>
<widget class="QMainWindow" name="DatabaseViewer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>736</width>
<height>456</height>
</rect>
</property>
<property name="windowTitle">
<string>Database viewer</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="spacing">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="rightMargin">
<number>0</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6" stretch="1,0,0">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QGraphicsView" name="graphicsView_A"/>
</item>
<item>
<widget class="QScrollArea" name="scrollArea_2">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>344</width>
<height>81</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<item row="0" column="0">
<widget class="QLabel" name="label_actionsA_2">
<property name="text">
<string>Actions</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_actionsA">
<property name="text">
<string>Actions</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_parentsA_2">
<property name="text">
<string>Parents</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_parentsA">
<property name="text">
<string>Parents</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_childrenA_2">
<property name="text">
<string>Children</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_childrenA">
<property name="text">
<string>Children</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="margin">
<number>12</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Index :</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Id :</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="label_indexA">
<property name="text">
<string>indexA</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_idA">
<property name="text">
<string>idA</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QSlider" name="horizontalSlider_A">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_5" stretch="1,0,0">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QGraphicsView" name="graphicsView_B"/>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>344</width>
<height>81</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
<item row="0" column="0">
<widget class="QLabel" name="label_actionsA_4">
<property name="text">
<string>Actions</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_actionsB">
<property name="text">
<string>Actions</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_parentsA_4">
<property name="text">
<string>Parents</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_parentsB">
<property name="text">
<string>Parents</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_childrenA_3">
<property name="text">
<string>Children</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_childrenB">
<property name="text">
<string>Children</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="margin">
<number>12</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Index :</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Id :</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_indexB">
<property name="text">
<string>indexB</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_idB">
<property name="text">
<string>idB</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QSlider" name="horizontalSlider_B">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksAbove</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>736</width>
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="actionOpen_database"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
</property>
<addaction name="actionGenerate_graph_dot"/>
<addaction name="actionGenerate_local_graph_dot"/>
<addaction name="separator"/>
<addaction name="actionClean_database"/>
<addaction name="actionClean_local_graph"/>
<addaction name="separator"/>
<addaction name="actionUpdate_base_ids"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
</widget>
<action name="actionOpen_database">
<property name="text">
<string>Open database</string>
</property>
</action>
<action name="actionQuit">
<property name="text">
<string>Quit</string>
</property>
</action>
<action name="actionGenerate_graph_dot">
<property name="text">
<string>Generate graph (.dot) ...</string>
</property>
</action>
<action name="actionGenerate_graph_only_weighted_locations">
<property name="text">
<string>Generate graph (only weighted locations) ...</string>
</property>
</action>
<action name="actionClean_database">
<property name="text">
<string>Clean database</string>
</property>
</action>
<action name="actionGenerate_local_graph_dot">
<property name="text">
<string>Generate local graph (.dot) ...</string>
</property>
</action>
<action name="actionClean_local_graph">
<property name="text">
<string>Clean local graph ...</string>
</property>
</action>
<action name="actionUpdate_base_ids">
<property name="text">
<string>Update base ids</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>543</width>
<width>585</width>
<height>368</height>
</rect>
</property>
@@ -147,7 +147,7 @@ p, li { white-space: pre-wrap; }
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://introlab.gel.usherbrooke.ca/mediawiki-introlab/index.php/RTAB-Map&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Home page&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://introlab.3it.usherbrooke.ca/mediawiki-introlab/index.php/RTAB-Map&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;Home page&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>

View File

@@ -138,6 +138,7 @@
<addaction name="actionDump_the_memory"/>
<addaction name="actionDump_the_prediction_matrix"/>
<addaction name="actionGenerate_map"/>
<addaction name="actionGenerate_local_map"/>
<addaction name="actionReset_the_memory"/>
<addaction name="separator"/>
<addaction name="actionAuto_screen_capture"/>
@@ -167,15 +168,7 @@
<addaction name="actionImageFiles"/>
<addaction name="actionVideo"/>
</widget>
<widget class="QMenu" name="menuAudio">
<property name="title">
<string>Audio</string>
</property>
<addaction name="actionMic"/>
<addaction name="actionAudioFile"/>
</widget>
<addaction name="menuImage"/>
<addaction name="menuAudio"/>
<addaction name="actionDatabase"/>
</widget>
<addaction name="menuSelect_source"/>
@@ -228,6 +221,12 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="UPlot" name="posteriorPlot" native="true"/>
</item>
@@ -263,8 +262,11 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents_3">
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>2</number>
<number>0</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout" columnstretch="10,0">
@@ -444,22 +446,7 @@
</layout>
</item>
<item>
<widget class="QFrame" name="frame_3">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="rtabmap::StatsToolBox" name="statsToolBox" native="true"/>
</item>
</layout>
</widget>
<widget class="rtabmap::StatsToolBox" name="statsToolBox" native="true"/>
</item>
<item>
<spacer name="verticalSpacer_2">
@@ -489,6 +476,18 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents_4">
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="spacing">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="UPlot" name="likelihoodPlot" native="true"/>
</item>
@@ -504,56 +503,35 @@
</attribute>
<widget class="QWidget" name="dockWidgetContents_2">
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="rtabmap::ConsoleWidget" name="widget" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_twist">
<property name="floating">
<bool>false</bool>
</property>
<widget class="QDockWidget" name="dockWidget_rawlikelihood">
<property name="windowTitle">
<string>Actions</string>
<string>Raw Likelihood</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
<number>8</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_5">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<widget class="QWidget" name="dockWidgetContents_6">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="rtabmap::TwistGridWidget" name="twistWidget" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_audioProcessedFrames">
<property name="windowTitle">
<string>Audio Processed Frames</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_9">
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="USpectrogram" name="widget_audioProcessedFrames" native="true"/>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_audioLoopFrames">
<property name="windowTitle">
<string>Audio Loop Frames</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_10">
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="USpectrogram" name="widget_audioLoopFrames" native="true"/>
<widget class="UPlot" name="rawLikelihoodPlot" native="true"/>
</item>
</layout>
</widget>
@@ -760,22 +738,6 @@
<string>Video...</string>
</property>
</action>
<action name="actionMic">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Mic</string>
</property>
</action>
<action name="actionAudioFile">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>File...</string>
</property>
</action>
<action name="actionDatabase">
<property name="checkable">
<bool>true</bool>
@@ -784,6 +746,11 @@
<string>Database...</string>
</property>
</action>
<action name="actionGenerate_local_map">
<property name="text">
<string>Generate local map...</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
@@ -809,18 +776,6 @@
<header>ConsoleWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>rtabmap::TwistGridWidget</class>
<extends>QWidget</extends>
<header>TwistWidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>USpectrogram</class>
<extends>QWidget</extends>
<header>utilite/USpectrogram.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../GuiLib.qrc"/>

File diff suppressed because it is too large Load Diff