From f6e21bd6c84b13ba8065ae1d87117d7b12df3d66 Mon Sep 17 00:00:00 2001 From: matlabbe Date: Tue, 30 May 2017 14:03:46 -0400 Subject: [PATCH] Integration of viso2 odometry approach. --- CMakeLists.txt | 22 ++ Version.h.in | 1 + corelib/include/rtabmap/core/Odometry.h | 3 +- corelib/include/rtabmap/core/OdometryFovis.h | 2 - corelib/include/rtabmap/core/OdometryViso2.h | 61 ++++ corelib/include/rtabmap/core/Parameters.h | 2 +- corelib/src/CMakeLists.txt | 12 + corelib/src/Odometry.cpp | 4 + corelib/src/OdometryViso2.cpp | 270 ++++++++++++++++++ .../include/rtabmap/gui/PreferencesDialog.h | 1 + guilib/src/MainWindow.cpp | 18 +- guilib/src/PreferencesDialog.cpp | 15 + guilib/src/ui/preferencesDialog.ui | 9 +- 13 files changed, 406 insertions(+), 14 deletions(-) create mode 100644 corelib/include/rtabmap/core/OdometryViso2.h create mode 100644 corelib/src/OdometryViso2.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c898db27..69aa8ce3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,6 +153,7 @@ option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON) option(WITH_OCTOMAP "Include Octomap support" ON) option(WITH_CPUTSDF "Include CPUTSDF support" ON) option(WITH_FOVIS "Include FOVIS support" ON) +option(WITH_VISO2 "Include VISO2 support" ON) option(PCL_OMP "With PCL OMP implementations" ON) FIND_PACKAGE(OpenCV REQUIRED QUIET) @@ -352,6 +353,14 @@ IF(WITH_FOVIS) ENDIF(libfovis_FOUND) ENDIF(WITH_FOVIS) +IF(WITH_VISO2) + FIND_PACKAGE(libviso2 QUIET) + IF(libviso2_FOUND) + MESSAGE(STATUS "Found libviso2: ${libviso2_INCLUDE_DIRS}") + ENDIF(libviso2_FOUND) +ENDIF(WITH_VISO2) + + IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND OR ANDROID OR RealSense_FOUND) #Newest versions require std11 IF(NOT MSVC) @@ -479,6 +488,11 @@ IF(NOT libfovis_FOUND) ELSE() SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${libfovis_LIBRARIES}) ENDIF() +IF(NOT libviso2_FOUND) + SET(VISO2 "//") +ELSE() + SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${libviso2_LIBRARIES}) +ENDIF() IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF) SET(CONF_VTK_QT true) SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} vtkGUISupportQt) @@ -810,6 +824,14 @@ ELSE() MESSAGE(STATUS " With libfovis = NO (libfovis not found)") ENDIF() +IF(libviso2_FOUND) +MESSAGE(STATUS " With libviso2 = YES (License: GPLv3)") +ELSEIF(NOT WITH_VISO2) +MESSAGE(STATUS " With libviso2 = NO (WITH_VISO2=OFF)") +ELSE() +MESSAGE(STATUS " With libviso2 = NO (libviso2 not found)") +ENDIF() + IF(QT4_FOUND) MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)") ELSEIF(Qt5_FOUND) diff --git a/Version.h.in b/Version.h.in index 61b6e313..5f751503 100644 --- a/Version.h.in +++ b/Version.h.in @@ -55,6 +55,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @OCTOMAP@#define RTABMAP_OCTOMAP @CPUTSDF@#define RTABMAP_CPUTSDF @FOVIS@#define RTABMAP_FOVIS +@VISO2@#define RTABMAP_VISO2 #endif /* VERSION_H_ */ diff --git a/corelib/include/rtabmap/core/Odometry.h b/corelib/include/rtabmap/core/Odometry.h index 04be4588..d4d06675 100644 --- a/corelib/include/rtabmap/core/Odometry.h +++ b/corelib/include/rtabmap/core/Odometry.h @@ -46,7 +46,8 @@ public: kTypeUndef = -1, kTypeF2M = 0, kTypeF2F = 1, - kTypeFovis = 2 + kTypeFovis = 2, + kTypeViso2 = 3 }; public: diff --git a/corelib/include/rtabmap/core/OdometryFovis.h b/corelib/include/rtabmap/core/OdometryFovis.h index 7acff1db..cbd93148 100644 --- a/corelib/include/rtabmap/core/OdometryFovis.h +++ b/corelib/include/rtabmap/core/OdometryFovis.h @@ -40,8 +40,6 @@ class StereoDepth; namespace rtabmap { -class Registration; - class RTABMAP_EXP OdometryFovis : public Odometry { public: diff --git a/corelib/include/rtabmap/core/OdometryViso2.h b/corelib/include/rtabmap/core/OdometryViso2.h new file mode 100644 index 00000000..f5768070 --- /dev/null +++ b/corelib/include/rtabmap/core/OdometryViso2.h @@ -0,0 +1,61 @@ +/* +Copyright (c) 2010-2016, 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 ODOMETRYVISO2_H_ +#define ODOMETRYVISO2_H_ + +#include + +class VisualOdometryStereo; + +namespace rtabmap { + +class RTABMAP_EXP OdometryViso2 : public Odometry +{ +public: + OdometryViso2(const rtabmap::ParametersMap & parameters = rtabmap::ParametersMap()); + virtual ~OdometryViso2(); + + virtual void reset(const Transform & initialPose = Transform::getIdentity()); + virtual Odometry::Type getType() {return Odometry::kTypeViso2;} + +private: + virtual Transform computeTransform(SensorData & image, const Transform & guess = Transform(), OdometryInfo * info = 0); + +private: + VisualOdometryStereo * viso2_; + int ref_frame_change_method_; // Reference frame method (defautl 0): 0=under inliers threshold, 1=min pixel motion, + int ref_frame_inlier_threshold_; // method 0. Change the reference frame if the number of inliers is low + double ref_frame_motion_threshold_; // method 1. Change the reference frame if last motion is small + bool lost_; + bool keep_reference_frame_; + Transform reference_motion_; +}; + +} + +#endif /* ODOMETRYVISO2_H_ */ diff --git a/corelib/include/rtabmap/core/Parameters.h b/corelib/include/rtabmap/core/Parameters.h index 4aee9c9e..f1508e22 100644 --- a/corelib/include/rtabmap/core/Parameters.h +++ b/corelib/include/rtabmap/core/Parameters.h @@ -363,7 +363,7 @@ class RTABMAP_EXP Parameters RTABMAP_PARAM(GTSAM, Optimizer, int, 1, "0=Levenberg 1=GaussNewton 2=Dogleg"); // Odometry - RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F) 2=Fovis"); + RTABMAP_PARAM(Odom, Strategy, int, 0, "0=Frame-to-Map (F2M) 1=Frame-to-Frame (F2F) 2=Fovis 3=viso2"); RTABMAP_PARAM(Odom, ResetCountdown, int, 0, "Automatically reset odometry after X consecutive images on which odometry cannot be computed (value=0 disables auto-reset)."); RTABMAP_PARAM(Odom, Holonomic, bool, true, "If the robot is holonomic (strafing commands can be issued). If not, y value will be estimated from x and yaw values (y=x*tan(yaw))."); RTABMAP_PARAM(Odom, FillInfoData, bool, true, "Fill info with data (inliers/outliers features)."); diff --git a/corelib/src/CMakeLists.txt b/corelib/src/CMakeLists.txt index 3b0f126b..d7bff1bf 100644 --- a/corelib/src/CMakeLists.txt +++ b/corelib/src/CMakeLists.txt @@ -61,6 +61,7 @@ SET(SRC_FILES OdometryMono.cpp OdometryF2F.cpp OdometryFovis.cpp + OdometryViso2.cpp Stereo.cpp StereoDense.cpp @@ -287,6 +288,17 @@ IF(libfovis_FOUND) ) ENDIF(libfovis_FOUND) +IF(libviso2_FOUND) + SET(INCLUDE_DIRS + ${INCLUDE_DIRS} + ${libviso2_INCLUDE_DIRS} + ) + SET(LIBRARIES + ${LIBRARIES} + ${libviso2_LIBRARIES} + ) +ENDIF(libviso2_FOUND) + #################################### # Generate resources files #################################### diff --git a/corelib/src/Odometry.cpp b/corelib/src/Odometry.cpp index 625ddebc..7426b084 100644 --- a/corelib/src/Odometry.cpp +++ b/corelib/src/Odometry.cpp @@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "rtabmap/core/Odometry.h" #include "rtabmap/core/OdometryF2F.h" #include "rtabmap/core/OdometryFovis.h" +#include "rtabmap/core/OdometryViso2.h" #include "rtabmap/core/OdometryInfo.h" #include "rtabmap/core/util3d.h" #include "rtabmap/core/util3d_mapping.h" @@ -57,6 +58,9 @@ Odometry * Odometry::create(Odometry::Type & type, const ParametersMap & paramet Odometry * odometry = 0; switch(type) { + case Odometry::kTypeViso2: + odometry = new OdometryViso2(parameters); + break; case Odometry::kTypeFovis: odometry = new OdometryFovis(parameters); break; diff --git a/corelib/src/OdometryViso2.cpp b/corelib/src/OdometryViso2.cpp new file mode 100644 index 00000000..9dc639fe --- /dev/null +++ b/corelib/src/OdometryViso2.cpp @@ -0,0 +1,270 @@ +/* +Copyright (c) 2010-2016, 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 "rtabmap/core/OdometryViso2.h" +#include "rtabmap/core/OdometryInfo.h" +#include "rtabmap/core/util2d.h" +#include "rtabmap/core/Version.h" +#include "rtabmap/utilite/ULogger.h" +#include "rtabmap/utilite/UTimer.h" +#include "rtabmap/utilite/UStl.h" + +#ifdef RTABMAP_VISO2 +#include + +double computeFeatureFlow(const std::vector& matches) + { + double total_flow = 0.0; + for (size_t i = 0; i < matches.size(); ++i) + { + double x_diff = matches[i].u1c - matches[i].u1p; + double y_diff = matches[i].v1c - matches[i].v1p; + total_flow += sqrt(x_diff * x_diff + y_diff * y_diff); + } + return total_flow / matches.size(); +} +#endif + +namespace rtabmap { + +OdometryViso2::OdometryViso2(const ParametersMap & parameters) : + Odometry(parameters), + viso2_(0), + ref_frame_change_method_(0), + ref_frame_inlier_threshold_(Parameters::defaultOdomVisKeyFrameThr()), + ref_frame_motion_threshold_(5.0), + lost_(false), + keep_reference_frame_(false), + reference_motion_(Transform::getIdentity()) +{ + Parameters::parse(parameters, Parameters::kOdomVisKeyFrameThr(), ref_frame_inlier_threshold_); +} + +OdometryViso2::~OdometryViso2() +{ +#ifdef RTABMAP_VISO2 + if(viso2_) + { + delete viso2_; + } +#endif +} + +void OdometryViso2::reset(const Transform & initialPose) +{ + Odometry::reset(initialPose); +#ifdef RTABMAP_VISO2 + if(viso2_) + { + delete viso2_; + viso2_ = 0; + } + lost_ = false; + reference_motion_.setIdentity(); +#endif +} + +// return not null transform if odometry is correctly computed +Transform OdometryViso2::computeTransform( + SensorData & data, + const Transform & guess, + OdometryInfo * info) +{ + Transform t; +#ifdef RTABMAP_VISO2 + //based on https://github.com/srv/viso2/blob/indigo/viso2_ros/src/stereo_odometer.cpp + + UTimer timer; + + if(!data.depthRaw().empty()) + { + UERROR("viso2 odometry doesn't support RGB-D data, only stereo. Aborting odometry update..."); + return t; + } + + if(data.imageRaw().empty() || + data.imageRaw().rows != data.rightRaw().rows || + data.imageRaw().cols != data.rightRaw().cols) + { + UERROR("Not compatible left (%dx%d) or right (%dx%d) image.", + data.imageRaw().rows, + data.imageRaw().cols, + data.rightRaw().rows, + data.rightRaw().cols); + return t; + } + + if(!(data.stereoCameraModel().isValidForProjection() && + data.stereoCameraModel().left().isValidForReprojection() && + data.stereoCameraModel().right().isValidForReprojection())) + { + UERROR("Invalid stereo camera model!"); + return t; + } + + cv::Mat leftGray; + if(data.imageRaw().type() == CV_8UC3) + { + cv::cvtColor(data.imageRaw(), leftGray, CV_BGR2GRAY); + } + else if(data.imageRaw().type() == CV_8UC1) + { + leftGray = data.imageRaw(); + } + else + { + UFATAL("Not supported color type!"); + } + cv::Mat rightGray; + if(data.rightRaw().type() == CV_8UC3) + { + cv::cvtColor(data.rightRaw(), rightGray, CV_BGR2GRAY); + } + else if(data.rightRaw().type() == CV_8UC1) + { + rightGray = data.rightRaw(); + } + else + { + UFATAL("Not supported color type!"); + } + + int32_t dims[] = {leftGray.cols, leftGray.rows, leftGray.cols}; + cv::Mat covariance; + if(viso2_ == 0) + { + VisualOdometryStereo::parameters params; + params.base = data.stereoCameraModel().baseline(); + params.calib.cu = data.stereoCameraModel().left().cx(); + params.calib.cv = data.stereoCameraModel().left().cy(); + params.calib.f = data.stereoCameraModel().left().fx(); + viso2_ = new VisualOdometryStereo(params); + + viso2_->process(leftGray.data, rightGray.data, dims); + t.setIdentity(); + covariance = cv::Mat::eye(6,6, CV_64FC1)*9999.0; + } + else + { + bool success = viso2_->process(leftGray.data, rightGray.data, dims, lost_ || keep_reference_frame_); + if (success) + { + Matrix motionViso = Matrix::inv(viso2_->getMotion()); + Transform motion(motionViso.val[0][0], motionViso.val[0][1], motionViso.val[0][2],motionViso.val[0][3], + motionViso.val[1][0], motionViso.val[1][1], motionViso.val[1][2],motionViso.val[1][3], + motionViso.val[2][0], motionViso.val[2][1], motionViso.val[2][2], motionViso.val[2][3]); + Transform camera_motion; + + if(lost_ || keep_reference_frame_) + { + camera_motion = reference_motion_.inverse() * motion; + } + else + { + camera_motion = motion; + } + reference_motion_ = motion; // store last motion as reference + + t=camera_motion; + + //based on values set in viso2_ros + covariance = cv::Mat::eye(6,6, CV_64FC1); + covariance.at(0,0) = 0.002; + covariance.at(1,1) = 0.002; + covariance.at(2,2) = 0.05; + covariance.at(3,3) = 0.09; + covariance.at(4,4) = 0.09; + covariance.at(5,5) = 0.09; + + lost_=false; + } + else + { + covariance = cv::Mat::eye(6,6, CV_64FC1)*9999.0; + lost_ = true; + } + + if(success) + { + // Proceed depending on the reference frame change method + if(ref_frame_change_method_==1) + { + // calculate current feature flow + double feature_flow = computeFeatureFlow(viso2_->getMatches()); + keep_reference_frame_ = (feature_flow < ref_frame_motion_threshold_); + } + else + { + keep_reference_frame_ = ref_frame_inlier_threshold_==0 || viso2_->getNumberOfInliers() > ref_frame_inlier_threshold_; + } + } + else + { + keep_reference_frame_ = false; + } + } + + if(!t.isNull() && !t.isIdentity() && !data.stereoCameraModel().localTransform().isIdentity() && !data.stereoCameraModel().localTransform().isNull()) + { + // from camera frame to base frame + t = data.stereoCameraModel().localTransform() * t * data.stereoCameraModel().localTransform().inverse(); + } + + if(info) + { + info->type = (int)kTypeViso2; + info->keyFrameAdded = !keep_reference_frame_; + info->matches = viso2_->getNumberOfMatches(); + info->inliers = viso2_->getNumberOfInliers(); + if(covariance.cols == 6 && covariance.rows == 6 && covariance.type() == CV_64FC1) + { + info->covariance = covariance; + } + + std::vector matches = viso2_->getMatches(); + info->refCorners.resize(matches.size()); + info->newCorners.resize(matches.size()); + info->cornerInliers.resize(matches.size()); + for (size_t i = 0; i < matches.size(); ++i) + { + info->refCorners[i].x = matches[i].u1c; + info->refCorners[i].y = matches[i].v1c; + info->newCorners[i].x = matches[i].u1p; + info->newCorners[i].y = matches[i].v1p; + info->cornerInliers[i] = i; + } + } + + UINFO("Odom update time = %fs lost=%s", timer.elapsed(), lost_?"true":"false"); + +#else + UERROR("RTAB-Map is not built with VISO2 support! Select another visual odometry approach."); +#endif + return t; +} + +} // namespace rtabmap diff --git a/guilib/include/rtabmap/gui/PreferencesDialog.h b/guilib/include/rtabmap/gui/PreferencesDialog.h index 5b4f777f..64128275 100644 --- a/guilib/include/rtabmap/gui/PreferencesDialog.h +++ b/guilib/include/rtabmap/gui/PreferencesDialog.h @@ -299,6 +299,7 @@ private slots: void addParameter(const QString & value); void updatePredictionPlot(); void updateKpROI(); + void updateOdometryVisibility(); void updateStereoDisparityVisibility(); void useOdomFeatures(); void useGridProjRayTracing(); diff --git a/guilib/src/MainWindow.cpp b/guilib/src/MainWindow.cpp index 55ab243d..535a3448 100644 --- a/guilib/src/MainWindow.cpp +++ b/guilib/src/MainWindow.cpp @@ -1188,7 +1188,7 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI { if(_ui->imageView_odometry->isFeaturesShown()) { - if(odom.info().type == 0) + if(odom.info().type == (int)Odometry::kTypeF2M) { if(_preferencesDialog->isOdomOnlyInliersShown()) { @@ -1210,10 +1210,10 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI Qt::yellow); } } - else if(odom.info().type == 1) + else if(odom.info().type == (int)Odometry::kTypeF2F || odom.info().type == (int)Odometry::kTypeViso2) { std::vector kpts; - cv::KeyPoint::convert(odom.info().refCorners, kpts); + cv::KeyPoint::convert(odom.info().refCorners, kpts, 7); _ui->imageView_odometry->setFeatures( kpts, odom.data().depthRaw(), @@ -1223,10 +1223,10 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI //detect if it is OdometryMono intitialization bool monoInitialization = false; - if(_preferencesDialog->getOdomStrategy() == 2 && odom.info().type == 1) - { - monoInitialization = true; - } + //if(_preferencesDialog->getOdomStrategy() == ?? && odom.info().type == (int)Odometry::kTypeF2F) + //{ + // monoInitialization = true; + //} _ui->imageView_odometry->clearLines(); if(lost && !monoInitialization) @@ -1256,7 +1256,7 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI _ui->imageView_odometry->setImageDepth(uCvMat2QImage(odom.data().depthOrRightRaw())); } - if(odom.info().type == 0) + if(odom.info().type == (int)Odometry::kTypeF2M) { if(_ui->imageView_odometry->isFeaturesShown() && !_preferencesDialog->isOdomOnlyInliersShown()) { @@ -1270,7 +1270,7 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI } } } - if(odom.info().type == 1 && odom.info().refCorners.size()) + if((odom.info().type == (int)Odometry::kTypeF2F || odom.info().type == (int)Odometry::kTypeViso2) && odom.info().refCorners.size()) { if(_ui->imageView_odometry->isFeaturesShown() || _ui->imageView_odometry->isLinesShown()) { diff --git a/guilib/src/PreferencesDialog.cpp b/guilib/src/PreferencesDialog.cpp index 0c8b03df..da3bd530 100644 --- a/guilib/src/PreferencesDialog.cpp +++ b/guilib/src/PreferencesDialog.cpp @@ -159,6 +159,13 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) : _ui->label_realsenseOdom->setEnabled(false); #endif +#ifndef RTABMAP_FOVIS + _ui->odom_strategy->setItemData(2, 0, Qt::UserRole - 1); +#endif +#ifndef RTABMAP_VISO2 + _ui->odom_strategy->setItemData(3, 0, Qt::UserRole - 1); +#endif + #ifndef RTABMAP_NONFREE _ui->comboBox_detector_strategy->setItemData(0, 0, Qt::UserRole - 1); _ui->comboBox_detector_strategy->setItemData(1, 0, Qt::UserRole - 1); @@ -872,6 +879,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) : //Odometry _ui->odom_strategy->setObjectName(Parameters::kOdomStrategy().c_str()); connect(_ui->odom_strategy, SIGNAL(currentIndexChanged(int)), _ui->stackedWidget_odometryType, SLOT(setCurrentIndex(int))); + connect(_ui->odom_strategy, SIGNAL(currentIndexChanged(int)), this, SLOT(updateOdometryVisibility())); _ui->odom_strategy->setCurrentIndex(Parameters::defaultOdomStrategy()); _ui->odom_countdown->setObjectName(Parameters::kOdomResetCountdown().c_str()); _ui->odom_holonomic->setObjectName(Parameters::kOdomHolonomic().c_str()); @@ -3823,6 +3831,13 @@ void PreferencesDialog::setupKpRoiPanel() _ui->doubleSpinBox_kp_roi3->setValue(strings[3].toDouble()*100.0); } +void PreferencesDialog::updateOdometryVisibility() +{ + _ui->stackedWidget_odometryType->setVisible( + _ui->odom_strategy->currentIndex() == 2 || // fovis + _ui->odom_strategy->currentIndex() == 3); // viso2 +} + void PreferencesDialog::updateKpROI() { QStringList strings; diff --git a/guilib/src/ui/preferencesDialog.ui b/guilib/src/ui/preferencesDialog.ui index 1dd01628..8e67b607 100644 --- a/guilib/src/ui/preferencesDialog.ui +++ b/guilib/src/ui/preferencesDialog.ui @@ -63,7 +63,7 @@ 0 - 0 + -530 678 2739 @@ -9704,6 +9704,11 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag Fovis + + + Viso2 + + @@ -10218,6 +10223,8 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag + +