Added close buttons to CameraViewer and OdometryViewer dialogs

This commit is contained in:
matlabbe
2015-04-06 13:35:44 -04:00
parent 19f59a8c60
commit 5b5a32839c
12 changed files with 427 additions and 627 deletions

View File

@@ -31,7 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/gui/RtabmapGuiExp.h" // DLL export/import defines #include "rtabmap/gui/RtabmapGuiExp.h" // DLL export/import defines
#include <rtabmap/utilite/UEventsHandler.h> #include <rtabmap/utilite/UEventsHandler.h>
#include <QWidget> #include <QDialog>
#include <rtabmap/core/SensorData.h> #include <rtabmap/core/SensorData.h>
namespace rtabmap { namespace rtabmap {
@@ -39,7 +39,7 @@ namespace rtabmap {
class ImageView; class ImageView;
class CloudViewer; class CloudViewer;
class RTABMAPGUI_EXP CameraViewer : public QWidget, public UEventsHandler class RTABMAPGUI_EXP CameraViewer : public QDialog, public UEventsHandler
{ {
Q_OBJECT Q_OBJECT
public: public:
@@ -49,7 +49,7 @@ public:
public slots: public slots:
void showImage(const rtabmap::SensorData & data); void showImage(const rtabmap::SensorData & data);
protected: protected:
void handleEvent(UEvent * event); virtual void handleEvent(UEvent * event);
private: private:
ImageView* imageView_; ImageView* imageView_;

View File

@@ -31,47 +31,50 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/gui/RtabmapGuiExp.h" // DLL export/import defines #include "rtabmap/gui/RtabmapGuiExp.h" // DLL export/import defines
#include "rtabmap/core/SensorData.h" #include "rtabmap/core/SensorData.h"
#include "rtabmap/gui/CloudViewer.h" #include "rtabmap/core/OdometryInfo.h"
#include <QDialog>
#include "rtabmap/utilite/UEventsHandler.h" #include "rtabmap/utilite/UEventsHandler.h"
#include "rtabmap/utilite/UTimer.h"
#include "rtabmap/utilite/UMutex.h" class QSpinBox;
class QDoubleSpinBox;
namespace rtabmap { namespace rtabmap {
class RTABMAPGUI_EXP OdometryViewer : public CloudViewer, public UEventsHandler class ImageView;
class CloudViewer;
class RTABMAPGUI_EXP OdometryViewer : public QDialog, public UEventsHandler
{ {
Q_OBJECT Q_OBJECT
public: public:
OdometryViewer(int maxClouds = 10, int decimation = 2, float voxelSize = 0.0f, int qualityWarningThr=0, QWidget * parent = 0); OdometryViewer(int maxClouds = 10, int decimation = 2, float voxelSize = 0.0f, int qualityWarningThr=0, QWidget * parent = 0);
virtual ~OdometryViewer() {} virtual ~OdometryViewer();
public slots: public slots:
virtual void clear(); virtual void clear();
protected: protected:
void handleAction(QAction * a);
virtual void handleEvent(UEvent * event); virtual void handleEvent(UEvent * event);
private slots: private slots:
void processData(); void processData(const rtabmap::SensorData & data, const rtabmap::OdometryInfo & info);
private: private:
UMutex dataMutex_; ImageView* imageView_;
std::list<rtabmap::SensorData> data_; CloudViewer* cloudView_;
int dataQuality_; bool processingData_;
bool odomImageShow_;
bool odomImageDepthShow_;
Transform lastOdomPose_; Transform lastOdomPose_;
UTimer timer_;
int maxClouds_;
float voxelSize_;
int decimation_;
int qualityWarningThr_; int qualityWarningThr_;
int id_; int id_;
std::map<int, pcl::PointCloud<pcl::PointXYZRGB>::Ptr > clouds_;
QAction * _aSetVoxelSize; QSpinBox * maxCloudsSpin_;
QAction * _aSetDecimation; QDoubleSpinBox * voxelSpin_;
QAction * _aSetCloudHistorySize; QSpinBox * decimationSpin_;
QAction * _aPause; int validDecimationValue_;
}; };
} /* namespace rtabmap */ } /* namespace rtabmap */

View File

@@ -57,8 +57,6 @@ class QDoubleSpinBox;
namespace rtabmap { namespace rtabmap {
class OdometryThread;
class CameraThread;
class Signature; class Signature;
class LoopClosureViewer; class LoopClosureViewer;
class CameraRGBD; class CameraRGBD;
@@ -245,9 +243,7 @@ private slots:
void updateBasicParameter(); void updateBasicParameter();
void openDatabaseViewer(); void openDatabaseViewer();
void showOpenNI2GroupBox(bool); void showOpenNI2GroupBox(bool);
void cleanOdometryTest();
void testOdometry(); void testOdometry();
void cleanRGBDCameraTest();
void testRGBDCamera(); void testRGBDCamera();
protected: protected:
@@ -299,10 +295,6 @@ private:
QProgressDialog * _progressDialog; QProgressDialog * _progressDialog;
//Odometry test
CameraThread * _cameraThread;
OdometryThread * _odomThread;
//calibration //calibration
CalibrationDialog * _calibrationDialog; CalibrationDialog * _calibrationDialog;

View File

@@ -34,12 +34,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/gui/UCv2Qt.h> #include <rtabmap/gui/UCv2Qt.h>
#include <QtCore/QMetaType> #include <QtCore/QMetaType>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDialogButtonBox>
namespace rtabmap { namespace rtabmap {
CameraViewer::CameraViewer(QWidget * parent) : CameraViewer::CameraViewer(QWidget * parent) :
QWidget(parent), QDialog(parent),
imageView_(new ImageView(this)), imageView_(new ImageView(this)),
cloudView_(new CloudViewer(this)), cloudView_(new CloudViewer(this)),
processingImages_(false) processingImages_(false)
@@ -48,13 +50,22 @@ CameraViewer::CameraViewer(QWidget * parent) :
imageView_->setImageDepthShown(true); imageView_->setImageDepthShown(true);
imageView_->setMinimumSize(320, 240); imageView_->setMinimumSize(320, 240);
QHBoxLayout * layout = new QHBoxLayout(this); QHBoxLayout * layout = new QHBoxLayout();
layout->setMargin(0); layout->setMargin(0);
layout->addWidget(imageView_); layout->addWidget(imageView_,1);
layout->addWidget(cloudView_); layout->addWidget(cloudView_,1);
layout->setStretch(0, 1);
layout->setStretch(1, 1); QDialogButtonBox * buttonBox = new QDialogButtonBox(this);
this->setLayout(layout); buttonBox->setStandardButtons(QDialogButtonBox::Close);
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
QVBoxLayout * vlayout = new QVBoxLayout(this);
vlayout->setMargin(0);
vlayout->setSpacing(0);
vlayout->addLayout(layout, 1);
vlayout->addWidget(buttonBox);
this->setLayout(vlayout);
} }
CameraViewer::~CameraViewer() CameraViewer::~CameraViewer()

View File

@@ -31,200 +31,320 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/OdometryEvent.h" #include "rtabmap/core/OdometryEvent.h"
#include "rtabmap/utilite/ULogger.h" #include "rtabmap/utilite/ULogger.h"
#include "rtabmap/utilite/UConversion.h" #include "rtabmap/utilite/UConversion.h"
#include <pcl/common/transforms.h> #include "rtabmap/gui/UCv2Qt.h"
#include <pcl/io/pcd_io.h>
#include <QInputDialog> #include "rtabmap/gui/ImageView.h"
#include <QAction> #include "rtabmap/gui/CloudViewer.h"
#include <QMenu>
#include <QtGui/QKeyEvent> #include <QPushButton>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QLabel>
#include <QHBoxLayout>
#include <QVBoxLayout>
namespace rtabmap { namespace rtabmap {
OdometryViewer::OdometryViewer(int maxClouds, int decimation, float voxelSize, int qualityWarningThr, QWidget * parent) : OdometryViewer::OdometryViewer(int maxClouds, int decimation, float voxelSize, int qualityWarningThr, QWidget * parent) :
CloudViewer(parent), QDialog(parent),
dataQuality_(-1), imageView_(new ImageView(this)),
cloudView_(new CloudViewer(this)),
processingData_(false),
odomImageShow_(true),
odomImageDepthShow_(true),
lastOdomPose_(Transform::getIdentity()), lastOdomPose_(Transform::getIdentity()),
maxClouds_(maxClouds),
voxelSize_(voxelSize),
decimation_(decimation),
qualityWarningThr_(qualityWarningThr), qualityWarningThr_(qualityWarningThr),
id_(0), id_(0),
_aSetVoxelSize(0), validDecimationValue_(1)
_aSetDecimation(0),
_aSetCloudHistorySize(0),
_aPause(0)
{ {
//add actions to CloudViewer menu qRegisterMetaType<rtabmap::SensorData>("rtabmap::SensorData");
_aSetVoxelSize = new QAction("Set voxel size...", this); qRegisterMetaType<rtabmap::OdometryInfo>("rtabmap::OdometryInfo");
_aSetDecimation = new QAction("Set depth image decimation...", this);
_aSetCloudHistorySize = new QAction("Set cloud history size...", this); imageView_->setImageDepthShown(true);
_aPause = new QAction("Pause", this); imageView_->setMinimumSize(320, 240);
_aPause->setCheckable(true);
menu()->addAction(_aSetVoxelSize); cloudView_->setCameraFree();
menu()->addAction(_aSetDecimation); cloudView_->setGridShown(true);
menu()->addAction(_aSetCloudHistorySize);
menu()->addAction(_aPause); QLabel * maxCloudsLabel = new QLabel("Max clouds", this);
QLabel * voxelLabel = new QLabel("Voxel", this);
QLabel * decimationLabel = new QLabel("Decimation", this);
maxCloudsSpin_ = new QSpinBox(this);
maxCloudsSpin_->setMinimum(0);
maxCloudsSpin_->setMaximum(100);
maxCloudsSpin_->setValue(maxClouds);
voxelSpin_ = new QDoubleSpinBox(this);
voxelSpin_->setMinimum(0);
voxelSpin_->setMaximum(1);
voxelSpin_->setDecimals(3);
voxelSpin_->setSingleStep(0.01);
voxelSpin_->setSuffix(" m");
voxelSpin_->setValue(voxelSize);
decimationSpin_ = new QSpinBox(this);
decimationSpin_->setMinimum(1);
decimationSpin_->setMaximum(16);
decimationSpin_->setValue(decimation);
QPushButton * clearButton = new QPushButton("clear", this);
QPushButton * closeButton = new QPushButton("close", this);
connect(clearButton, SIGNAL(clicked()), this, SLOT(clear()));
connect(closeButton, SIGNAL(clicked()), this, SLOT(reject()));
//layout
QHBoxLayout * layout = new QHBoxLayout();
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(imageView_,1);
layout->addWidget(cloudView_,1);
QHBoxLayout * hlayout2 = new QHBoxLayout();
hlayout2->setMargin(0);
hlayout2->addWidget(maxCloudsLabel);
hlayout2->addWidget(maxCloudsSpin_);
hlayout2->addWidget(voxelLabel);
hlayout2->addWidget(voxelSpin_);
hlayout2->addWidget(decimationLabel);
hlayout2->addWidget(decimationSpin_);
hlayout2->addStretch(1);
hlayout2->addWidget(clearButton);
hlayout2->addWidget(closeButton);
QVBoxLayout * vlayout = new QVBoxLayout(this);
vlayout->setMargin(0);
vlayout->setSpacing(0);
vlayout->addLayout(layout, 1);
vlayout->addLayout(hlayout2);
this->setLayout(vlayout);
}
OdometryViewer::~OdometryViewer()
{
this->unregisterFromEventsManager();
this->clear();
} }
void OdometryViewer::clear() void OdometryViewer::clear()
{ {
dataMutex_.lock(); cloudView_->clear();
data_.clear();
dataMutex_.unlock();
clouds_.clear();
CloudViewer::clear();
} }
void OdometryViewer::processData() void OdometryViewer::processData(const rtabmap::SensorData & data, const rtabmap::OdometryInfo & info)
{ {
rtabmap::SensorData data; processingData_ = true;
int quality = -1; int quality = info.inliers;
dataMutex_.lock();
if(data_.size())
{
data = data_.back();
data_.clear();
quality = dataQuality_;
dataQuality_ = -1;
}
dataMutex_.unlock();
if(!data.image().empty() && !data.depth().empty() && data.fx()>0.0f && data.fy()>0.0f && this->isVisible()) bool lost = false;
bool lostStateChanged = false;
if(data.pose().isNull())
{
UDEBUG("odom lost"); // use last pose
lostStateChanged = imageView_->getBackgroundColor() != Qt::darkRed;
imageView_->setBackgroundColor(Qt::darkRed);
cloudView_->setBackgroundColor(Qt::darkRed);
lost = true;
}
else if(info.inliers>0 &&
qualityWarningThr_ &&
info.inliers < qualityWarningThr_)
{
UDEBUG("odom warn, quality(inliers)=%d thr=%d", info.inliers, qualityWarningThr_);
lostStateChanged = imageView_->getBackgroundColor() == Qt::darkRed;
imageView_->setBackgroundColor(Qt::darkYellow);
cloudView_->setBackgroundColor(Qt::darkYellow);
}
else
{
UDEBUG("odom ok");
lostStateChanged = imageView_->getBackgroundColor() == Qt::darkRed;
imageView_->setBackgroundColor(cloudView_->getDefaultBackgroundColor());
cloudView_->setBackgroundColor(Qt::black);
}
if(!data.image().empty() && !data.depthOrRightImage().empty() && data.fx()>0.0f && data.fyOrBaseline()>0.0f)
{ {
UDEBUG("New pose = %s, quality=%d", data.pose().prettyPrint().c_str(), quality); UDEBUG("New pose = %s, quality=%d", data.pose().prettyPrint().c_str(), quality);
if(data.image().cols % decimationSpin_->value() == 0 &&
data.image().rows % decimationSpin_->value() == 0)
{
validDecimationValue_ = decimationSpin_->value();
}
else
{
UWARN("Decimation (%d) must be a denominator of the width and height of "
"the image (%d/%d). Using last valid decimation value (%d).",
decimationSpin_->value(),
data.image().cols,
data.image().rows,
validDecimationValue_);
}
// visualization: buffering the clouds // visualization: buffering the clouds
// Create the new cloud // Create the new cloud
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud; pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud;
if(data.depth().type() == CV_8UC1) if(!data.depth().empty())
{
cloud = util3d::cloudFromStereoImages(
data.image(),
data.depth(),
data.cx(), data.cy(),
data.fx(), data.fy(),
decimation_);
}
else
{ {
cloud = util3d::cloudFromDepthRGB( cloud = util3d::cloudFromDepthRGB(
data.image(), data.image(),
data.depth(), data.depth(),
data.cx(), data.cy(), data.cx(), data.cy(),
data.fx(), data.fy(), data.fx(), data.fy(),
decimation_); validDecimationValue_);
} }
else if(!data.rightImage().empty())
if(voxelSize_ > 0.0f)
{ {
cloud = util3d::voxelize<pcl::PointXYZRGB>(cloud, voxelSize_); cloud = util3d::cloudFromStereoImages(
data.image(),
data.rightImage(),
data.cx(), data.cy(),
data.fx(), data.baseline(),
validDecimationValue_);
} }
cloud = util3d::transformPointCloud<pcl::PointXYZRGB>(cloud, data.localTransform()); if(voxelSpin_->value() > 0.0f && cloud->size())
{
cloud = util3d::voxelize<pcl::PointXYZRGB>(cloud, voxelSpin_->value());
}
if(cloud->size())
{
cloud = util3d::transformPointCloud<pcl::PointXYZRGB>(cloud, data.localTransform());
}
if(!data.pose().isNull()) if(!data.pose().isNull())
{ {
lastOdomPose_ = data.pose(); lastOdomPose_ = data.pose();
if(this->getAddedClouds().contains("cloudtmp")) if(cloudView_->getAddedClouds().contains("cloudtmp"))
{ {
this->removeCloud("cloudtmp"); cloudView_->removeCloud("cloudtmp");
} }
data.id()?id_=data.id():++id_; data.id()?id_=data.id():++id_;
clouds_.insert(std::make_pair(id_, cloud)); while(maxCloudsSpin_->value()>0 && (int)cloudView_->getAddedClouds().size() > maxCloudsSpin_->value())
while(maxClouds_>0 && (int)clouds_.size() > maxClouds_)
{ {
this->removeCloud(uFormat("cloud%d", clouds_.begin()->first)); cloudView_->removeCloud(cloudView_->getAddedClouds().begin().key());
clouds_.erase(clouds_.begin());
} }
if(clouds_.size()) cloudView_->addOrUpdateCloud(uFormat("cloud%d", id_), cloud, data.pose());
{
this->addCloud(uFormat("cloud%d", clouds_.rbegin()->first), clouds_.rbegin()->second, data.pose());
}
this->updateCameraTargetPosition(data.pose()); cloudView_->updateCameraTargetPosition(data.pose());
if(qualityWarningThr_ && quality>=0 && quality < qualityWarningThr_)
{
this->setBackgroundColor(Qt::darkYellow);
}
else
{
this->setBackgroundColor(this->getDefaultBackgroundColor());
}
} }
else else
{ {
this->addOrUpdateCloud("cloudtmp", cloud, lastOdomPose_); cloudView_->addOrUpdateCloud("cloudtmp", cloud, lastOdomPose_);
this->setBackgroundColor(Qt::darkRed); }
}
if(!data.image().empty())
{
if(info.type == 0)
{
imageView_->setFeatures(info.words, Qt::yellow);
}
else if(info.type == 1)
{
imageView_->setFeatures(info.refCorners, Qt::red);
} }
this->update(); imageView_->clearLines();
if(lost)
{
if(lostStateChanged)
{
// save state
odomImageShow_ = imageView_->isImageShown();
odomImageDepthShow_ = imageView_->isImageDepthShown();
}
imageView_->setImageDepth(uCvMat2QImage(data.image()));
imageView_->setImageShown(true);
imageView_->setImageDepthShown(true);
}
else
{
if(lostStateChanged)
{
// restore state
imageView_->setImageShown(odomImageShow_);
imageView_->setImageDepthShown(odomImageDepthShow_);
}
imageView_->setImage(uCvMat2QImage(data.image()));
if(imageView_->isImageDepthShown())
{
imageView_->setImageDepth(uCvMat2QImage(data.depthOrRightImage()));
}
if(info.type == 0)
{
if(imageView_->isFeaturesShown())
{
for(unsigned int i=0; i<info.wordMatches.size(); ++i)
{
imageView_->setFeatureColor(info.wordMatches[i], Qt::red); // outliers
}
for(unsigned int i=0; i<info.wordInliers.size(); ++i)
{
imageView_->setFeatureColor(info.wordInliers[i], Qt::green); // inliers
}
}
}
else if(info.type == 1)
{
if(imageView_->isFeaturesShown() || imageView_->isLinesShown())
{
//draw lines
UASSERT(info.refCorners.size() == info.newCorners.size());
for(unsigned int i=0; i<info.cornerInliers.size(); ++i)
{
if(imageView_->isFeaturesShown())
{
imageView_->setFeatureColor(info.cornerInliers[i], Qt::green); // inliers
}
if(imageView_->isLinesShown())
{
imageView_->addLine(
info.refCorners[info.cornerInliers[i]].pt.x,
info.refCorners[info.cornerInliers[i]].pt.y,
info.newCorners[info.cornerInliers[i]].pt.x,
info.newCorners[info.cornerInliers[i]].pt.y,
Qt::blue);
}
}
imageView_->update();
}
}
}
if(!data.image().empty())
{
imageView_->setSceneRect(QRectF(0,0,(float)data.image().cols, (float)data.image().rows));
}
} }
cloudView_->update();
processingData_ = false;
} }
void OdometryViewer::handleEvent(UEvent * event) void OdometryViewer::handleEvent(UEvent * event)
{ {
if(!_aPause->isChecked()) if(!processingData_ && this->isVisible())
{ {
if(event->getClassName().compare("OdometryEvent") == 0) if(event->getClassName().compare("OdometryEvent") == 0)
{ {
rtabmap::OdometryEvent * odomEvent = (rtabmap::OdometryEvent*)event; rtabmap::OdometryEvent * odomEvent = (rtabmap::OdometryEvent*)event;
if(odomEvent->data().isValid())
bool empty = false;
dataMutex_.lock();
if(data_.empty())
{ {
data_.push_back(odomEvent->data()); processingData_ = true;
empty= true; QMetaObject::invokeMethod(this, "processData",
Q_ARG(rtabmap::SensorData, odomEvent->data()),
Q_ARG(rtabmap::OdometryInfo, odomEvent->info()));
} }
else
{
data_.back() = odomEvent->data();
}
dataQuality_ = odomEvent->info().inliers;
dataMutex_.unlock();
if(empty)
{
QMetaObject::invokeMethod(this, "processData");
}
}
}
}
void OdometryViewer::handleAction(QAction * a)
{
CloudViewer::handleAction(a);
if(a == _aSetVoxelSize)
{
bool ok;
double value = QInputDialog::getDouble(this, tr("Set voxel size"), tr("Size (0=disabled)"), voxelSize_, 0.0, 0.1, 2, &ok);
if(ok)
{
voxelSize_ = value;
}
}
else if(a == _aSetCloudHistorySize)
{
bool ok;
int value = QInputDialog::getInt(this, tr("Set cloud history size"), tr("Size (0=infinite)"), maxClouds_, 0, 100, 1, &ok);
if(ok)
{
maxClouds_ = value;
}
}
else if(a == _aSetDecimation)
{
bool ok;
int value = QInputDialog::getInt(this, tr("Set depth image decimation"), tr("Decimation"), decimation_, 1, 8, 1, &ok);
if(ok)
{
decimation_ = value;
} }
} }
} }

View File

@@ -81,11 +81,10 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui(0), _ui(0),
_indexModel(0), _indexModel(0),
_initialized(false), _initialized(false),
_cameraThread(0),
_odomThread(0),
_calibrationDialog(new CalibrationDialog(false, ".", this)) _calibrationDialog(new CalibrationDialog(false, ".", this))
{ {
ULOGGER_DEBUG(""); ULOGGER_DEBUG("");
_calibrationDialog->setWindowFlags(Qt::Window);
_ui = new Ui_preferencesDialog(); _ui = new Ui_preferencesDialog();
_ui->setupUi(this); _ui->setupUi(this);
@@ -3254,25 +3253,18 @@ void PreferencesDialog::testOdometry()
void PreferencesDialog::testOdometry(int type) void PreferencesDialog::testOdometry(int type)
{ {
if(_cameraThread)
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("A camera is already running!"));
return;
}
UASSERT(_odomThread == 0 && _cameraThread == 0);
CameraRGBD * camera = this->createCameraRGBD(); CameraRGBD * camera = this->createCameraRGBD();
if(!camera->init(this->getCameraInfoDir().toStdString())) if(camera == 0 || !camera->init(this->getCameraInfoDir().toStdString()))
{ {
QMessageBox::warning(this, QMessageBox::warning(this,
tr("RTAB-Map"), tr("RTAB-Map"),
tr("RGBD camera initialization failed!")); tr("RGBD camera initialization failed!"));
delete camera; if(camera)
camera = 0; {
delete camera;
}
return;
} }
else if(dynamic_cast<CameraOpenNI2*>(camera) != 0) else if(dynamic_cast<CameraOpenNI2*>(camera) != 0)
{ {
@@ -3287,110 +3279,56 @@ void PreferencesDialog::testOdometry(int type)
} }
camera->setMirroringEnabled(isSourceMirroring()); camera->setMirroringEnabled(isSourceMirroring());
ParametersMap parameters = this->getAllParameters();
if(camera) Odometry * odometry;
if(this->getOdomStrategy() == 1)
{ {
ParametersMap parameters = this->getAllParameters(); odometry = new OdometryOpticalFlow(parameters);
Odometry * odometry;
if(this->getOdomStrategy() == 1)
{
odometry = new OdometryOpticalFlow(parameters);
}
else
{
odometry = new OdometryBOW(parameters);
}
_odomThread = new OdometryThread(odometry); // take ownership of odometry
QDialog * window = new QDialog(this);
window->setWindowModality(Qt::WindowModal);
window->setWindowTitle(tr("Odometry viewer"));
window->setMinimumWidth(800);
window->setMinimumHeight(600);
connect( window, SIGNAL(finished(int)), this, SLOT(cleanOdometryTest()) );
OdometryViewer * odomViewer = new OdometryViewer(10,
_ui->spinBox_decimation_odom->value(),
_ui->doubleSpinBox_voxelSize_odom->value(),
this->getOdomQualityWarnThr(),
window);
connect( window, SIGNAL(finished(int)), odomViewer, SLOT(clear()) );
odomViewer->setCameraFree();
odomViewer->setGridShown(true);
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(odomViewer);
window->setLayout(layout);
UEventsManager::addHandler(_odomThread);
UEventsManager::addHandler(odomViewer);
_cameraThread = new CameraThread(camera);
UEventsManager::createPipe(_cameraThread, _odomThread, "CameraEvent");
UEventsManager::createPipe(_odomThread, odomViewer, "OdometryEvent");
window->showNormal();
_ui->pushButton_testOdometry->setEnabled(false);
QApplication::processEvents();
uSleep(500);
QApplication::processEvents();
_odomThread->start();
_cameraThread->start();
} }
} else
void PreferencesDialog::cleanOdometryTest()
{
UDEBUG("");
if(_cameraThread)
{ {
_cameraThread->join(true); odometry = new OdometryBOW(parameters);
delete _cameraThread;
_cameraThread = 0;
} }
if(_odomThread)
{
_odomThread->join(true);
delete _odomThread;
_odomThread = 0;
}
_ui->pushButton_testOdometry->setEnabled(true);
}
void PreferencesDialog::cleanRGBDCameraTest() OdometryThread odomThread(odometry); // take ownership of odometry
{ odomThread.registerToEventsManager();
UDEBUG("");
if(_cameraThread) OdometryViewer * odomViewer = new OdometryViewer(10,
{ _ui->spinBox_decimation_odom->value(),
_cameraThread->join(true); _ui->doubleSpinBox_voxelSize_odom->value(),
delete _cameraThread; this->getOdomQualityWarnThr(),
_cameraThread = 0; this);
} odomViewer->setWindowTitle(tr("Odometry viewer"));
_ui->pushButton_test_rgbd_camera->setEnabled(true); odomViewer->resize(1280, 480+QPushButton().minimumHeight());
odomViewer->registerToEventsManager();
CameraThread cameraThread(camera); // take ownership of camera
UEventsManager::createPipe(&cameraThread, &odomThread, "CameraEvent");
UEventsManager::createPipe(&odomThread, odomViewer, "OdometryEvent");
odomThread.start();
cameraThread.start();
odomViewer->exec();
delete odomViewer;
cameraThread.join(true);
odomThread.join(true);
} }
void PreferencesDialog::testRGBDCamera() void PreferencesDialog::testRGBDCamera()
{ {
if(_cameraThread)
{
QMessageBox::warning(this,
tr("RTAB-Map"),
tr("A camera is already running!"));
}
CameraRGBD * camera = this->createCameraRGBD(); CameraRGBD * camera = this->createCameraRGBD();
if(!camera->init(this->getCameraInfoDir().toStdString())) if(camera == 0 || !camera->init(this->getCameraInfoDir().toStdString()))
{ {
QMessageBox::warning(this, QMessageBox::warning(this,
tr("RTAB-Map"), tr("RTAB-Map"),
tr("RGBD camera initialization failed!")); tr("RGBD camera initialization failed!"));
delete camera; if(camera)
camera = 0; {
delete camera;
}
return;
} }
else if(dynamic_cast<CameraOpenNI2*>(camera) != 0) else if(dynamic_cast<CameraOpenNI2*>(camera) != 0)
{ {
@@ -3405,41 +3343,34 @@ void PreferencesDialog::testRGBDCamera()
} }
camera->setMirroringEnabled(isSourceMirroring()); camera->setMirroringEnabled(isSourceMirroring());
// Create DataRecorder without init it, just to show images...
CameraViewer * window = new CameraViewer(this);
window->setWindowTitle(tr("RGBD camera viewer"));
window->resize(1280, 480+QPushButton().minimumHeight());
window->registerToEventsManager();
if(camera) CameraThread cameraThread(camera);
{ UEventsManager::createPipe(&cameraThread, window, "CameraEvent");
_ui->pushButton_test_rgbd_camera->setEnabled(false);
// Create DataRecorder without init it, just to show images... cameraThread.start();
CameraViewer * window = new CameraViewer(this); window->exec();
window->setWindowModality(Qt::WindowModal); delete window;
window->setAttribute(Qt::WA_DeleteOnClose); cameraThread.join(true);
window->setWindowFlags(Qt::Dialog);
window->setWindowTitle(tr("RGBD camera viewer"));
window->setMinimumWidth(1280);
window->setMinimumHeight(480);
connect( window, SIGNAL(destroyed(QObject*)), this, SLOT(cleanRGBDCameraTest()) );
window->registerToEventsManager();
_cameraThread = new CameraThread(camera);
UEventsManager::createPipe(_cameraThread, window, "CameraEvent");
window->showNormal();
_cameraThread->start();
}
} }
void PreferencesDialog::calibrate() void PreferencesDialog::calibrate()
{ {
CameraRGBD * camera = this->createCameraRGBD(); CameraRGBD * camera = this->createCameraRGBD();
if(!camera->init("")) // don't set calibration folder to use raw images if(camera == 0 || !camera->init("")) // don't set calibration folder to use raw images
{ {
QMessageBox::warning(this, QMessageBox::warning(this,
tr("RTAB-Map"), tr("RTAB-Map"),
tr("RGBD camera initialization failed!")); tr("RGBD camera initialization failed!"));
delete camera; if(camera)
camera = 0; {
delete camera;
}
return;
} }
else if(dynamic_cast<CameraOpenNI2*>(camera) != 0) else if(dynamic_cast<CameraOpenNI2*>(camera) != 0)
{ {
@@ -3455,34 +3386,31 @@ void PreferencesDialog::calibrate()
camera->setMirroringEnabled(isSourceMirroring()); camera->setMirroringEnabled(isSourceMirroring());
if(camera) if(!this->getCameraInfoDir().isEmpty())
{ {
if(!this->getCameraInfoDir().isEmpty()) QDir dir(this->getCameraInfoDir());
if (!dir.exists())
{ {
QDir dir(this->getCameraInfoDir()); UINFO("Creating camera_info directory: \"%s\"", this->getCameraInfoDir().toStdString().c_str());
if (!dir.exists()) if(!dir.mkpath(this->getCameraInfoDir()))
{ {
UINFO("Creating camera_info directory: \"%s\"", this->getCameraInfoDir().toStdString().c_str()); UWARN("Could create camera_info directory: \"%s\"", this->getCameraInfoDir().toStdString().c_str());
if(!dir.mkpath(this->getCameraInfoDir()))
{
UWARN("Could create camera_info directory: \"%s\"", this->getCameraInfoDir().toStdString().c_str());
}
} }
} }
_calibrationDialog->setStereoMode(dynamic_cast<CameraStereoDC1394*>(camera)!=0);
_calibrationDialog->setSavingDirectory(this->getCameraInfoDir());
_calibrationDialog->registerToEventsManager();
CameraThread cameraThread(camera);
UEventsManager::createPipe(&cameraThread, _calibrationDialog, "CameraEvent");
cameraThread.start();
_calibrationDialog->exec();
_calibrationDialog->unregisterFromEventsManager();
cameraThread.join(true);
} }
_calibrationDialog->setStereoMode(dynamic_cast<CameraStereoDC1394*>(camera)!=0);
_calibrationDialog->setSavingDirectory(this->getCameraInfoDir());
_calibrationDialog->registerToEventsManager();
CameraThread cameraThread(camera);
UEventsManager::createPipe(&cameraThread, _calibrationDialog, "CameraEvent");
cameraThread.start();
_calibrationDialog->exec();
_calibrationDialog->unregisterFromEventsManager();
cameraThread.join(true);
} }
} }

View File

@@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>486</width> <width>486</width>
<height>369</height> <height>425</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">

View File

@@ -59,6 +59,10 @@ int main(int argc, char * argv[])
} }
else else
{ {
if(strcmp(argv[argc-1], "--help") == 0)
{
showUsage();
}
driver = atoi(argv[argc-1]); driver = atoi(argv[argc-1]);
if(driver < 0 || driver > 6) if(driver < 0 || driver > 6)
{ {
@@ -134,7 +138,7 @@ int main(int argc, char * argv[])
if(!camera->init()) if(!camera->init())
{ {
printf("Camera init failed!\n"); printf("Camera init failed! Please select another driver (see \"--help\").\n");
delete camera; delete camera;
exit(1); exit(1);
} }

View File

@@ -16,14 +16,8 @@ SET(LIBRARIES
${QT_LIBRARIES} ${QT_LIBRARIES}
) )
IF("${RTABMAP_QT_VERSION}" STREQUAL "4")
QT4_WRAP_CPP(moc_srcs OdomInfoWidget.h)
ELSE()
QT5_WRAP_CPP(moc_srcs OdomInfoWidget.h)
ENDIF()
SET(SRC_FILES SET(SRC_FILES
main.cpp OdomInfoWidget.cpp ${moc_srcs} main.cpp
) )
add_definitions(${PCL_DEFINITIONS}) add_definitions(${PCL_DEFINITIONS})

View File

@@ -1,208 +0,0 @@
/*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "OdomInfoWidget.h"
#include <rtabmap/utilite/ULogger.h>
#include <rtabmap/core/OdometryEvent.h>
#include <rtabmap/core/util3d.h>
#include <rtabmap/gui/ImageView.h>
#include <rtabmap/gui/UCv2Qt.h>
#include <QtCore/QMetaType>
#include <QtGui/QCloseEvent>
#include <QLabel>
#include <QVBoxLayout>
OdomInfoWidget::OdomInfoWidget(QWidget * parent) :
QWidget(parent),
imageView_(new rtabmap::ImageView(this)),
label_(new QLabel(this)),
processingOdomInfo_(false),
receivingRate_(0),
lastTime_(0),
odomImageShow_(true),
odomImageDepthShow_(false)
{
qRegisterMetaType<rtabmap::SensorData>("rtabmap::SensorData");
qRegisterMetaType<rtabmap::OdometryInfo>("rtabmap::OdometryInfo");
imageView_->setMinimumSize(320, 240);
QVBoxLayout * layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->addWidget(imageView_);
layout->addWidget(label_);
layout->setStretch(0,1);
this->setLayout(layout);
}
OdomInfoWidget::~OdomInfoWidget()
{
this->unregisterFromEventsManager();
}
void OdomInfoWidget::processOdomInfo(const rtabmap::SensorData & data, const rtabmap::OdometryInfo & info)
{
processingOdomInfo_ = true;
const rtabmap::Transform & pose = data.pose();
bool lost = false;
bool lostStateChanged = false;
if(pose.isNull())
{
// lost
lostStateChanged = imageView_->getBackgroundColor() != Qt::darkRed;
imageView_->setBackgroundColor(Qt::darkRed);
lost = true;
}
else
{
// ok
lostStateChanged = imageView_->getBackgroundColor() == Qt::darkRed;
imageView_->setBackgroundColor(Qt::black);
}
if(!data.image().empty())
{
if(imageView_->isFeaturesShown())
{
if(info.type == 0)
{
imageView_->setFeatures(info.words, Qt::yellow);
}
else if(info.type == 1)
{
imageView_->setFeatures(info.refCorners, Qt::red);
}
}
imageView_->clearLines();
if(lost)
{
if(lostStateChanged)
{
// save state
odomImageShow_ = imageView_->isImageShown();
odomImageDepthShow_ = imageView_->isImageDepthShown();
}
imageView_->setImageDepth(uCvMat2QImage(data.image()));
imageView_->setImageShown(true);
imageView_->setImageDepthShown(true);
}
else
{
if(lostStateChanged)
{
// restore state
imageView_->setImageShown(odomImageShow_);
imageView_->setImageDepthShown(odomImageDepthShow_);
}
imageView_->setImage(uCvMat2QImage(data.image()));
if(imageView_->isImageDepthShown())
{
imageView_->setImageDepth(uCvMat2QImage(data.depthOrRightImage()));
}
if(info.type == 0)
{
if(imageView_->isFeaturesShown())
{
for(unsigned int i=0; i<info.wordMatches.size(); ++i)
{
imageView_->setFeatureColor(info.wordMatches[i], Qt::red); // outliers
}
for(unsigned int i=0; i<info.wordInliers.size(); ++i)
{
imageView_->setFeatureColor(info.wordInliers[i], Qt::green); // inliers
}
}
}
else if(info.type == 1)
{
if(imageView_->isFeaturesShown() || imageView_->isLinesShown())
{
//draw lines
UASSERT(info.refCorners.size() == info.newCorners.size());
for(unsigned int i=0; i<info.cornerInliers.size(); ++i)
{
if(imageView_->isFeaturesShown())
{
imageView_->setFeatureColor(info.cornerInliers[i], Qt::green); // inliers
}
if(imageView_->isLinesShown())
{
imageView_->addLine(
info.refCorners[info.cornerInliers[i]].pt.x,
info.refCorners[info.cornerInliers[i]].pt.y,
info.newCorners[info.cornerInliers[i]].pt.x,
info.newCorners[info.cornerInliers[i]].pt.y,
Qt::blue);
}
}
imageView_->update();
}
}
}
if(!data.image().empty())
{
imageView_->setSceneRect(QRectF(0,0,(float)data.image().cols, (float)data.image().rows));
}
}
label_->setText(tr("Rate=~%1 Hz").arg(receivingRate_));
processingOdomInfo_ = false;
}
void OdomInfoWidget::closeEvent(QCloseEvent* event)
{
this->unregisterFromEventsManager();
event->accept();
}
void OdomInfoWidget::handleEvent(UEvent * event)
{
if(event->getClassName().compare("OdometryEvent") == 0)
{
rtabmap::OdometryEvent * odomEvent = (rtabmap::OdometryEvent*)event;
receivingRate_ = 1.0f/timer_.ticks();
// update max 10 Hz
if(UTimer::now() - lastTime_ > 0.1)
{
lastTime_ = UTimer::now();
if(!processingOdomInfo_ && this->isVisible())
{
QMetaObject::invokeMethod(this, "processOdomInfo",
Q_ARG(rtabmap::SensorData, odomEvent->data()),
Q_ARG(rtabmap::OdometryInfo, odomEvent->info()));
}
}
}
}

View File

@@ -1,66 +0,0 @@
/*
Copyright (c) 2010-2014, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Universite de Sherbrooke nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ODOMINFOWIDGET_H_
#define ODOMINFOWIDGET_H_
#include <rtabmap/utilite/UEventsHandler.h>
#include <QWidget>
#include <rtabmap/utilite/UTimer.h>
#include <rtabmap/core/SensorData.h>
#include <rtabmap/core/OdometryInfo.h>
class QLabel;
namespace rtabmap{
class ImageView;
}
class OdomInfoWidget : public QWidget, public UEventsHandler
{
Q_OBJECT
public:
OdomInfoWidget(QWidget * parent = 0);
virtual ~OdomInfoWidget();
public slots:
void processOdomInfo(const rtabmap::SensorData & data, const rtabmap::OdometryInfo & info);
protected:
virtual void closeEvent(QCloseEvent* event);
void handleEvent(UEvent * event);
private:
rtabmap::ImageView* imageView_;
QLabel* label_;
UTimer timer_;
bool processingOdomInfo_;
double receivingRate_;
double lastTime_;
bool odomImageShow_;
bool odomImageDepthShow_;
};
#endif /* ODOMINFOWIDGET_H_ */

View File

@@ -36,15 +36,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <rtabmap/core/DBReader.h> #include <rtabmap/core/DBReader.h>
#include <rtabmap/core/VWDictionary.h> #include <rtabmap/core/VWDictionary.h>
#include <QApplication> #include <QApplication>
#include <QPushButton>
#include <pcl/console/print.h> #include <pcl/console/print.h>
#include "OdomInfoWidget.h"
void showUsage() void showUsage()
{ {
printf("\nUsage:\n" printf("\nUsage:\n"
"odometryViewer [options]\n" "odometryViewer [options]\n"
"Options:\n" "Options:\n"
" -driver # Driver number to use: 0=OpenNI-PCL, 1=OpenNI2, 2=Freenect, 3=OpenNI-CV, 4=OpenNI-CV-ASUS\n" " -driver # Driver number to use: 0=OpenNI-PCL, 1=OpenNI2, 2=Freenect, 3=OpenNI-CV, 4=OpenNI-CV-ASUS, 5=Freenect2, 6=dc1394\n"
" -o # Odometry type (default 6): 0=SURF, 1=SIFT, 2=ORB, 3=FAST/FREAK, 4=FAST/BRIEF, 5=GFTT/FREAK, 6=GFTT/BRIEF, 7=BRISK\n" " -o # Odometry type (default 6): 0=SURF, 1=SIFT, 2=ORB, 3=FAST/FREAK, 4=FAST/BRIEF, 5=GFTT/FREAK, 6=GFTT/BRIEF, 7=BRISK\n"
" -nn # Nearest neighbor strategy (default 3): kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4\n" " -nn # Nearest neighbor strategy (default 3): kNNFlannNaive=0, kNNFlannKdTree=1, kNNFlannLSH=2, kNNBruteForce=3, kNNBruteForceGPU=4\n"
" -nndr # Nearest neighbor distance ratio (default 0.7)\n" " -nndr # Nearest neighbor distance ratio (default 0.7)\n"
@@ -90,6 +90,8 @@ int main (int argc, char * argv[])
{ {
ULogger::setType(ULogger::kTypeConsole); ULogger::setType(ULogger::kTypeConsole);
ULogger::setLevel(ULogger::kInfo); ULogger::setLevel(ULogger::kInfo);
ULogger::setPrintTime(false);
ULogger::setPrintWhere(false);
// parse arguments // parse arguments
float rate = 0.0; float rate = 0.0;
@@ -126,7 +128,7 @@ int main (int argc, char * argv[])
if(i < argc) if(i < argc)
{ {
driver = std::atoi(argv[i]); driver = std::atoi(argv[i]);
if(driver < 0 || driver > 4) if(driver < 0 || driver > 6)
{ {
showUsage(); showUsage();
} }
@@ -501,6 +503,8 @@ int main (int argc, char * argv[])
if(strcmp(argv[i], "-debug") == 0) if(strcmp(argv[i], "-debug") == 0)
{ {
ULogger::setLevel(ULogger::kDebug); ULogger::setLevel(ULogger::kDebug);
ULogger::setPrintTime(true);
ULogger::setPrintWhere(true);
continue; continue;
} }
@@ -680,23 +684,11 @@ int main (int argc, char * argv[])
} }
rtabmap::OdometryThread odomThread(odom); rtabmap::OdometryThread odomThread(odom);
rtabmap::OdometryViewer odomViewer(maxClouds, 2, 0.0, 50); rtabmap::OdometryViewer odomViewer(maxClouds, 2, 0.0, 50);
OdomInfoWidget odomInfoWidget;
UEventsManager::addHandler(&odomThread); UEventsManager::addHandler(&odomThread);
UEventsManager::addHandler(&odomViewer); UEventsManager::addHandler(&odomViewer);
UEventsManager::addHandler(&odomInfoWidget);
odomViewer.setCameraFree(); odomViewer.setWindowTitle("Odometry view");
odomViewer.setGridShown(true); odomViewer.resize(1280, 480+QPushButton().minimumHeight());
odomViewer.setWindowTitle("Odometry 3D view");
odomViewer.setMinimumWidth(800);
odomViewer.setMinimumHeight(500);
odomViewer.showNormal();
odomInfoWidget.setWindowTitle("Odometry info");
odomInfoWidget.showNormal();
app.processEvents();
if(inputDatabase.size()) if(inputDatabase.size())
{ {
@@ -756,6 +748,24 @@ int main (int argc, char * argv[])
} }
camera = new rtabmap::CameraOpenNICV(true, rate, t); camera = new rtabmap::CameraOpenNICV(true, rate, t);
} }
else if(driver == 5)
{
if(!rtabmap::CameraFreenect2::available())
{
UERROR("Not built with Freenect2 support...");
exit(-1);
}
camera = new rtabmap::CameraFreenect2(0, rate, t);
}
else if(driver == 6)
{
if(!rtabmap::CameraStereoDC1394::available())
{
UERROR("Not built with dc1394 support...");
exit(-1);
}
camera = new rtabmap::CameraStereoDC1394(rate, t);
}
else else
{ {
UFATAL("Camera driver (%d) not found!", driver); UFATAL("Camera driver (%d) not found!", driver);
@@ -763,16 +773,28 @@ int main (int argc, char * argv[])
//pcl::console::setVerbosityLevel(pcl::console::L_DEBUG); //pcl::console::setVerbosityLevel(pcl::console::L_DEBUG);
rtabmap::CameraThread cameraThread(camera); if(camera->init())
if(cameraThread.init())
{ {
odomThread.start(); if(camera->isCalibrated())
cameraThread.start(); {
rtabmap::CameraThread cameraThread(camera);
app.exec(); odomThread.start();
cameraThread.start();
cameraThread.kill(); odomViewer.exec();
odomThread.join(true);
cameraThread.kill();
odomThread.join(true);
}
else
{
printf("The camera is not calibrated! You should calibrate the camera first.\n");
}
}
else
{
printf("Failed to initialize the camera! Please select another driver (see \"--help\").\n");
} }
} }