提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:这里可以添加本文要记录的大概内容:
在Windows下配置ceres有很多bug,后来想到可以使用win10子系统wsl安装ceres,这样使用起来也方便,同时调用suitesparse的速度也不会变慢,花了一天时间配置,并且最后运行成功。
Ceres 是一个开源的非线性求解器,用途广泛,http://ceres-solver.org/features.html这里是官网。然后下面是大佬对Ceres在“Win10环境+Visual Stdio 2019”下的配置:https://blog.csdn.net/ndwonduosk_/article/details/117331564 可以参考。
wsl概述:适用于 Linux 的 Windows 子系统可让开发人员按原样运行 GNU/Linux 环境 - 包括大多数命令行工具、实用工具和应用程序 - 且不会产生传统虚拟机或双启动设置开销。(p.s.使用wsl 1或许更方便,我使用wsl 2 出现一些问题未能解决)。
参考:https://docs.microsoft.com/zh-cn/windows/wsl/install
我使用wsl 1内核,安装了Ubuntu-20.04,安装完成后sudo apt-get update,如果感觉速度较慢的话,可以自己更换国内镜像源,具体办法可以百度,很简单。
(1)WSL的非内核目录文件和windows是共享的,所以安装ceres之前可以先在windows中建立一个Ceres文件夹,然后在文件夹里“shift+鼠标右键”,选择“在此处打开Linux shell”
(2)打开Ubuntu-20.04,在命令行窗口,一步步地输入如下代码(step1 准备工作):
#利用git从官网下载安装包
git clone https://ceres-solver.googlesource.com/ceres-solver
# 安装CMake
sudo apt-get install cmake
# 安装google-glog 和 gflags
sudo apt-get install libgoogle-glog-dev libgflags-dev
# Use ATLAS for 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
综上所述,准备工作需要cmake、附属包glog、gflags,数值分析库Eigen3、系数矩阵求解包suitesparse(也可以选择简化版本CXSparse)。
step2 安装阶段:
# 解压ceres包
tar zxf ceres-solver-2.1.0.tar.gz
# 创建build目录,使用cmake编译
mkdir ceres-bin
cd ceres-bin
cmake ../ceres-solver-2.1.0
# 构建ceres工程,做测试
make -j3
make test
# 安装(建议sudo,避免权限问题)
sudo make install
step3 测试是否安装成功(进入bin目录下的测试文件):
bin/simple_bundle_adjuster ../ceres-solver-2.1.0/data/problem-16-22106-pre.txt
(1)测试helloworld.cc文件的编译、运行过程:
建立一个test文件夹,里面包含“CMakeLists.txt 和 helloworld.cc”
# CMakeList.txt 文件内容
find_package( Ceres REQUIRED )
include_directories( /mnt/d/Ceres/ceres-bin/include )#更换你的inclued目录
#if(COMMAND cmake_policy)
# cmake_policy(SET CMP0003 NEW)
#endif(COMMAND cmake_policy)
add_executable(helloworld helloworld.cc)
target_link_libraries(helloworld PRIVATE Ceres::ceres)
// hellowold.cc程序
#include "ceres/ceres.h"
#include "glog/logging.h"
using ceres::AutoDiffCostFunction;
using ceres::CostFunction;
using ceres::Problem;
using ceres::Solve;
using ceres::Solver;
// A templated cost functor that implements the residual r = 10 -
// x. The method operator() is templated so that we can then use an
// automatic differentiation wrapper around it to generate its
// derivatives.
struct CostFunctor {
template
bool operator()(const T* const x, T* residual) const {
residual[0] = 10.0 - x[0];
return true;
}
};
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
// The variable to solve for with its initial value. It will be
// mutated in place by the solver.
double x = 0.5;
const double initial_x = x;
// Build the problem.
Problem problem;
// Set up the only cost function (also known as residual). This uses
// auto-differentiation to obtain the derivative (jacobian).
CostFunction* cost_function =
new AutoDiffCostFunction(new CostFunctor);
problem.AddResidualBlock(cost_function, nullptr, &x);
// Run the solver!
Solver::Options options;
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;
}
在此处打开Linux shell,依次输入cmake . make ./helloworld
结果如下:
(2)测试 Eigen3 和 Suitesparse 的程序包链接:
建立一个test_eg3sp文件夹,里面包含“CMakeLists.txt 和 linear_solver.cpp”
# CMakeList.txt 文件
find_package( Ceres REQUIRED )
include_directories( /mnt/d/Ceres/ceres-bin/include )
include_directories( /usr/include/suitesparse ) # 你的suitesparse包include位置
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
add_executable(linear_solver linear_solver.cpp)
target_link_libraries(linear_solver PRIVATE Ceres::ceres)
// eigen + suitesparse 测试程序
#include
#include "Eigen/Eigen"
#include "Eigen/SPQRSupport"
using namespace Eigen ;
int main ( ) {
SparseMatrix < double > A ( 4 , 4 ) ;
std :: vector < Triplet < double > > triplets ;
// 初始化非零元素
int r [ 3 ] = { 0 , 1 , 2 } ;
int c [ 3 ] = { 1 , 2 , 2 } ;
double val [ 3 ] = { 6.1 , 7.2 , 8.3 } ;
for ( int i = 0 ; i < 3 ; ++ i )
triplets . push_back( Triplet < double >(r [ i ] , c [ i ] , val [ i ]) ) ;
// 初始化稀疏矩阵
A . setFromTriplets ( triplets . begin ( ) , triplets . end ( ) ) ;
std :: cout << "A = \n" << A << std :: endl ;
// 一个QR分解的实例
SPQR < SparseMatrix < double > > qr ;
// 计算分解
qr . compute ( A ) ;
// 求一个A x = b
Vector4d b ( 1 , 2 , 3 , 4 ) ;
Vector4d x = qr . solve ( b ) ;
std :: cout << "x = \n" << x << std::endl;
std :: cout << "A x = \n" << A * x << std:: endl;
return 0 ;
}
在此处打开Linux shell,依次输入cmake . make ./linear_solver
结果如下图:
(3)g++编译
g++ test.cpp -o test -rdynamic /usr/local/lib/libceres.a -lcholmod -llapack -lf77blas -lcxsparse -lglog -I /usr/loca/include -isystem /usr/include/eigen3 -I /usr/include/suitesparse
使用g++编译注意用 "-I"(大写I)引用include、lib等(p.s. 一个电脑成功,一个电脑失败)。
https://blog.csdn.net/xiamentingtao/article/details/50100549Eigen+suitesparse for windows 安装:https://blog.csdn.net/xiamentingtao/article/details/50100549