ceres的学习笔记

刚刚在项目中使用的到了ceres,从完全不了解、到安装使用解决问题,花费了整整一个周的时间。所以使用的时候过程中踩了不少的坑,所以特别想记录下来。

ceres解决的问题

Ceres solver 是谷歌开发的一款用于非线性优化的库,在谷歌的开源激光雷达slam项目cartographer中被大量使用。ceres的官网比较详细的使用教程,内容还是挺丰富。
ceres主要用于解决如下的非线性最小二乘的问题
在这里插入图片描述ρi(‖‖fi(xi1,…,xik)‖‖2) 这一部分被成为残差块(ResidualBlock),其中的fi(⋅) 叫做代价函数(CostFunction)。代价函数依赖于一系列参数[xi1,…,xik] ,这一系列参数(均为标量)称为参数块(ParameterBlock)。lj 和 uj 分别是变量块 xj 的上下边界。

安装

ceres可以通过命令行直接安装,也可以下载源码编译静态库使用。首先我们需要解决依赖的问题

依赖

ceres依赖挺多开源库的,但并不是必须的,可以在构建时关闭相应的依赖。

  • Eigen是必须的。
  • glog推荐使用,内部也提供了替代glog的minilog,但是性能赶不上glog,除了在android平台,其他平台建议使用glog。可以不用使用。
  • gflags在测试和示例中有使用到。可以不用使用。
  • SuiteSparse在解决大型稀疏线性系统所需。推荐使用。SuiteSparse需要BLAS和LAPACK。(我第一次编译的时候没有添加,为了加快求解的速度,不能不重新编译一下)
  • CXSparse 与SuiteSparse类似,但更简单,更慢。 CXSparse不依赖于LAPACK和BLAS。 这使得构建过程更简单,二进制文件更小。可以不用使用。
命令行安装

安装依赖

$ sudo apt-get install cmake
# google-glog + gflags
$ sudo apt-get install libgoogle-glog-dev
# BLAS & LAPACK
$ sudo apt-get install libatlas-base-dev
# Eigen3
$ sudo apt-get install libeigen3-dev
# SuiteSparse and CXSparse (optional)
$ sudo apt-get install libsuitesparse-dev
# - However, if you want to build Ceres as a *shared* library, you must
#   add the following PPA:
$ sudo add-apt-repository ppa:bzindovic/suitesparse-bugfix-1319687
$ sudo apt-get update
$ sudo apt-get install libsuitesparse-dev
下载源码编译ceres静态库

编译ceres依赖eigen和glog,因此需要先拉取eigen和glog。

# 拉取glog
$ git clone https://github.com/google/glog.git
# 修改option
# option (WITH_GFLAGS "Use gflags" OFF)
$ vi CMakeLists.txt
# 开始编译
$ cmake ..
$ make -j4
$ make DESTDIR=./output install

# 拉取eigen
$ git clone https://gitlab.com/libeigen/eigen.git

# 拉取ceres
$ git clone https://ceres-solver.googlesource.com/ceres-solver
$ cd ceres-solver
# 项目需求,切换到1.13.0版本
$ git checkout 1.13.0
$ git branch
* (HEAD detached at 1.13.0)
# 根据实际需求,修改option
# option(GFLAGS "Enable Google Flags." OFF)
# option(LAPACK "Enable use of LAPACK." OFF)
# option(OPENMP "Enable threaded solving in Ceres (requires OpenMP)" OFF)
# option(BUILD_TESTING "Enable tests" OFF)
# option(BUILD_EXAMPLES "Build examples" OFF)
vi CMakeList.txt

$ mkdir build && cd build

# 开始编译
$ cmake ..
$ make -j4
$ make DESTDIR=./output install

示例

$ ls
build  CMakeLists.txt  include  lib  test1.cpp
$ ls include
ceres  Eigen  glog
$ ls lib
libceres.a  libglog.a
test1.cpp是源自ceres官网的一个例子:
#include <iostream>
#include <ceres/ceres.h>

using namespace std;
using namespace ceres;

struct CostFunctor
{
    template <typename T>
    bool operator()(const T *const x, T *residual) const
    {
        residual[0] = T(10.0) - x[0];
        return true;
    }
};

int main(int argc, char **argv)
{
    google::InitGoogleLogging(argv[0]);

    // 寻优参数x的初始值,为5
    double initial_x = 5.0;
    double x = initial_x;

    // 第二部分:构建寻优问题
    Problem problem;
    CostFunction *cost_function =
        new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);
    problem.AddResidualBlock(cost_function, NULL, &x);

    //第三部分: 配置并运行求解器
    Solver::Options options;
    options.linear_solver_type = ceres::DENSE_QR;
    options.minimizer_progress_to_stdout = true;
    Solver::Summary summary;
    Solve(options, &problem, &summary);

    std::cout << summary.BriefReport() << "\n";
    std::cout << "x : " << initial_x << " -> " << x << "\n";
    return 0;
}
CMakeList.txt
$ cat CMakeList.txt
cmake_minimum_required(VERSION 3.4)
project(samples CXX)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)

# This project requires C++11.
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package (Threads REQUIRED)
add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
add_compile_options(-Wall)

FILE(GLOB samples_src_list ${PROJECT_SOURCE_DIR}/*.cpp)
message("${samples_src_list}")
link_directories(${PROJECT_SOURCE_DIR}/lib/)
foreach(src ${samples_src_list})
    string(REGEX MATCH "[^/]+$" src_file ${src})
    string(REPLACE ".cpp" "" exe_file_name ${src_file})
    set(exe_target ${PROJECT_NAME}_${exe_file_name})
    add_executable(${PROJECT_NAME}_${exe_file_name} ${src})

    target_include_directories(${PROJECT_NAME}_${exe_file_name} PUBLIC include)    
    target_link_libraries(${PROJECT_NAME}_${exe_file_name}
        ${CMAKE_THREAD_LIBS_INIT}
        ceres
        glog
    )

    install(TARGETS ${PROJECT_NAME}_${exe_file_name} RUNTIME DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/bin)
endforeach(src)
测试
$ ./samples_test1 
iter      cost      cost_change  |gradient|   |step|    tr_ratio  tr_radius  ls_iter  iter_time  total_time
   0  1.250000e+01    0.00e+00    5.00e+00   0.00e+00   0.00e+00  1.00e+04        0    7.20e-05    1.33e-04
   1  1.249750e-07    1.25e+01    5.00e-04   5.00e+00   1.00e+00  3.00e+04        1    6.20e-05    2.84e-04
   2  1.388518e-16    1.25e-07    1.67e-08   5.00e-04   1.00e+00  9.00e+04        1    2.19e-05    3.28e-04
Ceres Solver Report: Iterations: 3, Initial cost: 1.250000e+01, Final cost: 1.388518e-16, Termination: CONVERGENCE
x : 5 -> 10
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值