1、cmake报错:
![]()
CMakeLists.txt
文件中使用了过时的 CMake 最低版本要求(cmake_minimum_required(VERSION 2.8)
),而当前使用的 CMake 版本 不再支持小于 3.5 的版本号声明。
解决方法:
将第一行改为:
cmake_minimum_required(VERSION 3.10)
然后cmake编译安装。。。
记得先安装编译g2o,要不然报错:
方法:
安装依赖项:
sudo apt-get install qt5-qmake qt5-default libqglviewer-dev-qt5 libsuitesparse-dev libcxsparse3 libcholmod3
后按照cmake的方式对g2o编译安装即可。
最后记得:(不能光make)
sudo make install
3、编译报错:
原因:
G2O 的头文件使用了 C++17 特性(如
std::tuple_size_v
,std::string_view
,std::make_unique
),但编译器 没有启用 C++17 标准。
解决方法:
删除以下这行:
将编译文件修改为:
cmake_minimum_required(VERSION 3.10)
project(ch6)
set(CMAKE_CXX_STANDARD 17)# 显式设置为C++17标准
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS_RELEASE "-O3") # 仅设置优化,不指定标准
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
# OpenCV
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
# Ceres
find_package(Ceres REQUIRED)
include_directories(${CERES_INCLUDE_DIRS})
# g2o
find_package(G2O REQUIRED)
include_directories(${G2O_INCLUDE_DIRS})
# Eigen
include_directories("/usr/local/include/eigen3")
add_executable(gaussNewton gaussNewton.cpp)
target_link_libraries(gaussNewton ${OpenCV_LIBS})
add_executable(ceresCurveFitting ceresCurveFitting.cpp)
target_link_libraries(ceresCurveFitting ${OpenCV_LIBS} ${CERES_LIBRARIES})
add_executable(g2oCurveFitting g2oCurveFitting.cpp)
target_link_libraries(g2oCurveFitting ${OpenCV_LIBS} ${G2O_CORE_LIBRARY} ${G2O_STUFF_LIBRARY})
4、报错:
error: ‘make_unique’ is not a member of ‘g2o’; did you mean ‘std::make_unique’?
用了新版 g2o(从 GitHubmaster
分支构建的),而新版g2o
使用的是std::make_unique
(C++14及以上),但原代码用的是g2o::make_unique
。
解决方法:
编辑 g2oCurveFitting.cpp
文件
改为:
auto solver = std::make_unique<BlockSolverType>(std::make_unique<LinearSolverType>());
⚠️ 注意:必须
#include <memory>
,否则会提示make_unique
不可用。
补全一下代码片段
在你 main()
函数中这段逻辑大概率如下,请你确认并修改为:
#include <memory> // 加上这个!
int main(int argc, char** argv) {
...
// 构建 solver
using BlockSolverType = g2o::BlockSolver<g2o::BlockSolverTraits<3, 1>>;
using LinearSolverType = g2o::LinearSolverDense<BlockSolverType::PoseMatrixType>;
auto solver = std::make_unique<BlockSolverType>(std::make_unique<LinearSolverType>());
optimizer.setAlgorithm(new g2o::OptimizationAlgorithmLevenberg(std::move(solver)));
...
}
警告也一起修复
还有一些 warning:
virtual bool read(istream& in) {} // 没 return
应该补上 return true;
或 false;
:
virtual bool read(std::istream& in) override { return true; } virtual bool write(std::ostream& out) const override { return true; }
否则虽然不是致命错误,但也是不规范的虚函数定义,建议修复。
修改后部分代码:
然后保存重新编译即可。
运行
./gaussNewton
安装Ceres
安装依赖项:
sudo apt-get install liblapack-dev libsuitesparse-dev libcxsparse3 libgflags-dev libgoogle-glog-dev libgtest-dev
其他同上。
./ceresCurveFitting
./g2oCurveFitting
报错:
重复使用
std::unique_ptr
导致段错误
在代码中写了两次:
auto solver = std::make_unique<BlockSolverType>(std::make_unique<LinearSolverType>());
g2o::OptimizationAlgorithmLevenberg* algorithm = new g2o::OptimizationAlgorithmLevenberg(std::move(solver));
optimizer.setAlgorithm(new g2o::OptimizationAlgorithmLevenberg(std::move(solver)));
这里:
第一次 std::move(solver) 把 solver 所拥有的指针移交给了 algorithm
第二次 std::move(solver) 再次使用已经为空的 unique_ptr,导致空指针被传入 SparseOptimizer::setAlgorithm()
当你运行 optimizer.optimize() 时,内部调用了空指针成员函数,直接段错误
解决方案:
只构造一次 solver,并传一次
auto solver = std::make_unique<BlockSolverType>(std::make_unique<LinearSolverType>());
auto algorithm = new g2o::OptimizationAlgorithmLevenberg(std::move(solver));
g2o::SparseOptimizer optimizer;
optimizer.setAlgorithm(algorithm); // 只传一次
optimizer.setVerbose(true);
重新清除,编译,运行: