更新标注
parent
965140d945
commit
8dcefb5567
|
@ -67,7 +67,7 @@ Eigen::Matrix3d InverseRightJacobianSO3(const double x, const double y, const do
|
||||||
|
|
||||||
Eigen::Matrix3d NormalizeRotation(const Eigen::Matrix3d &R);
|
Eigen::Matrix3d NormalizeRotation(const Eigen::Matrix3d &R);
|
||||||
|
|
||||||
|
// 相关节点中使用,存放的是imu与cam的内外参
|
||||||
class ImuCamPose
|
class ImuCamPose
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -103,9 +103,10 @@ public:
|
||||||
Eigen::Matrix3d Rwb0;
|
Eigen::Matrix3d Rwb0;
|
||||||
Eigen::Matrix3d DR;
|
Eigen::Matrix3d DR;
|
||||||
|
|
||||||
int its;
|
int its; // 记录更新次数
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 逆深度点,后面节点虽然有用到,但是声明的节点并没有使用到,暂时不看
|
||||||
class InvDepthPoint
|
class InvDepthPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -124,6 +125,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Optimizable parameters are IMU pose
|
// Optimizable parameters are IMU pose
|
||||||
|
// 优化中关于位姿的节点,6自由度
|
||||||
class VertexPose : public g2o::BaseVertex<6,ImuCamPose>
|
class VertexPose : public g2o::BaseVertex<6,ImuCamPose>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -140,15 +142,21 @@ public:
|
||||||
virtual bool read(std::istream& is);
|
virtual bool read(std::istream& is);
|
||||||
virtual bool write(std::ostream& os) const;
|
virtual bool write(std::ostream& os) const;
|
||||||
|
|
||||||
|
// 重置函数,设定被优化变量的原始值
|
||||||
virtual void setToOriginImpl() {
|
virtual void setToOriginImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新
|
||||||
virtual void oplusImpl(const double* update_){
|
virtual void oplusImpl(const double* update_){
|
||||||
_estimate.Update(update_);
|
_estimate.Update(update_);
|
||||||
|
// https://github.com/RainerKuemmerle/g2o/blob/master/doc/README_IF_IT_WAS_WORKING_AND_IT_DOES_NOT.txt
|
||||||
|
// 官方讲解cache
|
||||||
|
// 需要在oplusImpl与setEstimate函数中添加
|
||||||
updateCache();
|
updateCache();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 优化中关于位姿的节点,4自由度 3个平移加一个航偏
|
||||||
class VertexPose4DoF : public g2o::BaseVertex<4,ImuCamPose>
|
class VertexPose4DoF : public g2o::BaseVertex<4,ImuCamPose>
|
||||||
{
|
{
|
||||||
// Translation and yaw are the only optimizable variables
|
// Translation and yaw are the only optimizable variables
|
||||||
|
@ -172,6 +180,7 @@ public:
|
||||||
virtual void setToOriginImpl() {
|
virtual void setToOriginImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 强制让旋转的前两维的更新量为0
|
||||||
virtual void oplusImpl(const double* update_){
|
virtual void oplusImpl(const double* update_){
|
||||||
double update6DoF[6];
|
double update6DoF[6];
|
||||||
update6DoF[0] = 0;
|
update6DoF[0] = 0;
|
||||||
|
@ -185,6 +194,9 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 速度节点
|
||||||
|
*/
|
||||||
class VertexVelocity : public g2o::BaseVertex<3,Eigen::Vector3d>
|
class VertexVelocity : public g2o::BaseVertex<3,Eigen::Vector3d>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -206,6 +218,9 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 陀螺仪偏置节点
|
||||||
|
*/
|
||||||
class VertexGyroBias : public g2o::BaseVertex<3,Eigen::Vector3d>
|
class VertexGyroBias : public g2o::BaseVertex<3,Eigen::Vector3d>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -227,7 +242,9 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 加速度计偏置节点
|
||||||
|
*/
|
||||||
class VertexAccBias : public g2o::BaseVertex<3,Eigen::Vector3d>
|
class VertexAccBias : public g2o::BaseVertex<3,Eigen::Vector3d>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -251,6 +268,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// Gravity direction vertex
|
// Gravity direction vertex
|
||||||
|
// 重力方向
|
||||||
class GDirection
|
class GDirection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -268,6 +286,9 @@ public:
|
||||||
int its;
|
int its;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 重力方向节点
|
||||||
|
*/
|
||||||
class VertexGDir : public g2o::BaseVertex<2,GDirection>
|
class VertexGDir : public g2o::BaseVertex<2,GDirection>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -290,6 +311,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// scale vertex
|
// scale vertex
|
||||||
|
/**
|
||||||
|
* @brief 尺度节点
|
||||||
|
*/
|
||||||
class VertexScale : public g2o::BaseVertex<1,double>
|
class VertexScale : public g2o::BaseVertex<1,double>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -315,6 +339,9 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// Inverse depth point (just one parameter, inverse depth at the host frame)
|
// Inverse depth point (just one parameter, inverse depth at the host frame)
|
||||||
|
/**
|
||||||
|
* @brief 没用
|
||||||
|
*/
|
||||||
class VertexInvDepth : public g2o::BaseVertex<1,InvDepthPoint>
|
class VertexInvDepth : public g2o::BaseVertex<1,InvDepthPoint>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -337,12 +364,13 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 视觉重投影的边
|
* @brief 单目视觉重投影的边
|
||||||
* 这里或许会有疑问,OptimizableTypes.h 里面不是定义了视觉重投影的边么?
|
* 这里或许会有疑问,OptimizableTypes.h 里面不是定义了视觉重投影的边么?
|
||||||
* 原因是这样,那里面定义的边也用,不过只是在纯视觉时,没有imu情况下,因为用已经定义好的节点就好
|
* 原因是这样,那里面定义的边也用,不过只是在纯视觉时,没有imu情况下,因为用已经定义好的节点就好
|
||||||
* 但是加入imu时,优化要有残差的边与重投影的边同时存在,且两个边可能连接同一个位姿节点,所以需要重新弄一个包含imu位姿的节点
|
* 但是加入imu时,优化要有残差的边与重投影的边同时存在,且两个边可能连接同一个位姿节点,所以需要重新弄一个包含imu位姿的节点
|
||||||
* 因此,边也需要重新写,并且在imu优化时使用这个边
|
* 因此,边也需要重新写,并且在imu优化时使用这个边
|
||||||
*/
|
*/
|
||||||
|
// 误差为2维, 类型为Eigen::Vector2d, 节点1类型为g2o::VertexSBAPointXYZ,节点二类型为VertexPose
|
||||||
class EdgeMono : public g2o::BaseBinaryEdge<2,Eigen::Vector2d,g2o::VertexSBAPointXYZ,VertexPose>
|
class EdgeMono : public g2o::BaseBinaryEdge<2,Eigen::Vector2d,g2o::VertexSBAPointXYZ,VertexPose>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -354,11 +382,12 @@ public:
|
||||||
virtual bool read(std::istream& is){return false;}
|
virtual bool read(std::istream& is){return false;}
|
||||||
virtual bool write(std::ostream& os) const{return false;}
|
virtual bool write(std::ostream& os) const{return false;}
|
||||||
|
|
||||||
|
// 计算重投影误差
|
||||||
void computeError(){
|
void computeError(){
|
||||||
const g2o::VertexSBAPointXYZ* VPoint = static_cast<const g2o::VertexSBAPointXYZ*>(_vertices[0]);
|
const g2o::VertexSBAPointXYZ* VPoint = static_cast<const g2o::VertexSBAPointXYZ*>(_vertices[0]);
|
||||||
const VertexPose* VPose = static_cast<const VertexPose*>(_vertices[1]);
|
const VertexPose* VPose = static_cast<const VertexPose*>(_vertices[1]);
|
||||||
const Eigen::Vector2d obs(_measurement);
|
const Eigen::Vector2d obs(_measurement);
|
||||||
_error = obs - VPose->estimate().Project(VPoint->estimate(),cam_idx);
|
_error = obs - VPose->estimate().Project(VPoint->estimate(),cam_idx); // 投影
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -379,6 +408,7 @@ public:
|
||||||
return J;
|
return J;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 由2*2的像素点信息矩阵变成了9*9的关于旋转平移与三维点坐标的信息矩阵
|
||||||
Eigen::Matrix<double,9,9> GetHessian(){
|
Eigen::Matrix<double,9,9> GetHessian(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,2,9> J;
|
Eigen::Matrix<double,2,9> J;
|
||||||
|
@ -391,6 +421,9 @@ public:
|
||||||
const int cam_idx;
|
const int cam_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 单目纯位姿一元边
|
||||||
|
*/
|
||||||
class EdgeMonoOnlyPose : public g2o::BaseUnaryEdge<2,Eigen::Vector2d,VertexPose>
|
class EdgeMonoOnlyPose : public g2o::BaseUnaryEdge<2,Eigen::Vector2d,VertexPose>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -426,11 +459,15 @@ public:
|
||||||
const int cam_idx;
|
const int cam_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 双目位姿三维点二元边
|
||||||
|
*/
|
||||||
class EdgeStereo : public g2o::BaseBinaryEdge<3,Eigen::Vector3d,g2o::VertexSBAPointXYZ,VertexPose>
|
class EdgeStereo : public g2o::BaseBinaryEdge<3,Eigen::Vector3d,g2o::VertexSBAPointXYZ,VertexPose>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||||
|
|
||||||
|
// 代码中都是0
|
||||||
EdgeStereo(int cam_idx_=0): cam_idx(cam_idx_){}
|
EdgeStereo(int cam_idx_=0): cam_idx(cam_idx_){}
|
||||||
|
|
||||||
virtual bool read(std::istream& is){return false;}
|
virtual bool read(std::istream& is){return false;}
|
||||||
|
@ -466,7 +503,9 @@ public:
|
||||||
const int cam_idx;
|
const int cam_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 双目纯位姿一元边
|
||||||
|
*/
|
||||||
class EdgeStereoOnlyPose : public g2o::BaseUnaryEdge<3,Eigen::Vector3d,VertexPose>
|
class EdgeStereoOnlyPose : public g2o::BaseUnaryEdge<3,Eigen::Vector3d,VertexPose>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -497,6 +536,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// TO COMMENT
|
// TO COMMENT
|
||||||
|
/**
|
||||||
|
* @brief 惯性边(误差为残差)
|
||||||
|
*/
|
||||||
class EdgeInertial : public g2o::BaseMultiEdge<9,Vector9d>
|
class EdgeInertial : public g2o::BaseMultiEdge<9,Vector9d>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -510,6 +552,7 @@ public:
|
||||||
void computeError();
|
void computeError();
|
||||||
virtual void linearizeOplus();
|
virtual void linearizeOplus();
|
||||||
|
|
||||||
|
// 关于pose1与2 的旋转平移速度,以及之间的偏置的信息矩阵
|
||||||
Eigen::Matrix<double,24,24> GetHessian(){
|
Eigen::Matrix<double,24,24> GetHessian(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,9,24> J;
|
Eigen::Matrix<double,9,24> J;
|
||||||
|
@ -522,6 +565,7 @@ public:
|
||||||
return J.transpose()*information()*J;
|
return J.transpose()*information()*J;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 没用
|
||||||
Eigen::Matrix<double,18,18> GetHessianNoPose1(){
|
Eigen::Matrix<double,18,18> GetHessianNoPose1(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,9,18> J;
|
Eigen::Matrix<double,9,18> J;
|
||||||
|
@ -533,6 +577,7 @@ public:
|
||||||
return J.transpose()*information()*J;
|
return J.transpose()*information()*J;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 关于pose2 的旋转平移信息矩阵
|
||||||
Eigen::Matrix<double,9,9> GetHessian2(){
|
Eigen::Matrix<double,9,9> GetHessian2(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,9,9> J;
|
Eigen::Matrix<double,9,9> J;
|
||||||
|
@ -541,14 +586,18 @@ public:
|
||||||
return J.transpose()*information()*J;
|
return J.transpose()*information()*J;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预积分中对应的状态对偏置的雅可比
|
||||||
const Eigen::Matrix3d JRg, JVg, JPg;
|
const Eigen::Matrix3d JRg, JVg, JPg;
|
||||||
const Eigen::Matrix3d JVa, JPa;
|
const Eigen::Matrix3d JVa, JPa;
|
||||||
IMU::Preintegrated* mpInt;
|
|
||||||
const double dt;
|
IMU::Preintegrated* mpInt; // 预积分
|
||||||
Eigen::Vector3d g;
|
const double dt; // 预积分时间
|
||||||
|
Eigen::Vector3d g; // 0, 0, -IMU::GRAVITY_VALUE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化惯性边(误差为残差)
|
||||||
|
*/
|
||||||
// Edge inertial whre gravity is included as optimizable variable and it is not supposed to be pointing in -z axis, as well as scale
|
// Edge inertial whre gravity is included as optimizable variable and it is not supposed to be pointing in -z axis, as well as scale
|
||||||
class EdgeInertialGS : public g2o::BaseMultiEdge<9,Vector9d>
|
class EdgeInertialGS : public g2o::BaseMultiEdge<9,Vector9d>
|
||||||
{
|
{
|
||||||
|
@ -570,6 +619,7 @@ public:
|
||||||
const double dt;
|
const double dt;
|
||||||
Eigen::Vector3d g, gI;
|
Eigen::Vector3d g, gI;
|
||||||
|
|
||||||
|
// 关于pose1与2 的旋转平移速度,以及之间的偏置,还有重力方向与尺度的信息矩阵
|
||||||
Eigen::Matrix<double,27,27> GetHessian(){
|
Eigen::Matrix<double,27,27> GetHessian(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,9,27> J;
|
Eigen::Matrix<double,9,27> J;
|
||||||
|
@ -584,6 +634,7 @@ public:
|
||||||
return J.transpose()*information()*J;
|
return J.transpose()*information()*J;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 与上面摆放不同
|
||||||
Eigen::Matrix<double,27,27> GetHessian2(){
|
Eigen::Matrix<double,27,27> GetHessian2(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,9,27> J;
|
Eigen::Matrix<double,9,27> J;
|
||||||
|
@ -598,6 +649,7 @@ public:
|
||||||
return J.transpose()*information()*J;
|
return J.transpose()*information()*J;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 关于偏置,重力方向与尺度的信息矩阵
|
||||||
Eigen::Matrix<double,9,9> GetHessian3(){
|
Eigen::Matrix<double,9,9> GetHessian3(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,9,9> J;
|
Eigen::Matrix<double,9,9> J;
|
||||||
|
@ -609,7 +661,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 下面的没有用到,其实也是获取状态的信息矩阵
|
||||||
Eigen::Matrix<double,1,1> GetHessianScale(){
|
Eigen::Matrix<double,1,1> GetHessianScale(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,9,1> J = _jacobianOplus[7];
|
Eigen::Matrix<double,9,1> J = _jacobianOplus[7];
|
||||||
|
@ -636,7 +688,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 陀螺仪偏置的二元边,除了残差及重投影误差外的第三个边,控制偏置变化
|
||||||
|
*/
|
||||||
class EdgeGyroRW : public g2o::BaseBinaryEdge<3,Eigen::Vector3d,VertexGyroBias,VertexGyroBias>
|
class EdgeGyroRW : public g2o::BaseBinaryEdge<3,Eigen::Vector3d,VertexGyroBias,VertexGyroBias>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -672,7 +726,9 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 加速度计偏置的二元边,除了残差及重投影误差外的第三个边,控制偏置变化
|
||||||
|
*/
|
||||||
class EdgeAccRW : public g2o::BaseBinaryEdge<3,Eigen::Vector3d,VertexAccBias,VertexAccBias>
|
class EdgeAccRW : public g2o::BaseBinaryEdge<3,Eigen::Vector3d,VertexAccBias,VertexAccBias>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -708,6 +764,9 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 先验类
|
||||||
|
*/
|
||||||
class ConstraintPoseImu
|
class ConstraintPoseImu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -717,7 +776,8 @@ public:
|
||||||
const Eigen::Vector3d &bg_, const Eigen::Vector3d &ba_, const Matrix15d &H_):
|
const Eigen::Vector3d &bg_, const Eigen::Vector3d &ba_, const Matrix15d &H_):
|
||||||
Rwb(Rwb_), twb(twb_), vwb(vwb_), bg(bg_), ba(ba_), H(H_)
|
Rwb(Rwb_), twb(twb_), vwb(vwb_), bg(bg_), ba(ba_), H(H_)
|
||||||
{
|
{
|
||||||
H = (H+H)/2;
|
H = (H+H)/2; // 对称化
|
||||||
|
// 令特征值小的位置变为0
|
||||||
Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double,15,15> > es(H);
|
Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double,15,15> > es(H);
|
||||||
Eigen::Matrix<double,15,1> eigs = es.eigenvalues();
|
Eigen::Matrix<double,15,1> eigs = es.eigenvalues();
|
||||||
for(int i=0;i<15;i++)
|
for(int i=0;i<15;i++)
|
||||||
|
@ -725,6 +785,8 @@ public:
|
||||||
eigs[i]=0;
|
eigs[i]=0;
|
||||||
H = es.eigenvectors()*eigs.asDiagonal()*es.eigenvectors().transpose();
|
H = es.eigenvectors()*eigs.asDiagonal()*es.eigenvectors().transpose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 形式不同
|
||||||
ConstraintPoseImu(const cv::Mat &Rwb_, const cv::Mat &twb_, const cv::Mat &vwb_,
|
ConstraintPoseImu(const cv::Mat &Rwb_, const cv::Mat &twb_, const cv::Mat &vwb_,
|
||||||
const IMU::Bias &b, const cv::Mat &H_)
|
const IMU::Bias &b, const cv::Mat &H_)
|
||||||
{
|
{
|
||||||
|
@ -753,6 +815,9 @@ public:
|
||||||
Matrix15d H;
|
Matrix15d H;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 先验边,前端优化单帧用到
|
||||||
|
*/
|
||||||
class EdgePriorPoseImu : public g2o::BaseMultiEdge<15,Vector15d>
|
class EdgePriorPoseImu : public g2o::BaseMultiEdge<15,Vector15d>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -775,6 +840,7 @@ public:
|
||||||
return J.transpose()*information()*J;
|
return J.transpose()*information()*J;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 没用到,除了旋转平移外的信息矩阵
|
||||||
Eigen::Matrix<double,9,9> GetHessianNoPose(){
|
Eigen::Matrix<double,9,9> GetHessianNoPose(){
|
||||||
linearizeOplus();
|
linearizeOplus();
|
||||||
Eigen::Matrix<double,15,9> J;
|
Eigen::Matrix<double,15,9> J;
|
||||||
|
@ -789,6 +855,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Priors for biases
|
// Priors for biases
|
||||||
|
/**
|
||||||
|
* @brief 根据给定值的加速度计先验边,目的是把优化量维持在先验附近
|
||||||
|
*/
|
||||||
class EdgePriorAcc : public g2o::BaseUnaryEdge<3,Eigen::Vector3d,VertexAccBias>
|
class EdgePriorAcc : public g2o::BaseUnaryEdge<3,Eigen::Vector3d,VertexAccBias>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -813,6 +882,9 @@ public:
|
||||||
const Eigen::Vector3d bprior;
|
const Eigen::Vector3d bprior;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 根据给定值的陀螺仪先验边,目的是把优化量维持在先验附近
|
||||||
|
*/
|
||||||
class EdgePriorGyro : public g2o::BaseUnaryEdge<3,Eigen::Vector3d,VertexGyroBias>
|
class EdgePriorGyro : public g2o::BaseUnaryEdge<3,Eigen::Vector3d,VertexGyroBias>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -837,7 +909,9 @@ public:
|
||||||
const Eigen::Vector3d bprior;
|
const Eigen::Vector3d bprior;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 4DOF的二元边,误差为给定的旋转平移改变量 与 两个输入节点之间的旋转平移改变量的偏差
|
||||||
|
*/
|
||||||
class Edge4DoF : public g2o::BaseBinaryEdge<6,Vector6d,VertexPose4DoF,VertexPose4DoF>
|
class Edge4DoF : public g2o::BaseBinaryEdge<6,Vector6d,VertexPose4DoF,VertexPose4DoF>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -167,6 +167,9 @@ void ImuCamPose::SetParam(const std::vector<Eigen::Matrix3d> &_Rcw, const std::v
|
||||||
bf = _bf;
|
bf = _bf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 单目投影
|
||||||
|
*/
|
||||||
Eigen::Vector2d ImuCamPose::Project(const Eigen::Vector3d &Xw, int cam_idx) const
|
Eigen::Vector2d ImuCamPose::Project(const Eigen::Vector3d &Xw, int cam_idx) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3d Xc = Rcw[cam_idx]*Xw+tcw[cam_idx];
|
Eigen::Vector3d Xc = Rcw[cam_idx]*Xw+tcw[cam_idx];
|
||||||
|
@ -174,6 +177,10 @@ Eigen::Vector2d ImuCamPose::Project(const Eigen::Vector3d &Xw, int cam_idx) cons
|
||||||
return pCamera[cam_idx]->project(Xc);
|
return pCamera[cam_idx]->project(Xc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 双目投影,都是0
|
||||||
|
* @return u v u`
|
||||||
|
*/
|
||||||
Eigen::Vector3d ImuCamPose::ProjectStereo(const Eigen::Vector3d &Xw, int cam_idx) const
|
Eigen::Vector3d ImuCamPose::ProjectStereo(const Eigen::Vector3d &Xw, int cam_idx) const
|
||||||
{
|
{
|
||||||
Eigen::Vector3d Pc = Rcw[cam_idx]*Xw+tcw[cam_idx];
|
Eigen::Vector3d Pc = Rcw[cam_idx]*Xw+tcw[cam_idx];
|
||||||
|
@ -219,6 +226,7 @@ void ImuCamPose::Update(const double *pu)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 更新世界坐标系
|
||||||
void ImuCamPose::UpdateW(const double *pu)
|
void ImuCamPose::UpdateW(const double *pu)
|
||||||
{
|
{
|
||||||
Eigen::Vector3d ur, ut;
|
Eigen::Vector3d ur, ut;
|
||||||
|
@ -606,7 +614,7 @@ void EdgeInertial::linearizeOplus()
|
||||||
_jacobianOplus[3].block<3,3>(6,0) = -JPa; // OK
|
_jacobianOplus[3].block<3,3>(6,0) = -JPa; // OK
|
||||||
|
|
||||||
// Jacobians wrt Pose 2
|
// Jacobians wrt Pose 2
|
||||||
// _jacobianOplus[3] 9*6矩阵 总体来说就是三个残差分别对pose2的旋转与平移(p)求导
|
// _jacobianOplus[4] 9*6矩阵 总体来说就是三个残差分别对pose2的旋转与平移(p)求导
|
||||||
_jacobianOplus[4].setZero();
|
_jacobianOplus[4].setZero();
|
||||||
// rotation
|
// rotation
|
||||||
_jacobianOplus[4].block<3,3>(0,0) = invJr; // OK
|
_jacobianOplus[4].block<3,3>(0,0) = invJr; // OK
|
||||||
|
@ -614,7 +622,7 @@ void EdgeInertial::linearizeOplus()
|
||||||
_jacobianOplus[4].block<3,3>(6,3) = Rbw1*Rwb2; // OK
|
_jacobianOplus[4].block<3,3>(6,3) = Rbw1*Rwb2; // OK
|
||||||
|
|
||||||
// Jacobians wrt Velocity 2
|
// Jacobians wrt Velocity 2
|
||||||
// _jacobianOplus[3] 9*3矩阵 总体来说就是三个残差分别对pose2的速度求导
|
// _jacobianOplus[5] 9*3矩阵 总体来说就是三个残差分别对pose2的速度求导
|
||||||
_jacobianOplus[5].setZero();
|
_jacobianOplus[5].setZero();
|
||||||
_jacobianOplus[5].block<3,3>(3,0) = Rbw1; // OK
|
_jacobianOplus[5].block<3,3>(3,0) = Rbw1; // OK
|
||||||
}
|
}
|
||||||
|
@ -930,6 +938,6 @@ Eigen::Matrix3d NormalizeRotation(const Eigen::Matrix3d &R)
|
||||||
// 2. 对于行列数不同的矩阵,例如3*4 或者 4*3 矩阵只有3个奇异向量,计算的时候如果是Thin 那么得出的UV矩阵列数只能是3,如果是full那么就是4
|
// 2. 对于行列数不同的矩阵,例如3*4 或者 4*3 矩阵只有3个奇异向量,计算的时候如果是Thin 那么得出的UV矩阵列数只能是3,如果是full那么就是4
|
||||||
// 3. thin会损失一部分数据,但是会加快计算,对于大型矩阵解算方程时,可以用thin加速得到结果
|
// 3. thin会损失一部分数据,但是会加快计算,对于大型矩阵解算方程时,可以用thin加速得到结果
|
||||||
Eigen::JacobiSVD<Eigen::Matrix3d> svd(R,Eigen::ComputeFullU | Eigen::ComputeFullV);
|
Eigen::JacobiSVD<Eigen::Matrix3d> svd(R,Eigen::ComputeFullU | Eigen::ComputeFullV);
|
||||||
return svd.matrixU()*svd.matrixV();
|
return svd.matrixU()*svd.matrixV().transpose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1601,6 +1601,7 @@ void LocalMapping::InitializeIMU(float priorG, float priorA, bool bFIBA)
|
||||||
if(mpCurrentKeyFrame->mTimeStamp-mFirstTs<minTime)
|
if(mpCurrentKeyFrame->mTimeStamp-mFirstTs<minTime)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// 正在做IMU的初始化,在tracking里面使用,如果为true,暂不添加关键帧
|
||||||
bInitializing = true;
|
bInitializing = true;
|
||||||
|
|
||||||
// 先处理新关键帧,防止堆积且保证数据量充足
|
// 先处理新关键帧,防止堆积且保证数据量充足
|
||||||
|
@ -1626,20 +1627,21 @@ void LocalMapping::InitializeIMU(float priorG, float priorA, bool bFIBA)
|
||||||
continue;
|
continue;
|
||||||
if (!(*itKF)->mPrevKF)
|
if (!(*itKF)->mPrevKF)
|
||||||
continue;
|
continue;
|
||||||
// Rwb(imu坐标转到初始化前世界坐标系下的坐标)*更新偏置后的速度,可以理解为在世界坐标系下的速度矢量
|
// 初始化时关于速度的预积分定义Ri.t()*(s*Vj - s*Vi - Rwg*g*tij)
|
||||||
dirG -= (*itKF)->mPrevKF->GetImuRotation()*(*itKF)->mpImuPreintegrated->GetUpdatedDeltaVelocity();
|
dirG -= (*itKF)->mPrevKF->GetImuRotation()*(*itKF)->mpImuPreintegrated->GetUpdatedDeltaVelocity();
|
||||||
// 求取实际的速度,位移/时间
|
// 求取实际的速度,位移/时间
|
||||||
cv::Mat _vel = ((*itKF)->GetImuPosition() - (*itKF)->mPrevKF->GetImuPosition())/(*itKF)->mpImuPreintegrated->dT;
|
cv::Mat _vel = ((*itKF)->GetImuPosition() - (*itKF)->mPrevKF->GetImuPosition())/(*itKF)->mpImuPreintegrated->dT;
|
||||||
(*itKF)->SetVelocity(_vel);
|
(*itKF)->SetVelocity(_vel);
|
||||||
(*itKF)->mPrevKF->SetVelocity(_vel);
|
(*itKF)->mPrevKF->SetVelocity(_vel);
|
||||||
}
|
}
|
||||||
|
// dirG = sV1 - sVn + n*Rwg*g*t
|
||||||
// 归一化
|
// 归一化
|
||||||
dirG = dirG/cv::norm(dirG);
|
dirG = dirG/cv::norm(dirG);
|
||||||
// 原本的重力方向
|
// 原本的重力方向
|
||||||
cv::Mat gI = (cv::Mat_<float>(3,1) << 0.0f, 0.0f, -1.0f);
|
cv::Mat gI = (cv::Mat_<float>(3,1) << 0.0f, 0.0f, -1.0f);
|
||||||
// 求速度方向与重力方向的角轴
|
// 求速度方向与重力方向的角轴
|
||||||
cv::Mat v = gI.cross(dirG);
|
cv::Mat v = gI.cross(dirG);
|
||||||
// 求角轴长度
|
// 求角轴模长
|
||||||
const float nv = cv::norm(v);
|
const float nv = cv::norm(v);
|
||||||
// 求转角大小
|
// 求转角大小
|
||||||
const float cosg = gI.dot(dirG);
|
const float cosg = gI.dot(dirG);
|
||||||
|
@ -1664,7 +1666,7 @@ void LocalMapping::InitializeIMU(float priorG, float priorA, bool bFIBA)
|
||||||
mInitTime = mpTracker->mLastFrame.mTimeStamp-vpKF.front()->mTimeStamp;
|
mInitTime = mpTracker->mLastFrame.mTimeStamp-vpKF.front()->mTimeStamp;
|
||||||
|
|
||||||
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
|
||||||
// 计算残差及偏置差,优化尺度重力方向及Ri Rj Vi Vj Pi Pj
|
// 计算残差及偏置差,优化尺度重力方向及速度偏置,偏置先验为0,双目时不优化尺度
|
||||||
Optimizer::InertialOptimization(mpAtlas->GetCurrentMap(), mRwg, mScale, mbg, mba, mbMonocular, infoInertial, false, false, priorG, priorA);
|
Optimizer::InertialOptimization(mpAtlas->GetCurrentMap(), mRwg, mScale, mbg, mba, mbMonocular, infoInertial, false, false, priorG, priorA);
|
||||||
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
@ -1736,10 +1738,11 @@ void LocalMapping::InitializeIMU(float priorG, float priorA, bool bFIBA)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mbNewInit=true;
|
mbNewInit=true; // 没用到
|
||||||
mnKFs=vpKF.size();
|
mnKFs=vpKF.size(); // 没用到
|
||||||
mIdxInit++;
|
mIdxInit++; // 没用到
|
||||||
|
|
||||||
|
// 里面存放的是来到Local线程,但还未处理的关键帧
|
||||||
for(list<KeyFrame*>::iterator lit = mlNewKeyFrames.begin(), lend=mlNewKeyFrames.end(); lit!=lend; lit++)
|
for(list<KeyFrame*>::iterator lit = mlNewKeyFrames.begin(), lend=mlNewKeyFrames.end(); lit!=lend; lit++)
|
||||||
{
|
{
|
||||||
(*lit)->SetBadFlag();
|
(*lit)->SetBadFlag();
|
||||||
|
|
30
src/Map.cc
30
src/Map.cc
|
@ -298,6 +298,14 @@ void Map::RotateMap(const cv::Mat &R)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 恢复尺度及重力方向
|
||||||
|
/** imu在localmapping中初始化,LocalMapping::InitializeIMU中使用,误差包含三个残差与两个偏置
|
||||||
|
* 地图融合时也会使用
|
||||||
|
* @param R 初始化时为Rgw
|
||||||
|
* @param s 尺度
|
||||||
|
* @param bScaledVel 将尺度更新到速度
|
||||||
|
* @param t 默认cv::Mat::zeros(cv::Size(1,3),CV_32F)
|
||||||
|
*/
|
||||||
void Map::ApplyScaledRotation(const cv::Mat &R, const float s, const bool bScaledVel, const cv::Mat t)
|
void Map::ApplyScaledRotation(const cv::Mat &R, const float s, const bool bScaledVel, const cv::Mat t)
|
||||||
{
|
{
|
||||||
unique_lock<mutex> lock(mMutexMap);
|
unique_lock<mutex> lock(mMutexMap);
|
||||||
|
@ -310,19 +318,36 @@ void Map::ApplyScaledRotation(const cv::Mat &R, const float s, const bool bScale
|
||||||
|
|
||||||
cv::Mat Tyw = Tyx*Txw;
|
cv::Mat Tyw = Tyx*Txw;
|
||||||
Tyw.rowRange(0,3).col(3) = Tyw.rowRange(0,3).col(3)+t;
|
Tyw.rowRange(0,3).col(3) = Tyw.rowRange(0,3).col(3)+t;
|
||||||
cv::Mat Ryw = Tyw.rowRange(0,3).colRange(0,3);
|
// Tyw 中旋转部分等于R,平移部分等于t
|
||||||
cv::Mat tyw = Tyw.rowRange(0,3).col(3);
|
// 做了很多操作,到最后还是得出了一个R跟t?感觉上面的操作像是预留了一些东西,比如在世界坐标系与第一帧有一定Rt时,只不过暂时没有用到
|
||||||
|
cv::Mat Ryw = Tyw.rowRange(0,3).colRange(0,3); // R
|
||||||
|
cv::Mat tyw = Tyw.rowRange(0,3).col(3); // t
|
||||||
|
|
||||||
for(set<KeyFrame*>::iterator sit=mspKeyFrames.begin(); sit!=mspKeyFrames.end(); sit++)
|
for(set<KeyFrame*>::iterator sit=mspKeyFrames.begin(); sit!=mspKeyFrames.end(); sit++)
|
||||||
{
|
{
|
||||||
|
// 更新关键帧位姿
|
||||||
|
/**
|
||||||
|
* | Rw2w1 tw2w1 | * | Rw1c s*tw1c | = | Rw2c s*Rw2w1*tw1c + tw2w1 |
|
||||||
|
* | 0 1 | | 0 1 | | 0 1 |
|
||||||
|
* 这么做比正常乘在旋转上少了个s,后面不需要这个s了,因为所有mp在下面已经全部转到了w2坐标系下,不存在尺度变化了
|
||||||
|
*
|
||||||
|
* | s*Rw2w1 tw2w1 | * | Rw1c tw1c | = | s*Rw2c s*Rw2w1*tw1c + tw2w1 |
|
||||||
|
* | 0 1 | | 0 1 | | 0 1 |
|
||||||
|
*/
|
||||||
|
|
||||||
KeyFrame* pKF = *sit;
|
KeyFrame* pKF = *sit;
|
||||||
cv::Mat Twc = pKF->GetPoseInverse();
|
cv::Mat Twc = pKF->GetPoseInverse();
|
||||||
Twc.rowRange(0,3).col(3)*=s;
|
Twc.rowRange(0,3).col(3)*=s;
|
||||||
|
|
||||||
|
// | Ryc s*Ryw*twc + tyw |
|
||||||
|
// | 0 1 |
|
||||||
cv::Mat Tyc = Tyw*Twc;
|
cv::Mat Tyc = Tyw*Twc;
|
||||||
|
|
||||||
cv::Mat Tcy = cv::Mat::eye(4,4,CV_32F);
|
cv::Mat Tcy = cv::Mat::eye(4,4,CV_32F);
|
||||||
Tcy.rowRange(0,3).colRange(0,3) = Tyc.rowRange(0,3).colRange(0,3).t();
|
Tcy.rowRange(0,3).colRange(0,3) = Tyc.rowRange(0,3).colRange(0,3).t();
|
||||||
Tcy.rowRange(0,3).col(3) = -Tcy.rowRange(0,3).colRange(0,3)*Tyc.rowRange(0,3).col(3);
|
Tcy.rowRange(0,3).col(3) = -Tcy.rowRange(0,3).colRange(0,3)*Tyc.rowRange(0,3).col(3);
|
||||||
pKF->SetPose(Tcy);
|
pKF->SetPose(Tcy);
|
||||||
|
// 更新关键帧速度
|
||||||
cv::Mat Vw = pKF->GetVelocity();
|
cv::Mat Vw = pKF->GetVelocity();
|
||||||
if(!bScaledVel)
|
if(!bScaledVel)
|
||||||
pKF->SetVelocity(Ryw*Vw);
|
pKF->SetVelocity(Ryw*Vw);
|
||||||
|
@ -332,6 +357,7 @@ void Map::ApplyScaledRotation(const cv::Mat &R, const float s, const bool bScale
|
||||||
}
|
}
|
||||||
for(set<MapPoint*>::iterator sit=mspMapPoints.begin(); sit!=mspMapPoints.end(); sit++)
|
for(set<MapPoint*>::iterator sit=mspMapPoints.begin(); sit!=mspMapPoints.end(); sit++)
|
||||||
{
|
{
|
||||||
|
// 更新每一个mp在世界坐标系下的坐标
|
||||||
MapPoint* pMP = *sit;
|
MapPoint* pMP = *sit;
|
||||||
pMP->SetWorldPos(s*Ryw*pMP->GetWorldPos()+tyw);
|
pMP->SetWorldPos(s*Ryw*pMP->GetWorldPos()+tyw);
|
||||||
pMP->UpdateNormalAndDepth();
|
pMP->UpdateNormalAndDepth();
|
||||||
|
|
|
@ -5069,7 +5069,8 @@ Eigen::MatrixXd Optimizer::Sparsify(const Eigen::MatrixXd &H, const int &start1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
Verbose::PrintMess("inertial optimization", Verbose::VERBOSITY_NORMAL);
|
Verbose::PrintMess("inertial optimization", Verbose::VERBOSITY_NORMAL);
|
||||||
int its = 200; // Check number of iterations
|
int its = 200; // Check number of iterations
|
||||||
|
|
|
@ -4582,12 +4582,25 @@ void Tracking::InformOnlyTracking(const bool &flag)
|
||||||
mbOnlyTracking = flag;
|
mbOnlyTracking = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 更新了关键帧的位姿,但需要修改普通帧的位姿,因为正常跟踪需要普通帧
|
||||||
|
* localmapping中初始化imu中使用,速度的走向(仅在imu模式使用),最开始速度定义于imu初始化时,每个关键帧都根据位移除以时间得到,经过非线性优化保存于KF中.
|
||||||
|
* 之后使用本函数,让上一帧与当前帧分别与他们对应的上一关键帧做速度叠加得到,后面新的frame速度由上一个帧速度决定,如果使用匀速模型(大多数情况下),通过imu积分更新速度。
|
||||||
|
* 新的关键帧继承于对应帧
|
||||||
|
* @param s 尺度
|
||||||
|
* @param b 初始化后第一帧的偏置
|
||||||
|
* @param pCurrentKeyFrame 当前关键帧
|
||||||
|
*/
|
||||||
void Tracking::UpdateFrameIMU(const float s, const IMU::Bias &b, KeyFrame* pCurrentKeyFrame)
|
void Tracking::UpdateFrameIMU(const float s, const IMU::Bias &b, KeyFrame* pCurrentKeyFrame)
|
||||||
{
|
{
|
||||||
Map * pMap = pCurrentKeyFrame->GetMap();
|
Map * pMap = pCurrentKeyFrame->GetMap();
|
||||||
unsigned int index = mnFirstFrameId;
|
unsigned int index = mnFirstFrameId; // unused
|
||||||
|
|
||||||
|
// 每一帧的参考关键帧
|
||||||
list<ORB_SLAM3::KeyFrame*>::iterator lRit = mlpReferences.begin();
|
list<ORB_SLAM3::KeyFrame*>::iterator lRit = mlpReferences.begin();
|
||||||
list<bool>::iterator lbL = mlbLost.begin();
|
list<bool>::iterator lbL = mlbLost.begin(); // 对应帧是否跟踪丢失
|
||||||
|
// mlRelativeFramePoses 存放的是Tcr
|
||||||
|
// 三个变量一一对应
|
||||||
for(list<cv::Mat>::iterator lit=mlRelativeFramePoses.begin(),lend=mlRelativeFramePoses.end();lit!=lend;lit++, lRit++, lbL++)
|
for(list<cv::Mat>::iterator lit=mlRelativeFramePoses.begin(),lend=mlRelativeFramePoses.end();lit!=lend;lit++, lRit++, lbL++)
|
||||||
{
|
{
|
||||||
if(*lbL)
|
if(*lbL)
|
||||||
|
@ -4605,11 +4618,11 @@ void Tracking::UpdateFrameIMU(const float s, const IMU::Bias &b, KeyFrame* pCurr
|
||||||
(*lit).rowRange(0,3).col(3)=(*lit).rowRange(0,3).col(3)*s;
|
(*lit).rowRange(0,3).col(3)=(*lit).rowRange(0,3).col(3)*s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 设置偏置
|
||||||
mLastBias = b;
|
mLastBias = b;
|
||||||
|
// 设置上一关键帧,如果说mpLastKeyFrame已经是经过添加的新的kf,而pCurrentKeyFrame还是上一个kf,mpLastKeyFrame直接指向之前的kf
|
||||||
mpLastKeyFrame = pCurrentKeyFrame;
|
mpLastKeyFrame = pCurrentKeyFrame;
|
||||||
|
// 更新偏置
|
||||||
mLastFrame.SetNewBias(mLastBias);
|
mLastFrame.SetNewBias(mLastBias);
|
||||||
mCurrentFrame.SetNewBias(mLastBias);
|
mCurrentFrame.SetNewBias(mLastBias);
|
||||||
|
|
||||||
|
@ -4622,10 +4635,12 @@ void Tracking::UpdateFrameIMU(const float s, const IMU::Bias &b, KeyFrame* pCurr
|
||||||
|
|
||||||
while(!mCurrentFrame.imuIsPreintegrated())
|
while(!mCurrentFrame.imuIsPreintegrated())
|
||||||
{
|
{
|
||||||
|
// 当前帧需要预积分完毕,这段函数实在localmapping里调用的
|
||||||
usleep(500);
|
usleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// frame的mpLastKeyFrame只是用于预积分(imu模式)
|
||||||
|
// TODO 如果上一帧正好是上一帧的上一关键帧(mLastFrame.mpLastKeyFrame与mLastFrame不可能是一个,可以验证一下)
|
||||||
if(mLastFrame.mnId == mLastFrame.mpLastKeyFrame->mnFrameId)
|
if(mLastFrame.mnId == mLastFrame.mpLastKeyFrame->mnFrameId)
|
||||||
{
|
{
|
||||||
mLastFrame.SetImuPoseVelocity(mLastFrame.mpLastKeyFrame->GetImuRotation(),
|
mLastFrame.SetImuPoseVelocity(mLastFrame.mpLastKeyFrame->GetImuRotation(),
|
||||||
|
@ -4638,12 +4653,13 @@ void Tracking::UpdateFrameIMU(const float s, const IMU::Bias &b, KeyFrame* pCurr
|
||||||
Rwb1 = mLastFrame.mpLastKeyFrame->GetImuRotation();
|
Rwb1 = mLastFrame.mpLastKeyFrame->GetImuRotation();
|
||||||
Vwb1 = mLastFrame.mpLastKeyFrame->GetVelocity();
|
Vwb1 = mLastFrame.mpLastKeyFrame->GetVelocity();
|
||||||
t12 = mLastFrame.mpImuPreintegrated->dT;
|
t12 = mLastFrame.mpImuPreintegrated->dT;
|
||||||
|
// 根据mLastFrame的上一个关键帧的信息(此时已经经过imu初始化了,所以关键帧的信息都是校正后的)以及imu的预积分重新计算上一帧的位姿
|
||||||
mLastFrame.SetImuPoseVelocity(Rwb1*mLastFrame.mpImuPreintegrated->GetUpdatedDeltaRotation(),
|
mLastFrame.SetImuPoseVelocity(Rwb1*mLastFrame.mpImuPreintegrated->GetUpdatedDeltaRotation(),
|
||||||
twb1 + Vwb1*t12 + 0.5f*t12*t12*Gz+ Rwb1*mLastFrame.mpImuPreintegrated->GetUpdatedDeltaPosition(),
|
twb1 + Vwb1*t12 + 0.5f*t12*t12*Gz+ Rwb1*mLastFrame.mpImuPreintegrated->GetUpdatedDeltaPosition(),
|
||||||
Vwb1 + Gz*t12 + Rwb1*mLastFrame.mpImuPreintegrated->GetUpdatedDeltaVelocity());
|
Vwb1 + Gz*t12 + Rwb1*mLastFrame.mpImuPreintegrated->GetUpdatedDeltaVelocity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 当前帧是否做了预积分
|
||||||
if (mCurrentFrame.mpImuPreintegrated)
|
if (mCurrentFrame.mpImuPreintegrated)
|
||||||
{
|
{
|
||||||
twb1 = mCurrentFrame.mpLastKeyFrame->GetImuPosition();
|
twb1 = mCurrentFrame.mpLastKeyFrame->GetImuPosition();
|
||||||
|
|
Loading…
Reference in New Issue