2020-12-01 11:58:17 +08:00
/**
2022-07-21 21:32:11 +08:00
* This file is part of ORB - SLAM3
*
* Copyright ( C ) 2017 - 2021 Carlos Campos , Richard Elvira , Juan J . G ó mez Rodr í guez , Jos é M . M . Montiel and Juan D . Tard ó s , University of Zaragoza .
* Copyright ( C ) 2014 - 2016 Ra ú l Mur - Artal , Jos é M . M . Montiel and Juan D . Tard ó s , University of Zaragoza .
*
* ORB - SLAM3 is free software : you can redistribute it and / or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* ORB - SLAM3 is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along with ORB - SLAM3 .
* If not , see < http : //www.gnu.org/licenses/>.
*/
2020-12-01 11:58:17 +08:00
# include "Optimizer.h"
# include <complex>
# include <Eigen/StdVector>
# include <Eigen/Dense>
# include <unsupported/Eigen/MatrixFunctions>
# include "Thirdparty/g2o/g2o/core/sparse_block_matrix.h"
# include "Thirdparty/g2o/g2o/core/block_solver.h"
# include "Thirdparty/g2o/g2o/core/optimization_algorithm_levenberg.h"
# include "Thirdparty/g2o/g2o/core/optimization_algorithm_gauss_newton.h"
# include "Thirdparty/g2o/g2o/solvers/linear_solver_eigen.h"
# include "Thirdparty/g2o/g2o/types/types_six_dof_expmap.h"
# include "Thirdparty/g2o/g2o/core/robust_kernel_impl.h"
# include "Thirdparty/g2o/g2o/solvers/linear_solver_dense.h"
# include "G2oTypes.h"
# include "Converter.h"
2022-07-21 21:32:11 +08:00
# include <mutex>
2020-12-01 11:58:17 +08:00
# include "OptimizableTypes.h"
namespace ORB_SLAM3
{
2022-07-21 21:32:11 +08:00
bool sortByVal ( const pair < MapPoint * , int > & a , const pair < MapPoint * , int > & b )
2020-12-01 11:58:17 +08:00
{
return ( a . second < b . second ) ;
}
2022-07-21 21:32:11 +08:00
/**************************************以下为单帧优化**************************************************************/
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
int Optimizer : : PoseOptimization ( Frame * pFrame )
2020-12-01 11:58:17 +08:00
{
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolver_6_3 : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
linearSolver = new g2o : : LinearSolverDense < g2o : : BlockSolver_6_3 : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolver_6_3 * solver_ptr = new g2o : : BlockSolver_6_3 ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
optimizer . setAlgorithm ( solver ) ;
2022-07-21 21:32:11 +08:00
int nInitialCorrespondences = 0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Frame vertex
g2o : : VertexSE3Expmap * vSE3 = new g2o : : VertexSE3Expmap ( ) ;
Sophus : : SE3 < float > Tcw = pFrame - > GetPose ( ) ;
vSE3 - > setEstimate ( g2o : : SE3Quat ( Tcw . unit_quaternion ( ) . cast < double > ( ) , Tcw . translation ( ) . cast < double > ( ) ) ) ;
vSE3 - > setId ( 0 ) ;
vSE3 - > setFixed ( false ) ;
optimizer . addVertex ( vSE3 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set MapPoint vertices
const int N = pFrame - > N ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPose * > vpEdgesMono ;
vector < ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPoseToBody * > vpEdgesMono_FHR ;
vector < size_t > vnIndexEdgeMono , vnIndexEdgeRight ;
vpEdgesMono . reserve ( N ) ;
vpEdgesMono_FHR . reserve ( N ) ;
vnIndexEdgeMono . reserve ( N ) ;
vnIndexEdgeRight . reserve ( N ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < g2o : : EdgeStereoSE3ProjectXYZOnlyPose * > vpEdgesStereo ;
vector < size_t > vnIndexEdgeStereo ;
vpEdgesStereo . reserve ( N ) ;
vnIndexEdgeStereo . reserve ( N ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float deltaMono = sqrt ( 5.991 ) ;
const float deltaStereo = sqrt ( 7.815 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
{
unique_lock < mutex > lock ( MapPoint : : mGlobalMutex ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( int i = 0 ; i < N ; i + + )
{
MapPoint * pMP = pFrame - > mvpMapPoints [ i ] ;
if ( pMP )
{
// Conventional SLAM
if ( ! pFrame - > mpCamera2 )
{
// Monocular observation
if ( pFrame - > mvuRight [ i ] < 0 )
{
nInitialCorrespondences + + ;
pFrame - > mvbOutlier [ i ] = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
const cv : : KeyPoint & kpUn = pFrame - > mvKeysUn [ i ] ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPose * e = new ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPose ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( 0 ) ) ) ;
e - > setMeasurement ( obs ) ;
const float invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( deltaMono ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > pCamera = pFrame - > mpCamera ;
e - > Xw = pMP - > GetWorldPos ( ) . cast < double > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpEdgesMono . push_back ( e ) ;
vnIndexEdgeMono . push_back ( i ) ;
}
else // Stereo observation
{
nInitialCorrespondences + + ;
pFrame - > mvbOutlier [ i ] = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 3 , 1 > obs ;
const cv : : KeyPoint & kpUn = pFrame - > mvKeysUn [ i ] ;
const float & kp_ur = pFrame - > mvuRight [ i ] ;
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : EdgeStereoSE3ProjectXYZOnlyPose * e = new g2o : : EdgeStereoSE3ProjectXYZOnlyPose ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( 0 ) ) ) ;
e - > setMeasurement ( obs ) ;
const float invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] ;
Eigen : : Matrix3d Info = Eigen : : Matrix3d : : Identity ( ) * invSigma2 ;
e - > setInformation ( Info ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( deltaStereo ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > fx = pFrame - > fx ;
e - > fy = pFrame - > fy ;
e - > cx = pFrame - > cx ;
e - > cy = pFrame - > cy ;
e - > bf = pFrame - > mbf ;
e - > Xw = pMP - > GetWorldPos ( ) . cast < double > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpEdgesStereo . push_back ( e ) ;
vnIndexEdgeStereo . push_back ( i ) ;
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// SLAM with respect a rigid body
else
{
nInitialCorrespondences + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
cv : : KeyPoint kpUn ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( i < pFrame - > Nleft )
{ // Left camera observation
kpUn = pFrame - > mvKeys [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ i ] = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPose * e = new ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPose ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( 0 ) ) ) ;
e - > setMeasurement ( obs ) ;
const float invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( deltaMono ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > pCamera = pFrame - > mpCamera ;
e - > Xw = pMP - > GetWorldPos ( ) . cast < double > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpEdgesMono . push_back ( e ) ;
vnIndexEdgeMono . push_back ( i ) ;
}
else
{
kpUn = pFrame - > mvKeysRight [ i - pFrame - > Nleft ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ i ] = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPoseToBody * e = new ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPoseToBody ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( 0 ) ) ) ;
e - > setMeasurement ( obs ) ;
const float invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( deltaMono ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > pCamera = pFrame - > mpCamera2 ;
e - > Xw = pMP - > GetWorldPos ( ) . cast < double > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > mTrl = g2o : : SE3Quat ( pFrame - > GetRelativePoseTrl ( ) . unit_quaternion ( ) . cast < double > ( ) , pFrame - > GetRelativePoseTrl ( ) . translation ( ) . cast < double > ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpEdgesMono_FHR . push_back ( e ) ;
vnIndexEdgeRight . push_back ( i ) ;
}
2020-12-01 11:58:17 +08:00
}
}
}
}
2022-07-21 21:32:11 +08:00
if ( nInitialCorrespondences < 3 )
return 0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// We perform 4 optimizations, after each optimization we classify observation as inlier/outlier
// At the next optimization, outliers are not included, but at the end they can be classified as inliers again.
const float chi2Mono [ 4 ] = { 5.991 , 5.991 , 5.991 , 5.991 } ;
const float chi2Stereo [ 4 ] = { 7.815 , 7.815 , 7.815 , 7.815 } ;
const int its [ 4 ] = { 10 , 10 , 10 , 10 } ;
int nBad = 0 ;
for ( size_t it = 0 ; it < 4 ; it + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
Tcw = pFrame - > GetPose ( ) ;
vSE3 - > setEstimate ( g2o : : SE3Quat ( Tcw . unit_quaternion ( ) . cast < double > ( ) , Tcw . translation ( ) . cast < double > ( ) ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . initializeOptimization ( 0 ) ;
optimizer . optimize ( its [ it ] ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
nBad = 0 ;
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
{
ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPose * e = vpEdgesMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const size_t idx = vnIndexEdgeMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pFrame - > mvbOutlier [ idx ] )
{
e - > computeError ( ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float chi2 = e - > chi2 ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( chi2 > chi2Mono [ it ] )
{
pFrame - > mvbOutlier [ idx ] = true ;
e - > setLevel ( 1 ) ;
nBad + + ;
}
else
{
pFrame - > mvbOutlier [ idx ] = false ;
e - > setLevel ( 0 ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( it = = 2 )
e - > setRobustKernel ( 0 ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesMono_FHR . size ( ) ; i < iend ; i + + )
{
ORB_SLAM3 : : EdgeSE3ProjectXYZOnlyPoseToBody * e = vpEdgesMono_FHR [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const size_t idx = vnIndexEdgeRight [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pFrame - > mvbOutlier [ idx ] )
{
e - > computeError ( ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float chi2 = e - > chi2 ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( chi2 > chi2Mono [ it ] )
{
pFrame - > mvbOutlier [ idx ] = true ;
e - > setLevel ( 1 ) ;
nBad + + ;
}
else
{
pFrame - > mvbOutlier [ idx ] = false ;
e - > setLevel ( 0 ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( it = = 2 )
e - > setRobustKernel ( 0 ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
{
g2o : : EdgeStereoSE3ProjectXYZOnlyPose * e = vpEdgesStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const size_t idx = vnIndexEdgeStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pFrame - > mvbOutlier [ idx ] )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
e - > computeError ( ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
const float chi2 = e - > chi2 ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( chi2 > chi2Stereo [ it ] )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ idx ] = true ;
e - > setLevel ( 1 ) ;
nBad + + ;
}
else
{
e - > setLevel ( 0 ) ;
pFrame - > mvbOutlier [ idx ] = false ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( it = = 2 )
e - > setRobustKernel ( 0 ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( optimizer . edges ( ) . size ( ) < 10 )
break ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Recover optimized pose and return number of inliers
g2o : : VertexSE3Expmap * vSE3_recov = static_cast < g2o : : VertexSE3Expmap * > ( optimizer . vertex ( 0 ) ) ;
g2o : : SE3Quat SE3quat_recov = vSE3_recov - > estimate ( ) ;
Sophus : : SE3 < float > pose ( SE3quat_recov . rotation ( ) . cast < float > ( ) ,
SE3quat_recov . translation ( ) . cast < float > ( ) ) ;
pFrame - > SetPose ( pose ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
return nInitialCorrespondences - nBad ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int Optimizer : : PoseInertialOptimizationLastKeyFrame ( Frame * pFrame , bool bRecInit )
{
g2o : : SparseOptimizer optimizer ;
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
linearSolver = new g2o : : LinearSolverDense < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmGaussNewton * solver = new g2o : : OptimizationAlgorithmGaussNewton ( solver_ptr ) ;
optimizer . setVerbose ( false ) ;
optimizer . setAlgorithm ( solver ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
int nInitialMonoCorrespondences = 0 ;
int nInitialStereoCorrespondences = 0 ;
int nInitialCorrespondences = 0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Frame vertex
VertexPose * VP = new VertexPose ( pFrame ) ;
VP - > setId ( 0 ) ;
VP - > setFixed ( false ) ;
optimizer . addVertex ( VP ) ;
VertexVelocity * VV = new VertexVelocity ( pFrame ) ;
VV - > setId ( 1 ) ;
VV - > setFixed ( false ) ;
optimizer . addVertex ( VV ) ;
VertexGyroBias * VG = new VertexGyroBias ( pFrame ) ;
VG - > setId ( 2 ) ;
VG - > setFixed ( false ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pFrame ) ;
VA - > setId ( 3 ) ;
VA - > setFixed ( false ) ;
optimizer . addVertex ( VA ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
// Set MapPoint vertices
const int N = pFrame - > N ;
const int Nleft = pFrame - > Nleft ;
const bool bRight = ( Nleft ! = - 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < EdgeMonoOnlyPose * > vpEdgesMono ;
vector < EdgeStereoOnlyPose * > vpEdgesStereo ;
vector < size_t > vnIndexEdgeMono ;
vector < size_t > vnIndexEdgeStereo ;
vpEdgesMono . reserve ( N ) ;
vpEdgesStereo . reserve ( N ) ;
vnIndexEdgeMono . reserve ( N ) ;
vnIndexEdgeStereo . reserve ( N ) ;
2020-12-01 11:58:17 +08:00
const float thHuberMono = sqrt ( 5.991 ) ;
const float thHuberStereo = sqrt ( 7.815 ) ;
{
2022-07-21 21:32:11 +08:00
unique_lock < mutex > lock ( MapPoint : : mGlobalMutex ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( int i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = pFrame - > mvpMapPoints [ i ] ;
if ( pMP )
2020-12-01 11:58:17 +08:00
{
cv : : KeyPoint kpUn ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
// Left monocular observation
// 这里说的Left monocular包含两种情况: 1.单目情况 2.两个相机情况下的相机1
if ( ( ! bRight & & pFrame - > mvuRight [ i ] < 0 ) | | i < Nleft )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
//如果是两个相机情况下的相机1
if ( i < Nleft ) // pair left-right
kpUn = pFrame - > mvKeys [ i ] ;
else
kpUn = pFrame - > mvKeysUn [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
nInitialMonoCorrespondences + + ;
pFrame - > mvbOutlier [ i ] = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeMonoOnlyPose * e = new EdgeMonoOnlyPose ( pMP - > GetWorldPos ( ) , 0 ) ;
e - > setVertex ( 0 , VP ) ;
2020-12-01 11:58:17 +08:00
e - > setMeasurement ( obs ) ;
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pFrame - > mpCamera - > uncertainty2 ( obs ) ;
const float invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2020-12-01 11:58:17 +08:00
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
optimizer . addEdge ( e ) ;
2022-07-21 21:32:11 +08:00
vpEdgesMono . push_back ( e ) ;
vnIndexEdgeMono . push_back ( i ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Stereo observation
else if ( ! bRight )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
nInitialStereoCorrespondences + + ;
pFrame - > mvbOutlier [ i ] = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
kpUn = pFrame - > mvKeysUn [ i ] ;
const float kp_ur = pFrame - > mvuRight [ i ] ;
Eigen : : Matrix < double , 3 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeStereoOnlyPose * e = new EdgeStereoOnlyPose ( pMP - > GetWorldPos ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , VP ) ;
2020-12-01 11:58:17 +08:00
e - > setMeasurement ( obs ) ;
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pFrame - > mpCamera - > uncertainty2 ( obs . head ( 2 ) ) ;
const float & invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
e - > setInformation ( Eigen : : Matrix3d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2020-12-01 11:58:17 +08:00
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberStereo ) ;
optimizer . addEdge ( e ) ;
2022-07-21 21:32:11 +08:00
vpEdgesStereo . push_back ( e ) ;
vnIndexEdgeStereo . push_back ( i ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Right monocular observation
if ( bRight & & i > = Nleft )
{
nInitialMonoCorrespondences + + ;
pFrame - > mvbOutlier [ i ] = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
kpUn = pFrame - > mvKeysRight [ i - Nleft ] ;
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeMonoOnlyPose * e = new EdgeMonoOnlyPose ( pMP - > GetWorldPos ( ) , 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , VP ) ;
e - > setMeasurement ( obs ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pFrame - > mpCamera - > uncertainty2 ( obs ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
vpEdgesMono . push_back ( e ) ;
vnIndexEdgeMono . push_back ( i ) ;
2020-12-01 11:58:17 +08:00
}
}
}
2022-07-21 21:32:11 +08:00
}
nInitialCorrespondences = nInitialMonoCorrespondences + nInitialStereoCorrespondences ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = pFrame - > mpLastKeyFrame ;
VertexPose * VPk = new VertexPose ( pKF ) ;
VPk - > setId ( 4 ) ;
VPk - > setFixed ( true ) ;
optimizer . addVertex ( VPk ) ;
VertexVelocity * VVk = new VertexVelocity ( pKF ) ;
VVk - > setId ( 5 ) ;
VVk - > setFixed ( true ) ;
optimizer . addVertex ( VVk ) ;
VertexGyroBias * VGk = new VertexGyroBias ( pKF ) ;
VGk - > setId ( 6 ) ;
VGk - > setFixed ( true ) ;
optimizer . addVertex ( VGk ) ;
VertexAccBias * VAk = new VertexAccBias ( pKF ) ;
VAk - > setId ( 7 ) ;
VAk - > setFixed ( true ) ;
optimizer . addVertex ( VAk ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeInertial * ei = new EdgeInertial ( pFrame - > mpImuPreintegrated ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ei - > setVertex ( 0 , VPk ) ;
ei - > setVertex ( 1 , VVk ) ;
ei - > setVertex ( 2 , VGk ) ;
ei - > setVertex ( 3 , VAk ) ;
ei - > setVertex ( 4 , VP ) ;
ei - > setVertex ( 5 , VV ) ;
optimizer . addEdge ( ei ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeGyroRW * egr = new EdgeGyroRW ( ) ;
egr - > setVertex ( 0 , VGk ) ;
egr - > setVertex ( 1 , VG ) ;
Eigen : : Matrix3d InfoG = pFrame - > mpImuPreintegrated - > C . block < 3 , 3 > ( 9 , 9 ) . cast < double > ( ) . inverse ( ) ;
egr - > setInformation ( InfoG ) ;
optimizer . addEdge ( egr ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeAccRW * ear = new EdgeAccRW ( ) ;
ear - > setVertex ( 0 , VAk ) ;
ear - > setVertex ( 1 , VA ) ;
Eigen : : Matrix3d InfoA = pFrame - > mpImuPreintegrated - > C . block < 3 , 3 > ( 12 , 12 ) . cast < double > ( ) . inverse ( ) ;
ear - > setInformation ( InfoA ) ;
optimizer . addEdge ( ear ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
// We perform 4 optimizations, after each optimization we classify observation as inlier/outlier
// At the next optimization, outliers are not included, but at the end they can be classified as inliers again.
float chi2Mono [ 4 ] = { 12 , 7.5 , 5.991 , 5.991 } ;
float chi2Stereo [ 4 ] = { 15.6 , 9.8 , 7.815 , 7.815 } ;
int its [ 4 ] = { 10 , 10 , 10 , 10 } ;
int nBad = 0 ;
int nBadMono = 0 ;
int nBadStereo = 0 ;
int nInliersMono = 0 ;
int nInliersStereo = 0 ;
int nInliers = 0 ;
for ( size_t it = 0 ; it < 4 ; it + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
optimizer . initializeOptimization ( 0 ) ;
optimizer . optimize ( its [ it ] ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
nBad = 0 ;
nBadMono = 0 ;
nBadStereo = 0 ;
nInliers = 0 ;
nInliersMono = 0 ;
nInliersStereo = 0 ;
float chi2close = 1.5 * chi2Mono [ it ] ;
// For monocular observations
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
EdgeMonoOnlyPose * e = vpEdgesMono [ i ] ;
const size_t idx = vnIndexEdgeMono [ i ] ;
if ( pFrame - > mvbOutlier [ idx ] )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
e - > computeError ( ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
const float chi2 = e - > chi2 ( ) ;
bool bClose = pFrame - > mvpMapPoints [ idx ] - > mTrackDepth < 10.f ;
if ( ( chi2 > chi2Mono [ it ] & & ! bClose ) | | ( bClose & & chi2 > chi2close ) | | ! e - > isDepthPositive ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ idx ] = true ;
e - > setLevel ( 1 ) ;
nBadMono + + ;
2020-12-01 11:58:17 +08:00
}
else
{
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ idx ] = false ;
e - > setLevel ( 0 ) ;
nInliersMono + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( it = = 2 )
e - > setRobustKernel ( 0 ) ;
}
// For stereo observations
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
{
EdgeStereoOnlyPose * e = vpEdgesStereo [ i ] ;
const size_t idx = vnIndexEdgeStereo [ i ] ;
if ( pFrame - > mvbOutlier [ idx ] )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
e - > computeError ( ) ;
}
const float chi2 = e - > chi2 ( ) ;
if ( chi2 > chi2Stereo [ it ] )
{
pFrame - > mvbOutlier [ idx ] = true ;
e - > setLevel ( 1 ) ; // not included in next optimization
nBadStereo + + ;
2020-12-01 11:58:17 +08:00
}
else
{
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ idx ] = false ;
e - > setLevel ( 0 ) ;
nInliersStereo + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( it = = 2 )
e - > setRobustKernel ( 0 ) ;
}
nInliers = nInliersMono + nInliersStereo ;
nBad = nBadMono + nBadStereo ;
if ( optimizer . edges ( ) . size ( ) < 10 )
{
break ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
// If not too much tracks, recover not too bad points
if ( ( nInliers < 30 ) & & ! bRecInit )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
nBad = 0 ;
const float chi2MonoOut = 18.f ;
const float chi2StereoOut = 24.f ;
EdgeMonoOnlyPose * e1 ;
EdgeStereoOnlyPose * e2 ;
for ( size_t i = 0 , iend = vnIndexEdgeMono . size ( ) ; i < iend ; i + + )
{
const size_t idx = vnIndexEdgeMono [ i ] ;
e1 = vpEdgesMono [ i ] ;
e1 - > computeError ( ) ;
if ( e1 - > chi2 ( ) < chi2MonoOut )
pFrame - > mvbOutlier [ idx ] = false ;
else
nBad + + ;
}
for ( size_t i = 0 , iend = vnIndexEdgeStereo . size ( ) ; i < iend ; i + + )
{
const size_t idx = vnIndexEdgeStereo [ i ] ;
e2 = vpEdgesStereo [ i ] ;
e2 - > computeError ( ) ;
if ( e2 - > chi2 ( ) < chi2StereoOut )
pFrame - > mvbOutlier [ idx ] = false ;
else
nBad + + ;
}
}
// Recover optimized pose, velocity and biases
pFrame - > SetImuPoseVelocity ( VP - > estimate ( ) . Rwb . cast < float > ( ) , VP - > estimate ( ) . twb . cast < float > ( ) , VV - > estimate ( ) . cast < float > ( ) ) ;
Vector6d b ;
b < < VG - > estimate ( ) , VA - > estimate ( ) ;
pFrame - > mImuBias = IMU : : Bias ( b [ 3 ] , b [ 4 ] , b [ 5 ] , b [ 0 ] , b [ 1 ] , b [ 2 ] ) ;
// Recover Hessian, marginalize keyFframe states and generate new prior for frame
Eigen : : Matrix < double , 15 , 15 > H ;
H . setZero ( ) ;
H . block < 9 , 9 > ( 0 , 0 ) + = ei - > GetHessian2 ( ) ;
H . block < 3 , 3 > ( 9 , 9 ) + = egr - > GetHessian2 ( ) ;
H . block < 3 , 3 > ( 12 , 12 ) + = ear - > GetHessian2 ( ) ;
int tot_in = 0 , tot_out = 0 ;
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
{
EdgeMonoOnlyPose * e = vpEdgesMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const size_t idx = vnIndexEdgeMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pFrame - > mvbOutlier [ idx ] )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
H . block < 6 , 6 > ( 0 , 0 ) + = e - > GetHessian ( ) ;
tot_in + + ;
2020-12-01 11:58:17 +08:00
}
else
2022-07-21 21:32:11 +08:00
tot_out + + ;
}
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
{
EdgeStereoOnlyPose * e = vpEdgesStereo [ i ] ;
const size_t idx = vnIndexEdgeStereo [ i ] ;
if ( ! pFrame - > mvbOutlier [ idx ] )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
H . block < 6 , 6 > ( 0 , 0 ) + = e - > GetHessian ( ) ;
tot_in + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
else
tot_out + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
pFrame - > mpcpi = new ConstraintPoseImu ( VP - > estimate ( ) . Rwb , VP - > estimate ( ) . twb , VV - > estimate ( ) , VG - > estimate ( ) , VA - > estimate ( ) , H ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
return nInitialCorrespondences - nBad ;
}
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
int Optimizer : : PoseInertialOptimizationLastFrame ( Frame * pFrame , bool bRecInit )
2020-12-01 11:58:17 +08:00
{
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
linearSolver = new g2o : : LinearSolverDense < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmGaussNewton * solver = new g2o : : OptimizationAlgorithmGaussNewton ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
optimizer . setAlgorithm ( solver ) ;
2022-07-21 21:32:11 +08:00
optimizer . setVerbose ( false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int nInitialMonoCorrespondences = 0 ;
int nInitialStereoCorrespondences = 0 ;
int nInitialCorrespondences = 0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Current Frame vertex
VertexPose * VP = new VertexPose ( pFrame ) ;
VP - > setId ( 0 ) ;
VP - > setFixed ( false ) ;
optimizer . addVertex ( VP ) ;
VertexVelocity * VV = new VertexVelocity ( pFrame ) ;
VV - > setId ( 1 ) ;
VV - > setFixed ( false ) ;
optimizer . addVertex ( VV ) ;
VertexGyroBias * VG = new VertexGyroBias ( pFrame ) ;
VG - > setId ( 2 ) ;
VG - > setFixed ( false ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pFrame ) ;
VA - > setId ( 3 ) ;
VA - > setFixed ( false ) ;
optimizer . addVertex ( VA ) ;
2020-12-01 11:58:17 +08:00
// Set MapPoint vertices
const int N = pFrame - > N ;
2022-07-21 21:32:11 +08:00
const int Nleft = pFrame - > Nleft ;
const bool bRight = ( Nleft ! = - 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < EdgeMonoOnlyPose * > vpEdgesMono ;
vector < EdgeStereoOnlyPose * > vpEdgesStereo ;
vector < size_t > vnIndexEdgeMono ;
2020-12-01 11:58:17 +08:00
vector < size_t > vnIndexEdgeStereo ;
2022-07-21 21:32:11 +08:00
vpEdgesMono . reserve ( N ) ;
2020-12-01 11:58:17 +08:00
vpEdgesStereo . reserve ( N ) ;
2022-07-21 21:32:11 +08:00
vnIndexEdgeMono . reserve ( N ) ;
2020-12-01 11:58:17 +08:00
vnIndexEdgeStereo . reserve ( N ) ;
2022-07-21 21:32:11 +08:00
const float thHuberMono = sqrt ( 5.991 ) ;
const float thHuberStereo = sqrt ( 7.815 ) ;
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
unique_lock < mutex > lock ( MapPoint : : mGlobalMutex ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( int i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = pFrame - > mvpMapPoints [ i ] ;
if ( pMP )
{
cv : : KeyPoint kpUn ;
// Left monocular observation
// 这里说的Left monocular包含两种情况: 1.单目情况 2.两个相机情况下的相机1
if ( ( ! bRight & & pFrame - > mvuRight [ i ] < 0 ) | | i < Nleft )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
//如果是两个相机情况下的相机1
if ( i < Nleft ) // pair left-right
kpUn = pFrame - > mvKeys [ i ] ;
else
kpUn = pFrame - > mvKeysUn [ i ] ;
nInitialMonoCorrespondences + + ;
2020-12-01 11:58:17 +08:00
pFrame - > mvbOutlier [ i ] = false ;
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
2020-12-01 11:58:17 +08:00
obs < < kpUn . pt . x , kpUn . pt . y ;
2022-07-21 21:32:11 +08:00
EdgeMonoOnlyPose * e = new EdgeMonoOnlyPose ( pMP - > GetWorldPos ( ) , 0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , VP ) ;
2020-12-01 11:58:17 +08:00
e - > setMeasurement ( obs ) ;
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pFrame - > mpCamera - > uncertainty2 ( obs ) ;
const float invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
2020-12-01 11:58:17 +08:00
optimizer . addEdge ( e ) ;
vpEdgesMono . push_back ( e ) ;
vnIndexEdgeMono . push_back ( i ) ;
}
2022-07-21 21:32:11 +08:00
// Stereo observation
else if ( ! bRight )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
nInitialStereoCorrespondences + + ;
2020-12-01 11:58:17 +08:00
pFrame - > mvbOutlier [ i ] = false ;
2022-07-21 21:32:11 +08:00
kpUn = pFrame - > mvKeysUn [ i ] ;
const float kp_ur = pFrame - > mvuRight [ i ] ;
Eigen : : Matrix < double , 3 , 1 > obs ;
2020-12-01 11:58:17 +08:00
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
EdgeStereoOnlyPose * e = new EdgeStereoOnlyPose ( pMP - > GetWorldPos ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , VP ) ;
2020-12-01 11:58:17 +08:00
e - > setMeasurement ( obs ) ;
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pFrame - > mpCamera - > uncertainty2 ( obs . head ( 2 ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float & invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
e - > setInformation ( Eigen : : Matrix3d : : Identity ( ) * invSigma2 ) ;
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberStereo ) ;
2020-12-01 11:58:17 +08:00
optimizer . addEdge ( e ) ;
vpEdgesStereo . push_back ( e ) ;
vnIndexEdgeStereo . push_back ( i ) ;
}
2022-07-21 21:32:11 +08:00
// Right monocular observation
if ( bRight & & i > = Nleft )
{
nInitialMonoCorrespondences + + ;
2020-12-01 11:58:17 +08:00
pFrame - > mvbOutlier [ i ] = false ;
2022-07-21 21:32:11 +08:00
kpUn = pFrame - > mvKeysRight [ i - Nleft ] ;
2020-12-01 11:58:17 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2022-07-21 21:32:11 +08:00
EdgeMonoOnlyPose * e = new EdgeMonoOnlyPose ( pMP - > GetWorldPos ( ) , 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , VP ) ;
2020-12-01 11:58:17 +08:00
e - > setMeasurement ( obs ) ;
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pFrame - > mpCamera - > uncertainty2 ( obs ) ;
const float invSigma2 = pFrame - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
2020-12-01 11:58:17 +08:00
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
2022-07-21 21:32:11 +08:00
rk - > setDelta ( thHuberMono ) ;
2020-12-01 11:58:17 +08:00
optimizer . addEdge ( e ) ;
vpEdgesMono . push_back ( e ) ;
vnIndexEdgeMono . push_back ( i ) ;
}
2022-07-21 21:32:11 +08:00
}
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
nInitialCorrespondences = nInitialMonoCorrespondences + nInitialStereoCorrespondences ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Previous Frame Vertex
Frame * pFp = pFrame - > mpPrevFrame ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexPose * VPk = new VertexPose ( pFp ) ;
VPk - > setId ( 4 ) ;
VPk - > setFixed ( false ) ;
optimizer . addVertex ( VPk ) ;
VertexVelocity * VVk = new VertexVelocity ( pFp ) ;
VVk - > setId ( 5 ) ;
VVk - > setFixed ( false ) ;
optimizer . addVertex ( VVk ) ;
VertexGyroBias * VGk = new VertexGyroBias ( pFp ) ;
VGk - > setId ( 6 ) ;
VGk - > setFixed ( false ) ;
optimizer . addVertex ( VGk ) ;
VertexAccBias * VAk = new VertexAccBias ( pFp ) ;
VAk - > setId ( 7 ) ;
VAk - > setFixed ( false ) ;
optimizer . addVertex ( VAk ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeInertial * ei = new EdgeInertial ( pFrame - > mpImuPreintegratedFrame ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ei - > setVertex ( 0 , VPk ) ;
ei - > setVertex ( 1 , VVk ) ;
ei - > setVertex ( 2 , VGk ) ;
ei - > setVertex ( 3 , VAk ) ;
ei - > setVertex ( 4 , VP ) ;
ei - > setVertex ( 5 , VV ) ;
optimizer . addEdge ( ei ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeGyroRW * egr = new EdgeGyroRW ( ) ;
egr - > setVertex ( 0 , VGk ) ;
egr - > setVertex ( 1 , VG ) ;
Eigen : : Matrix3d InfoG = pFrame - > mpImuPreintegrated - > C . block < 3 , 3 > ( 9 , 9 ) . cast < double > ( ) . inverse ( ) ;
egr - > setInformation ( InfoG ) ;
optimizer . addEdge ( egr ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeAccRW * ear = new EdgeAccRW ( ) ;
ear - > setVertex ( 0 , VAk ) ;
ear - > setVertex ( 1 , VA ) ;
Eigen : : Matrix3d InfoA = pFrame - > mpImuPreintegrated - > C . block < 3 , 3 > ( 12 , 12 ) . cast < double > ( ) . inverse ( ) ;
ear - > setInformation ( InfoA ) ;
optimizer . addEdge ( ear ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pFp - > mpcpi )
Verbose : : PrintMess ( " pFp->mpcpi does not exist!!! \n Previous Frame " + to_string ( pFp - > mnId ) , Verbose : : VERBOSITY_NORMAL ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgePriorPoseImu * ep = new EdgePriorPoseImu ( pFp - > mpcpi ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ep - > setVertex ( 0 , VPk ) ;
ep - > setVertex ( 1 , VVk ) ;
ep - > setVertex ( 2 , VGk ) ;
ep - > setVertex ( 3 , VAk ) ;
g2o : : RobustKernelHuber * rkp = new g2o : : RobustKernelHuber ;
ep - > setRobustKernel ( rkp ) ;
rkp - > setDelta ( 5 ) ;
optimizer . addEdge ( ep ) ;
2020-12-01 11:58:17 +08:00
// We perform 4 optimizations, after each optimization we classify observation as inlier/outlier
// At the next optimization, outliers are not included, but at the end they can be classified as inliers again.
2022-07-21 21:32:11 +08:00
const float chi2Mono [ 4 ] = { 5.991 , 5.991 , 5.991 , 5.991 } ;
const float chi2Stereo [ 4 ] = { 15.6f , 9.8f , 7.815f , 7.815f } ;
const int its [ 4 ] = { 10 , 10 , 10 , 10 } ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int nBad = 0 ;
int nBadMono = 0 ;
int nBadStereo = 0 ;
int nInliersMono = 0 ;
int nInliersStereo = 0 ;
int nInliers = 0 ;
for ( size_t it = 0 ; it < 4 ; it + + )
2020-12-01 11:58:17 +08:00
{
optimizer . initializeOptimization ( 0 ) ;
optimizer . optimize ( its [ it ] ) ;
2022-07-21 21:32:11 +08:00
nBad = 0 ;
nBadMono = 0 ;
nBadStereo = 0 ;
nInliers = 0 ;
nInliersMono = 0 ;
nInliersStereo = 0 ;
float chi2close = 1.5 * chi2Mono [ it ] ;
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
EdgeMonoOnlyPose * e = vpEdgesMono [ i ] ;
2020-12-01 11:58:17 +08:00
const size_t idx = vnIndexEdgeMono [ i ] ;
2022-07-21 21:32:11 +08:00
bool bClose = pFrame - > mvpMapPoints [ idx ] - > mTrackDepth < 10.f ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pFrame - > mvbOutlier [ idx ] )
2020-12-01 11:58:17 +08:00
{
e - > computeError ( ) ;
}
const float chi2 = e - > chi2 ( ) ;
2022-07-21 21:32:11 +08:00
if ( ( chi2 > chi2Mono [ it ] & & ! bClose ) | | ( bClose & & chi2 > chi2close ) | | ! e - > isDepthPositive ( ) )
{
pFrame - > mvbOutlier [ idx ] = true ;
2022-03-28 21:20:28 +08:00
e - > setLevel ( 1 ) ;
2022-07-21 21:32:11 +08:00
nBadMono + + ;
2020-12-01 11:58:17 +08:00
}
else
{
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ idx ] = false ;
2022-03-28 21:20:28 +08:00
e - > setLevel ( 0 ) ;
2022-07-21 21:32:11 +08:00
nInliersMono + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( it = = 2 )
2022-03-28 21:20:28 +08:00
e - > setRobustKernel ( 0 ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
EdgeStereoOnlyPose * e = vpEdgesStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const size_t idx = vnIndexEdgeStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pFrame - > mvbOutlier [ idx ] )
2020-12-01 11:58:17 +08:00
{
e - > computeError ( ) ;
}
const float chi2 = e - > chi2 ( ) ;
2022-07-21 21:32:11 +08:00
if ( chi2 > chi2Stereo [ it ] )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ idx ] = true ;
2020-12-01 11:58:17 +08:00
e - > setLevel ( 1 ) ;
2022-07-21 21:32:11 +08:00
nBadStereo + + ;
2020-12-01 11:58:17 +08:00
}
else
{
2022-07-21 21:32:11 +08:00
pFrame - > mvbOutlier [ idx ] = false ;
2020-12-01 11:58:17 +08:00
e - > setLevel ( 0 ) ;
2022-07-21 21:32:11 +08:00
nInliersStereo + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( it = = 2 )
2020-12-01 11:58:17 +08:00
e - > setRobustKernel ( 0 ) ;
}
2022-07-21 21:32:11 +08:00
nInliers = nInliersMono + nInliersStereo ;
nBad = nBadMono + nBadStereo ;
if ( optimizer . edges ( ) . size ( ) < 10 )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
break ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ( nInliers < 30 ) & & ! bRecInit )
{
nBad = 0 ;
const float chi2MonoOut = 18.f ;
const float chi2StereoOut = 24.f ;
EdgeMonoOnlyPose * e1 ;
EdgeStereoOnlyPose * e2 ;
for ( size_t i = 0 , iend = vnIndexEdgeMono . size ( ) ; i < iend ; i + + )
{
const size_t idx = vnIndexEdgeMono [ i ] ;
e1 = vpEdgesMono [ i ] ;
e1 - > computeError ( ) ;
if ( e1 - > chi2 ( ) < chi2MonoOut )
pFrame - > mvbOutlier [ idx ] = false ;
else
nBad + + ;
}
for ( size_t i = 0 , iend = vnIndexEdgeStereo . size ( ) ; i < iend ; i + + )
{
2020-12-01 11:58:17 +08:00
const size_t idx = vnIndexEdgeStereo [ i ] ;
2022-07-21 21:32:11 +08:00
e2 = vpEdgesStereo [ i ] ;
e2 - > computeError ( ) ;
if ( e2 - > chi2 ( ) < chi2StereoOut )
pFrame - > mvbOutlier [ idx ] = false ;
else
nBad + + ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
nInliers = nInliersMono + nInliersStereo ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Recover optimized pose, velocity and biases
pFrame - > SetImuPoseVelocity ( VP - > estimate ( ) . Rwb . cast < float > ( ) , VP - > estimate ( ) . twb . cast < float > ( ) , VV - > estimate ( ) . cast < float > ( ) ) ;
Vector6d b ;
b < < VG - > estimate ( ) , VA - > estimate ( ) ;
pFrame - > mImuBias = IMU : : Bias ( b [ 3 ] , b [ 4 ] , b [ 5 ] , b [ 0 ] , b [ 1 ] , b [ 2 ] ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Recover Hessian, marginalize previous frame states and generate new prior for frame
Eigen : : Matrix < double , 30 , 30 > H ;
H . setZero ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
H . block < 24 , 24 > ( 0 , 0 ) + = ei - > GetHessian ( ) ;
Eigen : : Matrix < double , 6 , 6 > Hgr = egr - > GetHessian ( ) ;
H . block < 3 , 3 > ( 9 , 9 ) + = Hgr . block < 3 , 3 > ( 0 , 0 ) ;
H . block < 3 , 3 > ( 9 , 24 ) + = Hgr . block < 3 , 3 > ( 0 , 3 ) ;
H . block < 3 , 3 > ( 24 , 9 ) + = Hgr . block < 3 , 3 > ( 3 , 0 ) ;
H . block < 3 , 3 > ( 24 , 24 ) + = Hgr . block < 3 , 3 > ( 3 , 3 ) ;
Eigen : : Matrix < double , 6 , 6 > Har = ear - > GetHessian ( ) ;
H . block < 3 , 3 > ( 12 , 12 ) + = Har . block < 3 , 3 > ( 0 , 0 ) ;
H . block < 3 , 3 > ( 12 , 27 ) + = Har . block < 3 , 3 > ( 0 , 3 ) ;
H . block < 3 , 3 > ( 27 , 12 ) + = Har . block < 3 , 3 > ( 3 , 0 ) ;
H . block < 3 , 3 > ( 27 , 27 ) + = Har . block < 3 , 3 > ( 3 , 3 ) ;
H . block < 15 , 15 > ( 0 , 0 ) + = ep - > GetHessian ( ) ;
int tot_in = 0 , tot_out = 0 ;
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
{
EdgeMonoOnlyPose * e = vpEdgesMono [ i ] ;
const size_t idx = vnIndexEdgeMono [ i ] ;
if ( ! pFrame - > mvbOutlier [ idx ] )
{
H . block < 6 , 6 > ( 15 , 15 ) + = e - > GetHessian ( ) ;
tot_in + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
else
tot_out + + ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
{
EdgeStereoOnlyPose * e = vpEdgesStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const size_t idx = vnIndexEdgeStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pFrame - > mvbOutlier [ idx ] )
{
H . block < 6 , 6 > ( 15 , 15 ) + = e - > GetHessian ( ) ;
tot_in + + ;
}
else
tot_out + + ;
}
H = Marginalize ( H , 0 , 14 ) ;
pFrame - > mpcpi = new ConstraintPoseImu ( VP - > estimate ( ) . Rwb , VP - > estimate ( ) . twb , VV - > estimate ( ) , VG - > estimate ( ) , VA - > estimate ( ) , H . block < 15 , 15 > ( 15 , 15 ) ) ;
delete pFp - > mpcpi ;
pFp - > mpcpi = NULL ;
return nInitialCorrespondences - nBad ;
}
Eigen : : MatrixXd Optimizer : : Marginalize ( const Eigen : : MatrixXd & H , const int & start , const int & end )
{
// Goal
// a | ab | ac a* | 0 | ac*
// ba | b | bc --> 0 | 0 | 0
// ca | cb | c ca* | 0 | c*
// Size of block before block to marginalize
const int a = start ;
// Size of block to marginalize
const int b = end - start + 1 ;
// Size of block after block to marginalize
const int c = H . cols ( ) - ( end + 1 ) ;
// Reorder as follows:
// a | ab | ac a | ac | ab
// ba | b | bc --> ca | c | cb
// ca | cb | c ba | bc | b
Eigen : : MatrixXd Hn = Eigen : : MatrixXd : : Zero ( H . rows ( ) , H . cols ( ) ) ;
if ( a > 0 )
{
Hn . block ( 0 , 0 , a , a ) = H . block ( 0 , 0 , a , a ) ;
Hn . block ( 0 , a + c , a , b ) = H . block ( 0 , a , a , b ) ;
Hn . block ( a + c , 0 , b , a ) = H . block ( a , 0 , b , a ) ;
}
if ( a > 0 & & c > 0 )
{
Hn . block ( 0 , a , a , c ) = H . block ( 0 , a + b , a , c ) ;
Hn . block ( a , 0 , c , a ) = H . block ( a + b , 0 , c , a ) ;
}
if ( c > 0 )
{
Hn . block ( a , a , c , c ) = H . block ( a + b , a + b , c , c ) ;
Hn . block ( a , a + c , c , b ) = H . block ( a + b , a , c , b ) ;
Hn . block ( a + c , a , b , c ) = H . block ( a , a + b , b , c ) ;
}
Hn . block ( a + c , a + c , b , b ) = H . block ( a , a , b , b ) ;
// Perform marginalization (Schur complement)
Eigen : : JacobiSVD < Eigen : : MatrixXd > svd ( Hn . block ( a + c , a + c , b , b ) , Eigen : : ComputeThinU | Eigen : : ComputeThinV ) ;
Eigen : : JacobiSVD < Eigen : : MatrixXd > : : SingularValuesType singularValues_inv = svd . singularValues ( ) ;
for ( int i = 0 ; i < b ; + + i )
{
if ( singularValues_inv ( i ) > 1e-6 )
singularValues_inv ( i ) = 1.0 / singularValues_inv ( i ) ;
else
singularValues_inv ( i ) = 0 ;
}
Eigen : : MatrixXd invHb = svd . matrixV ( ) * singularValues_inv . asDiagonal ( ) * svd . matrixU ( ) . transpose ( ) ;
Hn . block ( 0 , 0 , a + c , a + c ) = Hn . block ( 0 , 0 , a + c , a + c ) - Hn . block ( 0 , a + c , a + c , b ) * invHb * Hn . block ( a + c , 0 , b , a + c ) ;
Hn . block ( a + c , a + c , b , b ) = Eigen : : MatrixXd : : Zero ( b , b ) ;
Hn . block ( 0 , a + c , a + c , b ) = Eigen : : MatrixXd : : Zero ( a + c , b ) ;
Hn . block ( a + c , 0 , b , a + c ) = Eigen : : MatrixXd : : Zero ( b , a + c ) ;
// Inverse reorder
// a* | ac* | 0 a* | 0 | ac*
// ca* | c* | 0 --> 0 | 0 | 0
// 0 | 0 | 0 ca* | 0 | c*
Eigen : : MatrixXd res = Eigen : : MatrixXd : : Zero ( H . rows ( ) , H . cols ( ) ) ;
if ( a > 0 )
{
res . block ( 0 , 0 , a , a ) = Hn . block ( 0 , 0 , a , a ) ;
res . block ( 0 , a , a , b ) = Hn . block ( 0 , a + c , a , b ) ;
res . block ( a , 0 , b , a ) = Hn . block ( a + c , 0 , b , a ) ;
}
if ( a > 0 & & c > 0 )
{
res . block ( 0 , a + b , a , c ) = Hn . block ( 0 , a , a , c ) ;
res . block ( a + b , 0 , c , a ) = Hn . block ( a , 0 , c , a ) ;
}
if ( c > 0 )
{
res . block ( a + b , a + b , c , c ) = Hn . block ( a , a , c , c ) ;
res . block ( a + b , a , c , b ) = Hn . block ( a , a + c , c , b ) ;
res . block ( a , a + b , b , c ) = Hn . block ( a + c , a , b , c ) ;
}
res . block ( a , a , b , b ) = Hn . block ( a + c , a + c , b , b ) ;
return res ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
/**************************************以下为局部地图优化**************************************************************/
void Optimizer : : LocalBundleAdjustment (
KeyFrame * pKF , bool * pbStopFlag , Map * pMap , int & num_fixedKF , int & num_OptKF , int & num_MPs , int & num_edges )
2020-12-01 11:58:17 +08:00
{
// Local KeyFrames: First Breath Search from Current Keyframe
2022-07-21 21:32:11 +08:00
list < KeyFrame * > lLocalKeyFrames ;
2020-12-01 11:58:17 +08:00
lLocalKeyFrames . push_back ( pKF ) ;
pKF - > mnBALocalForKF = pKF - > mnId ;
2022-07-21 21:32:11 +08:00
Map * pCurrentMap = pKF - > GetMap ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const vector < KeyFrame * > vNeighKFs = pKF - > GetVectorCovisibleKeyFrames ( ) ;
for ( int i = 0 , iend = vNeighKFs . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vNeighKFs [ i ] ;
2020-12-01 11:58:17 +08:00
pKFi - > mnBALocalForKF = pKF - > mnId ;
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > isBad ( ) & & pKFi - > GetMap ( ) = = pCurrentMap )
2020-12-01 11:58:17 +08:00
lLocalKeyFrames . push_back ( pKFi ) ;
}
// Local MapPoints seen in Local KeyFrames
2022-03-28 21:20:28 +08:00
num_fixedKF = 0 ;
2022-07-21 21:32:11 +08:00
list < MapPoint * > lLocalMapPoints ;
set < MapPoint * > sNumObsMP ;
for ( list < KeyFrame * > : : iterator lit = lLocalKeyFrames . begin ( ) , lend = lLocalKeyFrames . end ( ) ; lit ! = lend ; lit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = * lit ;
if ( pKFi - > mnId = = pMap - > GetInitKFid ( ) )
2020-12-01 11:58:17 +08:00
{
num_fixedKF = 1 ;
}
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMPs = pKFi - > GetMapPointMatches ( ) ;
for ( vector < MapPoint * > : : iterator vit = vpMPs . begin ( ) , vend = vpMPs . end ( ) ; vit ! = vend ; vit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = * vit ;
if ( pMP )
if ( ! pMP - > isBad ( ) & & pMP - > GetMap ( ) = = pCurrentMap )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pMP - > mnBALocalForKF ! = pKF - > mnId )
2020-12-01 11:58:17 +08:00
{
lLocalMapPoints . push_back ( pMP ) ;
2022-07-21 21:32:11 +08:00
pMP - > mnBALocalForKF = pKF - > mnId ;
2020-12-01 11:58:17 +08:00
}
}
}
}
// Fixed Keyframes. Keyframes that see Local MapPoints but that are not Local Keyframes
2022-07-21 21:32:11 +08:00
list < KeyFrame * > lFixedCameras ;
for ( list < MapPoint * > : : iterator lit = lLocalMapPoints . begin ( ) , lend = lLocalMapPoints . end ( ) ; lit ! = lend ; lit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
map < KeyFrame * , tuple < int , int > > observations = ( * lit ) - > GetObservations ( ) ;
for ( map < KeyFrame * , tuple < int , int > > : : iterator mit = observations . begin ( ) , mend = observations . end ( ) ; mit ! = mend ; mit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = mit - > first ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mnBALocalForKF ! = pKF - > mnId & & pKFi - > mnBAFixedForKF ! = pKF - > mnId )
{
pKFi - > mnBAFixedForKF = pKF - > mnId ;
if ( ! pKFi - > isBad ( ) & & pKFi - > GetMap ( ) = = pCurrentMap )
2020-12-01 11:58:17 +08:00
lFixedCameras . push_back ( pKFi ) ;
}
}
}
num_fixedKF = lFixedCameras . size ( ) + num_fixedKF ;
2022-07-21 21:32:11 +08:00
if ( num_fixedKF = = 0 )
2020-12-01 11:58:17 +08:00
{
2022-03-28 21:20:28 +08:00
Verbose : : PrintMess ( " LM-LBA: There are 0 fixed KF in the optimizations, LBA aborted " , Verbose : : VERBOSITY_NORMAL ) ;
2021-08-09 19:34:51 +08:00
return ;
2020-12-01 11:58:17 +08:00
}
// Setup optimizer
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolver_6_3 : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolver_6_3 : : PoseMatrixType > ( ) ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolver_6_3 * solver_ptr = new g2o : : BlockSolver_6_3 ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2022-03-28 21:20:28 +08:00
if ( pMap - > IsInertial ( ) )
solver - > setUserLambdaInit ( 100.0 ) ;
2020-12-01 11:58:17 +08:00
optimizer . setAlgorithm ( solver ) ;
optimizer . setVerbose ( false ) ;
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
2020-12-01 11:58:17 +08:00
optimizer . setForceStopFlag ( pbStopFlag ) ;
unsigned long maxKFid = 0 ;
2022-03-28 21:20:28 +08:00
// DEBUG LBA
pCurrentMap - > msOptKFs . clear ( ) ;
pCurrentMap - > msFixedKFs . clear ( ) ;
2020-12-01 11:58:17 +08:00
// Set Local KeyFrame vertices
2022-07-21 21:32:11 +08:00
for ( list < KeyFrame * > : : iterator lit = lLocalKeyFrames . begin ( ) , lend = lLocalKeyFrames . end ( ) ; lit ! = lend ; lit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = * lit ;
g2o : : VertexSE3Expmap * vSE3 = new g2o : : VertexSE3Expmap ( ) ;
2022-03-28 21:20:28 +08:00
Sophus : : SE3 < float > Tcw = pKFi - > GetPose ( ) ;
vSE3 - > setEstimate ( g2o : : SE3Quat ( Tcw . unit_quaternion ( ) . cast < double > ( ) , Tcw . translation ( ) . cast < double > ( ) ) ) ;
2020-12-01 11:58:17 +08:00
vSE3 - > setId ( pKFi - > mnId ) ;
2022-07-21 21:32:11 +08:00
vSE3 - > setFixed ( pKFi - > mnId = = pMap - > GetInitKFid ( ) ) ;
2020-12-01 11:58:17 +08:00
optimizer . addVertex ( vSE3 ) ;
2022-07-21 21:32:11 +08:00
if ( pKFi - > mnId > maxKFid )
maxKFid = pKFi - > mnId ;
2022-03-28 21:20:28 +08:00
// DEBUG LBA
pCurrentMap - > msOptKFs . insert ( pKFi - > mnId ) ;
2020-12-01 11:58:17 +08:00
}
2022-03-28 21:20:28 +08:00
num_OptKF = lLocalKeyFrames . size ( ) ;
2020-12-01 11:58:17 +08:00
// Set Fixed KeyFrame vertices
2022-07-21 21:32:11 +08:00
for ( list < KeyFrame * > : : iterator lit = lFixedCameras . begin ( ) , lend = lFixedCameras . end ( ) ; lit ! = lend ; lit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = * lit ;
g2o : : VertexSE3Expmap * vSE3 = new g2o : : VertexSE3Expmap ( ) ;
2022-03-28 21:20:28 +08:00
Sophus : : SE3 < float > Tcw = pKFi - > GetPose ( ) ;
2022-07-21 21:32:11 +08:00
vSE3 - > setEstimate ( g2o : : SE3Quat ( Tcw . unit_quaternion ( ) . cast < double > ( ) , Tcw . translation ( ) . cast < double > ( ) ) ) ;
2020-12-01 11:58:17 +08:00
vSE3 - > setId ( pKFi - > mnId ) ;
vSE3 - > setFixed ( true ) ;
optimizer . addVertex ( vSE3 ) ;
2022-07-21 21:32:11 +08:00
if ( pKFi - > mnId > maxKFid )
maxKFid = pKFi - > mnId ;
2022-03-28 21:20:28 +08:00
// DEBUG LBA
pCurrentMap - > msFixedKFs . insert ( pKFi - > mnId ) ;
2020-12-01 11:58:17 +08:00
}
// Set MapPoint vertices
2022-07-21 21:32:11 +08:00
const int nExpectedSize = ( lLocalKeyFrames . size ( ) + lFixedCameras . size ( ) ) * lLocalMapPoints . size ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < ORB_SLAM3 : : EdgeSE3ProjectXYZ * > vpEdgesMono ;
2020-12-01 11:58:17 +08:00
vpEdgesMono . reserve ( nExpectedSize ) ;
2022-07-21 21:32:11 +08:00
vector < ORB_SLAM3 : : EdgeSE3ProjectXYZToBody * > vpEdgesBody ;
2020-12-01 11:58:17 +08:00
vpEdgesBody . reserve ( nExpectedSize ) ;
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFMono ;
2020-12-01 11:58:17 +08:00
vpEdgeKFMono . reserve ( nExpectedSize ) ;
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFBody ;
2020-12-01 11:58:17 +08:00
vpEdgeKFBody . reserve ( nExpectedSize ) ;
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeMono ;
2020-12-01 11:58:17 +08:00
vpMapPointEdgeMono . reserve ( nExpectedSize ) ;
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeBody ;
2020-12-01 11:58:17 +08:00
vpMapPointEdgeBody . reserve ( nExpectedSize ) ;
2022-07-21 21:32:11 +08:00
vector < g2o : : EdgeStereoSE3ProjectXYZ * > vpEdgesStereo ;
2020-12-01 11:58:17 +08:00
vpEdgesStereo . reserve ( nExpectedSize ) ;
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFStereo ;
2020-12-01 11:58:17 +08:00
vpEdgeKFStereo . reserve ( nExpectedSize ) ;
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeStereo ;
2020-12-01 11:58:17 +08:00
vpMapPointEdgeStereo . reserve ( nExpectedSize ) ;
const float thHuberMono = sqrt ( 5.991 ) ;
const float thHuberStereo = sqrt ( 7.815 ) ;
int nPoints = 0 ;
2022-03-28 21:20:28 +08:00
int nEdges = 0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( list < MapPoint * > : : iterator lit = lLocalMapPoints . begin ( ) , lend = lLocalMapPoints . end ( ) ; lit ! = lend ; lit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = * lit ;
g2o : : VertexSBAPointXYZ * vPoint = new g2o : : VertexSBAPointXYZ ( ) ;
2022-03-28 21:20:28 +08:00
vPoint - > setEstimate ( pMP - > GetWorldPos ( ) . cast < double > ( ) ) ;
2022-07-21 21:32:11 +08:00
int id = pMP - > mnId + maxKFid + 1 ;
2020-12-01 11:58:17 +08:00
vPoint - > setId ( id ) ;
vPoint - > setMarginalized ( true ) ;
optimizer . addVertex ( vPoint ) ;
nPoints + + ;
2022-07-21 21:32:11 +08:00
const map < KeyFrame * , tuple < int , int > > observations = pMP - > GetObservations ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set edges
for ( map < KeyFrame * , tuple < int , int > > : : const_iterator mit = observations . begin ( ) , mend = observations . end ( ) ; mit ! = mend ; mit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = mit - > first ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > isBad ( ) & & pKFi - > GetMap ( ) = = pCurrentMap )
2020-12-01 11:58:17 +08:00
{
2022-03-28 21:20:28 +08:00
const int leftIndex = get < 0 > ( mit - > second ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Monocular observation
2022-07-21 21:32:11 +08:00
if ( leftIndex ! = - 1 & & pKFi - > mvuRight [ get < 0 > ( mit - > second ) ] < 0 )
2020-12-01 11:58:17 +08:00
{
2022-03-28 21:20:28 +08:00
const cv : : KeyPoint & kpUn = pKFi - > mvKeysUn [ leftIndex ] ;
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
2020-12-01 11:58:17 +08:00
obs < < kpUn . pt . x , kpUn . pt . y ;
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZ * e = new ORB_SLAM3 : : EdgeSE3ProjectXYZ ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ) ;
2020-12-01 11:58:17 +08:00
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] ;
2022-07-21 21:32:11 +08:00
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2020-12-01 11:58:17 +08:00
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
e - > pCamera = pKFi - > mpCamera ;
optimizer . addEdge ( e ) ;
vpEdgesMono . push_back ( e ) ;
vpEdgeKFMono . push_back ( pKFi ) ;
vpMapPointEdgeMono . push_back ( pMP ) ;
nEdges + + ;
}
2022-07-21 21:32:11 +08:00
else if ( leftIndex ! = - 1 & & pKFi - > mvuRight [ get < 0 > ( mit - > second ) ] > = 0 ) // Stereo observation
2020-12-01 11:58:17 +08:00
{
2022-03-28 21:20:28 +08:00
const cv : : KeyPoint & kpUn = pKFi - > mvKeysUn [ leftIndex ] ;
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 3 , 1 > obs ;
2022-03-28 21:20:28 +08:00
const float kp_ur = pKFi - > mvuRight [ get < 0 > ( mit - > second ) ] ;
2020-12-01 11:58:17 +08:00
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2022-07-21 21:32:11 +08:00
g2o : : EdgeStereoSE3ProjectXYZ * e = new g2o : : EdgeStereoSE3ProjectXYZ ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ) ;
2020-12-01 11:58:17 +08:00
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] ;
2022-07-21 21:32:11 +08:00
Eigen : : Matrix3d Info = Eigen : : Matrix3d : : Identity ( ) * invSigma2 ;
2020-12-01 11:58:17 +08:00
e - > setInformation ( Info ) ;
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2020-12-01 11:58:17 +08:00
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberStereo ) ;
e - > fx = pKFi - > fx ;
e - > fy = pKFi - > fy ;
e - > cx = pKFi - > cx ;
e - > cy = pKFi - > cy ;
e - > bf = pKFi - > mbf ;
optimizer . addEdge ( e ) ;
vpEdgesStereo . push_back ( e ) ;
vpEdgeKFStereo . push_back ( pKFi ) ;
vpMapPointEdgeStereo . push_back ( pMP ) ;
nEdges + + ;
}
2022-07-21 21:32:11 +08:00
if ( pKFi - > mpCamera2 )
{
2020-12-01 11:58:17 +08:00
int rightIndex = get < 1 > ( mit - > second ) ;
2022-07-21 21:32:11 +08:00
if ( rightIndex ! = - 1 )
{
2020-12-01 11:58:17 +08:00
rightIndex - = pKFi - > NLeft ;
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
2020-12-01 11:58:17 +08:00
cv : : KeyPoint kp = pKFi - > mvKeysRight [ rightIndex ] ;
obs < < kp . pt . x , kp . pt . y ;
ORB_SLAM3 : : EdgeSE3ProjectXYZToBody * e = new ORB_SLAM3 : : EdgeSE3ProjectXYZToBody ( ) ;
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ) ;
2020-12-01 11:58:17 +08:00
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKFi - > mvInvLevelSigma2 [ kp . octave ] ;
2022-07-21 21:32:11 +08:00
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2020-12-01 11:58:17 +08:00
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
2022-07-21 21:32:11 +08:00
Sophus : : SE3f Trl = pKFi - > GetRelativePoseTrl ( ) ;
2022-03-28 21:20:28 +08:00
e - > mTrl = g2o : : SE3Quat ( Trl . unit_quaternion ( ) . cast < double > ( ) , Trl . translation ( ) . cast < double > ( ) ) ;
2020-12-01 11:58:17 +08:00
e - > pCamera = pKFi - > mpCamera2 ;
optimizer . addEdge ( e ) ;
vpEdgesBody . push_back ( e ) ;
vpEdgeKFBody . push_back ( pKFi ) ;
vpMapPointEdgeBody . push_back ( pMP ) ;
nEdges + + ;
}
}
}
}
}
2022-03-28 21:20:28 +08:00
num_edges = nEdges ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
if ( * pbStopFlag )
2022-03-28 21:20:28 +08:00
return ;
2020-12-01 11:58:17 +08:00
optimizer . initializeOptimization ( ) ;
2022-03-28 21:20:28 +08:00
optimizer . optimize ( 10 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < pair < KeyFrame * , MapPoint * > > vToErase ;
vToErase . reserve ( vpEdgesMono . size ( ) + vpEdgesBody . size ( ) + vpEdgesStereo . size ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Check inlier observations
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZ * e = vpEdgesMono [ i ] ;
MapPoint * pMP = vpMapPointEdgeMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > 5.991 | | ! e - > isDepthPositive ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpEdgeKFMono [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesBody . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZToBody * e = vpEdgesBody [ i ] ;
MapPoint * pMP = vpMapPointEdgeBody [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > 5.991 | | ! e - > isDepthPositive ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpEdgeKFBody [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
g2o : : EdgeStereoSE3ProjectXYZ * e = vpEdgesStereo [ i ] ;
MapPoint * pMP = vpMapPointEdgeStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > 7.815 | | ! e - > isDepthPositive ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpEdgeKFStereo [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
2020-12-01 11:58:17 +08:00
}
}
// Get Map Mutex
2022-03-28 21:20:28 +08:00
unique_lock < mutex > lock ( pMap - > mMutexMapUpdate ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! vToErase . empty ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vToErase . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vToErase [ i ] . first ;
MapPoint * pMPi = vToErase [ i ] . second ;
2020-12-01 11:58:17 +08:00
pKFi - > EraseMapPointMatch ( pMPi ) ;
pMPi - > EraseObservation ( pKFi ) ;
}
}
// Recover optimized data
2022-07-21 21:32:11 +08:00
// Keyframes
for ( list < KeyFrame * > : : iterator lit = lLocalKeyFrames . begin ( ) , lend = lLocalKeyFrames . end ( ) ; lit ! = lend ; lit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = * lit ;
g2o : : VertexSE3Expmap * vSE3 = static_cast < g2o : : VertexSE3Expmap * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
2020-12-01 11:58:17 +08:00
g2o : : SE3Quat SE3quat = vSE3 - > estimate ( ) ;
2022-03-28 21:20:28 +08:00
Sophus : : SE3f Tiw ( SE3quat . rotation ( ) . cast < float > ( ) , SE3quat . translation ( ) . cast < float > ( ) ) ;
pKFi - > SetPose ( Tiw ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Points
for ( list < MapPoint * > : : iterator lit = lLocalMapPoints . begin ( ) , lend = lLocalMapPoints . end ( ) ; lit ! = lend ; lit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = * lit ;
g2o : : VertexSBAPointXYZ * vPoint = static_cast < g2o : : VertexSBAPointXYZ * > ( optimizer . vertex ( pMP - > mnId + maxKFid + 1 ) ) ;
2022-03-28 21:20:28 +08:00
pMP - > SetWorldPos ( vPoint - > estimate ( ) . cast < float > ( ) ) ;
2020-12-01 11:58:17 +08:00
pMP - > UpdateNormalAndDepth ( ) ;
}
2022-03-28 21:20:28 +08:00
pMap - > IncreaseChangeIndex ( ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
void Optimizer : : LocalInertialBA (
KeyFrame * pKF , bool * pbStopFlag , Map * pMap , int & num_fixedKF , int & num_OptKF ,
int & num_MPs , int & num_edges , bool bLarge , bool bRecInit )
{
Map * pCurrentMap = pKF - > GetMap ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int maxOpt = 10 ;
int opt_it = 10 ;
if ( bLarge )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
maxOpt = 25 ;
opt_it = 4 ;
}
const int Nd = std : : min ( ( int ) pCurrentMap - > KeyFramesInMap ( ) - 2 , maxOpt ) ;
const unsigned long maxKFid = pKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpOptimizableKFs ;
const vector < KeyFrame * > vpNeighsKFs = pKF - > GetVectorCovisibleKeyFrames ( ) ;
list < KeyFrame * > lpOptVisKFs ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpOptimizableKFs . reserve ( Nd ) ;
vpOptimizableKFs . push_back ( pKF ) ;
pKF - > mnBALocalForKF = pKF - > mnId ;
for ( int i = 1 ; i < Nd ; i + + )
{
if ( vpOptimizableKFs . back ( ) - > mPrevKF )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
vpOptimizableKFs . push_back ( vpOptimizableKFs . back ( ) - > mPrevKF ) ;
vpOptimizableKFs . back ( ) - > mnBALocalForKF = pKF - > mnId ;
2020-12-01 11:58:17 +08:00
}
else
2022-07-21 21:32:11 +08:00
break ;
2021-12-08 22:09:39 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int N = vpOptimizableKFs . size ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Optimizable points seen by temporal optimizable keyframes
list < MapPoint * > lLocalMapPoints ;
for ( int i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMPs = vpOptimizableKFs [ i ] - > GetMapPointMatches ( ) ;
for ( vector < MapPoint * > : : iterator vit = vpMPs . begin ( ) , vend = vpMPs . end ( ) ; vit ! = vend ; vit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = * vit ;
if ( pMP )
if ( ! pMP - > isBad ( ) )
if ( pMP - > mnBALocalForKF ! = pKF - > mnId )
{
lLocalMapPoints . push_back ( pMP ) ;
pMP - > mnBALocalForKF = pKF - > mnId ;
}
2021-12-08 22:09:39 +08:00
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Fixed Keyframe: First frame previous KF to optimization window)
list < KeyFrame * > lFixedKeyFrames ;
if ( vpOptimizableKFs . back ( ) - > mPrevKF )
2021-12-08 22:09:39 +08:00
{
2022-07-21 21:32:11 +08:00
lFixedKeyFrames . push_back ( vpOptimizableKFs . back ( ) - > mPrevKF ) ;
vpOptimizableKFs . back ( ) - > mPrevKF - > mnBAFixedForKF = pKF - > mnId ;
}
else
{
vpOptimizableKFs . back ( ) - > mnBALocalForKF = 0 ;
vpOptimizableKFs . back ( ) - > mnBAFixedForKF = pKF - > mnId ;
lFixedKeyFrames . push_back ( vpOptimizableKFs . back ( ) ) ;
vpOptimizableKFs . pop_back ( ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Optimizable visual KFs
const int maxCovKF = 0 ;
for ( int i = 0 , iend = vpNeighsKFs . size ( ) ; i < iend ; i + + )
{
if ( lpOptVisKFs . size ( ) > = maxCovKF )
break ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpNeighsKFs [ i ] ;
if ( pKFi - > mnBALocalForKF = = pKF - > mnId | | pKFi - > mnBAFixedForKF = = pKF - > mnId )
continue ;
pKFi - > mnBALocalForKF = pKF - > mnId ;
if ( ! pKFi - > isBad ( ) & & pKFi - > GetMap ( ) = = pCurrentMap )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
lpOptVisKFs . push_back ( pKFi ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMPs = pKFi - > GetMapPointMatches ( ) ;
for ( vector < MapPoint * > : : iterator vit = vpMPs . begin ( ) , vend = vpMPs . end ( ) ; vit ! = vend ; vit + + )
2021-12-08 22:09:39 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = * vit ;
if ( pMP )
if ( ! pMP - > isBad ( ) )
if ( pMP - > mnBALocalForKF ! = pKF - > mnId )
{
lLocalMapPoints . push_back ( pMP ) ;
pMP - > mnBALocalForKF = pKF - > mnId ;
}
2021-12-08 22:09:39 +08:00
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Fixed KFs which are not covisible optimizable
const int maxFixKF = 200 ;
for ( list < MapPoint * > : : iterator lit = lLocalMapPoints . begin ( ) , lend = lLocalMapPoints . end ( ) ; lit ! = lend ; lit + + )
{
map < KeyFrame * , tuple < int , int > > observations = ( * lit ) - > GetObservations ( ) ;
for ( map < KeyFrame * , tuple < int , int > > : : iterator mit = observations . begin ( ) , mend = observations . end ( ) ; mit ! = mend ; mit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = mit - > first ;
if ( pKFi - > mnBALocalForKF ! = pKF - > mnId & & pKFi - > mnBAFixedForKF ! = pKF - > mnId )
2021-12-08 22:09:39 +08:00
{
2022-07-21 21:32:11 +08:00
pKFi - > mnBAFixedForKF = pKF - > mnId ;
if ( ! pKFi - > isBad ( ) )
2021-12-08 22:09:39 +08:00
{
2022-07-21 21:32:11 +08:00
lFixedKeyFrames . push_back ( pKFi ) ;
break ;
2021-12-08 22:09:39 +08:00
}
}
}
2022-07-21 21:32:11 +08:00
if ( lFixedKeyFrames . size ( ) > = maxFixKF )
break ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
bool bNonFixed = ( lFixedKeyFrames . size ( ) = = 0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Setup optimizer
g2o : : SparseOptimizer optimizer ;
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bLarge )
{
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
solver - > setUserLambdaInit ( 1e-2 ) ; // to avoid iterating for finding optimal lambda
optimizer . setAlgorithm ( solver ) ;
}
else
{
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
solver - > setUserLambdaInit ( 1e0 ) ;
optimizer . setAlgorithm ( solver ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Set Local temporal KeyFrame vertices
N = vpOptimizableKFs . size ( ) ;
for ( int i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpOptimizableKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexPose * VP = new VertexPose ( pKFi ) ;
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( false ) ;
optimizer . addVertex ( VP ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
VV - > setFixed ( false ) ;
optimizer . addVertex ( VV ) ;
VertexGyroBias * VG = new VertexGyroBias ( pKFi ) ;
VG - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
VG - > setFixed ( false ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pKFi ) ;
VA - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
VA - > setFixed ( false ) ;
optimizer . addVertex ( VA ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
// Set Local visual KeyFrame vertices
for ( list < KeyFrame * > : : iterator it = lpOptVisKFs . begin ( ) , itEnd = lpOptVisKFs . end ( ) ; it ! = itEnd ; it + + )
{
KeyFrame * pKFi = * it ;
VertexPose * VP = new VertexPose ( pKFi ) ;
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( false ) ;
optimizer . addVertex ( VP ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Fixed KeyFrame vertices
for ( list < KeyFrame * > : : iterator lit = lFixedKeyFrames . begin ( ) , lend = lFixedKeyFrames . end ( ) ; lit ! = lend ; lit + + )
{
KeyFrame * pKFi = * lit ;
VertexPose * VP = new VertexPose ( pKFi ) ;
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( true ) ;
optimizer . addVertex ( VP ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu ) // This should be done only for keyframe just before temporal window
{
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
VV - > setFixed ( true ) ;
optimizer . addVertex ( VV ) ;
VertexGyroBias * VG = new VertexGyroBias ( pKFi ) ;
VG - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
VG - > setFixed ( true ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pKFi ) ;
VA - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
VA - > setFixed ( true ) ;
optimizer . addVertex ( VA ) ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Create intertial constraints
vector < EdgeInertial * > vei ( N , ( EdgeInertial * ) NULL ) ;
vector < EdgeGyroRW * > vegr ( N , ( EdgeGyroRW * ) NULL ) ;
vector < EdgeAccRW * > vear ( N , ( EdgeAccRW * ) NULL ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
for ( int i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpOptimizableKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > mPrevKF )
{
cout < < " NOT INERTIAL LINK TO PREVIOUS FRAME!!!! " < < endl ;
continue ;
}
if ( pKFi - > bImu & & pKFi - > mPrevKF - > bImu & & pKFi - > mpImuPreintegrated )
{
pKFi - > mpImuPreintegrated - > SetNewBias ( pKFi - > mPrevKF - > GetImuBias ( ) ) ;
g2o : : HyperGraph : : Vertex * VP1 = optimizer . vertex ( pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 1 ) ;
g2o : : HyperGraph : : Vertex * VG1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 2 ) ;
g2o : : HyperGraph : : Vertex * VA1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 3 ) ;
g2o : : HyperGraph : : Vertex * VP2 = optimizer . vertex ( pKFi - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
g2o : : HyperGraph : : Vertex * VG2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
g2o : : HyperGraph : : Vertex * VA2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
if ( ! VP1 | | ! VV1 | | ! VG1 | | ! VA1 | | ! VP2 | | ! VV2 | | ! VG2 | | ! VA2 )
{
cerr < < " Error " < < VP1 < < " , " < < VV1 < < " , " < < VG1 < < " , " < < VA1 < < " , " < < VP2 < < " , " < < VV2 < < " , " < < VG2 < < " , " < < VA2 < < endl ;
continue ;
}
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
vei [ i ] = new EdgeInertial ( pKFi - > mpImuPreintegrated ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vei [ i ] - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP1 ) ) ;
vei [ i ] - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV1 ) ) ;
vei [ i ] - > setVertex ( 2 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG1 ) ) ;
vei [ i ] - > setVertex ( 3 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA1 ) ) ;
vei [ i ] - > setVertex ( 4 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP2 ) ) ;
vei [ i ] - > setVertex ( 5 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV2 ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( i = = N - 1 | | bRecInit )
{
// All inertial residuals are included without robust cost function, but not that one linking the
// last optimizable keyframe inside of the local window and the first fixed keyframe out. The
// information matrix for this measurement is also downweighted. This is done to avoid accumulating
// error due to fixing variables.
g2o : : RobustKernelHuber * rki = new g2o : : RobustKernelHuber ;
vei [ i ] - > setRobustKernel ( rki ) ;
if ( i = = N - 1 )
vei [ i ] - > setInformation ( vei [ i ] - > information ( ) * 1e-2 ) ;
rki - > setDelta ( sqrt ( 16.92 ) ) ;
}
optimizer . addEdge ( vei [ i ] ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vegr [ i ] = new EdgeGyroRW ( ) ;
vegr [ i ] - > setVertex ( 0 , VG1 ) ;
vegr [ i ] - > setVertex ( 1 , VG2 ) ;
Eigen : : Matrix3d InfoG = pKFi - > mpImuPreintegrated - > C . block < 3 , 3 > ( 9 , 9 ) . cast < double > ( ) . inverse ( ) ;
vegr [ i ] - > setInformation ( InfoG ) ;
optimizer . addEdge ( vegr [ i ] ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vear [ i ] = new EdgeAccRW ( ) ;
vear [ i ] - > setVertex ( 0 , VA1 ) ;
vear [ i ] - > setVertex ( 1 , VA2 ) ;
Eigen : : Matrix3d InfoA = pKFi - > mpImuPreintegrated - > C . block < 3 , 3 > ( 12 , 12 ) . cast < double > ( ) . inverse ( ) ;
vear [ i ] - > setInformation ( InfoA ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( vear [ i ] ) ;
}
else
cout < < " ERROR building inertial edge " < < endl ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Set MapPoint vertices
const int nExpectedSize = ( N + lFixedKeyFrames . size ( ) ) * lLocalMapPoints . size ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Mono
vector < EdgeMono * > vpEdgesMono ;
vpEdgesMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFMono ;
vpEdgeKFMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeMono ;
vpMapPointEdgeMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Stereo
vector < EdgeStereo * > vpEdgesStereo ;
vpEdgesStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFStereo ;
vpEdgeKFStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeStereo ;
vpMapPointEdgeStereo . reserve ( nExpectedSize ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
const float thHuberMono = sqrt ( 5.991 ) ;
const float chi2Mono2 = 5.991 ;
const float thHuberStereo = sqrt ( 7.815 ) ;
const float chi2Stereo2 = 7.815 ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
const unsigned long iniMPid = maxKFid * 5 ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
map < int , int > mVisEdges ;
for ( int i = 0 ; i < N ; i + + )
{
KeyFrame * pKFi = vpOptimizableKFs [ i ] ;
mVisEdges [ pKFi - > mnId ] = 0 ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
for ( list < KeyFrame * > : : iterator lit = lFixedKeyFrames . begin ( ) , lend = lFixedKeyFrames . end ( ) ; lit ! = lend ; lit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
mVisEdges [ ( * lit ) - > mnId ] = 0 ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( list < MapPoint * > : : iterator lit = lLocalMapPoints . begin ( ) , lend = lLocalMapPoints . end ( ) ; lit ! = lend ; lit + + )
{
MapPoint * pMP = * lit ;
g2o : : VertexSBAPointXYZ * vPoint = new g2o : : VertexSBAPointXYZ ( ) ;
vPoint - > setEstimate ( pMP - > GetWorldPos ( ) . cast < double > ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
unsigned long id = pMP - > mnId + iniMPid + 1 ;
vPoint - > setId ( id ) ;
vPoint - > setMarginalized ( true ) ;
optimizer . addVertex ( vPoint ) ;
const map < KeyFrame * , tuple < int , int > > observations = pMP - > GetObservations ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Create visual constraints
for ( map < KeyFrame * , tuple < int , int > > : : const_iterator mit = observations . begin ( ) , mend = observations . end ( ) ; mit ! = mend ; mit + + )
{
KeyFrame * pKFi = mit - > first ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mnBALocalForKF ! = pKF - > mnId & & pKFi - > mnBAFixedForKF ! = pKF - > mnId )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > isBad ( ) & & pKFi - > GetMap ( ) = = pCurrentMap )
{
const int leftIndex = get < 0 > ( mit - > second ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
cv : : KeyPoint kpUn ;
2021-08-09 19:34:51 +08:00
2022-07-21 21:32:11 +08:00
// Monocular left observation
if ( leftIndex ! = - 1 & & pKFi - > mvuRight [ leftIndex ] < 0 )
{
mVisEdges [ pKFi - > mnId ] + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
kpUn = pKFi - > mvKeysUn [ leftIndex ] ;
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeMono * e = new EdgeMono ( 0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pKFi - > mpCamera - > uncertainty2 ( obs ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float & invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
vpEdgesMono . push_back ( e ) ;
vpEdgeKFMono . push_back ( pKFi ) ;
vpMapPointEdgeMono . push_back ( pMP ) ;
}
// Stereo-observation
else if ( leftIndex ! = - 1 ) // Stereo observation
{
kpUn = pKFi - > mvKeysUn [ leftIndex ] ;
mVisEdges [ pKFi - > mnId ] + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float kp_ur = pKFi - > mvuRight [ leftIndex ] ;
Eigen : : Matrix < double , 3 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeStereo * e = new EdgeStereo ( 0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pKFi - > mpCamera - > uncertainty2 ( obs . head ( 2 ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float & invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
e - > setInformation ( Eigen : : Matrix3d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberStereo ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
vpEdgesStereo . push_back ( e ) ;
vpEdgeKFStereo . push_back ( pKFi ) ;
vpMapPointEdgeStereo . push_back ( pMP ) ;
2022-03-28 21:20:28 +08:00
}
2022-07-21 21:32:11 +08:00
// Monocular right observation
if ( pKFi - > mpCamera2 )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
int rightIndex = get < 1 > ( mit - > second ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( rightIndex ! = - 1 )
{
rightIndex - = pKFi - > NLeft ;
mVisEdges [ pKFi - > mnId ] + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
cv : : KeyPoint kp = pKFi - > mvKeysRight [ rightIndex ] ;
obs < < kp . pt . x , kp . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeMono * e = new EdgeMono ( 1 ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Add here uncerteinty
const float unc2 = pKFi - > mpCamera - > uncertainty2 ( obs ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float & invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] / unc2 ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
vpEdgesMono . push_back ( e ) ;
vpEdgeKFMono . push_back ( pKFi ) ;
vpMapPointEdgeMono . push_back ( pMP ) ;
2022-03-28 21:20:28 +08:00
}
2020-12-01 11:58:17 +08:00
}
}
}
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// cout << "Total map points: " << lLocalMapPoints.size() << endl;
// TODO debug会报错先注释掉
for ( map < int , int > : : iterator mit = mVisEdges . begin ( ) , mend = mVisEdges . end ( ) ; mit ! = mend ; mit + + )
{
assert ( mit - > second > = 3 ) ;
2020-12-01 11:58:17 +08:00
}
optimizer . initializeOptimization ( ) ;
2022-07-21 21:32:11 +08:00
optimizer . computeActiveErrors ( ) ;
float err = optimizer . activeRobustChi2 ( ) ;
optimizer . optimize ( opt_it ) ; // Originally to 2
float err_end = optimizer . activeRobustChi2 ( ) ;
if ( pbStopFlag )
optimizer . setForceStopFlag ( pbStopFlag ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < pair < KeyFrame * , MapPoint * > > vToErase ;
vToErase . reserve ( vpEdgesMono . size ( ) + vpEdgesStereo . size ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Check inlier observations
// Mono
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
EdgeMono * e = vpEdgesMono [ i ] ;
MapPoint * pMP = vpMapPointEdgeMono [ i ] ;
bool bClose = pMP - > mTrackDepth < 10.f ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ( e - > chi2 ( ) > chi2Mono2 & & ! bClose ) | | ( e - > chi2 ( ) > 1.5f * chi2Mono2 & & bClose ) | | ! e - > isDepthPositive ( ) )
{
KeyFrame * pKFi = vpEdgeKFMono [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Stereo
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
EdgeStereo * e = vpEdgesStereo [ i ] ;
MapPoint * pMP = vpMapPointEdgeStereo [ i ] ;
if ( pMP - > isBad ( ) )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > chi2Stereo2 )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpEdgeKFStereo [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
2022-03-28 21:20:28 +08:00
}
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Get Map Mutex and erase outliers
unique_lock < mutex > lock ( pMap - > mMutexMapUpdate ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// TODO: Some convergence problems have been detected here
if ( ( 2 * err < err_end | | isnan ( err ) | | isnan ( err_end ) ) & & ! bLarge ) // bGN)
{
cout < < " FAIL LOCAL-INERTIAL BA!!!! " < < endl ;
return ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! vToErase . empty ( ) )
{
for ( size_t i = 0 ; i < vToErase . size ( ) ; i + + )
{
KeyFrame * pKFi = vToErase [ i ] . first ;
MapPoint * pMPi = vToErase [ i ] . second ;
pKFi - > EraseMapPointMatch ( pMPi ) ;
pMPi - > EraseObservation ( pKFi ) ;
2022-03-28 21:20:28 +08:00
}
2022-07-21 21:32:11 +08:00
}
for ( list < KeyFrame * > : : iterator lit = lFixedKeyFrames . begin ( ) , lend = lFixedKeyFrames . end ( ) ; lit ! = lend ; lit + + )
( * lit ) - > mnBAFixedForKF = 0 ;
// Recover optimized data
// Local temporal Keyframes
N = vpOptimizableKFs . size ( ) ;
for ( int i = 0 ; i < N ; i + + )
{
KeyFrame * pKFi = vpOptimizableKFs [ i ] ;
VertexPose * VP = static_cast < VertexPose * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
Sophus : : SE3f Tcw ( VP - > estimate ( ) . Rcw [ 0 ] . cast < float > ( ) , VP - > estimate ( ) . tcw [ 0 ] . cast < float > ( ) ) ;
pKFi - > SetPose ( Tcw ) ;
pKFi - > mnBALocalForKF = 0 ;
if ( pKFi - > bImu )
2021-12-08 22:09:39 +08:00
{
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = static_cast < VertexVelocity * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ) ;
pKFi - > SetVelocity ( VV - > estimate ( ) . cast < float > ( ) ) ;
VertexGyroBias * VG = static_cast < VertexGyroBias * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ) ;
VertexAccBias * VA = static_cast < VertexAccBias * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ) ;
Vector6d b ;
b < < VG - > estimate ( ) , VA - > estimate ( ) ;
pKFi - > SetNewBias ( IMU : : Bias ( b [ 3 ] , b [ 4 ] , b [ 5 ] , b [ 0 ] , b [ 1 ] , b [ 2 ] ) ) ;
2021-12-08 22:09:39 +08:00
}
2022-07-21 21:32:11 +08:00
}
// Local visual KeyFrame
for ( list < KeyFrame * > : : iterator it = lpOptVisKFs . begin ( ) , itEnd = lpOptVisKFs . end ( ) ; it ! = itEnd ; it + + )
{
KeyFrame * pKFi = * it ;
VertexPose * VP = static_cast < VertexPose * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
Sophus : : SE3f Tcw ( VP - > estimate ( ) . Rcw [ 0 ] . cast < float > ( ) , VP - > estimate ( ) . tcw [ 0 ] . cast < float > ( ) ) ;
pKFi - > SetPose ( Tcw ) ;
pKFi - > mnBALocalForKF = 0 ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Points
for ( list < MapPoint * > : : iterator lit = lLocalMapPoints . begin ( ) , lend = lLocalMapPoints . end ( ) ; lit ! = lend ; lit + + )
{
MapPoint * pMP = * lit ;
g2o : : VertexSBAPointXYZ * vPoint = static_cast < g2o : : VertexSBAPointXYZ * > ( optimizer . vertex ( pMP - > mnId + iniMPid + 1 ) ) ;
pMP - > SetWorldPos ( vPoint - > estimate ( ) . cast < float > ( ) ) ;
pMP - > UpdateNormalAndDepth ( ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
pMap - > IncreaseChangeIndex ( ) ;
}
/**************************************以下为全局优化**************************************************************/
void Optimizer : : GlobalBundleAdjustemnt (
Map * pMap , int nIterations , bool * pbStopFlag , const unsigned long nLoopKF , const bool bRobust )
{
vector < KeyFrame * > vpKFs = pMap - > GetAllKeyFrames ( ) ;
vector < MapPoint * > vpMP = pMap - > GetAllMapPoints ( ) ;
BundleAdjustment ( vpKFs , vpMP , nIterations , pbStopFlag , nLoopKF , bRobust ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
void Optimizer : : BundleAdjustment (
const vector < KeyFrame * > & vpKFs , const vector < MapPoint * > & vpMP ,
int nIterations , bool * pbStopFlag , const unsigned long nLoopKF , const bool bRobust )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
vector < bool > vbNotIncludedMP ;
vbNotIncludedMP . resize ( vpMP . size ( ) ) ;
Map * pMap = vpKFs [ 0 ] - > GetMap ( ) ;
2020-12-01 11:58:17 +08:00
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolver_6_3 : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolver_6_3 : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolver_6_3 * solver_ptr = new g2o : : BlockSolver_6_3 ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2022-03-28 21:20:28 +08:00
optimizer . setAlgorithm ( solver ) ;
2022-07-21 21:32:11 +08:00
optimizer . setVerbose ( false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
optimizer . setForceStopFlag ( pbStopFlag ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
long unsigned int maxKFid = 0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nExpectedSize = ( vpKFs . size ( ) ) * vpMP . size ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < ORB_SLAM3 : : EdgeSE3ProjectXYZ * > vpEdgesMono ;
vpEdgesMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < ORB_SLAM3 : : EdgeSE3ProjectXYZToBody * > vpEdgesBody ;
vpEdgesBody . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFMono ;
vpEdgeKFMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFBody ;
vpEdgeKFBody . reserve ( nExpectedSize ) ;
vector < MapPoint * > vpMapPointEdgeMono ;
vpMapPointEdgeMono . reserve ( nExpectedSize ) ;
vector < MapPoint * > vpMapPointEdgeBody ;
vpMapPointEdgeBody . reserve ( nExpectedSize ) ;
vector < g2o : : EdgeStereoSE3ProjectXYZ * > vpEdgesStereo ;
vpEdgesStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFStereo ;
vpEdgeKFStereo . reserve ( nExpectedSize ) ;
vector < MapPoint * > vpMapPointEdgeStereo ;
vpMapPointEdgeStereo . reserve ( nExpectedSize ) ;
// Set KeyFrame vertices
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = vpKFs [ i ] ;
if ( pKF - > isBad ( ) )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
g2o : : VertexSE3Expmap * vSE3 = new g2o : : VertexSE3Expmap ( ) ;
Sophus : : SE3 < float > Tcw = pKF - > GetPose ( ) ;
vSE3 - > setEstimate ( g2o : : SE3Quat ( Tcw . unit_quaternion ( ) . cast < double > ( ) , Tcw . translation ( ) . cast < double > ( ) ) ) ;
vSE3 - > setId ( pKF - > mnId ) ;
vSE3 - > setFixed ( pKF - > mnId = = pMap - > GetInitKFid ( ) ) ;
optimizer . addVertex ( vSE3 ) ;
if ( pKF - > mnId > maxKFid )
maxKFid = pKF - > mnId ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float thHuber2D = sqrt ( 5.99 ) ;
const float thHuber3D = sqrt ( 7.815 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set MapPoint vertices
for ( size_t i = 0 ; i < vpMP . size ( ) ; i + + )
{
MapPoint * pMP = vpMP [ i ] ;
if ( pMP - > isBad ( ) )
continue ;
g2o : : VertexSBAPointXYZ * vPoint = new g2o : : VertexSBAPointXYZ ( ) ;
vPoint - > setEstimate ( pMP - > GetWorldPos ( ) . cast < double > ( ) ) ;
const int id = pMP - > mnId + maxKFid + 1 ;
vPoint - > setId ( id ) ;
vPoint - > setMarginalized ( true ) ;
optimizer . addVertex ( vPoint ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const map < KeyFrame * , tuple < int , int > > observations = pMP - > GetObservations ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int nEdges = 0 ;
// SET EDGES
for ( map < KeyFrame * , tuple < int , int > > : : const_iterator mit = observations . begin ( ) ; mit ! = observations . end ( ) ; mit + + )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = mit - > first ;
if ( pKF - > isBad ( ) | | pKF - > mnId > maxKFid )
2022-03-28 21:20:28 +08:00
continue ;
2022-07-21 21:32:11 +08:00
if ( optimizer . vertex ( id ) = = NULL | | optimizer . vertex ( pKF - > mnId ) = = NULL )
continue ;
nEdges + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int leftIndex = get < 0 > ( mit - > second ) ;
if ( leftIndex ! = - 1 & & pKF - > mvuRight [ get < 0 > ( mit - > second ) ] < 0 )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
const cv : : KeyPoint & kpUn = pKF - > mvKeysUn [ leftIndex ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZ * e = new ORB_SLAM3 : : EdgeSE3ProjectXYZ ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKF - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKF - > mvInvLevelSigma2 [ kpUn . octave ] ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bRobust )
{
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuber2D ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > pCamera = pKF - > mpCamera ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpEdgesMono . push_back ( e ) ;
vpEdgeKFMono . push_back ( pKF ) ;
vpMapPointEdgeMono . push_back ( pMP ) ;
}
else if ( leftIndex ! = - 1 & & pKF - > mvuRight [ leftIndex ] > = 0 ) // Stereo observation
{
const cv : : KeyPoint & kpUn = pKF - > mvKeysUn [ leftIndex ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 3 , 1 > obs ;
const float kp_ur = pKF - > mvuRight [ get < 0 > ( mit - > second ) ] ;
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : EdgeStereoSE3ProjectXYZ * e = new g2o : : EdgeStereoSE3ProjectXYZ ( ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKF - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKF - > mvInvLevelSigma2 [ kpUn . octave ] ;
Eigen : : Matrix3d Info = Eigen : : Matrix3d : : Identity ( ) * invSigma2 ;
e - > setInformation ( Info ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bRobust )
{
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuber3D ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > fx = pKF - > fx ;
e - > fy = pKF - > fy ;
e - > cx = pKF - > cx ;
e - > cy = pKF - > cy ;
e - > bf = pKF - > mbf ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpEdgesStereo . push_back ( e ) ;
vpEdgeKFStereo . push_back ( pKF ) ;
vpMapPointEdgeStereo . push_back ( pMP ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKF - > mpCamera2 )
{
int rightIndex = get < 1 > ( mit - > second ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( rightIndex ! = - 1 & & rightIndex < pKF - > mvKeysRight . size ( ) )
{
rightIndex - = pKF - > NLeft ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
cv : : KeyPoint kp = pKF - > mvKeysRight [ rightIndex ] ;
obs < < kp . pt . x , kp . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZToBody * e = new ORB_SLAM3 : : EdgeSE3ProjectXYZToBody ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKF - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKF - > mvInvLevelSigma2 [ kp . octave ] ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuber2D ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3f Trl = pKF - > GetRelativePoseTrl ( ) ;
e - > mTrl = g2o : : SE3Quat ( Trl . unit_quaternion ( ) . cast < double > ( ) , Trl . translation ( ) . cast < double > ( ) ) ;
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
e - > pCamera = pKF - > mpCamera2 ;
optimizer . addEdge ( e ) ;
vpEdgesBody . push_back ( e ) ;
vpEdgeKFBody . push_back ( pKF ) ;
vpMapPointEdgeBody . push_back ( pMP ) ;
}
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
if ( nEdges = = 0 )
{
optimizer . removeVertex ( vPoint ) ;
vbNotIncludedMP [ i ] = true ;
}
else
{
vbNotIncludedMP [ i ] = false ;
}
2022-03-28 21:20:28 +08:00
}
2021-08-09 19:34:51 +08:00
2022-07-21 21:32:11 +08:00
// Optimize!
optimizer . setVerbose ( false ) ;
2022-03-28 21:20:28 +08:00
optimizer . initializeOptimization ( ) ;
2022-07-21 21:32:11 +08:00
optimizer . optimize ( nIterations ) ;
Verbose : : PrintMess ( " BA: End of the optimization " , Verbose : : VERBOSITY_NORMAL ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Recover optimized data
// Keyframes
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = vpKFs [ i ] ;
if ( pKF - > isBad ( ) )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
g2o : : VertexSE3Expmap * vSE3 = static_cast < g2o : : VertexSE3Expmap * > ( optimizer . vertex ( pKF - > mnId ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : SE3Quat SE3quat = vSE3 - > estimate ( ) ;
if ( nLoopKF = = pMap - > GetOriginKF ( ) - > mnId )
{
pKF - > SetPose ( Sophus : : SE3f ( SE3quat . rotation ( ) . cast < float > ( ) , SE3quat . translation ( ) . cast < float > ( ) ) ) ;
2022-03-28 21:20:28 +08:00
}
2022-07-21 21:32:11 +08:00
else
{
pKF - > mTcwGBA = Sophus : : SE3d ( SE3quat . rotation ( ) , SE3quat . translation ( ) ) . cast < float > ( ) ;
pKF - > mnBAGlobalForKF = nLoopKF ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3f mTwc = pKF - > GetPoseInverse ( ) ;
Sophus : : SE3f mTcGBA_c = pKF - > mTcwGBA * mTwc ;
Eigen : : Vector3f vector_dist = mTcGBA_c . translation ( ) ;
double dist = vector_dist . norm ( ) ;
if ( dist > 1 )
{
int numMonoBadPoints = 0 , numMonoOptPoints = 0 ;
int numStereoBadPoints = 0 , numStereoOptPoints = 0 ;
vector < MapPoint * > vpMonoMPsOpt , vpStereoMPsOpt ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i2 = 0 , iend = vpEdgesMono . size ( ) ; i2 < iend ; i2 + + )
{
ORB_SLAM3 : : EdgeSE3ProjectXYZ * e = vpEdgesMono [ i2 ] ;
MapPoint * pMP = vpMapPointEdgeMono [ i2 ] ;
KeyFrame * pKFedge = vpEdgeKFMono [ i2 ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKF ! = pKFedge )
{
continue ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
if ( e - > chi2 ( ) > 5.991 | | ! e - > isDepthPositive ( ) )
{
numMonoBadPoints + + ;
}
else
{
numMonoOptPoints + + ;
vpMonoMPsOpt . push_back ( pMP ) ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i2 = 0 , iend = vpEdgesStereo . size ( ) ; i2 < iend ; i2 + + )
{
g2o : : EdgeStereoSE3ProjectXYZ * e = vpEdgesStereo [ i2 ] ;
MapPoint * pMP = vpMapPointEdgeStereo [ i2 ] ;
KeyFrame * pKFedge = vpEdgeKFMono [ i2 ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKF ! = pKFedge )
{
continue ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > 7.815 | | ! e - > isDepthPositive ( ) )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
numStereoBadPoints + + ;
}
else
{
numStereoOptPoints + + ;
vpStereoMPsOpt . push_back ( pMP ) ;
2022-03-28 21:20:28 +08:00
}
2022-07-21 21:32:11 +08:00
}
}
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
// Points
for ( size_t i = 0 ; i < vpMP . size ( ) ; i + + )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
if ( vbNotIncludedMP [ i ] )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
MapPoint * pMP = vpMP [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
g2o : : VertexSBAPointXYZ * vPoint = static_cast < g2o : : VertexSBAPointXYZ * > ( optimizer . vertex ( pMP - > mnId + maxKFid + 1 ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( nLoopKF = = pMap - > GetOriginKF ( ) - > mnId )
{
pMP - > SetWorldPos ( vPoint - > estimate ( ) . cast < float > ( ) ) ;
pMP - > UpdateNormalAndDepth ( ) ;
2021-12-08 22:09:39 +08:00
}
2022-07-21 21:32:11 +08:00
else
2021-12-08 22:09:39 +08:00
{
2022-07-21 21:32:11 +08:00
pMP - > mPosGBA = vPoint - > estimate ( ) . cast < float > ( ) ;
pMP - > mnBAGlobalForKF = nLoopKF ;
2021-12-08 22:09:39 +08:00
}
2022-03-28 21:20:28 +08:00
}
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
void Optimizer : : FullInertialBA (
Map * pMap , int its , const bool bFixLocal , const long unsigned int nLoopId , bool * pbStopFlag ,
bool bInit , float priorG , float priorA , Eigen : : VectorXd * vSingVal , bool * bHess )
{
long unsigned int maxKFid = pMap - > GetMaxKFid ( ) ;
const vector < KeyFrame * > vpKFs = pMap - > GetAllKeyFrames ( ) ;
const vector < MapPoint * > vpMPs = pMap - > GetAllMapPoints ( ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Setup optimizer
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
2022-03-28 21:20:28 +08:00
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
solver - > setUserLambdaInit ( 1e-5 ) ;
optimizer . setAlgorithm ( solver ) ;
optimizer . setVerbose ( false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
optimizer . setForceStopFlag ( pbStopFlag ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int nNonFixed = 0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set KeyFrame vertices
KeyFrame * pIncKF ;
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
{
KeyFrame * pKFi = vpKFs [ i ] ;
if ( pKFi - > mnId > maxKFid )
continue ;
VertexPose * VP = new VertexPose ( pKFi ) ;
2022-03-28 21:20:28 +08:00
VP - > setId ( pKFi - > mnId ) ;
2022-07-21 21:32:11 +08:00
pIncKF = pKFi ;
bool bFixed = false ;
if ( bFixLocal )
{
bFixed = ( pKFi - > mnBALocalForKF > = ( maxKFid - 1 ) ) | | ( pKFi - > mnBAFixedForKF > = ( maxKFid - 1 ) ) ;
if ( ! bFixed )
nNonFixed + + ;
VP - > setFixed ( bFixed ) ;
}
2022-03-28 21:20:28 +08:00
optimizer . addVertex ( VP ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
VV - > setFixed ( bFixed ) ;
2022-03-28 21:20:28 +08:00
optimizer . addVertex ( VV ) ;
2022-07-21 21:32:11 +08:00
if ( ! bInit )
{
VertexGyroBias * VG = new VertexGyroBias ( pKFi ) ;
VG - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
VG - > setFixed ( bFixed ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pKFi ) ;
VA - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
VA - > setFixed ( bFixed ) ;
optimizer . addVertex ( VA ) ;
}
2020-12-01 11:58:17 +08:00
}
2021-12-08 22:09:39 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bInit )
2021-12-08 22:09:39 +08:00
{
2022-07-21 21:32:11 +08:00
VertexGyroBias * VG = new VertexGyroBias ( pIncKF ) ;
VG - > setId ( 4 * maxKFid + 2 ) ;
VG - > setFixed ( false ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pIncKF ) ;
VA - > setId ( 4 * maxKFid + 3 ) ;
VA - > setFixed ( false ) ;
optimizer . addVertex ( VA ) ;
2022-03-28 21:20:28 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bFixLocal )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
if ( nNonFixed < 3 )
return ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// IMU links
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > mPrevKF )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " NOT INERTIAL LINK TO PREVIOUS FRAME! " , Verbose : : VERBOSITY_NORMAL ) ;
2020-12-01 11:58:17 +08:00
continue ;
2021-12-08 22:09:39 +08:00
}
2022-07-21 21:32:11 +08:00
if ( pKFi - > mPrevKF & & pKFi - > mnId < = maxKFid )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pKFi - > isBad ( ) | | pKFi - > mPrevKF - > mnId > maxKFid )
2021-12-08 22:09:39 +08:00
continue ;
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu & & pKFi - > mPrevKF - > bImu )
2021-12-08 22:09:39 +08:00
{
2022-07-21 21:32:11 +08:00
pKFi - > mpImuPreintegrated - > SetNewBias ( pKFi - > mPrevKF - > GetImuBias ( ) ) ;
g2o : : HyperGraph : : Vertex * VP1 = optimizer . vertex ( pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : HyperGraph : : Vertex * VG1 ;
g2o : : HyperGraph : : Vertex * VA1 ;
g2o : : HyperGraph : : Vertex * VG2 ;
g2o : : HyperGraph : : Vertex * VA2 ;
if ( ! bInit )
{
VG1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 2 ) ;
VA1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 3 ) ;
VG2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
VA2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
}
else
{
VG1 = optimizer . vertex ( 4 * maxKFid + 2 ) ;
VA1 = optimizer . vertex ( 4 * maxKFid + 3 ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : HyperGraph : : Vertex * VP2 = optimizer . vertex ( pKFi - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! bInit )
{
if ( ! VP1 | | ! VV1 | | ! VG1 | | ! VA1 | | ! VP2 | | ! VV2 | | ! VG2 | | ! VA2 )
{
cout < < " Error " < < VP1 < < " , " < < VV1 < < " , " < < VG1 < < " , " < < VA1 < < " , " < < VP2 < < " , " < < VV2 < < " , " < < VG2 < < " , " < < VA2 < < endl ;
continue ;
}
}
else
{
if ( ! VP1 | | ! VV1 | | ! VG1 | | ! VA1 | | ! VP2 | | ! VV2 )
{
cout < < " Error " < < VP1 < < " , " < < VV1 < < " , " < < VG1 < < " , " < < VA1 < < " , " < < VP2 < < " , " < < VV2 < < endl ;
continue ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeInertial * ei = new EdgeInertial ( pKFi - > mpImuPreintegrated ) ;
ei - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP1 ) ) ;
ei - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV1 ) ) ;
ei - > setVertex ( 2 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG1 ) ) ;
ei - > setVertex ( 3 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA1 ) ) ;
ei - > setVertex ( 4 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP2 ) ) ;
ei - > setVertex ( 5 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV2 ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rki = new g2o : : RobustKernelHuber ;
ei - > setRobustKernel ( rki ) ;
rki - > setDelta ( sqrt ( 16.92 ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( ei ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! bInit )
{
EdgeGyroRW * egr = new EdgeGyroRW ( ) ;
egr - > setVertex ( 0 , VG1 ) ;
egr - > setVertex ( 1 , VG2 ) ;
Eigen : : Matrix3d InfoG = pKFi - > mpImuPreintegrated - > C . block < 3 , 3 > ( 9 , 9 ) . cast < double > ( ) . inverse ( ) ;
egr - > setInformation ( InfoG ) ;
egr - > computeError ( ) ;
optimizer . addEdge ( egr ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeAccRW * ear = new EdgeAccRW ( ) ;
ear - > setVertex ( 0 , VA1 ) ;
ear - > setVertex ( 1 , VA2 ) ;
Eigen : : Matrix3d InfoA = pKFi - > mpImuPreintegrated - > C . block < 3 , 3 > ( 12 , 12 ) . cast < double > ( ) . inverse ( ) ;
ear - > setInformation ( InfoA ) ;
ear - > computeError ( ) ;
optimizer . addEdge ( ear ) ;
}
}
else
cout < < pKFi - > mnId < < " or " < < pKFi - > mPrevKF - > mnId < < " no imu " < < endl ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bInit )
{
g2o : : HyperGraph : : Vertex * VG = optimizer . vertex ( 4 * maxKFid + 2 ) ;
g2o : : HyperGraph : : Vertex * VA = optimizer . vertex ( 4 * maxKFid + 3 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Add prior to comon biases
Eigen : : Vector3f bprior ;
bprior . setZero ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgePriorAcc * epa = new EdgePriorAcc ( bprior ) ;
epa - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA ) ) ;
double infoPriorA = priorA ; //
epa - > setInformation ( infoPriorA * Eigen : : Matrix3d : : Identity ( ) ) ;
optimizer . addEdge ( epa ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgePriorGyro * epg = new EdgePriorGyro ( bprior ) ;
epg - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG ) ) ;
double infoPriorG = priorG ; //
epg - > setInformation ( infoPriorG * Eigen : : Matrix3d : : Identity ( ) ) ;
optimizer . addEdge ( epg ) ;
}
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
const float thHuberMono = sqrt ( 5.991 ) ;
const float thHuberStereo = sqrt ( 7.815 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const unsigned long iniMPid = maxKFid * 5 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < bool > vbNotIncludedMP ( vpMPs . size ( ) , false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vpMPs . size ( ) ; i + + )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = vpMPs [ i ] ;
g2o : : VertexSBAPointXYZ * vPoint = new g2o : : VertexSBAPointXYZ ( ) ;
2022-03-28 21:20:28 +08:00
vPoint - > setEstimate ( pMP - > GetWorldPos ( ) . cast < double > ( ) ) ;
2022-07-21 21:32:11 +08:00
unsigned long id = pMP - > mnId + iniMPid + 1 ;
2022-03-28 21:20:28 +08:00
vPoint - > setId ( id ) ;
vPoint - > setMarginalized ( true ) ;
optimizer . addVertex ( vPoint ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const map < KeyFrame * , tuple < int , int > > observations = pMP - > GetObservations ( ) ;
bool bAllFixed = true ;
// Set edges
for ( map < KeyFrame * , tuple < int , int > > : : const_iterator mit = observations . begin ( ) , mend = observations . end ( ) ; mit ! = mend ; mit + + )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = mit - > first ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mnId > maxKFid )
2022-03-28 21:20:28 +08:00
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > isBad ( ) )
2022-03-28 21:20:28 +08:00
{
const int leftIndex = get < 0 > ( mit - > second ) ;
cv : : KeyPoint kpUn ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( leftIndex ! = - 1 & & pKFi - > mvuRight [ get < 0 > ( mit - > second ) ] < 0 ) // Monocular observation
2022-03-28 21:20:28 +08:00
{
kpUn = pKFi - > mvKeysUn [ leftIndex ] ;
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
2022-03-28 21:20:28 +08:00
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeMono * e = new EdgeMono ( 0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizableGraph : : Vertex * VP = dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
if ( bAllFixed )
if ( ! VP - > fixed ( ) )
bAllFixed = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , VP ) ;
e - > setMeasurement ( obs ) ;
const float invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2022-03-28 21:20:28 +08:00
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
optimizer . addEdge ( e ) ;
}
2022-07-21 21:32:11 +08:00
else if ( leftIndex ! = - 1 & & pKFi - > mvuRight [ leftIndex ] > = 0 ) // stereo observation
2022-03-28 21:20:28 +08:00
{
kpUn = pKFi - > mvKeysUn [ leftIndex ] ;
const float kp_ur = pKFi - > mvuRight [ leftIndex ] ;
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 3 , 1 > obs ;
2022-03-28 21:20:28 +08:00
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeStereo * e = new EdgeStereo ( 0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizableGraph : : Vertex * VP = dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
if ( bAllFixed )
if ( ! VP - > fixed ( ) )
bAllFixed = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , VP ) ;
e - > setMeasurement ( obs ) ;
const float invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setInformation ( Eigen : : Matrix3d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2022-03-28 21:20:28 +08:00
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberStereo ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
optimizer . addEdge ( e ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mpCamera2 )
{ // Monocular right observation
2022-03-28 21:20:28 +08:00
int rightIndex = get < 1 > ( mit - > second ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( rightIndex ! = - 1 & & rightIndex < pKFi - > mvKeysRight . size ( ) )
{
2022-03-28 21:20:28 +08:00
rightIndex - = pKFi - > NLeft ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 2 , 1 > obs ;
kpUn = pKFi - > mvKeysRight [ rightIndex ] ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeMono * e = new EdgeMono ( 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizableGraph : : Vertex * VP = dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
if ( bAllFixed )
if ( ! VP - > fixed ( ) )
bAllFixed = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , VP ) ;
e - > setMeasurement ( obs ) ;
const float invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2022-03-28 21:20:28 +08:00
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
optimizer . addEdge ( e ) ;
}
2021-12-08 22:09:39 +08:00
}
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( bAllFixed )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
optimizer . removeVertex ( vPoint ) ;
vbNotIncludedMP [ i ] = true ;
2020-12-01 11:58:17 +08:00
}
2021-12-08 22:09:39 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
if ( * pbStopFlag )
return ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . initializeOptimization ( ) ;
optimizer . optimize ( its ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Recover optimized data
// Keyframes
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
{
KeyFrame * pKFi = vpKFs [ i ] ;
if ( pKFi - > mnId > maxKFid )
2021-12-08 22:09:39 +08:00
continue ;
2022-07-21 21:32:11 +08:00
VertexPose * VP = static_cast < VertexPose * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
if ( nLoopId = = 0 )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
Sophus : : SE3f Tcw ( VP - > estimate ( ) . Rcw [ 0 ] . cast < float > ( ) , VP - > estimate ( ) . tcw [ 0 ] . cast < float > ( ) ) ;
pKFi - > SetPose ( Tcw ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
else
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
pKFi - > mTcwGBA = Sophus : : SE3f ( VP - > estimate ( ) . Rcw [ 0 ] . cast < float > ( ) , VP - > estimate ( ) . tcw [ 0 ] . cast < float > ( ) ) ;
pKFi - > mnBAGlobalForKF = nLoopId ;
2022-03-28 21:20:28 +08:00
}
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = static_cast < VertexVelocity * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ) ;
if ( nLoopId = = 0 )
{
pKFi - > SetVelocity ( VV - > estimate ( ) . cast < float > ( ) ) ;
}
else
{
pKFi - > mVwbGBA = VV - > estimate ( ) . cast < float > ( ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexGyroBias * VG ;
VertexAccBias * VA ;
if ( ! bInit )
{
VG = static_cast < VertexGyroBias * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ) ;
VA = static_cast < VertexAccBias * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ) ;
}
else
{
VG = static_cast < VertexGyroBias * > ( optimizer . vertex ( 4 * maxKFid + 2 ) ) ;
VA = static_cast < VertexAccBias * > ( optimizer . vertex ( 4 * maxKFid + 3 ) ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Vector6d vb ;
vb < < VG - > estimate ( ) , VA - > estimate ( ) ;
IMU : : Bias b ( vb [ 3 ] , vb [ 4 ] , vb [ 5 ] , vb [ 0 ] , vb [ 1 ] , vb [ 2 ] ) ;
if ( nLoopId = = 0 )
{
pKFi - > SetNewBias ( b ) ;
}
else
{
pKFi - > mBiasGBA = b ;
}
}
2021-12-08 22:09:39 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Points
for ( size_t i = 0 ; i < vpMPs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( vbNotIncludedMP [ i ] )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
MapPoint * pMP = vpMPs [ i ] ;
g2o : : VertexSBAPointXYZ * vPoint = static_cast < g2o : : VertexSBAPointXYZ * > ( optimizer . vertex ( pMP - > mnId + iniMPid + 1 ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( nLoopId = = 0 )
{
pMP - > SetWorldPos ( vPoint - > estimate ( ) . cast < float > ( ) ) ;
pMP - > UpdateNormalAndDepth ( ) ;
}
else
{
pMP - > mPosGBA = vPoint - > estimate ( ) . cast < float > ( ) ;
pMP - > mnBAGlobalForKF = nLoopId ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
pMap - > IncreaseChangeIndex ( ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
/**************************************以下为尺度与重力优化**************************************************************/
void Optimizer : : InertialOptimization (
Map * pMap , Eigen : : Matrix3d & Rwg , double & scale , Eigen : : Vector3d & bg , Eigen : : Vector3d & ba , bool bMono ,
Eigen : : MatrixXd & covInertial , bool bFixedVel , bool bGauss , float priorG , float priorA )
2020-12-01 11:58:17 +08:00
{
2022-03-28 21:20:28 +08:00
Verbose : : PrintMess ( " inertial optimization " , Verbose : : VERBOSITY_NORMAL ) ;
2021-08-09 19:34:51 +08:00
int its = 200 ;
2022-03-28 21:20:28 +08:00
long unsigned int maxKFid = pMap - > GetMaxKFid ( ) ;
2022-07-21 21:32:11 +08:00
const vector < KeyFrame * > vpKFs = pMap - > GetAllKeyFrames ( ) ;
2020-12-01 11:58:17 +08:00
// Setup optimizer
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( priorG ! = 0.f )
2022-03-28 21:20:28 +08:00
solver - > setUserLambdaInit ( 1e3 ) ;
2020-12-01 11:58:17 +08:00
optimizer . setAlgorithm ( solver ) ;
// Set KeyFrame vertices (fixed poses and optimizable velocities)
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
if ( pKFi - > mnId > maxKFid )
2022-03-28 21:20:28 +08:00
continue ;
2022-07-21 21:32:11 +08:00
VertexPose * VP = new VertexPose ( pKFi ) ;
2020-12-01 11:58:17 +08:00
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( true ) ;
optimizer . addVertex ( VP ) ;
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + ( pKFi - > mnId ) + 1 ) ;
2022-03-28 21:20:28 +08:00
if ( bFixedVel )
VV - > setFixed ( true ) ;
else
2021-12-08 22:09:39 +08:00
VV - > setFixed ( false ) ;
2020-12-01 11:58:17 +08:00
optimizer . addVertex ( VV ) ;
}
// Biases
2022-07-21 21:32:11 +08:00
VertexGyroBias * VG = new VertexGyroBias ( vpKFs . front ( ) ) ;
VG - > setId ( maxKFid * 2 + 2 ) ;
2022-03-28 21:20:28 +08:00
if ( bFixedVel )
VG - > setFixed ( true ) ;
else
VG - > setFixed ( false ) ;
2020-12-01 11:58:17 +08:00
optimizer . addVertex ( VG ) ;
2022-07-21 21:32:11 +08:00
VertexAccBias * VA = new VertexAccBias ( vpKFs . front ( ) ) ;
VA - > setId ( maxKFid * 2 + 3 ) ;
2022-03-28 21:20:28 +08:00
if ( bFixedVel )
VA - > setFixed ( true ) ;
else
VA - > setFixed ( false ) ;
2020-12-01 11:58:17 +08:00
optimizer . addVertex ( VA ) ;
// prior acc bias
2022-03-28 21:20:28 +08:00
Eigen : : Vector3f bprior ;
bprior . setZero ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgePriorAcc * epa = new EdgePriorAcc ( bprior ) ;
epa - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA ) ) ;
2020-12-01 11:58:17 +08:00
double infoPriorA = priorA ;
2022-07-21 21:32:11 +08:00
epa - > setInformation ( infoPriorA * Eigen : : Matrix3d : : Identity ( ) ) ;
2020-12-01 11:58:17 +08:00
optimizer . addEdge ( epa ) ;
2022-07-21 21:32:11 +08:00
EdgePriorGyro * epg = new EdgePriorGyro ( bprior ) ;
epg - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG ) ) ;
2020-12-01 11:58:17 +08:00
double infoPriorG = priorG ;
2022-07-21 21:32:11 +08:00
epg - > setInformation ( infoPriorG * Eigen : : Matrix3d : : Identity ( ) ) ;
2020-12-01 11:58:17 +08:00
optimizer . addEdge ( epg ) ;
// Gravity and scale
2022-07-21 21:32:11 +08:00
VertexGDir * VGDir = new VertexGDir ( Rwg ) ;
VGDir - > setId ( maxKFid * 2 + 4 ) ;
2022-03-28 21:20:28 +08:00
VGDir - > setFixed ( false ) ;
2020-12-01 11:58:17 +08:00
optimizer . addVertex ( VGDir ) ;
2022-07-21 21:32:11 +08:00
VertexScale * VS = new VertexScale ( scale ) ;
VS - > setId ( maxKFid * 2 + 5 ) ;
2022-03-28 21:20:28 +08:00
VS - > setFixed ( ! bMono ) ; // Fixed for stereo case
2020-12-01 11:58:17 +08:00
optimizer . addVertex ( VS ) ;
// Graph edges
// IMU links with gravity and scale
2022-07-21 21:32:11 +08:00
vector < EdgeInertialGS * > vpei ;
2020-12-01 11:58:17 +08:00
vpei . reserve ( vpKFs . size ( ) ) ;
2022-07-21 21:32:11 +08:00
vector < pair < KeyFrame * , KeyFrame * > > vppUsedKF ;
2020-12-01 11:58:17 +08:00
vppUsedKF . reserve ( vpKFs . size ( ) ) ;
2022-07-21 21:32:11 +08:00
// std::cout << "build optimization graph" << std::endl;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mPrevKF & & pKFi - > mnId < = maxKFid )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pKFi - > isBad ( ) | | pKFi - > mPrevKF - > mnId > maxKFid )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > mpImuPreintegrated )
2022-03-28 21:20:28 +08:00
std : : cout < < " Not preintegrated measurement " < < std : : endl ;
2020-12-01 11:58:17 +08:00
pKFi - > mpImuPreintegrated - > SetNewBias ( pKFi - > mPrevKF - > GetImuBias ( ) ) ;
2022-07-21 21:32:11 +08:00
g2o : : HyperGraph : : Vertex * VP1 = optimizer . vertex ( pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV1 = optimizer . vertex ( maxKFid + ( pKFi - > mPrevKF - > mnId ) + 1 ) ;
g2o : : HyperGraph : : Vertex * VP2 = optimizer . vertex ( pKFi - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV2 = optimizer . vertex ( maxKFid + ( pKFi - > mnId ) + 1 ) ;
g2o : : HyperGraph : : Vertex * VG = optimizer . vertex ( maxKFid * 2 + 2 ) ;
g2o : : HyperGraph : : Vertex * VA = optimizer . vertex ( maxKFid * 2 + 3 ) ;
g2o : : HyperGraph : : Vertex * VGDir = optimizer . vertex ( maxKFid * 2 + 4 ) ;
g2o : : HyperGraph : : Vertex * VS = optimizer . vertex ( maxKFid * 2 + 5 ) ;
if ( ! VP1 | | ! VV1 | | ! VG | | ! VA | | ! VP2 | | ! VV2 | | ! VGDir | | ! VS )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
cout < < " Error " < < VP1 < < " , " < < VV1 < < " , " < < VG < < " , " < < VA < < " , " < < VP2 < < " , " < < VV2 < < " , " < < VGDir < < " , " < < VS < < endl ;
2020-12-01 11:58:17 +08:00
continue ;
}
2022-07-21 21:32:11 +08:00
EdgeInertialGS * ei = new EdgeInertialGS ( pKFi - > mpImuPreintegrated ) ;
ei - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP1 ) ) ;
ei - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV1 ) ) ;
ei - > setVertex ( 2 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG ) ) ;
ei - > setVertex ( 3 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA ) ) ;
ei - > setVertex ( 4 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP2 ) ) ;
ei - > setVertex ( 5 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV2 ) ) ;
ei - > setVertex ( 6 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VGDir ) ) ;
ei - > setVertex ( 7 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VS ) ) ;
2020-12-01 11:58:17 +08:00
vpei . push_back ( ei ) ;
2022-07-21 21:32:11 +08:00
vppUsedKF . push_back ( make_pair ( pKFi - > mPrevKF , pKFi ) ) ;
2020-12-01 11:58:17 +08:00
optimizer . addEdge ( ei ) ;
}
}
// Compute error for different scales
2022-07-21 21:32:11 +08:00
std : : set < g2o : : HyperGraph : : Edge * > setEdges = optimizer . edges ( ) ;
2020-12-01 11:58:17 +08:00
optimizer . setVerbose ( false ) ;
optimizer . initializeOptimization ( ) ;
optimizer . optimize ( its ) ;
2022-03-28 21:20:28 +08:00
scale = VS - > estimate ( ) ;
2020-12-01 11:58:17 +08:00
// Recover optimized data
// Biases
2022-07-21 21:32:11 +08:00
VG = static_cast < VertexGyroBias * > ( optimizer . vertex ( maxKFid * 2 + 2 ) ) ;
VA = static_cast < VertexAccBias * > ( optimizer . vertex ( maxKFid * 2 + 3 ) ) ;
2020-12-01 11:58:17 +08:00
Vector6d vb ;
vb < < VG - > estimate ( ) , VA - > estimate ( ) ;
bg < < VG - > estimate ( ) ;
ba < < VA - > estimate ( ) ;
scale = VS - > estimate ( ) ;
2022-07-21 21:32:11 +08:00
IMU : : Bias b ( vb [ 3 ] , vb [ 4 ] , vb [ 5 ] , vb [ 0 ] , vb [ 1 ] , vb [ 2 ] ) ;
2022-03-28 21:20:28 +08:00
Rwg = VGDir - > estimate ( ) . Rwg ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Keyframes velocities and biases
2022-03-28 21:20:28 +08:00
const int N = vpKFs . size ( ) ;
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
if ( pKFi - > mnId > maxKFid )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = static_cast < VertexVelocity * > ( optimizer . vertex ( maxKFid + ( pKFi - > mnId ) + 1 ) ) ;
2022-03-28 21:20:28 +08:00
Eigen : : Vector3d Vw = VV - > estimate ( ) ; // Velocity is scaled after
pKFi - > SetVelocity ( Vw . cast < float > ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
if ( ( pKFi - > GetGyroBias ( ) - bg . cast < float > ( ) ) . norm ( ) > 0.01 )
2020-12-01 11:58:17 +08:00
{
2022-03-28 21:20:28 +08:00
pKFi - > SetNewBias ( b ) ;
if ( pKFi - > mpImuPreintegrated )
pKFi - > mpImuPreintegrated - > Reintegrate ( ) ;
}
else
pKFi - > SetNewBias ( b ) ;
}
}
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
void Optimizer : : InertialOptimization ( Map * pMap , Eigen : : Vector3d & bg , Eigen : : Vector3d & ba , float priorG , float priorA )
{
int its = 200 ; // Check number of iterations
long unsigned int maxKFid = pMap - > GetMaxKFid ( ) ;
2022-07-21 21:32:11 +08:00
const vector < KeyFrame * > vpKFs = pMap - > GetAllKeyFrames ( ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Setup optimizer
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2022-03-28 21:20:28 +08:00
solver - > setUserLambdaInit ( 1e3 ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
optimizer . setAlgorithm ( solver ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Set KeyFrame vertices (fixed poses and optimizable velocities)
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
if ( pKFi - > mnId > maxKFid )
2022-03-28 21:20:28 +08:00
continue ;
2022-07-21 21:32:11 +08:00
VertexPose * VP = new VertexPose ( pKFi ) ;
2022-03-28 21:20:28 +08:00
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( true ) ;
optimizer . addVertex ( VP ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + ( pKFi - > mnId ) + 1 ) ;
2022-03-28 21:20:28 +08:00
VV - > setFixed ( false ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
optimizer . addVertex ( VV ) ;
2020-12-01 11:58:17 +08:00
}
2022-03-28 21:20:28 +08:00
// Biases
2022-07-21 21:32:11 +08:00
VertexGyroBias * VG = new VertexGyroBias ( vpKFs . front ( ) ) ;
VG - > setId ( maxKFid * 2 + 2 ) ;
2022-03-28 21:20:28 +08:00
VG - > setFixed ( false ) ;
optimizer . addVertex ( VG ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexAccBias * VA = new VertexAccBias ( vpKFs . front ( ) ) ;
VA - > setId ( maxKFid * 2 + 3 ) ;
2022-03-28 21:20:28 +08:00
VA - > setFixed ( false ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
optimizer . addVertex ( VA ) ;
// prior acc bias
Eigen : : Vector3f bprior ;
bprior . setZero ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgePriorAcc * epa = new EdgePriorAcc ( bprior ) ;
epa - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA ) ) ;
2022-03-28 21:20:28 +08:00
double infoPriorA = priorA ;
2022-07-21 21:32:11 +08:00
epa - > setInformation ( infoPriorA * Eigen : : Matrix3d : : Identity ( ) ) ;
2022-03-28 21:20:28 +08:00
optimizer . addEdge ( epa ) ;
2022-07-21 21:32:11 +08:00
EdgePriorGyro * epg = new EdgePriorGyro ( bprior ) ;
epg - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG ) ) ;
2022-03-28 21:20:28 +08:00
double infoPriorG = priorG ;
2022-07-21 21:32:11 +08:00
epg - > setInformation ( infoPriorG * Eigen : : Matrix3d : : Identity ( ) ) ;
2022-03-28 21:20:28 +08:00
optimizer . addEdge ( epg ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Gravity and scale
2022-07-21 21:32:11 +08:00
VertexGDir * VGDir = new VertexGDir ( Eigen : : Matrix3d : : Identity ( ) ) ;
VGDir - > setId ( maxKFid * 2 + 4 ) ;
2022-03-28 21:20:28 +08:00
VGDir - > setFixed ( true ) ;
optimizer . addVertex ( VGDir ) ;
2022-07-21 21:32:11 +08:00
VertexScale * VS = new VertexScale ( 1.0 ) ;
VS - > setId ( maxKFid * 2 + 5 ) ;
2022-03-28 21:20:28 +08:00
VS - > setFixed ( true ) ; // Fixed since scale is obtained from already well initialized map
optimizer . addVertex ( VS ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Graph edges
// IMU links with gravity and scale
2022-07-21 21:32:11 +08:00
vector < EdgeInertialGS * > vpei ;
2022-03-28 21:20:28 +08:00
vpei . reserve ( vpKFs . size ( ) ) ;
2022-07-21 21:32:11 +08:00
vector < pair < KeyFrame * , KeyFrame * > > vppUsedKF ;
2022-03-28 21:20:28 +08:00
vppUsedKF . reserve ( vpKFs . size ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mPrevKF & & pKFi - > mnId < = maxKFid )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pKFi - > isBad ( ) | | pKFi - > mPrevKF - > mnId > maxKFid )
2020-12-01 11:58:17 +08:00
continue ;
2022-03-28 21:20:28 +08:00
pKFi - > mpImuPreintegrated - > SetNewBias ( pKFi - > mPrevKF - > GetImuBias ( ) ) ;
2022-07-21 21:32:11 +08:00
g2o : : HyperGraph : : Vertex * VP1 = optimizer . vertex ( pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV1 = optimizer . vertex ( maxKFid + ( pKFi - > mPrevKF - > mnId ) + 1 ) ;
g2o : : HyperGraph : : Vertex * VP2 = optimizer . vertex ( pKFi - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV2 = optimizer . vertex ( maxKFid + ( pKFi - > mnId ) + 1 ) ;
g2o : : HyperGraph : : Vertex * VG = optimizer . vertex ( maxKFid * 2 + 2 ) ;
g2o : : HyperGraph : : Vertex * VA = optimizer . vertex ( maxKFid * 2 + 3 ) ;
g2o : : HyperGraph : : Vertex * VGDir = optimizer . vertex ( maxKFid * 2 + 4 ) ;
g2o : : HyperGraph : : Vertex * VS = optimizer . vertex ( maxKFid * 2 + 5 ) ;
if ( ! VP1 | | ! VV1 | | ! VG | | ! VA | | ! VP2 | | ! VV2 | | ! VGDir | | ! VS )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
cout < < " Error " < < VP1 < < " , " < < VV1 < < " , " < < VG < < " , " < < VA < < " , " < < VP2 < < " , " < < VV2 < < " , " < < VGDir < < " , " < < VS < < endl ;
2020-12-01 11:58:17 +08:00
continue ;
}
2022-07-21 21:32:11 +08:00
EdgeInertialGS * ei = new EdgeInertialGS ( pKFi - > mpImuPreintegrated ) ;
ei - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP1 ) ) ;
ei - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV1 ) ) ;
ei - > setVertex ( 2 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG ) ) ;
ei - > setVertex ( 3 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA ) ) ;
ei - > setVertex ( 4 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP2 ) ) ;
ei - > setVertex ( 5 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV2 ) ) ;
ei - > setVertex ( 6 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VGDir ) ) ;
ei - > setVertex ( 7 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VS ) ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
vpei . push_back ( ei ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vppUsedKF . push_back ( make_pair ( pKFi - > mPrevKF , pKFi ) ) ;
2022-03-28 21:20:28 +08:00
optimizer . addEdge ( ei ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-03-28 21:20:28 +08:00
// Compute error for different scales
optimizer . setVerbose ( false ) ;
optimizer . initializeOptimization ( ) ;
optimizer . optimize ( its ) ;
2020-12-01 11:58:17 +08:00
// Recover optimized data
2022-03-28 21:20:28 +08:00
// Biases
2022-07-21 21:32:11 +08:00
VG = static_cast < VertexGyroBias * > ( optimizer . vertex ( maxKFid * 2 + 2 ) ) ;
VA = static_cast < VertexAccBias * > ( optimizer . vertex ( maxKFid * 2 + 3 ) ) ;
2022-03-28 21:20:28 +08:00
Vector6d vb ;
vb < < VG - > estimate ( ) , VA - > estimate ( ) ;
bg < < VG - > estimate ( ) ;
ba < < VA - > estimate ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
IMU : : Bias b ( vb [ 3 ] , vb [ 4 ] , vb [ 5 ] , vb [ 0 ] , vb [ 1 ] , vb [ 2 ] ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Keyframes velocities and biases
2022-03-28 21:20:28 +08:00
const int N = vpKFs . size ( ) ;
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
if ( pKFi - > mnId > maxKFid )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = static_cast < VertexVelocity * > ( optimizer . vertex ( maxKFid + ( pKFi - > mnId ) + 1 ) ) ;
2022-03-28 21:20:28 +08:00
Eigen : : Vector3d Vw = VV - > estimate ( ) ;
pKFi - > SetVelocity ( Vw . cast < float > ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
if ( ( pKFi - > GetGyroBias ( ) - bg . cast < float > ( ) ) . norm ( ) > 0.01 )
2020-12-01 11:58:17 +08:00
{
2022-03-28 21:20:28 +08:00
pKFi - > SetNewBias ( b ) ;
if ( pKFi - > mpImuPreintegrated )
pKFi - > mpImuPreintegrated - > Reintegrate ( ) ;
2020-12-01 11:58:17 +08:00
}
2022-03-28 21:20:28 +08:00
else
pKFi - > SetNewBias ( b ) ;
2020-12-01 11:58:17 +08:00
}
2022-03-28 21:20:28 +08:00
}
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
void Optimizer : : InertialOptimization ( Map * pMap , Eigen : : Matrix3d & Rwg , double & scale )
{
int its = 10 ;
long unsigned int maxKFid = pMap - > GetMaxKFid ( ) ;
2022-07-21 21:32:11 +08:00
const vector < KeyFrame * > vpKFs = pMap - > GetAllKeyFrames ( ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Setup optimizer
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
2022-03-28 21:20:28 +08:00
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmGaussNewton * solver = new g2o : : OptimizationAlgorithmGaussNewton ( solver_ptr ) ;
2022-03-28 21:20:28 +08:00
optimizer . setAlgorithm ( solver ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Set KeyFrame vertices (all variables are fixed)
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
if ( pKFi - > mnId > maxKFid )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
VertexPose * VP = new VertexPose ( pKFi ) ;
2022-03-28 21:20:28 +08:00
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( true ) ;
optimizer . addVertex ( VP ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + 1 + ( pKFi - > mnId ) ) ;
2022-03-28 21:20:28 +08:00
VV - > setFixed ( true ) ;
optimizer . addVertex ( VV ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
// Vertex of fixed biases
2022-07-21 21:32:11 +08:00
VertexGyroBias * VG = new VertexGyroBias ( vpKFs . front ( ) ) ;
VG - > setId ( 2 * ( maxKFid + 1 ) + ( pKFi - > mnId ) ) ;
2022-03-28 21:20:28 +08:00
VG - > setFixed ( true ) ;
optimizer . addVertex ( VG ) ;
2022-07-21 21:32:11 +08:00
VertexAccBias * VA = new VertexAccBias ( vpKFs . front ( ) ) ;
VA - > setId ( 3 * ( maxKFid + 1 ) + ( pKFi - > mnId ) ) ;
2022-03-28 21:20:28 +08:00
VA - > setFixed ( true ) ;
optimizer . addVertex ( VA ) ;
2020-12-01 11:58:17 +08:00
}
2022-03-28 21:20:28 +08:00
// Gravity and scale
2022-07-21 21:32:11 +08:00
VertexGDir * VGDir = new VertexGDir ( Rwg ) ;
VGDir - > setId ( 4 * ( maxKFid + 1 ) ) ;
2022-03-28 21:20:28 +08:00
VGDir - > setFixed ( false ) ;
optimizer . addVertex ( VGDir ) ;
2022-07-21 21:32:11 +08:00
VertexScale * VS = new VertexScale ( scale ) ;
VS - > setId ( 4 * ( maxKFid + 1 ) + 1 ) ;
2022-03-28 21:20:28 +08:00
VS - > setFixed ( false ) ;
optimizer . addVertex ( VS ) ;
2021-12-08 22:09:39 +08:00
2022-03-28 21:20:28 +08:00
// Graph edges
int count_edges = 0 ;
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mPrevKF & & pKFi - > mnId < = maxKFid )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pKFi - > isBad ( ) | | pKFi - > mPrevKF - > mnId > maxKFid )
2022-03-28 21:20:28 +08:00
continue ;
2022-07-21 21:32:11 +08:00
g2o : : HyperGraph : : Vertex * VP1 = optimizer . vertex ( pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV1 = optimizer . vertex ( ( maxKFid + 1 ) + pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VP2 = optimizer . vertex ( pKFi - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV2 = optimizer . vertex ( ( maxKFid + 1 ) + pKFi - > mnId ) ;
g2o : : HyperGraph : : Vertex * VG = optimizer . vertex ( 2 * ( maxKFid + 1 ) + pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VA = optimizer . vertex ( 3 * ( maxKFid + 1 ) + pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VGDir = optimizer . vertex ( 4 * ( maxKFid + 1 ) ) ;
g2o : : HyperGraph : : Vertex * VS = optimizer . vertex ( 4 * ( maxKFid + 1 ) + 1 ) ;
if ( ! VP1 | | ! VV1 | | ! VG | | ! VA | | ! VP2 | | ! VV2 | | ! VGDir | | ! VS )
2022-03-28 21:20:28 +08:00
{
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " Error " + to_string ( VP1 - > id ( ) ) + " , " + to_string ( VV1 - > id ( ) ) + " , " + to_string ( VG - > id ( ) ) + " , " + to_string ( VA - > id ( ) ) + " , " + to_string ( VP2 - > id ( ) ) + " , " + to_string ( VV2 - > id ( ) ) + " , " + to_string ( VGDir - > id ( ) ) + " , " + to_string ( VS - > id ( ) ) , Verbose : : VERBOSITY_NORMAL ) ;
2020-12-01 11:58:17 +08:00
2022-03-28 21:20:28 +08:00
continue ;
}
count_edges + + ;
2022-07-21 21:32:11 +08:00
EdgeInertialGS * ei = new EdgeInertialGS ( pKFi - > mpImuPreintegrated ) ;
ei - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP1 ) ) ;
ei - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV1 ) ) ;
ei - > setVertex ( 2 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG ) ) ;
ei - > setVertex ( 3 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA ) ) ;
ei - > setVertex ( 4 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP2 ) ) ;
ei - > setVertex ( 5 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV2 ) ) ;
ei - > setVertex ( 6 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VGDir ) ) ;
ei - > setVertex ( 7 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VS ) ) ;
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
2022-03-28 21:20:28 +08:00
ei - > setRobustKernel ( rk ) ;
rk - > setDelta ( 1.f ) ;
optimizer . addEdge ( ei ) ;
}
2020-12-01 11:58:17 +08:00
}
2021-12-08 22:09:39 +08:00
2022-03-28 21:20:28 +08:00
// Compute error for different scales
optimizer . setVerbose ( false ) ;
optimizer . initializeOptimization ( ) ;
optimizer . computeActiveErrors ( ) ;
float err = optimizer . activeRobustChi2 ( ) ;
optimizer . optimize ( its ) ;
optimizer . computeActiveErrors ( ) ;
float err_end = optimizer . activeRobustChi2 ( ) ;
// Recover optimized data
scale = VS - > estimate ( ) ;
Rwg = VGDir - > estimate ( ) . Rwg ;
2020-12-01 11:58:17 +08:00
}
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
/**************************************以下为sim3优化**************************************************************/
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int Optimizer : : OptimizeSim3 (
KeyFrame * pKF1 , KeyFrame * pKF2 , vector < MapPoint * > & vpMatches1 , g2o : : Sim3 & g2oS12 , const float th2 ,
const bool bFixScale , Eigen : : Matrix < double , 7 , 7 > & mAcumHessian , const bool bAllPoints )
{
2020-12-01 11:58:17 +08:00
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
linearSolver = new g2o : : LinearSolverDense < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
optimizer . setAlgorithm ( solver ) ;
2022-07-21 21:32:11 +08:00
// Camera poses
const Eigen : : Matrix3f R1w = pKF1 - > GetRotation ( ) ;
const Eigen : : Vector3f t1w = pKF1 - > GetTranslation ( ) ;
const Eigen : : Matrix3f R2w = pKF2 - > GetRotation ( ) ;
const Eigen : : Vector3f t2w = pKF2 - > GetTranslation ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Sim3 vertex
ORB_SLAM3 : : VertexSim3Expmap * vSim3 = new ORB_SLAM3 : : VertexSim3Expmap ( ) ;
vSim3 - > _fix_scale = bFixScale ;
vSim3 - > setEstimate ( g2oS12 ) ;
vSim3 - > setId ( 0 ) ;
vSim3 - > setFixed ( false ) ;
vSim3 - > pCamera1 = pKF1 - > mpCamera ;
vSim3 - > pCamera2 = pKF2 - > mpCamera ;
optimizer . addVertex ( vSim3 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set MapPoint vertices
const int N = vpMatches1 . size ( ) ;
const vector < MapPoint * > vpMapPoints1 = pKF1 - > GetMapPointMatches ( ) ;
vector < ORB_SLAM3 : : EdgeSim3ProjectXYZ * > vpEdges12 ;
vector < ORB_SLAM3 : : EdgeInverseSim3ProjectXYZ * > vpEdges21 ;
vector < size_t > vnIndexEdge ;
vector < bool > vbIsInKF2 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vnIndexEdge . reserve ( 2 * N ) ;
vpEdges12 . reserve ( 2 * N ) ;
vpEdges21 . reserve ( 2 * N ) ;
vbIsInKF2 . reserve ( 2 * N ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float deltaHuber = sqrt ( th2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int nCorrespondences = 0 ;
int nBadMPs = 0 ;
int nInKF2 = 0 ;
int nOutKF2 = 0 ;
int nMatchWithoutMP = 0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < int > vIdsOnlyInKF2 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( int i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( ! vpMatches1 [ i ] )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
MapPoint * pMP1 = vpMapPoints1 [ i ] ;
MapPoint * pMP2 = vpMatches1 [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int id1 = 2 * i + 1 ;
const int id2 = 2 * ( i + 1 ) ;
const int i2 = get < 0 > ( pMP2 - > GetIndexInKeyFrame ( pKF2 ) ) ;
Eigen : : Vector3f P3D1c ;
Eigen : : Vector3f P3D2c ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP1 & & pMP2 )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( ! pMP1 - > isBad ( ) & & ! pMP2 - > isBad ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
g2o : : VertexSBAPointXYZ * vPoint1 = new g2o : : VertexSBAPointXYZ ( ) ;
Eigen : : Vector3f P3D1w = pMP1 - > GetWorldPos ( ) ;
P3D1c = R1w * P3D1w + t1w ;
vPoint1 - > setEstimate ( P3D1c . cast < double > ( ) ) ;
vPoint1 - > setId ( id1 ) ;
vPoint1 - > setFixed ( true ) ;
optimizer . addVertex ( vPoint1 ) ;
g2o : : VertexSBAPointXYZ * vPoint2 = new g2o : : VertexSBAPointXYZ ( ) ;
Eigen : : Vector3f P3D2w = pMP2 - > GetWorldPos ( ) ;
P3D2c = R2w * P3D2w + t2w ;
vPoint2 - > setEstimate ( P3D2c . cast < double > ( ) ) ;
vPoint2 - > setId ( id2 ) ;
vPoint2 - > setFixed ( true ) ;
optimizer . addVertex ( vPoint2 ) ;
}
else
{
nBadMPs + + ;
continue ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
else
{
nMatchWithoutMP + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// TODO The 3D position in KF1 doesn't exist
if ( ! pMP2 - > isBad ( ) )
{
g2o : : VertexSBAPointXYZ * vPoint2 = new g2o : : VertexSBAPointXYZ ( ) ;
Eigen : : Vector3f P3D2w = pMP2 - > GetWorldPos ( ) ;
P3D2c = R2w * P3D2w + t2w ;
vPoint2 - > setEstimate ( P3D2c . cast < double > ( ) ) ;
vPoint2 - > setId ( id2 ) ;
vPoint2 - > setFixed ( true ) ;
optimizer . addVertex ( vPoint2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vIdsOnlyInKF2 . push_back ( id2 ) ;
}
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( i2 < 0 & & ! bAllPoints )
{
Verbose : : PrintMess ( " Remove point -> i2: " + to_string ( i2 ) + " ; bAllPoints: " + to_string ( bAllPoints ) , Verbose : : VERBOSITY_DEBUG ) ;
continue ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( P3D2c ( 2 ) < 0 )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " Sim3: Z coordinate is negative " , Verbose : : VERBOSITY_DEBUG ) ;
continue ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
nCorrespondences + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set edge x1 = S12*X2
Eigen : : Matrix < double , 2 , 1 > obs1 ;
const cv : : KeyPoint & kpUn1 = pKF1 - > mvKeysUn [ i ] ;
obs1 < < kpUn1 . pt . x , kpUn1 . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSim3ProjectXYZ * e12 = new ORB_SLAM3 : : EdgeSim3ProjectXYZ ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e12 - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id2 ) ) ) ;
e12 - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( 0 ) ) ) ;
e12 - > setMeasurement ( obs1 ) ;
const float & invSigmaSquare1 = pKF1 - > mvInvLevelSigma2 [ kpUn1 . octave ] ;
e12 - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigmaSquare1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk1 = new g2o : : RobustKernelHuber ;
e12 - > setRobustKernel ( rk1 ) ;
rk1 - > setDelta ( deltaHuber ) ;
optimizer . addEdge ( e12 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set edge x2 = S21*X1
Eigen : : Matrix < double , 2 , 1 > obs2 ;
cv : : KeyPoint kpUn2 ;
bool inKF2 ;
if ( i2 > = 0 )
{
kpUn2 = pKF2 - > mvKeysUn [ i2 ] ;
obs2 < < kpUn2 . pt . x , kpUn2 . pt . y ;
inKF2 = true ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
nInKF2 + + ;
}
else
{
float invz = 1 / P3D2c ( 2 ) ;
float x = P3D2c ( 0 ) * invz ;
float y = P3D2c ( 1 ) * invz ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
obs2 < < x , y ;
kpUn2 = cv : : KeyPoint ( cv : : Point2f ( x , y ) , pMP2 - > mnTrackScaleLevel ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
inKF2 = false ;
nOutKF2 + + ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeInverseSim3ProjectXYZ * e21 = new ORB_SLAM3 : : EdgeInverseSim3ProjectXYZ ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e21 - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id1 ) ) ) ;
e21 - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( 0 ) ) ) ;
e21 - > setMeasurement ( obs2 ) ;
float invSigmaSquare2 = pKF2 - > mvInvLevelSigma2 [ kpUn2 . octave ] ;
e21 - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigmaSquare2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk2 = new g2o : : RobustKernelHuber ;
e21 - > setRobustKernel ( rk2 ) ;
rk2 - > setDelta ( deltaHuber ) ;
optimizer . addEdge ( e21 ) ;
vpEdges12 . push_back ( e12 ) ;
vpEdges21 . push_back ( e21 ) ;
vnIndexEdge . push_back ( i ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vbIsInKF2 . push_back ( inKF2 ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Optimize!
optimizer . initializeOptimization ( ) ;
optimizer . optimize ( 5 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Check inliers
int nBad = 0 ;
int nBadOutKF2 = 0 ;
for ( size_t i = 0 ; i < vpEdges12 . size ( ) ; i + + )
{
ORB_SLAM3 : : EdgeSim3ProjectXYZ * e12 = vpEdges12 [ i ] ;
ORB_SLAM3 : : EdgeInverseSim3ProjectXYZ * e21 = vpEdges21 [ i ] ;
if ( ! e12 | | ! e21 )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( e12 - > chi2 ( ) > th2 | | e21 - > chi2 ( ) > th2 )
{
size_t idx = vnIndexEdge [ i ] ;
vpMatches1 [ idx ] = static_cast < MapPoint * > ( NULL ) ;
optimizer . removeEdge ( e12 ) ;
optimizer . removeEdge ( e21 ) ;
vpEdges12 [ i ] = static_cast < ORB_SLAM3 : : EdgeSim3ProjectXYZ * > ( NULL ) ;
vpEdges21 [ i ] = static_cast < ORB_SLAM3 : : EdgeInverseSim3ProjectXYZ * > ( NULL ) ;
nBad + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! vbIsInKF2 [ i ] )
{
nBadOutKF2 + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
continue ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Check if remove the robust adjustment improve the result
e12 - > setRobustKernel ( 0 ) ;
e21 - > setRobustKernel ( 0 ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
int nMoreIterations ;
if ( nBad > 0 )
nMoreIterations = 10 ;
else
nMoreIterations = 5 ;
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
if ( nCorrespondences - nBad < 10 )
return 0 ;
// Optimize again only with inliers
2020-12-01 11:58:17 +08:00
optimizer . initializeOptimization ( ) ;
2022-07-21 21:32:11 +08:00
optimizer . optimize ( nMoreIterations ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int nIn = 0 ;
mAcumHessian = Eigen : : MatrixXd : : Zero ( 7 , 7 ) ;
for ( size_t i = 0 ; i < vpEdges12 . size ( ) ; i + + )
{
ORB_SLAM3 : : EdgeSim3ProjectXYZ * e12 = vpEdges12 [ i ] ;
ORB_SLAM3 : : EdgeInverseSim3ProjectXYZ * e21 = vpEdges21 [ i ] ;
if ( ! e12 | | ! e21 )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e12 - > computeError ( ) ;
e21 - > computeError ( ) ;
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
if ( e12 - > chi2 ( ) > th2 | | e21 - > chi2 ( ) > th2 )
{
size_t idx = vnIndexEdge [ i ] ;
vpMatches1 [ idx ] = static_cast < MapPoint * > ( NULL ) ;
}
else
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
nIn + + ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Recover optimized Sim3
g2o : : VertexSim3Expmap * vSim3_recov = static_cast < g2o : : VertexSim3Expmap * > ( optimizer . vertex ( 0 ) ) ;
g2oS12 = vSim3_recov - > estimate ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
return nIn ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
/**************************************以下为地图回环优化**************************************************************/
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
void Optimizer : : OptimizeEssentialGraph (
Map * pMap , KeyFrame * pLoopKF , KeyFrame * pCurKF ,
const LoopClosing : : KeyFrameAndPose & NonCorrectedSim3 ,
const LoopClosing : : KeyFrameAndPose & CorrectedSim3 ,
const map < KeyFrame * , set < KeyFrame * > > & LoopConnections , const bool & bFixScale )
{
// Setup optimizer
g2o : : SparseOptimizer optimizer ;
optimizer . setVerbose ( false ) ;
g2o : : BlockSolver_7_3 : : LinearSolverType * linearSolver =
new g2o : : LinearSolverEigen < g2o : : BlockSolver_7_3 : : PoseMatrixType > ( ) ;
g2o : : BlockSolver_7_3 * solver_ptr = new g2o : : BlockSolver_7_3 ( linearSolver ) ;
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
solver - > setUserLambdaInit ( 1e-16 ) ;
optimizer . setAlgorithm ( solver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const vector < KeyFrame * > vpKFs = pMap - > GetAllKeyFrames ( ) ;
const vector < MapPoint * > vpMPs = pMap - > GetAllMapPoints ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const unsigned int nMaxKFid = pMap - > GetMaxKFid ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < g2o : : Sim3 , Eigen : : aligned_allocator < g2o : : Sim3 > > vScw ( nMaxKFid + 1 ) ;
vector < g2o : : Sim3 , Eigen : : aligned_allocator < g2o : : Sim3 > > vCorrectedSwc ( nMaxKFid + 1 ) ;
vector < g2o : : VertexSim3Expmap * > vpVertices ( nMaxKFid + 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < Eigen : : Vector3d > vZvectors ( nMaxKFid + 1 ) ; // For debugging
Eigen : : Vector3d z_vec ;
z_vec < < 0.0 , 0.0 , 1.0 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int minFeat = 100 ;
// Set KeyFrame vertices
for ( size_t i = 0 , iend = vpKFs . size ( ) ; i < iend ; i + + )
{
KeyFrame * pKF = vpKFs [ i ] ;
if ( pKF - > isBad ( ) )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
g2o : : VertexSim3Expmap * VSim3 = new g2o : : VertexSim3Expmap ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator it = CorrectedSim3 . find ( pKF ) ;
if ( it ! = CorrectedSim3 . end ( ) )
{
vScw [ nIDi ] = it - > second ;
VSim3 - > setEstimate ( it - > second ) ;
}
else
{
Sophus : : SE3d Tcw = pKF - > GetPose ( ) . cast < double > ( ) ;
g2o : : Sim3 Siw ( Tcw . unit_quaternion ( ) , Tcw . translation ( ) , 1.0 ) ;
vScw [ nIDi ] = Siw ;
VSim3 - > setEstimate ( Siw ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( pKF - > mnId = = pMap - > GetInitKFid ( ) )
VSim3 - > setFixed ( true ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VSim3 - > setId ( nIDi ) ;
VSim3 - > setMarginalized ( false ) ;
VSim3 - > _fix_scale = bFixScale ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addVertex ( VSim3 ) ;
vZvectors [ nIDi ] = vScw [ nIDi ] . rotation ( ) * z_vec ; // For debugging
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpVertices [ nIDi ] = VSim3 ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
set < pair < long unsigned int , long unsigned int > > sInsertedEdges ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const Eigen : : Matrix < double , 7 , 7 > matLambda = Eigen : : Matrix < double , 7 , 7 > : : Identity ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Loop edges
int count_loop = 0 ;
for ( map < KeyFrame * , set < KeyFrame * > > : : const_iterator mit = LoopConnections . begin ( ) , mend = LoopConnections . end ( ) ; mit ! = mend ; mit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = mit - > first ;
const long unsigned int nIDi = pKF - > mnId ;
const set < KeyFrame * > & spConnections = mit - > second ;
const g2o : : Sim3 Siw = vScw [ nIDi ] ;
const g2o : : Sim3 Swi = Siw . inverse ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( set < KeyFrame * > : : const_iterator sit = spConnections . begin ( ) , send = spConnections . end ( ) ; sit ! = send ; sit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
const long unsigned int nIDj = ( * sit ) - > mnId ;
if ( ( nIDi ! = pCurKF - > mnId | | nIDj ! = pLoopKF - > mnId ) & & pKF - > GetWeight ( * sit ) < minFeat )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
const g2o : : Sim3 Sjw = vScw [ nIDj ] ;
const g2o : : Sim3 Sji = Sjw * Swi ;
g2o : : EdgeSim3 * e = new g2o : : EdgeSim3 ( ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDj ) ) ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
e - > setMeasurement ( Sji ) ;
e - > information ( ) = matLambda ;
optimizer . addEdge ( e ) ;
count_loop + + ;
sInsertedEdges . insert ( make_pair ( min ( nIDi , nIDj ) , max ( nIDi , nIDj ) ) ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
// Set normal edges
for ( size_t i = 0 , iend = vpKFs . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = vpKFs [ i ] ;
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Swi ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator iti = NonCorrectedSim3 . find ( pKF ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( iti ! = NonCorrectedSim3 . end ( ) )
Swi = ( iti - > second ) . inverse ( ) ;
else
Swi = vScw [ nIDi ] . inverse ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
KeyFrame * pParentKF = pKF - > GetParent ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Spanning tree edge
if ( pParentKF )
{
int nIDj = pParentKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Sjw ;
LoopClosing : : KeyFrameAndPose : : const_iterator itj = NonCorrectedSim3 . find ( pParentKF ) ;
if ( itj ! = NonCorrectedSim3 . end ( ) )
Sjw = itj - > second ;
2020-12-01 11:58:17 +08:00
else
2022-07-21 21:32:11 +08:00
Sjw = vScw [ nIDj ] ;
g2o : : Sim3 Sji = Sjw * Swi ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : EdgeSim3 * e = new g2o : : EdgeSim3 ( ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDj ) ) ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
e - > setMeasurement ( Sji ) ;
e - > information ( ) = matLambda ;
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Loop edges
const set < KeyFrame * > sLoopEdges = pKF - > GetLoopEdges ( ) ;
for ( set < KeyFrame * > : : const_iterator sit = sLoopEdges . begin ( ) , send = sLoopEdges . end ( ) ; sit ! = send ; sit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pLKF = * sit ;
if ( pLKF - > mnId < pKF - > mnId )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Slw ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator itl = NonCorrectedSim3 . find ( pLKF ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( itl ! = NonCorrectedSim3 . end ( ) )
Slw = itl - > second ;
else
Slw = vScw [ pLKF - > mnId ] ;
g2o : : Sim3 Sli = Slw * Swi ;
g2o : : EdgeSim3 * el = new g2o : : EdgeSim3 ( ) ;
el - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pLKF - > mnId ) ) ) ;
el - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
el - > setMeasurement ( Sli ) ;
el - > information ( ) = matLambda ;
optimizer . addEdge ( el ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
// Covisibility graph edges
const vector < KeyFrame * > vpConnectedKFs = pKF - > GetCovisiblesByWeight ( minFeat ) ;
for ( vector < KeyFrame * > : : const_iterator vit = vpConnectedKFs . begin ( ) ; vit ! = vpConnectedKFs . end ( ) ; vit + + )
{
KeyFrame * pKFn = * vit ;
if ( pKFn & & pKFn ! = pParentKF & & ! pKF - > hasChild ( pKFn ) /*&& !sLoopEdges.count(pKFn)*/ )
{
if ( ! pKFn - > isBad ( ) & & pKFn - > mnId < pKF - > mnId )
{
if ( sInsertedEdges . count ( make_pair ( min ( pKF - > mnId , pKFn - > mnId ) , max ( pKF - > mnId , pKFn - > mnId ) ) ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Snw ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator itn = NonCorrectedSim3 . find ( pKFn ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
if ( itn ! = NonCorrectedSim3 . end ( ) )
Snw = itn - > second ;
else
Snw = vScw [ pKFn - > mnId ] ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Sni = Snw * Swi ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : EdgeSim3 * en = new g2o : : EdgeSim3 ( ) ;
en - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFn - > mnId ) ) ) ;
en - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
en - > setMeasurement ( Sni ) ;
en - > information ( ) = matLambda ;
optimizer . addEdge ( en ) ;
}
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Inertial edges if inertial
if ( pKF - > bImu & & pKF - > mPrevKF )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Spw ;
LoopClosing : : KeyFrameAndPose : : const_iterator itp = NonCorrectedSim3 . find ( pKF - > mPrevKF ) ;
if ( itp ! = NonCorrectedSim3 . end ( ) )
Spw = itp - > second ;
else
Spw = vScw [ pKF - > mPrevKF - > mnId ] ;
g2o : : Sim3 Spi = Spw * Swi ;
g2o : : EdgeSim3 * ep = new g2o : : EdgeSim3 ( ) ;
ep - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKF - > mPrevKF - > mnId ) ) ) ;
ep - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
ep - > setMeasurement ( Spi ) ;
ep - > information ( ) = matLambda ;
optimizer . addEdge ( ep ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
optimizer . initializeOptimization ( ) ;
optimizer . computeActiveErrors ( ) ;
optimizer . optimize ( 20 ) ;
optimizer . computeActiveErrors ( ) ;
unique_lock < mutex > lock ( pMap - > mMutexMapUpdate ) ;
// SE3 Pose Recovering. Sim3:[sR t;0 1] -> SE3:[R t/s;0 1]
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : VertexSim3Expmap * VSim3 = static_cast < g2o : : VertexSim3Expmap * > ( optimizer . vertex ( nIDi ) ) ;
g2o : : Sim3 CorrectedSiw = VSim3 - > estimate ( ) ;
vCorrectedSwc [ nIDi ] = CorrectedSiw . inverse ( ) ;
double s = CorrectedSiw . scale ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3f Tiw ( CorrectedSiw . rotation ( ) . cast < float > ( ) , CorrectedSiw . translation ( ) . cast < float > ( ) / s ) ;
pKFi - > SetPose ( Tiw ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Correct points. Transform to "non-optimized" reference keyframe pose and transform back with optimized pose
for ( size_t i = 0 , iend = vpMPs . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = vpMPs [ i ] ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
int nIDr ;
if ( pMP - > mnCorrectedByKF = = pCurKF - > mnId )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
nIDr = pMP - > mnCorrectedReference ;
2020-12-01 11:58:17 +08:00
}
else
{
2022-07-21 21:32:11 +08:00
KeyFrame * pRefKF = pMP - > GetReferenceKeyFrame ( ) ;
nIDr = pRefKF - > mnId ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Srw = vScw [ nIDr ] ;
g2o : : Sim3 correctedSwr = vCorrectedSwc [ nIDr ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 3 , 1 > eigP3Dw = pMP - > GetWorldPos ( ) . cast < double > ( ) ;
Eigen : : Matrix < double , 3 , 1 > eigCorrectedP3Dw = correctedSwr . map ( Srw . map ( eigP3Dw ) ) ;
pMP - > SetWorldPos ( eigCorrectedP3Dw . cast < float > ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
pMP - > UpdateNormalAndDepth ( ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// TODO Check this changeindex
pMap - > IncreaseChangeIndex ( ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
void Optimizer : : OptimizeEssentialGraph4DoF (
Map * pMap , KeyFrame * pLoopKF , KeyFrame * pCurKF ,
const LoopClosing : : KeyFrameAndPose & NonCorrectedSim3 ,
const LoopClosing : : KeyFrameAndPose & CorrectedSim3 ,
const map < KeyFrame * , set < KeyFrame * > > & LoopConnections )
{
typedef g2o : : BlockSolver < g2o : : BlockSolverTraits < 4 , 4 > > BlockSolver_4_4 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Setup optimizer
g2o : : SparseOptimizer optimizer ;
optimizer . setVerbose ( false ) ;
g2o : : BlockSolverX : : LinearSolverType * linearSolver =
new g2o : : LinearSolverEigen < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
optimizer . setAlgorithm ( solver ) ;
2022-07-21 21:32:11 +08:00
const vector < KeyFrame * > vpKFs = pMap - > GetAllKeyFrames ( ) ;
const vector < MapPoint * > vpMPs = pMap - > GetAllMapPoints ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const unsigned int nMaxKFid = pMap - > GetMaxKFid ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < g2o : : Sim3 , Eigen : : aligned_allocator < g2o : : Sim3 > > vScw ( nMaxKFid + 1 ) ;
vector < g2o : : Sim3 , Eigen : : aligned_allocator < g2o : : Sim3 > > vCorrectedSwc ( nMaxKFid + 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < VertexPose4DoF * > vpVertices ( nMaxKFid + 1 ) ;
const int minFeat = 100 ;
// Set KeyFrame vertices
for ( size_t i = 0 , iend = vpKFs . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = vpKFs [ i ] ;
if ( pKF - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexPose4DoF * V4DoF ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator it = CorrectedSim3 . find ( pKF ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( it ! = CorrectedSim3 . end ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
vScw [ nIDi ] = it - > second ;
const g2o : : Sim3 Swc = it - > second . inverse ( ) ;
Eigen : : Matrix3d Rwc = Swc . rotation ( ) . toRotationMatrix ( ) ;
Eigen : : Vector3d twc = Swc . translation ( ) ;
V4DoF = new VertexPose4DoF ( Rwc , twc , pKF ) ;
}
else
{
Sophus : : SE3d Tcw = pKF - > GetPose ( ) . cast < double > ( ) ;
g2o : : Sim3 Siw ( Tcw . unit_quaternion ( ) , Tcw . translation ( ) , 1.0 ) ;
vScw [ nIDi ] = Siw ;
V4DoF = new VertexPose4DoF ( pKF ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( pKF = = pLoopKF )
V4DoF - > setFixed ( true ) ;
V4DoF - > setId ( nIDi ) ;
V4DoF - > setMarginalized ( false ) ;
optimizer . addVertex ( V4DoF ) ;
vpVertices [ nIDi ] = V4DoF ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
set < pair < long unsigned int , long unsigned int > > sInsertedEdges ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Edge used in posegraph has still 6Dof, even if updates of camera poses are just in 4DoF
Eigen : : Matrix < double , 6 , 6 > matLambda = Eigen : : Matrix < double , 6 , 6 > : : Identity ( ) ;
matLambda ( 0 , 0 ) = 1e3 ;
matLambda ( 1 , 1 ) = 1e3 ;
matLambda ( 0 , 0 ) = 1e3 ;
// Set Loop edges
Edge4DoF * e_loop ;
for ( map < KeyFrame * , set < KeyFrame * > > : : const_iterator mit = LoopConnections . begin ( ) , mend = LoopConnections . end ( ) ; mit ! = mend ; mit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = mit - > first ;
const long unsigned int nIDi = pKF - > mnId ;
const set < KeyFrame * > & spConnections = mit - > second ;
const g2o : : Sim3 Siw = vScw [ nIDi ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( set < KeyFrame * > : : const_iterator sit = spConnections . begin ( ) , send = spConnections . end ( ) ; sit ! = send ; sit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
const long unsigned int nIDj = ( * sit ) - > mnId ;
if ( ( nIDi ! = pCurKF - > mnId | | nIDj ! = pLoopKF - > mnId ) & & pKF - > GetWeight ( * sit ) < minFeat )
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
const g2o : : Sim3 Sjw = vScw [ nIDj ] ;
const g2o : : Sim3 Sij = Siw * Sjw . inverse ( ) ;
Eigen : : Matrix4d Tij ;
Tij . block < 3 , 3 > ( 0 , 0 ) = Sij . rotation ( ) . toRotationMatrix ( ) ;
Tij . block < 3 , 1 > ( 0 , 3 ) = Sij . translation ( ) ;
Tij ( 3 , 3 ) = 1. ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Edge4DoF * e = new Edge4DoF ( Tij ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDj ) ) ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > information ( ) = matLambda ;
e_loop = e ;
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
sInsertedEdges . insert ( make_pair ( min ( nIDi , nIDj ) , max ( nIDi , nIDj ) ) ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
// 1. Set normal edges
for ( size_t i = 0 , iend = vpKFs . size ( ) ; i < iend ; i + + )
{
KeyFrame * pKF = vpKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Siw ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Use noncorrected poses for posegraph edges
LoopClosing : : KeyFrameAndPose : : const_iterator iti = NonCorrectedSim3 . find ( pKF ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( iti ! = NonCorrectedSim3 . end ( ) )
Siw = iti - > second ;
else
Siw = vScw [ nIDi ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// 1.1.0 Spanning tree edge
KeyFrame * pParentKF = static_cast < KeyFrame * > ( NULL ) ;
if ( pParentKF )
{
int nIDj = pParentKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Swj ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator itj = NonCorrectedSim3 . find ( pParentKF ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( itj ! = NonCorrectedSim3 . end ( ) )
Swj = ( itj - > second ) . inverse ( ) ;
else
Swj = vScw [ nIDj ] . inverse ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Sij = Siw * Swj ;
Eigen : : Matrix4d Tij ;
Tij . block < 3 , 3 > ( 0 , 0 ) = Sij . rotation ( ) . toRotationMatrix ( ) ;
Tij . block < 3 , 1 > ( 0 , 3 ) = Sij . translation ( ) ;
Tij ( 3 , 3 ) = 1. ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Edge4DoF * e = new Edge4DoF ( Tij ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDj ) ) ) ;
e - > information ( ) = matLambda ;
optimizer . addEdge ( e ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// 1.1.1 Inertial edges
KeyFrame * prevKF = pKF - > mPrevKF ;
if ( prevKF )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
int nIDj = prevKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Swj ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator itj = NonCorrectedSim3 . find ( prevKF ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( itj ! = NonCorrectedSim3 . end ( ) )
Swj = ( itj - > second ) . inverse ( ) ;
else
Swj = vScw [ nIDj ] . inverse ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Sij = Siw * Swj ;
Eigen : : Matrix4d Tij ;
Tij . block < 3 , 3 > ( 0 , 0 ) = Sij . rotation ( ) . toRotationMatrix ( ) ;
Tij . block < 3 , 1 > ( 0 , 3 ) = Sij . translation ( ) ;
Tij ( 3 , 3 ) = 1. ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Edge4DoF * e = new Edge4DoF ( Tij ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDj ) ) ) ;
e - > information ( ) = matLambda ;
optimizer . addEdge ( e ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// 1.2 Loop edges
const set < KeyFrame * > sLoopEdges = pKF - > GetLoopEdges ( ) ;
for ( set < KeyFrame * > : : const_iterator sit = sLoopEdges . begin ( ) , send = sLoopEdges . end ( ) ; sit ! = send ; sit + + )
{
KeyFrame * pLKF = * sit ;
if ( pLKF - > mnId < pKF - > mnId )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Swl ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator itl = NonCorrectedSim3 . find ( pLKF ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( itl ! = NonCorrectedSim3 . end ( ) )
Swl = itl - > second . inverse ( ) ;
else
Swl = vScw [ pLKF - > mnId ] . inverse ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Sil = Siw * Swl ;
Eigen : : Matrix4d Til ;
Til . block < 3 , 3 > ( 0 , 0 ) = Sil . rotation ( ) . toRotationMatrix ( ) ;
Til . block < 3 , 1 > ( 0 , 3 ) = Sil . translation ( ) ;
Til ( 3 , 3 ) = 1. ;
Edge4DoF * e = new Edge4DoF ( Til ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pLKF - > mnId ) ) ) ;
e - > information ( ) = matLambda ;
optimizer . addEdge ( e ) ;
}
}
// 1.3 Covisibility graph edges
const vector < KeyFrame * > vpConnectedKFs = pKF - > GetCovisiblesByWeight ( minFeat ) ;
for ( vector < KeyFrame * > : : const_iterator vit = vpConnectedKFs . begin ( ) ; vit ! = vpConnectedKFs . end ( ) ; vit + + )
{
KeyFrame * pKFn = * vit ;
if ( pKFn & & pKFn ! = pParentKF & & pKFn ! = prevKF & & pKFn ! = pKF - > mNextKF & & ! pKF - > hasChild ( pKFn ) & & ! sLoopEdges . count ( pKFn ) )
{
if ( ! pKFn - > isBad ( ) & & pKFn - > mnId < pKF - > mnId )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( sInsertedEdges . count ( make_pair ( min ( pKF - > mnId , pKFn - > mnId ) , max ( pKF - > mnId , pKFn - > mnId ) ) ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Swn ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
LoopClosing : : KeyFrameAndPose : : const_iterator itn = NonCorrectedSim3 . find ( pKFn ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( itn ! = NonCorrectedSim3 . end ( ) )
Swn = itn - > second . inverse ( ) ;
else
Swn = vScw [ pKFn - > mnId ] . inverse ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Sin = Siw * Swn ;
Eigen : : Matrix4d Tin ;
Tin . block < 3 , 3 > ( 0 , 0 ) = Sin . rotation ( ) . toRotationMatrix ( ) ;
Tin . block < 3 , 1 > ( 0 , 3 ) = Sin . translation ( ) ;
Tin ( 3 , 3 ) = 1. ;
Edge4DoF * e = new Edge4DoF ( Tin ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFn - > mnId ) ) ) ;
e - > information ( ) = matLambda ;
2020-12-01 11:58:17 +08:00
optimizer . addEdge ( e ) ;
}
}
}
}
2022-03-28 21:20:28 +08:00
optimizer . initializeOptimization ( ) ;
2022-07-21 21:32:11 +08:00
optimizer . computeActiveErrors ( ) ;
optimizer . optimize ( 20 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
unique_lock < mutex > lock ( pMap - > mMutexMapUpdate ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// SE3 Pose Recovering. Sim3:[sR t;0 1] -> SE3:[R t/s;0 1]
for ( size_t i = 0 ; i < vpKFs . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexPose4DoF * Vi = static_cast < VertexPose4DoF * > ( optimizer . vertex ( nIDi ) ) ;
Eigen : : Matrix3d Ri = Vi - > estimate ( ) . Rcw [ 0 ] ;
Eigen : : Vector3d ti = Vi - > estimate ( ) . tcw [ 0 ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 CorrectedSiw = g2o : : Sim3 ( Ri , ti , 1. ) ;
vCorrectedSwc [ nIDi ] = CorrectedSiw . inverse ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3d Tiw ( CorrectedSiw . rotation ( ) , CorrectedSiw . translation ( ) ) ;
pKFi - > SetPose ( Tiw . cast < float > ( ) ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Correct points. Transform to "non-optimized" reference keyframe pose and transform back with optimized pose
for ( size_t i = 0 , iend = vpMPs . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
MapPoint * pMP = vpMPs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
int nIDr ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
KeyFrame * pRefKF = pMP - > GetReferenceKeyFrame ( ) ;
nIDr = pRefKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Srw = vScw [ nIDr ] ;
g2o : : Sim3 correctedSwr = vCorrectedSwc [ nIDr ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Eigen : : Matrix < double , 3 , 1 > eigP3Dw = pMP - > GetWorldPos ( ) . cast < double > ( ) ;
Eigen : : Matrix < double , 3 , 1 > eigCorrectedP3Dw = correctedSwr . map ( Srw . map ( eigP3Dw ) ) ;
pMP - > SetWorldPos ( eigCorrectedP3Dw . cast < float > ( ) ) ;
2020-12-01 11:58:17 +08:00
pMP - > UpdateNormalAndDepth ( ) ;
}
pMap - > IncreaseChangeIndex ( ) ;
}
2022-07-21 21:32:11 +08:00
/**************************************以下为地图融合优化**************************************************************/
void Optimizer : : LocalBundleAdjustment (
KeyFrame * pMainKF , vector < KeyFrame * > vpAdjustKF , vector < KeyFrame * > vpFixedKF , bool * pbStopFlag )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
bool bShowImages = false ;
vector < MapPoint * > vpMPs ;
2020-12-01 11:58:17 +08:00
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
g2o : : BlockSolver_6_3 : : LinearSolverType * linearSolver ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolver_6_3 : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolver_6_3 * solver_ptr = new g2o : : BlockSolver_6_3 ( linearSolver ) ;
2021-09-03 14:24:01 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
optimizer . setAlgorithm ( solver ) ;
2022-07-21 21:32:11 +08:00
optimizer . setVerbose ( false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
optimizer . setForceStopFlag ( pbStopFlag ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
long unsigned int maxKFid = 0 ;
set < KeyFrame * > spKeyFrameBA ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Map * pCurrentMap = pMainKF - > GetMap ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set fixed KeyFrame vertices
int numInsertedPoints = 0 ;
for ( KeyFrame * pKFi : vpFixedKF )
{
if ( pKFi - > isBad ( ) | | pKFi - > GetMap ( ) ! = pCurrentMap )
{
Verbose : : PrintMess ( " ERROR LBA: KF is bad or is not in the current map " , Verbose : : VERBOSITY_NORMAL ) ;
continue ;
}
pKFi - > mnBALocalForMerge = pMainKF - > mnId ;
g2o : : VertexSE3Expmap * vSE3 = new g2o : : VertexSE3Expmap ( ) ;
Sophus : : SE3 < float > Tcw = pKFi - > GetPose ( ) ;
vSE3 - > setEstimate ( g2o : : SE3Quat ( Tcw . unit_quaternion ( ) . cast < double > ( ) , Tcw . translation ( ) . cast < double > ( ) ) ) ;
vSE3 - > setId ( pKFi - > mnId ) ;
vSE3 - > setFixed ( true ) ;
optimizer . addVertex ( vSE3 ) ;
if ( pKFi - > mnId > maxKFid )
maxKFid = pKFi - > mnId ;
set < MapPoint * > spViewMPs = pKFi - > GetMapPoints ( ) ;
for ( MapPoint * pMPi : spViewMPs )
{
if ( pMPi )
if ( ! pMPi - > isBad ( ) & & pMPi - > GetMap ( ) = = pCurrentMap )
if ( pMPi - > mnBALocalForMerge ! = pMainKF - > mnId )
{
vpMPs . push_back ( pMPi ) ;
pMPi - > mnBALocalForMerge = pMainKF - > mnId ;
numInsertedPoints + + ;
}
}
spKeyFrameBA . insert ( pKFi ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set non fixed Keyframe vertices
set < KeyFrame * > spAdjustKF ( vpAdjustKF . begin ( ) , vpAdjustKF . end ( ) ) ;
numInsertedPoints = 0 ;
for ( KeyFrame * pKFi : vpAdjustKF )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pKFi - > isBad ( ) | | pKFi - > GetMap ( ) ! = pCurrentMap )
continue ;
pKFi - > mnBALocalForMerge = pMainKF - > mnId ;
g2o : : VertexSE3Expmap * vSE3 = new g2o : : VertexSE3Expmap ( ) ;
Sophus : : SE3 < float > Tcw = pKFi - > GetPose ( ) ;
vSE3 - > setEstimate ( g2o : : SE3Quat ( Tcw . unit_quaternion ( ) . cast < double > ( ) , Tcw . translation ( ) . cast < double > ( ) ) ) ;
vSE3 - > setId ( pKFi - > mnId ) ;
optimizer . addVertex ( vSE3 ) ;
if ( pKFi - > mnId > maxKFid )
maxKFid = pKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
set < MapPoint * > spViewMPs = pKFi - > GetMapPoints ( ) ;
for ( MapPoint * pMPi : spViewMPs )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pMPi )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( ! pMPi - > isBad ( ) & & pMPi - > GetMap ( ) = = pCurrentMap )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pMPi - > mnBALocalForMerge ! = pMainKF - > mnId )
{
vpMPs . push_back ( pMPi ) ;
pMPi - > mnBALocalForMerge = pMainKF - > mnId ;
numInsertedPoints + + ;
}
}
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
spKeyFrameBA . insert ( pKFi ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nExpectedSize = ( vpAdjustKF . size ( ) + vpFixedKF . size ( ) ) * vpMPs . size ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < ORB_SLAM3 : : EdgeSE3ProjectXYZ * > vpEdgesMono ;
vpEdgesMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFMono ;
vpEdgeKFMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeMono ;
vpMapPointEdgeMono . reserve ( nExpectedSize ) ;
vector < g2o : : EdgeStereoSE3ProjectXYZ * > vpEdgesStereo ;
vpEdgesStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFStereo ;
vpEdgeKFStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeStereo ;
vpMapPointEdgeStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float thHuber2D = sqrt ( 5.99 ) ;
const float thHuber3D = sqrt ( 7.815 ) ;
// Set MapPoint vertices
map < KeyFrame * , int > mpObsKFs ;
map < KeyFrame * , int > mpObsFinalKFs ;
map < MapPoint * , int > mpObsMPs ;
for ( unsigned int i = 0 ; i < vpMPs . size ( ) ; + + i )
{
MapPoint * pMPi = vpMPs [ i ] ;
if ( pMPi - > isBad ( ) )
continue ;
g2o : : VertexSBAPointXYZ * vPoint = new g2o : : VertexSBAPointXYZ ( ) ;
vPoint - > setEstimate ( pMPi - > GetWorldPos ( ) . cast < double > ( ) ) ;
const int id = pMPi - > mnId + maxKFid + 1 ;
vPoint - > setId ( id ) ;
vPoint - > setMarginalized ( true ) ;
optimizer . addVertex ( vPoint ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const map < KeyFrame * , tuple < int , int > > observations = pMPi - > GetObservations ( ) ;
int nEdges = 0 ;
// SET EDGES
for ( map < KeyFrame * , tuple < int , int > > : : const_iterator mit = observations . begin ( ) ; mit ! = observations . end ( ) ; mit + + )
{
KeyFrame * pKF = mit - > first ;
if ( pKF - > isBad ( ) | | pKF - > mnId > maxKFid | | pKF - > mnBALocalForMerge ! = pMainKF - > mnId | | ! pKF - > GetMapPoint ( get < 0 > ( mit - > second ) ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
nEdges + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const cv : : KeyPoint & kpUn = pKF - > mvKeysUn [ get < 0 > ( mit - > second ) ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKF - > mvuRight [ get < 0 > ( mit - > second ) ] < 0 ) // Monocular
{
mpObsMPs [ pMPi ] + + ;
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZ * e = new ORB_SLAM3 : : EdgeSE3ProjectXYZ ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKF - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKF - > mvInvLevelSigma2 [ kpUn . octave ] ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuber2D ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > pCamera = pKF - > mpCamera ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpEdgesMono . push_back ( e ) ;
vpEdgeKFMono . push_back ( pKF ) ;
vpMapPointEdgeMono . push_back ( pMPi ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
mpObsKFs [ pKF ] + + ;
}
else // RGBD or Stereo
{
mpObsMPs [ pMPi ] + = 2 ;
Eigen : : Matrix < double , 3 , 1 > obs ;
const float kp_ur = pKF - > mvuRight [ get < 0 > ( mit - > second ) ] ;
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : EdgeStereoSE3ProjectXYZ * e = new g2o : : EdgeStereoSE3ProjectXYZ ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKF - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKF - > mvInvLevelSigma2 [ kpUn . octave ] ;
Eigen : : Matrix3d Info = Eigen : : Matrix3d : : Identity ( ) * invSigma2 ;
e - > setInformation ( Info ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuber3D ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > fx = pKF - > fx ;
e - > fy = pKF - > fy ;
e - > cx = pKF - > cx ;
e - > cy = pKF - > cy ;
e - > bf = pKF - > mbf ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addEdge ( e ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpEdgesStereo . push_back ( e ) ;
vpEdgeKFStereo . push_back ( pKF ) ;
vpMapPointEdgeStereo . push_back ( pMPi ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
mpObsKFs [ pKF ] + + ;
2020-12-01 11:58:17 +08:00
}
}
}
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
if ( * pbStopFlag )
return ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . initializeOptimization ( ) ;
optimizer . optimize ( 5 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
bool bDoMore = true ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
if ( * pbStopFlag )
bDoMore = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
map < unsigned long int , int > mWrongObsKF ;
if ( bDoMore )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
// Check inlier observations
int badMonoMP = 0 , badStereoMP = 0 ;
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
ORB_SLAM3 : : EdgeSE3ProjectXYZ * e = vpEdgesMono [ i ] ;
MapPoint * pMP = vpMapPointEdgeMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > 5.991 | | ! e - > isDepthPositive ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
e - > setLevel ( 1 ) ;
badMonoMP + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
e - > setRobustKernel ( 0 ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
{
g2o : : EdgeStereoSE3ProjectXYZ * e = vpEdgesStereo [ i ] ;
MapPoint * pMP = vpMapPointEdgeStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
if ( e - > chi2 ( ) > 7.815 | | ! e - > isDepthPositive ( ) )
2020-12-01 11:58:17 +08:00
{
e - > setLevel ( 1 ) ;
2022-07-21 21:32:11 +08:00
badStereoMP + + ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
e - > setRobustKernel ( 0 ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " [BA]: First optimization(Huber), there are " + to_string ( badMonoMP ) + " monocular and " + to_string ( badStereoMP ) + " stereo bad edges " , Verbose : : VERBOSITY_DEBUG ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . initializeOptimization ( 0 ) ;
optimizer . optimize ( 10 ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < pair < KeyFrame * , MapPoint * > > vToErase ;
vToErase . reserve ( vpEdgesMono . size ( ) + vpEdgesStereo . size ( ) ) ;
set < MapPoint * > spErasedMPs ;
set < KeyFrame * > spErasedKFs ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Check inlier observations
int badMonoMP = 0 , badStereoMP = 0 ;
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
{
ORB_SLAM3 : : EdgeSE3ProjectXYZ * e = vpEdgesMono [ i ] ;
MapPoint * pMP = vpMapPointEdgeMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > 5.991 | | ! e - > isDepthPositive ( ) )
{
KeyFrame * pKFi = vpEdgeKFMono [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
mWrongObsKF [ pKFi - > mnId ] + + ;
badMonoMP + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
spErasedMPs . insert ( pMP ) ;
spErasedKFs . insert ( pKFi ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
{
g2o : : EdgeStereoSE3ProjectXYZ * e = vpEdgesStereo [ i ] ;
MapPoint * pMP = vpMapPointEdgeStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
if ( e - > chi2 ( ) > 7.815 | | ! e - > isDepthPositive ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpEdgeKFStereo [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
mWrongObsKF [ pKFi - > mnId ] + + ;
badStereoMP + + ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
spErasedMPs . insert ( pMP ) ;
spErasedKFs . insert ( pKFi ) ;
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " [BA]: Second optimization, there are " + to_string ( badMonoMP ) + " monocular and " + to_string ( badStereoMP ) + " sterero bad edges " , Verbose : : VERBOSITY_DEBUG ) ;
// Get Map Mutex
unique_lock < mutex > lock ( pMainKF - > GetMap ( ) - > mMutexMapUpdate ) ;
if ( ! vToErase . empty ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vToErase . size ( ) ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vToErase [ i ] . first ;
MapPoint * pMPi = vToErase [ i ] . second ;
pKFi - > EraseMapPointMatch ( pMPi ) ;
pMPi - > EraseObservation ( pKFi ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
}
for ( unsigned int i = 0 ; i < vpMPs . size ( ) ; + + i )
{
MapPoint * pMPi = vpMPs [ i ] ;
if ( pMPi - > isBad ( ) )
continue ;
const map < KeyFrame * , tuple < int , int > > observations = pMPi - > GetObservations ( ) ;
for ( map < KeyFrame * , tuple < int , int > > : : const_iterator mit = observations . begin ( ) ; mit ! = observations . end ( ) ; mit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKF = mit - > first ;
if ( pKF - > isBad ( ) | | pKF - > mnId > maxKFid | | pKF - > mnBALocalForKF ! = pMainKF - > mnId | | ! pKF - > GetMapPoint ( get < 0 > ( mit - > second ) ) )
continue ;
if ( pKF - > mvuRight [ get < 0 > ( mit - > second ) ] < 0 ) // Monocular
{
mpObsFinalKFs [ pKF ] + + ;
}
else // RGBD or Stereo
{
mpObsFinalKFs [ pKF ] + + ;
}
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
// Recover optimized data
// Keyframes
for ( KeyFrame * pKFi : vpAdjustKF )
{
if ( pKFi - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : VertexSE3Expmap * vSE3 = static_cast < g2o : : VertexSE3Expmap * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
g2o : : SE3Quat SE3quat = vSE3 - > estimate ( ) ;
Sophus : : SE3f Tiw ( SE3quat . rotation ( ) . cast < float > ( ) , SE3quat . translation ( ) . cast < float > ( ) ) ;
int numMonoBadPoints = 0 , numMonoOptPoints = 0 ;
int numStereoBadPoints = 0 , numStereoOptPoints = 0 ;
vector < MapPoint * > vpMonoMPsOpt , vpStereoMPsOpt ;
vector < MapPoint * > vpMonoMPsBad , vpStereoMPsBad ;
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
{
ORB_SLAM3 : : EdgeSE3ProjectXYZ * e = vpEdgesMono [ i ] ;
MapPoint * pMP = vpMapPointEdgeMono [ i ] ;
KeyFrame * pKFedge = vpEdgeKFMono [ i ] ;
if ( pKFi ! = pKFedge )
{
continue ;
}
if ( pMP - > isBad ( ) )
continue ;
if ( e - > chi2 ( ) > 5.991 | | ! e - > isDepthPositive ( ) )
{
numMonoBadPoints + + ;
vpMonoMPsBad . push_back ( pMP ) ;
}
else
{
numMonoOptPoints + + ;
vpMonoMPsOpt . push_back ( pMP ) ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
{
g2o : : EdgeStereoSE3ProjectXYZ * e = vpEdgesStereo [ i ] ;
MapPoint * pMP = vpMapPointEdgeStereo [ i ] ;
KeyFrame * pKFedge = vpEdgeKFMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi ! = pKFedge )
{
continue ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > 7.815 | | ! e - > isDepthPositive ( ) )
{
numStereoBadPoints + + ;
vpStereoMPsBad . push_back ( pMP ) ;
}
else
{
numStereoOptPoints + + ;
vpStereoMPsOpt . push_back ( pMP ) ;
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
pKFi - > SetPose ( Tiw ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Points
for ( MapPoint * pMPi : vpMPs )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( pMPi - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : VertexSBAPointXYZ * vPoint = static_cast < g2o : : VertexSBAPointXYZ * > ( optimizer . vertex ( pMPi - > mnId + maxKFid + 1 ) ) ;
pMPi - > SetWorldPos ( vPoint - > estimate ( ) . cast < float > ( ) ) ;
pMPi - > UpdateNormalAndDepth ( ) ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
void Optimizer : : OptimizeEssentialGraph (
KeyFrame * pCurKF , vector < KeyFrame * > & vpFixedKFs , vector < KeyFrame * > & vpFixedCorrectedKFs ,
vector < KeyFrame * > & vpNonFixedKFs , vector < MapPoint * > & vpNonCorrectedMPs )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " Opt_Essential: There are " + to_string ( vpFixedKFs . size ( ) ) + " KFs fixed in the merged map " , Verbose : : VERBOSITY_DEBUG ) ;
Verbose : : PrintMess ( " Opt_Essential: There are " + to_string ( vpFixedCorrectedKFs . size ( ) ) + " KFs fixed in the old map " , Verbose : : VERBOSITY_DEBUG ) ;
Verbose : : PrintMess ( " Opt_Essential: There are " + to_string ( vpNonFixedKFs . size ( ) ) + " KFs non-fixed in the merged map " , Verbose : : VERBOSITY_DEBUG ) ;
Verbose : : PrintMess ( " Opt_Essential: There are " + to_string ( vpNonCorrectedMPs . size ( ) ) + " MPs non-corrected in the merged map " , Verbose : : VERBOSITY_DEBUG ) ;
2020-12-01 11:58:17 +08:00
g2o : : SparseOptimizer optimizer ;
2022-07-21 21:32:11 +08:00
optimizer . setVerbose ( false ) ;
g2o : : BlockSolver_7_3 : : LinearSolverType * linearSolver =
new g2o : : LinearSolverEigen < g2o : : BlockSolver_7_3 : : PoseMatrixType > ( ) ;
g2o : : BlockSolver_7_3 * solver_ptr = new g2o : : BlockSolver_7_3 ( linearSolver ) ;
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
solver - > setUserLambdaInit ( 1e-16 ) ;
optimizer . setAlgorithm ( solver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Map * pMap = pCurKF - > GetMap ( ) ;
const unsigned int nMaxKFid = pMap - > GetMaxKFid ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < g2o : : Sim3 , Eigen : : aligned_allocator < g2o : : Sim3 > > vScw ( nMaxKFid + 1 ) ;
vector < g2o : : Sim3 , Eigen : : aligned_allocator < g2o : : Sim3 > > vCorrectedSwc ( nMaxKFid + 1 ) ;
vector < g2o : : VertexSim3Expmap * > vpVertices ( nMaxKFid + 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < bool > vpGoodPose ( nMaxKFid + 1 ) ;
vector < bool > vpBadPose ( nMaxKFid + 1 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int minFeat = 100 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( KeyFrame * pKFi : vpFixedKFs )
{
if ( pKFi - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : VertexSim3Expmap * VSim3 = new g2o : : VertexSim3Expmap ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3d Tcw = pKFi - > GetPose ( ) . cast < double > ( ) ;
g2o : : Sim3 Siw ( Tcw . unit_quaternion ( ) , Tcw . translation ( ) , 1.0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vCorrectedSwc [ nIDi ] = Siw . inverse ( ) ;
VSim3 - > setEstimate ( Siw ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VSim3 - > setFixed ( true ) ;
2022-03-28 21:20:28 +08:00
2022-07-21 21:32:11 +08:00
VSim3 - > setId ( nIDi ) ;
VSim3 - > setMarginalized ( false ) ;
VSim3 - > _fix_scale = true ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addVertex ( VSim3 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpVertices [ nIDi ] = VSim3 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpGoodPose [ nIDi ] = true ;
vpBadPose [ nIDi ] = false ;
}
Verbose : : PrintMess ( " Opt_Essential: vpFixedKFs loaded " , Verbose : : VERBOSITY_DEBUG ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
set < unsigned long > sIdKF ;
for ( KeyFrame * pKFi : vpFixedCorrectedKFs )
{
if ( pKFi - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : VertexSim3Expmap * VSim3 = new g2o : : VertexSim3Expmap ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3d Tcw = pKFi - > GetPose ( ) . cast < double > ( ) ;
g2o : : Sim3 Siw ( Tcw . unit_quaternion ( ) , Tcw . translation ( ) , 1.0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vCorrectedSwc [ nIDi ] = Siw . inverse ( ) ;
VSim3 - > setEstimate ( Siw ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3d Tcw_bef = pKFi - > mTcwBefMerge . cast < double > ( ) ;
vScw [ nIDi ] = g2o : : Sim3 ( Tcw_bef . unit_quaternion ( ) , Tcw_bef . translation ( ) , 1.0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VSim3 - > setFixed ( true ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VSim3 - > setId ( nIDi ) ;
VSim3 - > setMarginalized ( false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addVertex ( VSim3 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpVertices [ nIDi ] = VSim3 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
sIdKF . insert ( nIDi ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vpGoodPose [ nIDi ] = true ;
vpBadPose [ nIDi ] = true ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( KeyFrame * pKFi : vpNonFixedKFs )
{
if ( pKFi - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( sIdKF . count ( nIDi ) ) // It has already added in the corrected merge KFs
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : VertexSim3Expmap * VSim3 = new g2o : : VertexSim3Expmap ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3d Tcw = pKFi - > GetPose ( ) . cast < double > ( ) ;
g2o : : Sim3 Siw ( Tcw . unit_quaternion ( ) , Tcw . translation ( ) , 1.0 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vScw [ nIDi ] = Siw ;
VSim3 - > setEstimate ( Siw ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VSim3 - > setFixed ( false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VSim3 - > setId ( nIDi ) ;
VSim3 - > setMarginalized ( false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . addVertex ( VSim3 ) ;
vpVertices [ nIDi ] = VSim3 ;
sIdKF . insert ( nIDi ) ;
vpGoodPose [ nIDi ] = false ;
vpBadPose [ nIDi ] = true ;
2020-12-01 11:58:17 +08:00
}
2021-09-03 14:24:01 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpKFs ;
vpKFs . reserve ( vpFixedKFs . size ( ) + vpFixedCorrectedKFs . size ( ) + vpNonFixedKFs . size ( ) ) ;
vpKFs . insert ( vpKFs . end ( ) , vpFixedKFs . begin ( ) , vpFixedKFs . end ( ) ) ;
vpKFs . insert ( vpKFs . end ( ) , vpFixedCorrectedKFs . begin ( ) , vpFixedCorrectedKFs . end ( ) ) ;
vpKFs . insert ( vpKFs . end ( ) , vpNonFixedKFs . begin ( ) , vpNonFixedKFs . end ( ) ) ;
set < KeyFrame * > spKFs ( vpKFs . begin ( ) , vpKFs . end ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const Eigen : : Matrix < double , 7 , 7 > matLambda = Eigen : : Matrix < double , 7 , 7 > : : Identity ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( KeyFrame * pKFi : vpKFs )
{
int num_connections = 0 ;
const int nIDi = pKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 correctedSwi ;
g2o : : Sim3 Swi ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( vpGoodPose [ nIDi ] )
correctedSwi = vCorrectedSwc [ nIDi ] ;
if ( vpBadPose [ nIDi ] )
Swi = vScw [ nIDi ] . inverse ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
KeyFrame * pParentKFi = pKFi - > GetParent ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Spanning tree edge
if ( pParentKFi & & spKFs . find ( pParentKFi ) ! = spKFs . end ( ) )
{
int nIDj = pParentKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Sjw ;
bool bHasRelation = false ;
if ( vpGoodPose [ nIDi ] & & vpGoodPose [ nIDj ] )
{
Sjw = vCorrectedSwc [ nIDj ] . inverse ( ) ;
bHasRelation = true ;
}
else if ( vpBadPose [ nIDi ] & & vpBadPose [ nIDj ] )
{
Sjw = vScw [ nIDj ] ;
bHasRelation = true ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bHasRelation )
{
g2o : : Sim3 Sji = Sjw * Swi ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : EdgeSim3 * e = new g2o : : EdgeSim3 ( ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDj ) ) ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
e - > setMeasurement ( Sji ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > information ( ) = matLambda ;
optimizer . addEdge ( e ) ;
num_connections + + ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Loop edges
const set < KeyFrame * > sLoopEdges = pKFi - > GetLoopEdges ( ) ;
for ( set < KeyFrame * > : : const_iterator sit = sLoopEdges . begin ( ) , send = sLoopEdges . end ( ) ; sit ! = send ; sit + + )
{
KeyFrame * pLKF = * sit ;
if ( spKFs . find ( pLKF ) ! = spKFs . end ( ) & & pLKF - > mnId < pKFi - > mnId )
{
g2o : : Sim3 Slw ;
bool bHasRelation = false ;
if ( vpGoodPose [ nIDi ] & & vpGoodPose [ pLKF - > mnId ] )
{
Slw = vCorrectedSwc [ pLKF - > mnId ] . inverse ( ) ;
bHasRelation = true ;
}
else if ( vpBadPose [ nIDi ] & & vpBadPose [ pLKF - > mnId ] )
{
Slw = vScw [ pLKF - > mnId ] ;
bHasRelation = true ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bHasRelation )
{
g2o : : Sim3 Sli = Slw * Swi ;
g2o : : EdgeSim3 * el = new g2o : : EdgeSim3 ( ) ;
el - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pLKF - > mnId ) ) ) ;
el - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
el - > setMeasurement ( Sli ) ;
el - > information ( ) = matLambda ;
optimizer . addEdge ( el ) ;
num_connections + + ;
}
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Covisibility graph edges
const vector < KeyFrame * > vpConnectedKFs = pKFi - > GetCovisiblesByWeight ( minFeat ) ;
for ( vector < KeyFrame * > : : const_iterator vit = vpConnectedKFs . begin ( ) ; vit ! = vpConnectedKFs . end ( ) ; vit + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFn = * vit ;
if ( pKFn & & pKFn ! = pParentKFi & & ! pKFi - > hasChild ( pKFn ) & & ! sLoopEdges . count ( pKFn ) & & spKFs . find ( pKFn ) ! = spKFs . end ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( ! pKFn - > isBad ( ) & & pKFn - > mnId < pKFi - > mnId )
{
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : Sim3 Snw = vScw [ pKFn - > mnId ] ;
bool bHasRelation = false ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( vpGoodPose [ nIDi ] & & vpGoodPose [ pKFn - > mnId ] )
{
Snw = vCorrectedSwc [ pKFn - > mnId ] . inverse ( ) ;
bHasRelation = true ;
}
else if ( vpBadPose [ nIDi ] & & vpBadPose [ pKFn - > mnId ] )
{
Snw = vScw [ pKFn - > mnId ] ;
bHasRelation = true ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( bHasRelation )
{
g2o : : Sim3 Sni = Snw * Swi ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : EdgeSim3 * en = new g2o : : EdgeSim3 ( ) ;
en - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFn - > mnId ) ) ) ;
en - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( nIDi ) ) ) ;
en - > setMeasurement ( Sni ) ;
en - > information ( ) = matLambda ;
optimizer . addEdge ( en ) ;
num_connections + + ;
}
}
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
if ( num_connections = = 0 )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " Opt_Essential: KF " + to_string ( pKFi - > mnId ) + " has 0 connections " , Verbose : : VERBOSITY_DEBUG ) ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Optimize!
optimizer . initializeOptimization ( ) ;
optimizer . optimize ( 20 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
unique_lock < mutex > lock ( pMap - > mMutexMapUpdate ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// SE3 Pose Recovering. Sim3:[sR t;0 1] -> SE3:[R t/s;0 1]
for ( KeyFrame * pKFi : vpNonFixedKFs )
{
if ( pKFi - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const int nIDi = pKFi - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : VertexSim3Expmap * VSim3 = static_cast < g2o : : VertexSim3Expmap * > ( optimizer . vertex ( nIDi ) ) ;
g2o : : Sim3 CorrectedSiw = VSim3 - > estimate ( ) ;
vCorrectedSwc [ nIDi ] = CorrectedSiw . inverse ( ) ;
double s = CorrectedSiw . scale ( ) ;
Sophus : : SE3d Tiw ( CorrectedSiw . rotation ( ) , CorrectedSiw . translation ( ) / s ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
pKFi - > mTcwBefMerge = pKFi - > GetPose ( ) ;
pKFi - > mTwcBefMerge = pKFi - > GetPoseInverse ( ) ;
pKFi - > SetPose ( Tiw . cast < float > ( ) ) ;
}
// Correct points. Transform to "non-optimized" reference keyframe pose and transform back with optimized pose
for ( MapPoint * pMPi : vpNonCorrectedMPs )
{
if ( pMPi - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
KeyFrame * pRefKF = pMPi - > GetReferenceKeyFrame ( ) ;
while ( pRefKF - > isBad ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
if ( ! pRefKF )
{
Verbose : : PrintMess ( " MP " + to_string ( pMPi - > mnId ) + " without a valid reference KF " , Verbose : : VERBOSITY_DEBUG ) ;
break ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
pMPi - > EraseObservation ( pRefKF ) ;
pRefKF = pMPi - > GetReferenceKeyFrame ( ) ;
}
2021-12-08 22:09:39 +08:00
2022-07-21 21:32:11 +08:00
if ( vpBadPose [ pRefKF - > mnId ] )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
Sophus : : SE3f TNonCorrectedwr = pRefKF - > mTwcBefMerge ;
Sophus : : SE3f Twr = pRefKF - > GetPoseInverse ( ) ;
Eigen : : Vector3f eigCorrectedP3Dw = Twr * TNonCorrectedwr . inverse ( ) * pMPi - > GetWorldPos ( ) ;
pMPi - > SetWorldPos ( eigCorrectedP3Dw ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
pMPi - > UpdateNormalAndDepth ( ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
else
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
cout < < " ERROR: MapPoint has a reference KF from another map " < < endl ;
2020-12-01 11:58:17 +08:00
}
}
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
void Optimizer : : MergeInertialBA (
KeyFrame * pCurrKF , KeyFrame * pMergeKF , bool * pbStopFlag , Map * pMap , LoopClosing : : KeyFrameAndPose & corrPoses )
{
const int Nd = 6 ;
const unsigned long maxKFid = pCurrKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpOptimizableKFs ;
vpOptimizableKFs . reserve ( 2 * Nd ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// For cov KFS, inertial parameters are not optimized
const int maxCovKF = 30 ;
vector < KeyFrame * > vpOptimizableCovKFs ;
vpOptimizableCovKFs . reserve ( maxCovKF ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Add sliding window for current KF
vpOptimizableKFs . push_back ( pCurrKF ) ;
pCurrKF - > mnBALocalForKF = pCurrKF - > mnId ;
for ( int i = 1 ; i < Nd ; i + + )
{
if ( vpOptimizableKFs . back ( ) - > mPrevKF )
{
vpOptimizableKFs . push_back ( vpOptimizableKFs . back ( ) - > mPrevKF ) ;
vpOptimizableKFs . back ( ) - > mnBALocalForKF = pCurrKF - > mnId ;
}
else
break ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
list < KeyFrame * > lFixedKeyFrames ;
if ( vpOptimizableKFs . back ( ) - > mPrevKF )
{
vpOptimizableCovKFs . push_back ( vpOptimizableKFs . back ( ) - > mPrevKF ) ;
vpOptimizableKFs . back ( ) - > mPrevKF - > mnBALocalForKF = pCurrKF - > mnId ;
}
else
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
vpOptimizableCovKFs . push_back ( vpOptimizableKFs . back ( ) ) ;
vpOptimizableKFs . pop_back ( ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Add temporal neighbours to merge KF (previous and next KFs)
vpOptimizableKFs . push_back ( pMergeKF ) ;
pMergeKF - > mnBALocalForKF = pCurrKF - > mnId ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Previous KFs
for ( int i = 1 ; i < ( Nd / 2 ) ; i + + )
{
if ( vpOptimizableKFs . back ( ) - > mPrevKF )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
vpOptimizableKFs . push_back ( vpOptimizableKFs . back ( ) - > mPrevKF ) ;
vpOptimizableKFs . back ( ) - > mnBALocalForKF = pCurrKF - > mnId ;
2020-12-01 11:58:17 +08:00
}
else
2022-07-21 21:32:11 +08:00
break ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// We fix just once the old map
if ( vpOptimizableKFs . back ( ) - > mPrevKF )
{
lFixedKeyFrames . push_back ( vpOptimizableKFs . back ( ) - > mPrevKF ) ;
vpOptimizableKFs . back ( ) - > mPrevKF - > mnBAFixedForKF = pCurrKF - > mnId ;
}
else
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
vpOptimizableKFs . back ( ) - > mnBALocalForKF = 0 ;
vpOptimizableKFs . back ( ) - > mnBAFixedForKF = pCurrKF - > mnId ;
lFixedKeyFrames . push_back ( vpOptimizableKFs . back ( ) ) ;
vpOptimizableKFs . pop_back ( ) ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Next KFs
if ( pMergeKF - > mNextKF )
{
vpOptimizableKFs . push_back ( pMergeKF - > mNextKF ) ;
vpOptimizableKFs . back ( ) - > mnBALocalForKF = pCurrKF - > mnId ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
while ( vpOptimizableKFs . size ( ) < ( 2 * Nd ) )
{
if ( vpOptimizableKFs . back ( ) - > mNextKF )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
vpOptimizableKFs . push_back ( vpOptimizableKFs . back ( ) - > mNextKF ) ;
vpOptimizableKFs . back ( ) - > mnBALocalForKF = pCurrKF - > mnId ;
2020-12-01 11:58:17 +08:00
}
else
2022-07-21 21:32:11 +08:00
break ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
int N = vpOptimizableKFs . size ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Optimizable points seen by optimizable keyframes
list < MapPoint * > lLocalMapPoints ;
map < MapPoint * , int > mLocalObs ;
for ( int i = 0 ; i < N ; i + + )
{
vector < MapPoint * > vpMPs = vpOptimizableKFs [ i ] - > GetMapPointMatches ( ) ;
for ( vector < MapPoint * > : : iterator vit = vpMPs . begin ( ) , vend = vpMPs . end ( ) ; vit ! = vend ; vit + + )
{
// Using mnBALocalForKF we avoid redundance here, one MP can not be added several times to lLocalMapPoints
MapPoint * pMP = * vit ;
if ( pMP )
if ( ! pMP - > isBad ( ) )
if ( pMP - > mnBALocalForKF ! = pCurrKF - > mnId )
{
mLocalObs [ pMP ] = 1 ;
lLocalMapPoints . push_back ( pMP ) ;
pMP - > mnBALocalForKF = pCurrKF - > mnId ;
}
else
{
mLocalObs [ pMP ] + + ;
}
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
std : : vector < std : : pair < MapPoint * , int > > pairs ;
pairs . reserve ( mLocalObs . size ( ) ) ;
for ( auto itr = mLocalObs . begin ( ) ; itr ! = mLocalObs . end ( ) ; + + itr )
pairs . push_back ( * itr ) ;
sort ( pairs . begin ( ) , pairs . end ( ) , sortByVal ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Fixed Keyframes. Keyframes that see Local MapPoints but that are not Local Keyframes
int i = 0 ;
for ( vector < pair < MapPoint * , int > > : : iterator lit = pairs . begin ( ) , lend = pairs . end ( ) ; lit ! = lend ; lit + + , i + + )
{
map < KeyFrame * , tuple < int , int > > observations = lit - > first - > GetObservations ( ) ;
if ( i > = maxCovKF )
break ;
for ( map < KeyFrame * , tuple < int , int > > : : iterator mit = observations . begin ( ) , mend = observations . end ( ) ; mit ! = mend ; mit + + )
{
KeyFrame * pKFi = mit - > first ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mnBALocalForKF ! = pCurrKF - > mnId & & pKFi - > mnBAFixedForKF ! = pCurrKF - > mnId ) // If optimizable or already included...
{
pKFi - > mnBALocalForKF = pCurrKF - > mnId ;
if ( ! pKFi - > isBad ( ) )
{
vpOptimizableCovKFs . push_back ( pKFi ) ;
break ;
}
}
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : SparseOptimizer optimizer ;
g2o : : BlockSolverX : : LinearSolverType * linearSolver ;
linearSolver = new g2o : : LinearSolverEigen < g2o : : BlockSolverX : : PoseMatrixType > ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : BlockSolverX * solver_ptr = new g2o : : BlockSolverX ( linearSolver ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : OptimizationAlgorithmLevenberg * solver = new g2o : : OptimizationAlgorithmLevenberg ( solver_ptr ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
solver - > setUserLambdaInit ( 1e3 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
optimizer . setAlgorithm ( solver ) ;
optimizer . setVerbose ( false ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Local KeyFrame vertices
N = vpOptimizableKFs . size ( ) ;
for ( int i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
KeyFrame * pKFi = vpOptimizableKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexPose * VP = new VertexPose ( pKFi ) ;
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( false ) ;
optimizer . addVertex ( VP ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu )
{
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
VV - > setFixed ( false ) ;
optimizer . addVertex ( VV ) ;
VertexGyroBias * VG = new VertexGyroBias ( pKFi ) ;
VG - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
VG - > setFixed ( false ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pKFi ) ;
VA - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
VA - > setFixed ( false ) ;
optimizer . addVertex ( VA ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set Local cov keyframes vertices
int Ncov = vpOptimizableCovKFs . size ( ) ;
for ( int i = 0 ; i < Ncov ; i + + )
{
KeyFrame * pKFi = vpOptimizableCovKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexPose * VP = new VertexPose ( pKFi ) ;
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( false ) ;
optimizer . addVertex ( VP ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu )
{
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
VV - > setFixed ( false ) ;
optimizer . addVertex ( VV ) ;
VertexGyroBias * VG = new VertexGyroBias ( pKFi ) ;
VG - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
VG - > setFixed ( false ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pKFi ) ;
VA - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
VA - > setFixed ( false ) ;
optimizer . addVertex ( VA ) ;
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Set Fixed KeyFrame vertices
for ( list < KeyFrame * > : : iterator lit = lFixedKeyFrames . begin ( ) , lend = lFixedKeyFrames . end ( ) ; lit ! = lend ; lit + + )
{
KeyFrame * pKFi = * lit ;
VertexPose * VP = new VertexPose ( pKFi ) ;
VP - > setId ( pKFi - > mnId ) ;
VP - > setFixed ( true ) ;
optimizer . addVertex ( VP ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu )
{
VertexVelocity * VV = new VertexVelocity ( pKFi ) ;
VV - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
VV - > setFixed ( true ) ;
optimizer . addVertex ( VV ) ;
VertexGyroBias * VG = new VertexGyroBias ( pKFi ) ;
VG - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
VG - > setFixed ( true ) ;
optimizer . addVertex ( VG ) ;
VertexAccBias * VA = new VertexAccBias ( pKFi ) ;
VA - > setId ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
VA - > setFixed ( true ) ;
optimizer . addVertex ( VA ) ;
}
}
// Create intertial constraints
vector < EdgeInertial * > vei ( N , ( EdgeInertial * ) NULL ) ;
vector < EdgeGyroRW * > vegr ( N , ( EdgeGyroRW * ) NULL ) ;
vector < EdgeAccRW * > vear ( N , ( EdgeAccRW * ) NULL ) ;
for ( int i = 0 ; i < N ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
// cout << "inserting inertial edge " << i << endl;
KeyFrame * pKFi = vpOptimizableKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > mPrevKF )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " NOT INERTIAL LINK TO PREVIOUS FRAME!!!! " , Verbose : : VERBOSITY_NORMAL ) ;
continue ;
}
if ( pKFi - > bImu & & pKFi - > mPrevKF - > bImu & & pKFi - > mpImuPreintegrated )
{
pKFi - > mpImuPreintegrated - > SetNewBias ( pKFi - > mPrevKF - > GetImuBias ( ) ) ;
g2o : : HyperGraph : : Vertex * VP1 = optimizer . vertex ( pKFi - > mPrevKF - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 1 ) ;
g2o : : HyperGraph : : Vertex * VG1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 2 ) ;
g2o : : HyperGraph : : Vertex * VA1 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mPrevKF - > mnId ) + 3 ) ;
g2o : : HyperGraph : : Vertex * VP2 = optimizer . vertex ( pKFi - > mnId ) ;
g2o : : HyperGraph : : Vertex * VV2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ;
g2o : : HyperGraph : : Vertex * VG2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ;
g2o : : HyperGraph : : Vertex * VA2 = optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ;
if ( ! VP1 | | ! VV1 | | ! VG1 | | ! VA1 | | ! VP2 | | ! VV2 | | ! VG2 | | ! VA2 )
{
cerr < < " Error " < < VP1 < < " , " < < VV1 < < " , " < < VG1 < < " , " < < VA1 < < " , " < < VP2 < < " , " < < VV2 < < " , " < < VG2 < < " , " < < VA2 < < endl ;
2020-12-01 11:58:17 +08:00
continue ;
2022-07-21 21:32:11 +08:00
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vei [ i ] = new EdgeInertial ( pKFi - > mpImuPreintegrated ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vei [ i ] - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP1 ) ) ;
vei [ i ] - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV1 ) ) ;
vei [ i ] - > setVertex ( 2 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VG1 ) ) ;
vei [ i ] - > setVertex ( 3 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VA1 ) ) ;
vei [ i ] - > setVertex ( 4 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VP2 ) ) ;
vei [ i ] - > setVertex ( 5 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( VV2 ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// TODO Uncomment
g2o : : RobustKernelHuber * rki = new g2o : : RobustKernelHuber ;
vei [ i ] - > setRobustKernel ( rki ) ;
rki - > setDelta ( sqrt ( 16.92 ) ) ;
optimizer . addEdge ( vei [ i ] ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vegr [ i ] = new EdgeGyroRW ( ) ;
vegr [ i ] - > setVertex ( 0 , VG1 ) ;
vegr [ i ] - > setVertex ( 1 , VG2 ) ;
Eigen : : Matrix3d InfoG = pKFi - > mpImuPreintegrated - > C . block < 3 , 3 > ( 9 , 9 ) . cast < double > ( ) . inverse ( ) ;
vegr [ i ] - > setInformation ( InfoG ) ;
optimizer . addEdge ( vegr [ i ] ) ;
vear [ i ] = new EdgeAccRW ( ) ;
vear [ i ] - > setVertex ( 0 , VA1 ) ;
vear [ i ] - > setVertex ( 1 , VA2 ) ;
Eigen : : Matrix3d InfoA = pKFi - > mpImuPreintegrated - > C . block < 3 , 3 > ( 12 , 12 ) . cast < double > ( ) . inverse ( ) ;
vear [ i ] - > setInformation ( InfoA ) ;
optimizer . addEdge ( vear [ i ] ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
else
Verbose : : PrintMess ( " ERROR building inertial edge " , Verbose : : VERBOSITY_NORMAL ) ;
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
Verbose : : PrintMess ( " end inserting inertial edges " , Verbose : : VERBOSITY_NORMAL ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Set MapPoint vertices
const int nExpectedSize = ( N + Ncov + lFixedKeyFrames . size ( ) ) * lLocalMapPoints . size ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Mono
vector < EdgeMono * > vpEdgesMono ;
vpEdgesMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFMono ;
vpEdgeKFMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeMono ;
vpMapPointEdgeMono . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Stereo
vector < EdgeStereo * > vpEdgesStereo ;
vpEdgesStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < KeyFrame * > vpEdgeKFStereo ;
vpEdgeKFStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < MapPoint * > vpMapPointEdgeStereo ;
vpMapPointEdgeStereo . reserve ( nExpectedSize ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const float thHuberMono = sqrt ( 5.991 ) ;
const float chi2Mono2 = 5.991 ;
const float thHuberStereo = sqrt ( 7.815 ) ;
const float chi2Stereo2 = 7.815 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const unsigned long iniMPid = maxKFid * 5 ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( list < MapPoint * > : : iterator lit = lLocalMapPoints . begin ( ) , lend = lLocalMapPoints . end ( ) ; lit ! = lend ; lit + + )
{
MapPoint * pMP = * lit ;
if ( ! pMP )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : VertexSBAPointXYZ * vPoint = new g2o : : VertexSBAPointXYZ ( ) ;
vPoint - > setEstimate ( pMP - > GetWorldPos ( ) . cast < double > ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
unsigned long id = pMP - > mnId + iniMPid + 1 ;
vPoint - > setId ( id ) ;
vPoint - > setMarginalized ( true ) ;
optimizer . addVertex ( vPoint ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
const map < KeyFrame * , tuple < int , int > > observations = pMP - > GetObservations ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Create visual constraints
for ( map < KeyFrame * , tuple < int , int > > : : const_iterator mit = observations . begin ( ) , mend = observations . end ( ) ; mit ! = mend ; mit + + )
{
KeyFrame * pKFi = mit - > first ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pKFi )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ( pKFi - > mnBALocalForKF ! = pCurrKF - > mnId ) & & ( pKFi - > mnBAFixedForKF ! = pCurrKF - > mnId ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mnId > maxKFid )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
continue ;
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( optimizer . vertex ( id ) = = NULL | | optimizer . vertex ( pKFi - > mnId ) = = NULL )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( ! pKFi - > isBad ( ) )
{
const cv : : KeyPoint & kpUn = pKFi - > mvKeysUn [ get < 0 > ( mit - > second ) ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > mvuRight [ get < 0 > ( mit - > second ) ] < 0 ) // Monocular observation
{
Eigen : : Matrix < double , 2 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeMono * e = new EdgeMono ( ) ;
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] ;
e - > setInformation ( Eigen : : Matrix2d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberMono ) ;
optimizer . addEdge ( e ) ;
vpEdgesMono . push_back ( e ) ;
vpEdgeKFMono . push_back ( pKFi ) ;
vpMapPointEdgeMono . push_back ( pMP ) ;
}
else // stereo observation
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
const float kp_ur = pKFi - > mvuRight [ get < 0 > ( mit - > second ) ] ;
Eigen : : Matrix < double , 3 , 1 > obs ;
obs < < kpUn . pt . x , kpUn . pt . y , kp_ur ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
EdgeStereo * e = new EdgeStereo ( ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
e - > setVertex ( 0 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( id ) ) ) ;
e - > setVertex ( 1 , dynamic_cast < g2o : : OptimizableGraph : : Vertex * > ( optimizer . vertex ( pKFi - > mnId ) ) ) ;
e - > setMeasurement ( obs ) ;
const float & invSigma2 = pKFi - > mvInvLevelSigma2 [ kpUn . octave ] ;
e - > setInformation ( Eigen : : Matrix3d : : Identity ( ) * invSigma2 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
g2o : : RobustKernelHuber * rk = new g2o : : RobustKernelHuber ;
e - > setRobustKernel ( rk ) ;
rk - > setDelta ( thHuberStereo ) ;
2020-12-01 11:58:17 +08:00
optimizer . addEdge ( e ) ;
2022-07-21 21:32:11 +08:00
vpEdgesStereo . push_back ( e ) ;
vpEdgeKFStereo . push_back ( pKFi ) ;
vpMapPointEdgeStereo . push_back ( pMP ) ;
2020-12-01 11:58:17 +08:00
}
}
}
}
2022-07-21 21:32:11 +08:00
if ( pbStopFlag )
optimizer . setForceStopFlag ( pbStopFlag ) ;
if ( pbStopFlag )
if ( * pbStopFlag )
return ;
2020-12-01 11:58:17 +08:00
optimizer . initializeOptimization ( ) ;
2022-07-21 21:32:11 +08:00
optimizer . optimize ( 8 ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
vector < pair < KeyFrame * , MapPoint * > > vToErase ;
vToErase . reserve ( vpEdgesMono . size ( ) + vpEdgesStereo . size ( ) ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Check inlier observations
// Mono
for ( size_t i = 0 , iend = vpEdgesMono . size ( ) ; i < iend ; i + + )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
EdgeMono * e = vpEdgesMono [ i ] ;
MapPoint * pMP = vpMapPointEdgeMono [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( e - > chi2 ( ) > chi2Mono2 )
{
KeyFrame * pKFi = vpEdgeKFMono [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Stereo
for ( size_t i = 0 , iend = vpEdgesStereo . size ( ) ; i < iend ; i + + )
{
EdgeStereo * e = vpEdgesStereo [ i ] ;
MapPoint * pMP = vpMapPointEdgeStereo [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pMP - > isBad ( ) )
continue ;
if ( e - > chi2 ( ) > chi2Stereo2 )
{
KeyFrame * pKFi = vpEdgeKFStereo [ i ] ;
vToErase . push_back ( make_pair ( pKFi , pMP ) ) ;
}
2020-12-01 11:58:17 +08:00
}
2022-07-21 21:32:11 +08:00
// Get Map Mutex and erase outliers
unique_lock < mutex > lock ( pMap - > mMutexMapUpdate ) ;
if ( ! vToErase . empty ( ) )
2020-12-01 11:58:17 +08:00
{
2022-07-21 21:32:11 +08:00
for ( size_t i = 0 ; i < vToErase . size ( ) ; i + + )
{
KeyFrame * pKFi = vToErase [ i ] . first ;
MapPoint * pMPi = vToErase [ i ] . second ;
pKFi - > EraseMapPointMatch ( pMPi ) ;
pMPi - > EraseObservation ( pKFi ) ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
// Recover optimized data
// Keyframes
for ( int i = 0 ; i < N ; i + + )
{
KeyFrame * pKFi = vpOptimizableKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexPose * VP = static_cast < VertexPose * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
Sophus : : SE3f Tcw ( VP - > estimate ( ) . Rcw [ 0 ] . cast < float > ( ) , VP - > estimate ( ) . tcw [ 0 ] . cast < float > ( ) ) ;
pKFi - > SetPose ( Tcw ) ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
Sophus : : SE3d Tiw = pKFi - > GetPose ( ) . cast < double > ( ) ;
g2o : : Sim3 g2oSiw ( Tiw . unit_quaternion ( ) , Tiw . translation ( ) , 1.0 ) ;
corrPoses [ pKFi ] = g2oSiw ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
if ( pKFi - > bImu )
{
VertexVelocity * VV = static_cast < VertexVelocity * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ) ;
pKFi - > SetVelocity ( VV - > estimate ( ) . cast < float > ( ) ) ;
VertexGyroBias * VG = static_cast < VertexGyroBias * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ) ;
VertexAccBias * VA = static_cast < VertexAccBias * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ) ;
Vector6d b ;
b < < VG - > estimate ( ) , VA - > estimate ( ) ;
pKFi - > SetNewBias ( IMU : : Bias ( b [ 3 ] , b [ 4 ] , b [ 5 ] , b [ 0 ] , b [ 1 ] , b [ 2 ] ) ) ;
}
}
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
for ( int i = 0 ; i < Ncov ; i + + )
{
KeyFrame * pKFi = vpOptimizableCovKFs [ i ] ;
2020-12-01 11:58:17 +08:00
2022-07-21 21:32:11 +08:00
VertexPose * VP = static_cast < VertexPose * > ( optimizer . vertex ( pKFi - > mnId ) ) ;
Sophus : : SE3f Tcw ( VP - > estimate ( ) . Rcw [ 0 ] . cast < float > ( ) , VP - > estimate ( ) . tcw [ 0 ] . cast < float > ( ) ) ;
pKFi - > SetPose ( Tcw ) ;
Sophus : : SE3d Tiw = pKFi - > GetPose ( ) . cast < double > ( ) ;
g2o : : Sim3 g2oSiw ( Tiw . unit_quaternion ( ) , Tiw . translation ( ) , 1.0 ) ;
corrPoses [ pKFi ] = g2oSiw ;
if ( pKFi - > bImu )
{
VertexVelocity * VV = static_cast < VertexVelocity * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 1 ) ) ;
pKFi - > SetVelocity ( VV - > estimate ( ) . cast < float > ( ) ) ;
VertexGyroBias * VG = static_cast < VertexGyroBias * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 2 ) ) ;
VertexAccBias * VA = static_cast < VertexAccBias * > ( optimizer . vertex ( maxKFid + 3 * ( pKFi - > mnId ) + 3 ) ) ;
Vector6d b ;
b < < VG - > estimate ( ) , VA - > estimate ( ) ;
pKFi - > SetNewBias ( IMU : : Bias ( b [ 3 ] , b [ 4 ] , b [ 5 ] , b [ 0 ] , b [ 1 ] , b [ 2 ] ) ) ;
}
}
// Points
for ( list < MapPoint * > : : iterator lit = lLocalMapPoints . begin ( ) , lend = lLocalMapPoints . end ( ) ; lit ! = lend ; lit + + )
{
MapPoint * pMP = * lit ;
g2o : : VertexSBAPointXYZ * vPoint = static_cast < g2o : : VertexSBAPointXYZ * > ( optimizer . vertex ( pMP - > mnId + iniMPid + 1 ) ) ;
pMP - > SetWorldPos ( vPoint - > estimate ( ) . cast < float > ( ) ) ;
2020-12-01 11:58:17 +08:00
pMP - > UpdateNormalAndDepth ( ) ;
}
2022-07-21 21:32:11 +08:00
2020-12-01 11:58:17 +08:00
pMap - > IncreaseChangeIndex ( ) ;
}
2022-07-21 21:32:11 +08:00
} // namespace ORB_SLAM