mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
Integration of viso2 odometry approach.
This commit is contained in:
@@ -153,6 +153,7 @@ option(WITH_REALSENSE_SLAM "Include RealSenseSlam support" ON)
|
|||||||
option(WITH_OCTOMAP "Include Octomap support" ON)
|
option(WITH_OCTOMAP "Include Octomap support" ON)
|
||||||
option(WITH_CPUTSDF "Include CPUTSDF support" ON)
|
option(WITH_CPUTSDF "Include CPUTSDF support" ON)
|
||||||
option(WITH_FOVIS "Include FOVIS support" ON)
|
option(WITH_FOVIS "Include FOVIS support" ON)
|
||||||
|
option(WITH_VISO2 "Include VISO2 support" ON)
|
||||||
option(PCL_OMP "With PCL OMP implementations" ON)
|
option(PCL_OMP "With PCL OMP implementations" ON)
|
||||||
|
|
||||||
FIND_PACKAGE(OpenCV REQUIRED QUIET)
|
FIND_PACKAGE(OpenCV REQUIRED QUIET)
|
||||||
@@ -352,6 +353,14 @@ IF(WITH_FOVIS)
|
|||||||
ENDIF(libfovis_FOUND)
|
ENDIF(libfovis_FOUND)
|
||||||
ENDIF(WITH_FOVIS)
|
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)
|
IF(G2O_FOUND OR GTSAM_FOUND OR ZED_FOUND OR ANDROID OR RealSense_FOUND)
|
||||||
#Newest versions require std11
|
#Newest versions require std11
|
||||||
IF(NOT MSVC)
|
IF(NOT MSVC)
|
||||||
@@ -479,6 +488,11 @@ IF(NOT libfovis_FOUND)
|
|||||||
ELSE()
|
ELSE()
|
||||||
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${libfovis_LIBRARIES})
|
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${libfovis_LIBRARIES})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
IF(NOT libviso2_FOUND)
|
||||||
|
SET(VISO2 "//")
|
||||||
|
ELSE()
|
||||||
|
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} ${libviso2_LIBRARIES})
|
||||||
|
ENDIF()
|
||||||
IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF)
|
IF(ADD_VTK_GUI_SUPPORT_QT_TO_CONF)
|
||||||
SET(CONF_VTK_QT true)
|
SET(CONF_VTK_QT true)
|
||||||
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} vtkGUISupportQt)
|
SET(CONF_DEPENDENCIES ${CONF_DEPENDENCIES} vtkGUISupportQt)
|
||||||
@@ -810,6 +824,14 @@ ELSE()
|
|||||||
MESSAGE(STATUS " With libfovis = NO (libfovis not found)")
|
MESSAGE(STATUS " With libfovis = NO (libfovis not found)")
|
||||||
ENDIF()
|
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)
|
IF(QT4_FOUND)
|
||||||
MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)")
|
MESSAGE(STATUS " With Qt4 = YES (License: Open Source or Commercial)")
|
||||||
ELSEIF(Qt5_FOUND)
|
ELSEIF(Qt5_FOUND)
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
@OCTOMAP@#define RTABMAP_OCTOMAP
|
@OCTOMAP@#define RTABMAP_OCTOMAP
|
||||||
@CPUTSDF@#define RTABMAP_CPUTSDF
|
@CPUTSDF@#define RTABMAP_CPUTSDF
|
||||||
@FOVIS@#define RTABMAP_FOVIS
|
@FOVIS@#define RTABMAP_FOVIS
|
||||||
|
@VISO2@#define RTABMAP_VISO2
|
||||||
|
|
||||||
#endif /* VERSION_H_ */
|
#endif /* VERSION_H_ */
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ public:
|
|||||||
kTypeUndef = -1,
|
kTypeUndef = -1,
|
||||||
kTypeF2M = 0,
|
kTypeF2M = 0,
|
||||||
kTypeF2F = 1,
|
kTypeF2F = 1,
|
||||||
kTypeFovis = 2
|
kTypeFovis = 2,
|
||||||
|
kTypeViso2 = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ class StereoDepth;
|
|||||||
|
|
||||||
namespace rtabmap {
|
namespace rtabmap {
|
||||||
|
|
||||||
class Registration;
|
|
||||||
|
|
||||||
class RTABMAP_EXP OdometryFovis : public Odometry
|
class RTABMAP_EXP OdometryFovis : public Odometry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
61
corelib/include/rtabmap/core/OdometryViso2.h
Normal file
61
corelib/include/rtabmap/core/OdometryViso2.h
Normal file
@@ -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 <rtabmap/core/Odometry.h>
|
||||||
|
|
||||||
|
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_ */
|
||||||
@@ -363,7 +363,7 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(GTSAM, Optimizer, int, 1, "0=Levenberg 1=GaussNewton 2=Dogleg");
|
RTABMAP_PARAM(GTSAM, Optimizer, int, 1, "0=Levenberg 1=GaussNewton 2=Dogleg");
|
||||||
|
|
||||||
// Odometry
|
// 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, 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, 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).");
|
RTABMAP_PARAM(Odom, FillInfoData, bool, true, "Fill info with data (inliers/outliers features).");
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ SET(SRC_FILES
|
|||||||
OdometryMono.cpp
|
OdometryMono.cpp
|
||||||
OdometryF2F.cpp
|
OdometryF2F.cpp
|
||||||
OdometryFovis.cpp
|
OdometryFovis.cpp
|
||||||
|
OdometryViso2.cpp
|
||||||
|
|
||||||
Stereo.cpp
|
Stereo.cpp
|
||||||
StereoDense.cpp
|
StereoDense.cpp
|
||||||
@@ -287,6 +288,17 @@ IF(libfovis_FOUND)
|
|||||||
)
|
)
|
||||||
ENDIF(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
|
# Generate resources files
|
||||||
####################################
|
####################################
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "rtabmap/core/Odometry.h"
|
#include "rtabmap/core/Odometry.h"
|
||||||
#include "rtabmap/core/OdometryF2F.h"
|
#include "rtabmap/core/OdometryF2F.h"
|
||||||
#include "rtabmap/core/OdometryFovis.h"
|
#include "rtabmap/core/OdometryFovis.h"
|
||||||
|
#include "rtabmap/core/OdometryViso2.h"
|
||||||
#include "rtabmap/core/OdometryInfo.h"
|
#include "rtabmap/core/OdometryInfo.h"
|
||||||
#include "rtabmap/core/util3d.h"
|
#include "rtabmap/core/util3d.h"
|
||||||
#include "rtabmap/core/util3d_mapping.h"
|
#include "rtabmap/core/util3d_mapping.h"
|
||||||
@@ -57,6 +58,9 @@ Odometry * Odometry::create(Odometry::Type & type, const ParametersMap & paramet
|
|||||||
Odometry * odometry = 0;
|
Odometry * odometry = 0;
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
|
case Odometry::kTypeViso2:
|
||||||
|
odometry = new OdometryViso2(parameters);
|
||||||
|
break;
|
||||||
case Odometry::kTypeFovis:
|
case Odometry::kTypeFovis:
|
||||||
odometry = new OdometryFovis(parameters);
|
odometry = new OdometryFovis(parameters);
|
||||||
break;
|
break;
|
||||||
|
|||||||
270
corelib/src/OdometryViso2.cpp
Normal file
270
corelib/src/OdometryViso2.cpp
Normal file
@@ -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 <viso_stereo.h>
|
||||||
|
|
||||||
|
double computeFeatureFlow(const std::vector<Matcher::p_match>& 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<double>(0,0) = 0.002;
|
||||||
|
covariance.at<double>(1,1) = 0.002;
|
||||||
|
covariance.at<double>(2,2) = 0.05;
|
||||||
|
covariance.at<double>(3,3) = 0.09;
|
||||||
|
covariance.at<double>(4,4) = 0.09;
|
||||||
|
covariance.at<double>(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<Matcher::p_match> 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
|
||||||
@@ -299,6 +299,7 @@ private slots:
|
|||||||
void addParameter(const QString & value);
|
void addParameter(const QString & value);
|
||||||
void updatePredictionPlot();
|
void updatePredictionPlot();
|
||||||
void updateKpROI();
|
void updateKpROI();
|
||||||
|
void updateOdometryVisibility();
|
||||||
void updateStereoDisparityVisibility();
|
void updateStereoDisparityVisibility();
|
||||||
void useOdomFeatures();
|
void useOdomFeatures();
|
||||||
void useGridProjRayTracing();
|
void useGridProjRayTracing();
|
||||||
|
|||||||
@@ -1188,7 +1188,7 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
|
|||||||
{
|
{
|
||||||
if(_ui->imageView_odometry->isFeaturesShown())
|
if(_ui->imageView_odometry->isFeaturesShown())
|
||||||
{
|
{
|
||||||
if(odom.info().type == 0)
|
if(odom.info().type == (int)Odometry::kTypeF2M)
|
||||||
{
|
{
|
||||||
if(_preferencesDialog->isOdomOnlyInliersShown())
|
if(_preferencesDialog->isOdomOnlyInliersShown())
|
||||||
{
|
{
|
||||||
@@ -1210,10 +1210,10 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
|
|||||||
Qt::yellow);
|
Qt::yellow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(odom.info().type == 1)
|
else if(odom.info().type == (int)Odometry::kTypeF2F || odom.info().type == (int)Odometry::kTypeViso2)
|
||||||
{
|
{
|
||||||
std::vector<cv::KeyPoint> kpts;
|
std::vector<cv::KeyPoint> kpts;
|
||||||
cv::KeyPoint::convert(odom.info().refCorners, kpts);
|
cv::KeyPoint::convert(odom.info().refCorners, kpts, 7);
|
||||||
_ui->imageView_odometry->setFeatures(
|
_ui->imageView_odometry->setFeatures(
|
||||||
kpts,
|
kpts,
|
||||||
odom.data().depthRaw(),
|
odom.data().depthRaw(),
|
||||||
@@ -1223,10 +1223,10 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
|
|||||||
|
|
||||||
//detect if it is OdometryMono intitialization
|
//detect if it is OdometryMono intitialization
|
||||||
bool monoInitialization = false;
|
bool monoInitialization = false;
|
||||||
if(_preferencesDialog->getOdomStrategy() == 2 && odom.info().type == 1)
|
//if(_preferencesDialog->getOdomStrategy() == ?? && odom.info().type == (int)Odometry::kTypeF2F)
|
||||||
{
|
//{
|
||||||
monoInitialization = true;
|
// monoInitialization = true;
|
||||||
}
|
//}
|
||||||
|
|
||||||
_ui->imageView_odometry->clearLines();
|
_ui->imageView_odometry->clearLines();
|
||||||
if(lost && !monoInitialization)
|
if(lost && !monoInitialization)
|
||||||
@@ -1256,7 +1256,7 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
|
|||||||
_ui->imageView_odometry->setImageDepth(uCvMat2QImage(odom.data().depthOrRightRaw()));
|
_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())
|
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())
|
if(_ui->imageView_odometry->isFeaturesShown() || _ui->imageView_odometry->isLinesShown())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -159,6 +159,13 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
_ui->label_realsenseOdom->setEnabled(false);
|
_ui->label_realsenseOdom->setEnabled(false);
|
||||||
#endif
|
#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
|
#ifndef RTABMAP_NONFREE
|
||||||
_ui->comboBox_detector_strategy->setItemData(0, 0, Qt::UserRole - 1);
|
_ui->comboBox_detector_strategy->setItemData(0, 0, Qt::UserRole - 1);
|
||||||
_ui->comboBox_detector_strategy->setItemData(1, 0, Qt::UserRole - 1);
|
_ui->comboBox_detector_strategy->setItemData(1, 0, Qt::UserRole - 1);
|
||||||
@@ -872,6 +879,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
|||||||
//Odometry
|
//Odometry
|
||||||
_ui->odom_strategy->setObjectName(Parameters::kOdomStrategy().c_str());
|
_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)), _ui->stackedWidget_odometryType, SLOT(setCurrentIndex(int)));
|
||||||
|
connect(_ui->odom_strategy, SIGNAL(currentIndexChanged(int)), this, SLOT(updateOdometryVisibility()));
|
||||||
_ui->odom_strategy->setCurrentIndex(Parameters::defaultOdomStrategy());
|
_ui->odom_strategy->setCurrentIndex(Parameters::defaultOdomStrategy());
|
||||||
_ui->odom_countdown->setObjectName(Parameters::kOdomResetCountdown().c_str());
|
_ui->odom_countdown->setObjectName(Parameters::kOdomResetCountdown().c_str());
|
||||||
_ui->odom_holonomic->setObjectName(Parameters::kOdomHolonomic().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);
|
_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()
|
void PreferencesDialog::updateKpROI()
|
||||||
{
|
{
|
||||||
QStringList strings;
|
QStringList strings;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>-530</y>
|
||||||
<width>678</width>
|
<width>678</width>
|
||||||
<height>2739</height>
|
<height>2739</height>
|
||||||
</rect>
|
</rect>
|
||||||
@@ -9704,6 +9704,11 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<string>Fovis</string>
|
<string>Fovis</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Viso2</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
@@ -10218,6 +10223,8 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_67"/>
|
||||||
|
<widget class="QWidget" name="page_68"/>
|
||||||
<widget class="QWidget" name="page_26">
|
<widget class="QWidget" name="page_26">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_88">
|
<layout class="QVBoxLayout" name="verticalLayout_88">
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
Reference in New Issue
Block a user