Ceres Solver 协方差的求解思路

一、理论

(1)、系统观测值是均值为0,协方差为单位矩阵

(2)、系统观测值是均值为0,协方差不是单位矩阵

注意:这个S是观测值的协方差矩阵;比如对于GPS/INS组合的导航系统,S应该是GPS位置观测值的协方差矩阵;

二、SVD分解求矩阵伪逆

C++代码

#include <iostream>
#include <Eigen/SVD>
#include <Eigen/Core>

using namespace std;


// 利用Eigen库,采用SVD分解的方法求解矩阵伪逆,默认误差er为0
Eigen::MatrixXd pinv_eigen_based(Eigen::MatrixXd & origin, const float er = 0) {
    // 进行svd分解
    Eigen::JacobiSVD<Eigen::MatrixXd> svd_holder(origin,
                                                 Eigen::ComputeThinU |
                                                 Eigen::ComputeThinV);
    // 构建SVD分解结果
    Eigen::MatrixXd U = svd_holder.matrixU();
    Eigen::MatrixXd V = svd_holder.matrixV();
    Eigen::MatrixXd D = svd_holder.singularValues();

    // 构建S矩阵
    Eigen::MatrixXd S(V.cols(), U.cols());
    S.setZero();

    for (unsigned int i = 0; i < D.size(); ++i) {

        if (D(i, 0) > er) {
            S(i, i) = 1 / D(i, 0);
        } else {
            S(i, i) = 0;
        }
    }

    // pinv_matrix = V * S * U^T
    return V * S * U.transpose();
}



int main() {
    // 设置矩阵行数、列数
    const int ROW = 3;
    const int COL = 4;

    // 生成大小 ROW * COL 的随机矩阵
    Eigen::MatrixXd A;
    A = Eigen::MatrixXd::Random(ROW, COL);
    
    // 打印矩阵A
    cout << "矩阵A为:" << endl;
    cout << A << endl;
    
    // 打印矩阵A的伪逆矩阵
    cout << "矩阵A的伪逆为:" << endl;
    cout << pinv_eigen_based(A) << endl;
}

三、ceres-solver  求协方差

      Eigen::Matrix<double,6,6, Eigen::RowMajor> cov_pose = Eigen::Matrix<double,6,6, Eigen::RowMajor>::Zero();
      
      ceres::Covariance::Options cov_options;
      ceres::Covariance covariance(cov_options);
      
      std::vector<std::pair<const double*, const double*>> covariance_blocks;
      covariance_blocks.push_back(std::make_pair(para_Pose[WINDOW_SIZE], para_Pose[WINDOW_SIZE]));
  
     // 有时候出现 rank问题,忽略一下
     if( covariance.Compute(covariance_blocks, &problem) )
     {
       covariance.GetCovarianceBlockInTangentSpace(para_Pose[WINDOW_SIZE],para_Pose[WINDOW_SIZE], cov_pose.data());  
     }
      
     std::cout <<"cov_pose.diagonal() ="<< cov_pose.diagonal() << std::endl;

备注:

微信:j15212774116,  欢迎讨论 !

参考文献

Guess you like

Origin blog.csdn.net/hltt3838/article/details/121438307