mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 09:30:25 +08:00
0.16.3: Added OKVIS support (tested only on EuRoC dataset). Added IMU/IMUThread classes. Added OdomOKVIS/ConfigPath and Rtabmap/ImagesAlreadyRectified parameters. MainWindow, limited odom local feature map to maximum 50 meters from current pose (to avoid VTK glitching with near/far clipping plane).
This commit is contained in:
@@ -32,6 +32,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "rtabmap/core/CameraRGB.h"
|
||||
#include "rtabmap/core/CameraStereo.h"
|
||||
#include "rtabmap/core/CameraThread.h"
|
||||
#include "rtabmap/core/IMUThread.h"
|
||||
#include "rtabmap/core/CameraEvent.h"
|
||||
#include "rtabmap/core/DBReader.h"
|
||||
#include "rtabmap/core/Parameters.h"
|
||||
@@ -135,6 +136,7 @@ MainWindow::MainWindow(PreferencesDialog * prefDialog, QWidget * parent, bool sh
|
||||
_state(kIdle),
|
||||
_camera(0),
|
||||
_odomThread(0),
|
||||
_imuThread(0),
|
||||
_preferencesDialog(0),
|
||||
_aboutDialog(0),
|
||||
_exportCloudsDialog(0),
|
||||
@@ -759,6 +761,11 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
||||
UERROR("Camera must be already deleted here!");
|
||||
delete _camera;
|
||||
_camera = 0;
|
||||
if(_imuThread)
|
||||
{
|
||||
delete _imuThread;
|
||||
_imuThread = 0;
|
||||
}
|
||||
}
|
||||
if(_odomThread)
|
||||
{
|
||||
@@ -1179,18 +1186,22 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
|
||||
int i=0;
|
||||
for(std::map<int, cv::Point3f>::const_iterator iter=odom.info().localMap.begin(); iter!=odom.info().localMap.end(); ++iter)
|
||||
{
|
||||
(*cloud)[i].x = iter->second.x;
|
||||
(*cloud)[i].y = iter->second.y;
|
||||
(*cloud)[i].z = iter->second.z;
|
||||
|
||||
// green = inlier, yellow = outliers
|
||||
bool inlier = odom.info().words.find(iter->first) != odom.info().words.end();
|
||||
(*cloud)[i].r = inlier?0:255;
|
||||
(*cloud)[i].g = 255;
|
||||
(*cloud)[i].b = 0;
|
||||
if(!_preferencesDialog->isOdomOnlyInliersShown() || inlier)
|
||||
// filter very far features from current location
|
||||
if(uNormSquared(iter->second.x-odom.pose().x(), iter->second.y-odom.pose().y(), iter->second.z-odom.pose().z()) < 50*50)
|
||||
{
|
||||
++i;
|
||||
(*cloud)[i].x = iter->second.x;
|
||||
(*cloud)[i].y = iter->second.y;
|
||||
(*cloud)[i].z = iter->second.z;
|
||||
|
||||
// green = inlier, yellow = outliers
|
||||
bool inlier = odom.info().words.find(iter->first) != odom.info().words.end();
|
||||
(*cloud)[i].r = inlier?0:255;
|
||||
(*cloud)[i].g = 255;
|
||||
(*cloud)[i].b = 0;
|
||||
if(!_preferencesDialog->isOdomOnlyInliersShown() || inlier)
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
cloud->resize(i);
|
||||
@@ -4788,6 +4799,13 @@ void MainWindow::startDetection()
|
||||
_odomThread = 0;
|
||||
}
|
||||
|
||||
if(_imuThread)
|
||||
{
|
||||
UERROR("ImuThread must be already deleted here?!");
|
||||
delete _imuThread;
|
||||
_imuThread = 0;
|
||||
}
|
||||
|
||||
if(!camera->odomProvided() && !_preferencesDialog->isOdomDisabled())
|
||||
{
|
||||
ParametersMap odomParameters = parameters;
|
||||
@@ -4803,12 +4821,42 @@ void MainWindow::startDetection()
|
||||
// Only Frame To Frame supports all VisCorType
|
||||
odomParameters.insert(ParametersPair(Parameters::kVisCorType(), _preferencesDialog->getParameter(Parameters::kVisCorType())));
|
||||
}
|
||||
_imuThread = 0;
|
||||
if((_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcStereoImages ||
|
||||
_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcRGBDImages ||
|
||||
_preferencesDialog->getSourceDriver() == PreferencesDialog::kSrcImages) &&
|
||||
!_preferencesDialog->getIMUPath().isEmpty())
|
||||
{
|
||||
if(odomStrategy != Odometry::kTypeOkvis)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Source IMU Path"),
|
||||
tr("IMU path is set but odometry chosen doesn't support IMU, ignoring IMU..."), QMessageBox::Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
_imuThread = new IMUThread(_preferencesDialog->getIMURate(), _preferencesDialog->getIMULocalTransform());
|
||||
if(!_imuThread->init(_preferencesDialog->getIMUPath().toStdString()))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Source IMU Path"),
|
||||
tr("Initialization of IMU data has failed! Path=%1.").arg(_preferencesDialog->getIMUPath()), QMessageBox::Ok);
|
||||
delete _camera;
|
||||
_camera = 0;
|
||||
delete _imuThread;
|
||||
_imuThread = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Odometry * odom = Odometry::create(odomParameters);
|
||||
_odomThread = new OdometryThread(odom, _preferencesDialog->getOdomBufferSize());
|
||||
|
||||
UEventsManager::addHandler(_odomThread);
|
||||
UEventsManager::createPipe(_camera, _odomThread, "CameraEvent");
|
||||
UEventsManager::createPipe(_camera, this, "CameraEvent");
|
||||
if(_imuThread)
|
||||
{
|
||||
UEventsManager::createPipe(_imuThread, _odomThread, "IMUEvent");
|
||||
}
|
||||
_odomThread->start();
|
||||
}
|
||||
}
|
||||
@@ -4910,6 +4958,11 @@ void MainWindow::stopDetection()
|
||||
|
||||
ULOGGER_DEBUG("");
|
||||
// kill the processes
|
||||
if(_imuThread)
|
||||
{
|
||||
_imuThread->join(true);
|
||||
}
|
||||
|
||||
if(_camera)
|
||||
{
|
||||
_camera->join(true);
|
||||
@@ -4922,6 +4975,11 @@ void MainWindow::stopDetection()
|
||||
}
|
||||
|
||||
// delete the processes
|
||||
if(_imuThread)
|
||||
{
|
||||
delete _imuThread;
|
||||
_imuThread = 0;
|
||||
}
|
||||
if(_camera)
|
||||
{
|
||||
delete _camera;
|
||||
@@ -7319,6 +7377,10 @@ void MainWindow::changeState(MainWindow::State newState)
|
||||
if(_camera)
|
||||
{
|
||||
_camera->start();
|
||||
if(_imuThread)
|
||||
{
|
||||
_imuThread->start();
|
||||
}
|
||||
ULogger::setTreadIdFilter(_preferencesDialog->getGeneralLoggerThreads());
|
||||
}
|
||||
break;
|
||||
@@ -7351,6 +7413,10 @@ void MainWindow::changeState(MainWindow::State newState)
|
||||
if(_camera)
|
||||
{
|
||||
_camera->start();
|
||||
if(_imuThread)
|
||||
{
|
||||
_imuThread->start();
|
||||
}
|
||||
ULogger::setTreadIdFilter(_preferencesDialog->getGeneralLoggerThreads());
|
||||
}
|
||||
}
|
||||
@@ -7384,6 +7450,10 @@ void MainWindow::changeState(MainWindow::State newState)
|
||||
// kill sensors
|
||||
if(_camera)
|
||||
{
|
||||
if(_imuThread)
|
||||
{
|
||||
_imuThread->join(true);
|
||||
}
|
||||
_camera->join(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,23 +344,28 @@ void OdometryViewer::processData(const rtabmap::OdometryEvent & odom)
|
||||
// 3d features
|
||||
if(featuresShown_->isChecked())
|
||||
{
|
||||
if(!odom.info().localMap.empty())
|
||||
if(!odom.info().localMap.empty() && !odom.pose().isNull())
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
|
||||
cloud->resize(odom.info().localMap.size());
|
||||
int i=0;
|
||||
for(std::map<int, cv::Point3f>::const_iterator iter=odom.info().localMap.begin(); iter!=odom.info().localMap.end(); ++iter)
|
||||
{
|
||||
(*cloud)[i].x = iter->second.x;
|
||||
(*cloud)[i].y = iter->second.y;
|
||||
(*cloud)[i].z = iter->second.z;
|
||||
// filter very far features from current location
|
||||
if(uNormSquared(iter->second.x-odom.pose().x(), iter->second.y-odom.pose().y(), iter->second.z-odom.pose().z()) < 50*50)
|
||||
{
|
||||
(*cloud)[i].x = iter->second.x;
|
||||
(*cloud)[i].y = iter->second.y;
|
||||
(*cloud)[i].z = iter->second.z;
|
||||
|
||||
// green = inlier, yellow = outliers
|
||||
bool inlier = odom.info().words.find(iter->first) != odom.info().words.end();
|
||||
(*cloud)[i].r = inlier?0:255;
|
||||
(*cloud)[i].g = 255;
|
||||
(*cloud)[i++].b = 0;
|
||||
// green = inlier, yellow = outliers
|
||||
bool inlier = odom.info().words.find(iter->first) != odom.info().words.end();
|
||||
(*cloud)[i].r = inlier?0:255;
|
||||
(*cloud)[i].g = 255;
|
||||
(*cloud)[i++].b = 0;
|
||||
}
|
||||
}
|
||||
cloud->resize(i);
|
||||
|
||||
if(!cloudView_->addCloud("featuresOdom", cloud))
|
||||
{
|
||||
|
||||
@@ -56,6 +56,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "rtabmap/core/CameraThread.h"
|
||||
#include "rtabmap/core/CameraRGB.h"
|
||||
#include "rtabmap/core/CameraStereo.h"
|
||||
#include "rtabmap/core/IMUThread.h"
|
||||
#include "rtabmap/core/Memory.h"
|
||||
#include "rtabmap/core/VWDictionary.h"
|
||||
#include "rtabmap/core/Optimizer.h"
|
||||
@@ -172,6 +173,9 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
#ifndef RTABMAP_ORB_SLAM2
|
||||
_ui->odom_strategy->setItemData(5, 0, Qt::UserRole - 1);
|
||||
#endif
|
||||
#ifndef RTABMAP_OKVIS
|
||||
_ui->odom_strategy->setItemData(6, 0, Qt::UserRole - 1);
|
||||
#endif
|
||||
|
||||
#ifndef RTABMAP_NONFREE
|
||||
_ui->comboBox_detector_strategy->setItemData(0, 0, Qt::UserRole - 1);
|
||||
@@ -561,6 +565,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->toolButton_cameraRGBDImages_path_rgb, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesPathRGB()));
|
||||
connect(_ui->toolButton_cameraRGBDImages_path_depth, SIGNAL(clicked()), this, SLOT(selectSourceRGBDImagesPathDepth()));
|
||||
connect(_ui->toolButton_cameraImages_path_scans, SIGNAL(clicked()), this, SLOT(selectSourceImagesPathScans()));
|
||||
connect(_ui->toolButton_cameraImages_path_imu, SIGNAL(clicked()), this, SLOT(selectSourceImagesPathIMU()));
|
||||
connect(_ui->toolButton_cameraImages_odom, SIGNAL(clicked()), this, SLOT(selectSourceImagesPathOdom()));
|
||||
connect(_ui->toolButton_cameraImages_gt, SIGNAL(clicked()), this, SLOT(selectSourceImagesPathGt()));
|
||||
connect(_ui->lineEdit_cameraRGBDImages_path_rgb, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
@@ -579,6 +584,9 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->lineEdit_cameraImages_gt, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->comboBox_cameraImages_gtFormat, SIGNAL(currentIndexChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->doubleSpinBox_maxPoseTimeDiff, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->lineEdit_cameraImages_path_imu, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->lineEdit_cameraImages_imu_transform, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->spinBox_cameraImages_max_imu_rate, SIGNAL(valueChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->groupBox_depthFromScan, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->groupBox_depthFromScan_fillHoles, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->radioButton_depthFromScan_vertical, SIGNAL(toggled(bool)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
@@ -674,6 +682,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->general_checkBox_createIntermediateNodes->setObjectName(Parameters::kRtabmapCreateIntermediateNodes().c_str());
|
||||
_ui->general_spinBox_maxRetrieved->setObjectName(Parameters::kRtabmapMaxRetrieved().c_str());
|
||||
_ui->general_checkBox_startNewMapOnLoopClosure->setObjectName(Parameters::kRtabmapStartNewMapOnLoopClosure().c_str());
|
||||
_ui->general_checkBox_imagesAlreadyRectified->setObjectName(Parameters::kRtabmapImagesAlreadyRectified().c_str());
|
||||
_ui->lineEdit_workingDirectory->setObjectName(Parameters::kRtabmapWorkingDirectory().c_str());
|
||||
connect(_ui->toolButton_workingDirectory, SIGNAL(clicked()), this, SLOT(changeWorkingDirectory()));
|
||||
|
||||
@@ -1072,6 +1081,11 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
_ui->spinBox_OdomORBSLAM2MaxFeatures->setObjectName(Parameters::kOdomORBSLAM2MaxFeatures().c_str());
|
||||
_ui->spinBox_OdomORBSLAM2MapSize->setObjectName(Parameters::kOdomORBSLAM2MapSize().c_str());
|
||||
|
||||
// Odometry Okvis
|
||||
_ui->lineEdit_OdomOkvisPath->setObjectName(Parameters::kOdomOKVISConfigPath().c_str());
|
||||
connect(_ui->toolButton_OdomOkvisPath, SIGNAL(clicked()), this, SLOT(changeOdometryOKVISConfigPath()));
|
||||
|
||||
|
||||
//Stereo
|
||||
_ui->stereo_winWidth->setObjectName(Parameters::kStereoWinWidth().c_str());
|
||||
_ui->stereo_winHeight->setObjectName(Parameters::kStereoWinHeight().c_str());
|
||||
@@ -1621,6 +1635,9 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
||||
_ui->lineEdit_cameraImages_gt->setText("");
|
||||
_ui->comboBox_cameraImages_gtFormat->setCurrentIndex(0);
|
||||
_ui->doubleSpinBox_maxPoseTimeDiff->setValue(0.02);
|
||||
_ui->lineEdit_cameraImages_path_imu->setText("");
|
||||
_ui->lineEdit_cameraImages_imu_transform->setText("0 0 1 0 -1 0 1 0 0");
|
||||
_ui->spinBox_cameraImages_max_imu_rate->setValue(0);
|
||||
|
||||
_ui->groupBox_scanFromDepth->setChecked(false);
|
||||
_ui->spinBox_cameraScanFromDepth_decimation->setValue(8);
|
||||
@@ -2021,6 +2038,10 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
|
||||
_ui->lineEdit_cameraImages_gt->setText(settings.value("gt_path", _ui->lineEdit_cameraImages_gt->text()).toString());
|
||||
_ui->comboBox_cameraImages_gtFormat->setCurrentIndex(settings.value("gt_format", _ui->comboBox_cameraImages_gtFormat->currentIndex()).toInt());
|
||||
_ui->doubleSpinBox_maxPoseTimeDiff->setValue(settings.value("max_pose_time_diff", _ui->doubleSpinBox_maxPoseTimeDiff->value()).toDouble());
|
||||
|
||||
_ui->lineEdit_cameraImages_path_imu->setText(settings.value("imu_path", _ui->lineEdit_cameraImages_path_imu->text()).toString());
|
||||
_ui->lineEdit_cameraImages_imu_transform->setText(settings.value("imu_local_transform", _ui->lineEdit_cameraImages_imu_transform->text()).toString());
|
||||
_ui->spinBox_cameraImages_max_imu_rate->setValue(settings.value("imu_rate", _ui->spinBox_cameraImages_max_imu_rate->value()).toInt());
|
||||
settings.endGroup(); // images
|
||||
|
||||
settings.beginGroup("Video");
|
||||
@@ -2430,6 +2451,9 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath) const
|
||||
settings.setValue("gt_path", _ui->lineEdit_cameraImages_gt->text());
|
||||
settings.setValue("gt_format", _ui->comboBox_cameraImages_gtFormat->currentIndex());
|
||||
settings.setValue("max_pose_time_diff", _ui->doubleSpinBox_maxPoseTimeDiff->value());
|
||||
settings.setValue("imu_path", _ui->lineEdit_cameraImages_path_imu->text());
|
||||
settings.setValue("imu_local_transform", _ui->lineEdit_cameraImages_imu_transform->text());
|
||||
settings.setValue("imu_rate", _ui->spinBox_cameraImages_max_imu_rate->value());
|
||||
settings.endGroup(); // images
|
||||
|
||||
settings.beginGroup("Video");
|
||||
@@ -3344,6 +3368,21 @@ void PreferencesDialog::selectSourceImagesPathScans()
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesDialog::selectSourceImagesPathIMU()
|
||||
{
|
||||
QString dir = _ui->lineEdit_cameraImages_path_imu->text();
|
||||
if(dir.isEmpty())
|
||||
{
|
||||
dir = getWorkingDirectory();
|
||||
}
|
||||
QString path = QFileDialog::getOpenFileName(this, tr("Select file "), dir, tr("EuRoC IMU file (*.csv)"));
|
||||
if(path.size())
|
||||
{
|
||||
_ui->lineEdit_cameraImages_path_imu->setText(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PreferencesDialog::selectSourceRGBDImagesPathDepth()
|
||||
{
|
||||
QString dir = _ui->lineEdit_cameraRGBDImages_path_depth->text();
|
||||
@@ -4161,6 +4200,23 @@ void PreferencesDialog::changeOdometryORBSLAM2Vocabulary()
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesDialog::changeOdometryOKVISConfigPath()
|
||||
{
|
||||
QString path;
|
||||
if(_ui->lineEdit_OdomOkvisPath->text().isEmpty())
|
||||
{
|
||||
path = QFileDialog::getOpenFileName(this, tr("OKVIS Config"), this->getWorkingDirectory(), tr("OKVIS config (*.yaml)"));
|
||||
}
|
||||
else
|
||||
{
|
||||
path = QFileDialog::getOpenFileName(this, tr("OKVIS Config"), _ui->lineEdit_OdomOkvisPath->text(), tr("OKVIS config (*.yaml)"));
|
||||
}
|
||||
if(!path.isEmpty())
|
||||
{
|
||||
_ui->lineEdit_OdomOkvisPath->setText(path);
|
||||
}
|
||||
}
|
||||
|
||||
void PreferencesDialog::changeIcpPMConfigPath()
|
||||
{
|
||||
QString path;
|
||||
@@ -4701,6 +4757,24 @@ Transform PreferencesDialog::getLaserLocalTransform() const
|
||||
return t;
|
||||
}
|
||||
|
||||
QString PreferencesDialog::getIMUPath() const
|
||||
{
|
||||
return _ui->lineEdit_cameraImages_path_imu->text();
|
||||
}
|
||||
Transform PreferencesDialog::getIMULocalTransform() const
|
||||
{
|
||||
Transform t = Transform::fromString(_ui->lineEdit_cameraImages_imu_transform->text().replace("PI_2", QString::number(3.141592/2.0)).toStdString());
|
||||
if(t.isNull())
|
||||
{
|
||||
return Transform::getIdentity();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
int PreferencesDialog::getIMURate() const
|
||||
{
|
||||
return _ui->spinBox_cameraImages_max_imu_rate->value();
|
||||
}
|
||||
|
||||
bool PreferencesDialog::isSourceDatabaseStampsUsed() const
|
||||
{
|
||||
return _ui->source_checkBox_useDbStamps->isChecked();
|
||||
@@ -4939,6 +5013,7 @@ Camera * PreferencesDialog::createCamera(bool useRawImages, bool useColor)
|
||||
_ui->checkBox_cameraImages_timestamps->isChecked(),
|
||||
_ui->lineEdit_cameraImages_timestamps->text().toStdString(),
|
||||
_ui->checkBox_cameraImages_syncTimeStamps->isChecked());
|
||||
|
||||
}
|
||||
else if (driver == kSrcStereoUsb)
|
||||
{
|
||||
@@ -5251,6 +5326,31 @@ void PreferencesDialog::testOdometry()
|
||||
return;
|
||||
}
|
||||
|
||||
IMUThread * imuThread = 0;
|
||||
if((this->getSourceDriver() == kSrcStereoImages ||
|
||||
this->getSourceDriver() == kSrcRGBDImages ||
|
||||
this->getSourceDriver() == kSrcImages) &&
|
||||
!_ui->lineEdit_cameraImages_path_imu->text().isEmpty())
|
||||
{
|
||||
if(this->getOdomStrategy() != Odometry::kTypeOkvis)
|
||||
{
|
||||
QMessageBox::warning(this, tr("Source IMU Path"),
|
||||
tr("IMU path is set but odometry chosen doesn't support IMU, ignoring IMU..."), QMessageBox::Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
imuThread = new IMUThread(_ui->spinBox_cameraImages_max_imu_rate->value(), this->getIMULocalTransform());
|
||||
if(!imuThread->init(_ui->lineEdit_cameraImages_path_imu->text().toStdString()))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Source IMU Path"),
|
||||
tr("Initialization of IMU data has failed! Path=%1.").arg(_ui->lineEdit_cameraImages_path_imu->text()), QMessageBox::Ok);
|
||||
delete camera;
|
||||
delete imuThread;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParametersMap parameters = this->getAllParameters();
|
||||
if(getOdomRegistrationApproach() < 3)
|
||||
{
|
||||
@@ -5309,16 +5409,31 @@ void PreferencesDialog::testOdometry()
|
||||
cameraThread.setDistortionModel(_ui->lineEdit_source_distortionModel->text().toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
UEventsManager::createPipe(&cameraThread, &odomThread, "CameraEvent");
|
||||
if(imuThread)
|
||||
{
|
||||
UEventsManager::createPipe(imuThread, &odomThread, "IMUEvent");
|
||||
}
|
||||
UEventsManager::createPipe(&odomThread, odomViewer, "OdometryEvent");
|
||||
UEventsManager::createPipe(odomViewer, &odomThread, "OdometryResetEvent");
|
||||
|
||||
odomThread.start();
|
||||
cameraThread.start();
|
||||
|
||||
if(imuThread)
|
||||
{
|
||||
imuThread->start();
|
||||
}
|
||||
|
||||
odomViewer->exec();
|
||||
delete odomViewer;
|
||||
|
||||
if(imuThread)
|
||||
{
|
||||
imuThread->join(true);
|
||||
delete imuThread;
|
||||
}
|
||||
cameraThread.join(true);
|
||||
odomThread.join(true);
|
||||
}
|
||||
|
||||
@@ -63,16 +63,25 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>673</width>
|
||||
<height>2834</height>
|
||||
<y>-499</y>
|
||||
<width>678</width>
|
||||
<height>2811</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<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>
|
||||
@@ -86,7 +95,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>7</number>
|
||||
<number>18</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||
@@ -2687,7 +2696,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<item row="3" column="0">
|
||||
<widget class="QLineEdit" name="lineEdit_sourceLocalTransform">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Format (3 values): x y z<br/>Format (6 values): x y z roll pitch yaw<br/>Format (7 values): x y z qx qy qz qw<br/>Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>KITTI: /base_link to /gray_camera = 0 0 1 -1 0 0 0 -1 0<br/>KITTI: /base_link to /color_camera = 0 0 1 0 -1 0 0 -0.06 0 -1 0 0<br/>KITTI: /base_footprint to /gray_camera = 0 0 1 0 -1 0 0 0 0 -1 0 1.67<br/>KITTI: /base_footprint to /gray_camera = 0 0 1 0 -1 0 0 -0.06 0 -1 0 1.67</p><p>EuRoC MAV: /base_link to /cam0 = [0 0 1 0; 0 -1 0 0; 1 0 0 0; 0 0 0 1]*T_BS</p></body></html></string>
|
||||
<string><html><head/><body><p>Format (3 values): x y z<br/>Format (6 values): x y z roll pitch yaw<br/>Format (7 values): x y z qx qy qz qw<br/>Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>KITTI: /base_link to /gray_camera = 0 0 1 -1 0 0 0 -1 0<br/>KITTI: /base_link to /color_camera = 0 0 1 0 -1 0 0 -0.06 0 -1 0 0<br/>KITTI: /base_footprint to /gray_camera = 0 0 1 0 -1 0 0 0 0 -1 0 1.67<br/>KITTI: /base_footprint to /gray_camera = 0 0 1 0 -1 0 0 -0.06 0 -1 0 1.67</p><p>EuRoC MAV: /base_link to /cam0 = T_BS*T_SC0 = -0.0257742 0.00375623 0.999661 0.00981073 -0.999557 -0.0149672 -0.0257155 0.064677 0.0148655 -0.999881 0.00414038 -0.0216401</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0 0 1 -1 0 0 0 -1 0</string>
|
||||
@@ -4817,11 +4826,27 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<string>Directory of images (optional settings)</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_93">
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<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>
|
||||
<layout class="QGridLayout" name="gridLayout_68" columnstretch="0,0,1">
|
||||
<item row="6" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_gt">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_odom">
|
||||
<property name="text">
|
||||
@@ -4889,6 +4914,13 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_syncTimeStamps">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLabel" name="label_288">
|
||||
<property name="text">
|
||||
@@ -4915,8 +4947,8 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_syncTimeStamps">
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_timestamps">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
@@ -4948,13 +4980,6 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_timestamps">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_path_scans">
|
||||
<property name="text">
|
||||
@@ -4975,10 +5000,13 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_gt">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
<item row="11" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_cameraImages_max_scan_pts">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>KITTI: 130 000 points</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -5049,16 +5077,6 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_cameraImages_max_scan_pts">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>KITTI: 130 000 points</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_laser_transform">
|
||||
<property name="toolTip">
|
||||
@@ -5239,6 +5257,79 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="2">
|
||||
<widget class="QLabel" name="label_464">
|
||||
<property name="text">
|
||||
<string>Local transform from /base_link to /imu_link. Mouse over the box to show formats.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="2">
|
||||
<widget class="QLabel" name="label_463">
|
||||
<property name="text">
|
||||
<string>Path to file containing optional IMU data (*.csv [EuRoC format]).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_path_imu">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_path_imu">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_imu_transform">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Format (3 values): x y z<br/>Format (6 values): x y z roll pitch yaw<br/>Format (7 values): x y z qx qy qz qw<br/>Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>EuRoC: /base_link to /imu = 0 0 1 0 -1 0 1 0 0</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0 0 0 0 0 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="2">
|
||||
<widget class="QLabel" name="label_465">
|
||||
<property name="text">
|
||||
<string>IMU Rate. To synchronize capture rate with IMU timestamps, set to 0. This can be set a little over the actual IMU rate to keep up with camera capture rate if images are dropped by odometry.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_cameraImages_max_imu_rate">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>KITTI: 130 000 points</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
@@ -6015,6 +6106,16 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="general_checkBox_createIntermediateNodes">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDoubleSpinBox" name="general_doubleSpinBox_detectionRate">
|
||||
<property name="suffix">
|
||||
@@ -6041,13 +6142,26 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="general_checkBox_createIntermediateNodes">
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_467">
|
||||
<property name="text">
|
||||
<string>Images are already rectified. By default RTAB-Map assumes that received images are rectified. If they are not, they can be rectified by RTAB-Map if this parameter is false.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="general_checkBox_imagesAlreadyRectified">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -10476,6 +10590,11 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<string>ORB SLAM 2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>OKVIS</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
@@ -10747,7 +10866,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget_odometryType">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>6</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_52">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_77">
|
||||
@@ -12746,6 +12865,75 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_54">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_85" stretch="0,1">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_odomORBSLAM2_2">
|
||||
<property name="title">
|
||||
<string>OKVIS</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_128" stretch="0,1">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_466">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>OKVIS: <a href="https://github.com/ethz-asl/okvis"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/ethz-asl/okvis</span></a></p><p>IMU input required. Currently tested only with EuRoC data set.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_98" columnstretch="0,0,1">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_OdomOkvisPath"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_469">
|
||||
<property name="text">
|
||||
<string>Path to OKVIS config file (*.yaml). While OKVIS requires calibrations in the config file, they are ignored as those from received images are used instead.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QToolButton" name="toolButton_OdomOkvisPath">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_69">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_26">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_88">
|
||||
<item>
|
||||
@@ -13685,7 +13873,16 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<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>
|
||||
@@ -13765,7 +13962,16 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<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>
|
||||
@@ -13877,7 +14083,16 @@ Lower the ratio -> higher the precision. 0 means disabled, matching the neare
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="leftMargin">
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user