自学内容网 自学内容网

G2O 通过工厂函数类 OptimizationAlgorithmFactory 来生成固定搭配的优化算法

         OptimizationAlgorithmFactory 类位于 optimization_algorithm_factory.h

//***g2o源码 g2o/g2o/core/optimization_algorithm_factory.h ***//
/**
   * \brief create solvers based on their short name
   *
   * Factory to allocate solvers based on their short name.
   * The Factory is implemented as a sigleton and the single
   * instance can be accessed via the instance() function.
   */
/**
   * \brief 工厂类用于根据优化算法的名称创建不同的优化算法(OptimizationAlgorithm)
   *
   * 工厂类是单例模式(singleton)的实现,可以通过instance()方法获取唯一的实例,
   * 并通过destroy()方法释放实例。
   */
  class G2O_CORE_API OptimizationAlgorithmFactory
  {
    public:
      typedef std::list<AbstractOptimizationAlgorithmCreator*>      CreatorList;

      //! return the instance
      //! 获取工厂类的唯一实例
      static OptimizationAlgorithmFactory* instance();

      //! free the instance
      //! 释放唯一实例
      static void destroy();

      /**
       * register a specific creator for allocating a solver
       * 注册特定的创建者 creator 以分配求解器 solver
       */
      void registerSolver(AbstractOptimizationAlgorithmCreator* c);

      /**
       * unregister a specific creator for allocating a solver
       */
      void unregisterSolver(AbstractOptimizationAlgorithmCreator* c);
      
      /**
       * construct a solver based on its name, e.g., var, fix3_2_cholmod
       * 根据名称 tag 来创建求解器 solver
       */
      OptimizationAlgorithm* construct(const std::string& tag, OptimizationAlgorithmProperty& solverProperty) const;

      //! list the known solvers into a stream
      //! 将已知的求解器 solver 列到流中
      void listSolvers(std::ostream& os) const;

      //! return the underlying list of creators
      //! 返回创建者 creators 的基本列表
      const CreatorList& creatorList() const { return _creator;}

    protected:
      OptimizationAlgorithmFactory();
      ~OptimizationAlgorithmFactory();

      CreatorList _creator;

      CreatorList::const_iterator findSolver(const std::string& name) const;
      CreatorList::iterator findSolver(const std::string& name);

    private:
      static OptimizationAlgorithmFactory* factoryInstance;
  };
 

        示例代码: 

// 这里使用一个工厂函数同时初始化迭代方式和线性求解方式,后续可以将迭代方式(总求解器 solver)和线性求解方式(线性求解器 LinearSolver)分开
    // 创建一个指向g2o::OptimizationAlgorithmFactory的实例指针
    g2o::OptimizationAlgorithmFactory *solver_factory = g2o::OptimizationAlgorithmFactory::instance();
    // 定义一个 g2o::OptimizationAlgorithmProperty 类型的对象用于存储与优化算法相关的元信息
    g2o::OptimizationAlgorithmProperty solver_property;
    // 根据名称 tag 创建求解器 solver,调用 construct() 时,函数会将所构建的求解器相关的元信息存储到这个对象中,
    // 比如该求解器的名称、是否需要舒尔补、位姿自由度、地图路标自由度等。
    g2o::OptimizationAlgorithm *solver = solver_factory->construct("lm_var", solver_property);

    std::unique_ptr<g2o::SparseOptimizer> graph_ptr_;
    graph_ptr_.reset(new g2o::SparseOptimizer());
    graph_ptr_->setAlgorithm(solver);

    if (!graph_ptr_->solver()) {
        LOG(ERROR) << "G2O 优化器创建失败!";
    }

    // 初始化鲁棒核函数的工厂函数
    g2o::RobustKernelFactory *robust_kernel_factory_ = g2o::RobustKernelFactory::instance();

        其中,OptimizationAlgorithm* construct(const std::string& tag, OptimizationAlgorithmProperty& solverProperty) const; 函数中 tag 的所有可用算法与其对应描述有: 

//*** g2o源码 g2o/g2o/solvers/cholmod/solver_cholmod.cpp ***//
G2O_REGISTER_OPTIMIZATION_LIBRARY(cholmod);

G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_var_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "gn_var_cholmod",
        "Gauss-Newton: Cholesky solver using CHOLMOD (variable blocksize)",
        "CHOLMOD", false, Eigen::Dynamic, Eigen::Dynamic)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_fix3_2_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "gn_fix3_2_cholmod",
        "Gauss-Newton: Cholesky solver using CHOLMOD (fixed blocksize)",
        "CHOLMOD", true, 3, 2)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_fix6_3_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "gn_fix6_3_cholmod",
        "Gauss-Newton: Cholesky solver using CHOLMOD (fixed blocksize)",
        "CHOLMOD", true, 6, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_fix7_3_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "gn_fix7_3_cholmod",
        "Gauss-Newton: Cholesky solver using CHOLMOD (fixed blocksize)",
        "CHOLMOD", true, 7, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_var_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "lm_var_cholmod",
        "Levenberg: Cholesky solver using CHOLMOD (variable blocksize)",
        "CHOLMOD", false, Eigen::Dynamic, Eigen::Dynamic)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_fix3_2_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "lm_fix3_2_cholmod",
        "Levenberg: Cholesky solver using CHOLMOD (fixed blocksize)", "CHOLMOD",
        true, 3, 2)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_fix6_3_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "lm_fix6_3_cholmod",
        "Levenberg: Cholesky solver using CHOLMOD (fixed blocksize)", "CHOLMOD",
        true, 6, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_fix7_3_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "lm_fix7_3_cholmod",
        "Levenberg: Cholesky solver using CHOLMOD (fixed blocksize)", "CHOLMOD",
        true, 7, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    dl_var_cholmod,
    new CholmodSolverCreator(OptimizationAlgorithmProperty(
        "dl_var_cholmod",
        "Dogleg: Cholesky solver using CHOLMOD (variable blocksize)", "CHOLMOD",
        false, Eigen::Dynamic, Eigen::Dynamic)));
//*** g2o源码 g2o/g2o/solvers/csparse/solver_csparse.cpp ***//
  G2O_REGISTER_OPTIMIZATION_LIBRARY(csparse);

  G2O_REGISTER_OPTIMIZATION_ALGORITHM(gn_var_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("gn_var_csparse", "Gauss-Newton: Cholesky solver using CSparse (variable blocksize)", "CSparse", false, Eigen::Dynamic, Eigen::Dynamic)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(gn_fix3_2_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("gn_fix3_2_csparse", "Gauss-Newton: Cholesky solver using CSparse (fixed blocksize)", "CSparse", true, 3, 2)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(gn_fix6_3_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("gn_fix6_3_csparse", "Gauss-Newton: Cholesky solver using CSparse (fixed blocksize)", "CSparse", true, 6, 3)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(gn_fix7_3_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("gn_fix7_3_csparse", "Gauss-Newton: Cholesky solver using CSparse (fixed blocksize)", "CSparse", true, 7, 3)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(lm_var_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("lm_var_csparse", "Levenberg: Cholesky solver using CSparse (variable blocksize)", "CSparse", false, Eigen::Dynamic, Eigen::Dynamic)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(lm_fix3_2_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("lm_fix3_2_csparse", "Levenberg: Cholesky solver using CSparse (fixed blocksize)", "CSparse", true, 3, 2)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(lm_fix6_3_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("lm_fix6_3_csparse", "Levenberg: Cholesky solver using CSparse (fixed blocksize)", "CSparse", true, 6, 3)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(lm_fix7_3_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("lm_fix7_3_csparse", "Levenberg: Cholesky solver using CSparse (fixed blocksize)", "CSparse", true, 7, 3)));

  G2O_REGISTER_OPTIMIZATION_ALGORITHM(dl_var_csparse, new CSparseSolverCreator(OptimizationAlgorithmProperty("dl_var_csparse", "Dogleg: Cholesky solver using CSparse (variable blocksize)", "CSparse", false, Eigen::Dynamic, Eigen::Dynamic)));
//*** g2o源码 g2o/g2o/solvers/eigen/solver_eigen.cpp ***//
  G2O_REGISTER_OPTIMIZATION_LIBRARY(eigen);

  G2O_REGISTER_OPTIMIZATION_ALGORITHM(gn_var, new EigenSolverCreator(OptimizationAlgorithmProperty("gn_var", "Gauss-Newton: Cholesky solver using Eigen's Sparse Cholesky methods (variable blocksize)", "Eigen", false, Eigen::Dynamic, Eigen::Dynamic)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(gn_fix3_2, new EigenSolverCreator(OptimizationAlgorithmProperty("gn_fix3_2", "Gauss-Newton: Cholesky solver using  Eigen's Sparse Cholesky (fixed blocksize)", "Eigen", true, 3, 2)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(gn_fix6_3, new EigenSolverCreator(OptimizationAlgorithmProperty("gn_fix6_3", "Gauss-Newton: Cholesky solver using  Eigen's Sparse Cholesky (fixed blocksize)", "Eigen", true, 6, 3)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(gn_fix7_3, new EigenSolverCreator(OptimizationAlgorithmProperty("gn_fix7_3", "Gauss-Newton: Cholesky solver using  Eigen's Sparse Cholesky (fixed blocksize)", "Eigen", true, 7, 3)));

  G2O_REGISTER_OPTIMIZATION_ALGORITHM(lm_var, new EigenSolverCreator(OptimizationAlgorithmProperty("lm_var", "Levenberg: Cholesky solver using Eigen's Sparse Cholesky methods (variable blocksize)", "Eigen", false, Eigen::Dynamic, Eigen::Dynamic)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(lm_fix3_2, new EigenSolverCreator(OptimizationAlgorithmProperty("lm_fix3_2", "Levenberg: Cholesky solver using  Eigen's Sparse Cholesky (fixed blocksize)", "Eigen", true, 3, 2)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(lm_fix6_3, new EigenSolverCreator(OptimizationAlgorithmProperty("lm_fix6_3", "Levenberg: Cholesky solver using  Eigen's Sparse Cholesky (fixed blocksize)", "Eigen", true, 6, 3)));
  G2O_REGISTER_OPTIMIZATION_ALGORITHM(lm_fix7_3, new EigenSolverCreator(OptimizationAlgorithmProperty("lm_fix7_3", "Levenberg: Cholesky solver using  Eigen's Sparse Cholesky (fixed blocksize)", "Eigen", true, 7, 3)));

  G2O_REGISTER_OPTIMIZATION_ALGORITHM(dl_var, new EigenSolverCreator(OptimizationAlgorithmProperty("dl_var", "Dogleg: Cholesky solver using Eigen's Sparse Cholesky methods (variable blocksize)", "Eigen", false, Eigen::Dynamic, Eigen::Dynamic)));
//*** g2o源码 g2o/g2o/solvers/dense/solver_dense.cpp ***//
G2O_REGISTER_OPTIMIZATION_LIBRARY(dense);

G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_dense, new DenseSolverCreator(OptimizationAlgorithmProperty(
                  "gn_dense", "Gauss-Newton: Dense solver (variable blocksize)",
                  "Dense", false, Eigen::Dynamic, Eigen::Dynamic)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_dense3_2,
    new DenseSolverCreator(OptimizationAlgorithmProperty(
        "gn_dense3_2", "Gauss-Newton: Dense solver (fixed blocksize)", "Dense",
        true, 3, 2)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_dense6_3,
    new DenseSolverCreator(OptimizationAlgorithmProperty(
        "gn_dense6_3", "Gauss-Newton: Dense solver (fixed blocksize)", "Dense",
        true, 6, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_dense7_3,
    new DenseSolverCreator(OptimizationAlgorithmProperty(
        "gn_dense7_3", "Gauss-Newton: Dense solver (fixed blocksize)", "Dense",
        true, 7, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_dense, new DenseSolverCreator(OptimizationAlgorithmProperty(
                  "lm_dense", "Levenberg: Dense solver (variable blocksize)",
                  "Dense", false, -1, -1)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_dense3_2, new DenseSolverCreator(OptimizationAlgorithmProperty(
                     "lm_dense3_2", "Levenberg: Dense solver (fixed blocksize)",
                     "Dense", true, 3, 2)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_dense6_3, new DenseSolverCreator(OptimizationAlgorithmProperty(
                     "lm_dense6_3", "Levenberg: Dense solver (fixed blocksize)",
                     "Dense", true, 6, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_dense7_3, new DenseSolverCreator(OptimizationAlgorithmProperty(
                     "lm_dense7_3", "Levenberg: Dense solver (fixed blocksize)",
                     "Dense", true, 7, 3)));
//*** g2o源码 g2o/g2o/solvers/pcg/solver_pcg.cpp ***//
G2O_REGISTER_OPTIMIZATION_LIBRARY(pcg);

G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_pcg, new PCGSolverCreator(OptimizationAlgorithmProperty(
                "gn_pcg",
                "Gauss-Newton: PCG solver using block-Jacobi pre-conditioner "
                "(variable blocksize)",
                "PCG", false, Eigen::Dynamic, Eigen::Dynamic)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_pcg3_2, new PCGSolverCreator(OptimizationAlgorithmProperty(
                   "gn_pcg3_2",
                   "Gauss-Newton: PCG solver using block-Jacobi "
                   "pre-conditioner (fixed blocksize)",
                   "PCG", true, 3, 2)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_pcg6_3, new PCGSolverCreator(OptimizationAlgorithmProperty(
                   "gn_pcg6_3",
                   "Gauss-Newton: PCG solver using block-Jacobi "
                   "pre-conditioner (fixed blocksize)",
                   "PCG", true, 6, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    gn_pcg7_3, new PCGSolverCreator(OptimizationAlgorithmProperty(
                   "gn_pcg7_3",
                   "Gauss-Newton: PCG solver using block-Jacobi "
                   "pre-conditioner (fixed blocksize)",
                   "PCG", true, 7, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_pcg, new PCGSolverCreator(OptimizationAlgorithmProperty(
                "lm_pcg",
                "Levenberg: PCG solver using block-Jacobi pre-conditioner "
                "(variable blocksize)",
                "PCG", false, Eigen::Dynamic, Eigen::Dynamic)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_pcg3_2, new PCGSolverCreator(OptimizationAlgorithmProperty(
                   "lm_pcg3_2",
                   "Levenberg: PCG solver using block-Jacobi pre-conditioner "
                   "(fixed blocksize)",
                   "PCG", true, 3, 2)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_pcg6_3, new PCGSolverCreator(OptimizationAlgorithmProperty(
                   "lm_pcg6_3",
                   "Levenberg: PCG solver using block-Jacobi pre-conditioner "
                   "(fixed blocksize)",
                   "PCG", true, 6, 3)));
G2O_REGISTER_OPTIMIZATION_ALGORITHM(
    lm_pcg7_3, new PCGSolverCreator(OptimizationAlgorithmProperty(
                   "lm_pcg7_3",
                   "Levenberg: PCG solver using block-Jacobi pre-conditioner "
                   "(fixed blocksize)",
                   "PCG", true, 7, 3)));

参考

        [代码实践] G2O 学习记录(一):2D 位姿图优化

        [代码实践] G2O 学习记录(二):3D 位姿图优化


原文地址:https://blog.csdn.net/m0_49384824/article/details/142745642

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!