获取g2o优化后顶点协方差

    ifstream fin(input_str.c_str());

    if (!fin)
    {
        cout << "File " << input_str.c_str() << " does not exist!" << endl;
        return;
    }

    std::unique_ptr<g2o::BlockSolverX::LinearSolverType> linearSolver(new g2o::LinearSolverCholmod<g2o::BlockSolverX::PoseMatrixType>());
    std::unique_ptr<g2o::BlockSolverX> blockSolver(new g2o::BlockSolverX(std::move(linearSolver)));     // 矩阵块求解器

    g2o::OptimizationAlgorithmLevenberg* solver_algorithm = new g2o::OptimizationAlgorithmLevenberg(std::move(blockSolver));
    g2o::SparseOptimizer optimizer;
    optimizer.setAlgorithm(solver_algorithm);

    int vertexCnt = 0, edgeCnt = 0;
    while (!fin.eof())
    {
        string name;
        fin >> name;
        if (name == "VERTEX_SE3:QUAT")
        {
            g2o::VertexSE3* v = new g2o::VertexSE3();
            int index = 0;
            fin >> index;
            v->setId(index);
            v->read(fin);
            optimizer.addVertex(v);
            vertexCnt++;
            if (index == 0) v->setFixed(true);
        }
        else if (name == "EDGE_SE3:QUAT")
        {
            g2o::EdgeSE3* e = new g2o::EdgeSE3();
            int idx1 = 0, idx2 = 0;
            fin >> idx1 >> idx2;
            e->setId(edgeCnt++);
            e->setVertex(0, optimizer.vertices()[idx1]);
            e->setVertex(1, optimizer.vertices()[idx2]);
            e->read(fin);
            optimizer.addEdge(e);
        }
        if (!fin.good()) break;
    }

    cout << "Read total " << vertexCnt << " vertices, " << edgeCnt << " edges." << endl;

    cout << "Prepare optimization ..." << endl;
    optimizer.setVerbose(true);
    optimizer.initializeOptimization();
    cout << "Start optimation ..." << endl;
    optimizer.optimize(200);
    cout << "Saving optimization results ..." << endl;

    std::vector<std::pair<int, int> > indices;
    for (size_t i = 0; i < optimizer.vertices().size(); ++i)
    {
        const g2o::VertexSE3* v = static_cast<g2o::VertexSE3*> (optimizer.vertices()[i]);

        if(v == nullptr)
        {
            std::cout << v->hessianIndex() << "顶点是null" << std::endl;
            continue;
        }
        if(v->fixed())
        {
            std::cout << v->hessianIndex() << "顶点固定" << std::endl;
            continue;
        }

        std::cout << v->hessianIndex() << std::endl;

        indices.push_back(std::pair<int, int>(v->hessianIndex(), v->hessianIndex()));
    }

    g2o::SparseBlockMatrix<Eigen::MatrixXd> spinv;
    if (optimizer.computeMarginals(spinv, indices))
    {
        //for check
        std::cout << spinv << std::endl;
        const auto* b = spinv.blockCols()[0].begin()->second;
        std::cout << *b << std::endl;

        double cov_array[36]
        {
            (*b)(0,0),(*b)(0,1),(*b)(0,2),(*b)(0,3),(*b)(0,4),(*b)(0,5),
            (*b)(1,0),(*b)(1,1),(*b)(1,2),(*b)(1,3),(*b)(1,4),(*b)(1,5),
            (*b)(2,0),(*b)(2,1),(*b)(2,2),(*b)(2,3),(*b)(2,4),(*b)(2,5),
            (*b)(3,0),(*b)(3,1),(*b)(3,2),(*b)(3,3),(*b)(3,4),(*b)(3,5),
            (*b)(4,0),(*b)(4,1),(*b)(4,2),(*b)(4,3),(*b)(4,4),(*b)(4,5),
            (*b)(5,0),(*b)(5,1),(*b)(5,2),(*b)(5,3),(*b)(5,4),(*b)(5,5)
        };
    }

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贝叶斯优化中经常使用高斯过程 (Gaussian Process) 来建模目标函数,其中协方差函数 (Covariance Function) 是高斯过程的核心。高斯过程的协方差函数通常写作 $k(x, x')$,表示输入为 $x$ 和 $x'$ 的两个点之间的相关性。高斯过程的主要思想是通过已知的数据点来推断未知的数据点的分布,因此协方差函数需要满足以下性质: 1. 对于相同的输入点,协方差函数的输出值相同,即 $k(x,x') = k(x',x)$; 2. 对于任意的输入点,协方差函数的输出值必须为非负数,即 $k(x,x') \geq 0$; 3. 对于任意的输入点集合 $\{x_1, x_2, ..., x_n\}$,其对应的协方差矩阵 $K = [k(x_i, x_j)]_{n\times n}$ 必须是半正定的,即对于任意非零向量 $v$,有 $v^T K v \geq 0$。 常见的高斯过程协方差函数包括: 1. 高斯核函数 (Gaussian Kernel):$k(x, x') = \sigma_f^2 \exp\left(-\frac{(x-x')^2}{2\ell^2}\right)$,其中 $\sigma_f^2$ 表示函数值的方差,$\ell$ 表示长度尺度,控制函数的平滑度。 2. Matérn核函数 (Matérn Kernel):$k(x, x') = \frac{2^{1-\nu}}{\Gamma(\nu)} \left(\sqrt{2\nu}\frac{\|x-x'\|}{\ell}\right)^\nu K_\nu\left(\sqrt{2\nu}\frac{\|x-x'\|}{\ell}\right)$,其中 $\nu$ 表示核函数的光滑度,$\ell$ 表示长度尺度,$K_\nu$ 表示第二类修正的贝塞尔函数。 3. 指数核函数 (Exponential Kernel):$k(x, x') = \sigma_f^2 \exp\left(-\frac{\|x-x'\|}{\ell}\right)$,其中 $\sigma_f^2$ 表示函数值的方差,$\ell$ 表示长度尺度,控制函数的平滑度。 这些协方差函数可以根据实际问题的特征进行选择和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值