编译teb_local_planner报错:CHOLMODConfig.cmake
安装 CHOLMOD 依赖(必须先做)
bash
sudo apt update
sudo apt install -y \
libeigen3-dev \
libsuitesparse-dev \
libspdlog-dev
确认 cholmod 在:
bash
ls /usr/include/suitesparse/cholmod.h
ls /usr/lib/x86_64-linux-gnu/libcholmod.so
bash
sukai@sukai:~/3rdparty/g2o/build$ ls /usr/include/suitesparse
amd.h cholmod_config.h cholmod_partition.h spqr.hpp umfpack_get_determinant.h umfpack_qsymbolic.h umfpack_report_vector.h umfpack_triplet_to_col.h
btf.h cholmod_core.h cholmod_supernodal.h SuiteSparse_config.h umfpack_get_lunz.h umfpack_report_control.h umfpack_save_numeric.h umfpack_wsolve.h
camd.h cholmod_function.h cholmod_template.h SuiteSparseQR_C.h umfpack_get_numeric.h umfpack_report_info.h umfpack_save_symbolic.h
ccolamd.h cholmod_gpu.h colamd.h SuiteSparseQR_definitions.h umfpack_get_symbolic.h umfpack_report_matrix.h umfpack_scale.h
cholmod_blas.h cholmod_gpu_kernels.h cs.h SuiteSparseQR.hpp umfpack_global.h umfpack_report_numeric.h umfpack_solve.h
cholmod_camd.h cholmod.h klu.h umfpack_col_to_triplet.h umfpack.h umfpack_report_perm.h umfpack_symbolic.h
cholmod_check.h cholmod_io64.h ldl.h umfpack_defaults.h umfpack_load_numeric.h umfpack_report_status.h umfpack_tictoc.h
cholmod_cholesky.h cholmod_matrixops.h RBio.h umfpack_free_numeric.h umfpack_load_symbolic.h umfpack_report_symbolic.h umfpack_timer.h
cholmod_complexity.h cholmod_modify.h SLIP_LU.h umfpack_free_symbolic.h umfpack_numeric.h umfpack_report_triplet.h umfpack_transpose.h
安装g2o
CMake Error at cmake_modules/FindG2O.cmake:85 (message):
Could not find libg2o!
Call Stack (most recent call first):
CMakeLists.txt:45 (find_package)
1. 先安装 g2o 官方要求的依赖(优先安装完整依赖,避免编译缺失功能)
bash
sudo apt install -y cmake libeigen3-dev libspdlog-dev libsuitesparse-dev qtdeclarative5-dev qt5-qmake libqglviewer-dev-qt5
克隆g2o官方源码(确保网络通畅,若克隆缓慢可换国内镜像)
bash
git clone https://github.com/RainerKuemmerle/g2o.git
编译:
bash
用这个 指定 libcholmod 路径
cd ~/g2o
rm -rf build
mkdir build && cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DG2O_USE_CHOLMOD=ON \
-DCMAKE_MODULE_PATH=/home/sukai/3rdparty/g2o/cmake_modules \
-DCHOLMOD_INCLUDE_DIR=/usr/include/suitesparse \
-DCHOLMOD_LIBRARY=/usr/lib/x86_64-linux-gnu/libcholmod.so \
-DG2O_BUILD_APPS=OFF \
-DG2O_BUILD_EXAMPLES=OFF
make -j$(nproc)
sudo make install
sudo ldconfig
安装成功后
bash
pkg-config --modversion g2o
查不到 g2o
把上下面面的内容保存为文本文件,比如命名为 g2o.pc:
bash
sudo mkdir -p /usr/local/lib/pkgconfig
bash
sudo tee /usr/local/lib/pkgconfig/g2o.pc > /dev/null <<EOF
prefix=/usr/local
exec_prefix=\${prefix}
libdir=\${exec_prefix}/lib
includedir=\${prefix}/include
Name: g2o
Description: General Graph Optimization Library
Version: 0.2.0
Requires:
Libs: -L\${libdir} \
-lg2o_core \
-lg2o_stuff \
-lg2o_solver_csparse \
-lg2o_csparse_extension \
-lg2o_types_slam2d \
-lg2o_types_slam3d \
-lg2o_types_sba \
-lg2o_types_icp \
-lg2o_types_sim3 \
-lg2o_solver_dense \
-lg2o_solver_eigen \
-lg2o_solver_pcg \
-lg2o_solver_slam2d_linear \
-lg2o_solver_structure_only
Cflags: -I\${includedir}
EOF
然后刷新环境:
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
pkg-config --modversion g2o # 测试版本号显示
报错:
Finished <<< akm_navigation2 [0.08s] --- stderr: teb_local_planner CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required): Compatibility with CMake < 3.10 will be removed from a future version of CMake. Update the VERSION argument <min> value. Or, use the <min>...<max> syntax to tell CMake that the project requires at least <min> but has been updated to work with policies introduced by <max> or earlier. CMake Error at cmake_modules/FindG2O.cmake:85 (message): Could not find libg2o! Call Stack (most recent call first): CMakeLists.txt:45 (find_package) --- Failed <<< teb_local_planner [0.67s, exited with code 1] Summary: 55 packages finished [2.90s] 1 package failed: teb_local_planner 1 package had stderr output: teb_local_planner
在 teb_local_planner-for-ros2-humble/teb_local_planner/teb_local_planner/cmake_modules下找到 FindG2O.cmake
改写后的 FindG2O.cmake
bash
# FindG2O.cmake - Find g2o library and headers
cmake_minimum_required(VERSION 3.0)
if(NOT G2O_FIND_REQUIRED)
set(G2O_FIND_REQUIRED TRUE)
endif()
message(STATUS "Searching for g2o ...")
# 1. 先尝试用 pkg-config 找
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
pkg_check_modules(G2O_PKG g2o)
endif()
if(G2O_PKG_FOUND)
set(G2O_INCLUDE_DIRS ${G2O_PKG_INCLUDE_DIRS})
set(G2O_LIBRARIES ${G2O_PKG_LIBRARIES})
message(STATUS "Found g2o via pkg-config:")
message(STATUS " include dirs: ${G2O_INCLUDE_DIRS}")
message(STATUS " libs: ${G2O_LIBRARIES}")
else()
# 2. pkg-config没找到,用 find_path 和 find_library 手动找
find_path(G2O_INCLUDE_DIR
NAMES core math_groups types
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES include/g2o include
NO_DEFAULT_PATH
)
if(NOT G2O_INCLUDE_DIR)
# 试用默认路径
find_path(G2O_INCLUDE_DIR
NAMES core math_groups types
PATH_SUFFIXES include/g2o include
)
endif()
# 查找库文件,多种可能
find_library(G2O_CORE_LIB
NAMES g2o_core g2o_core_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
find_library(G2O_STUFF_LIB
NAMES g2o_stuff g2o_stuff_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
find_library(G2O_TYPES_SLAM2D_LIB
NAMES g2o_types_slam2d g2o_types_slam2d_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
find_library(G2O_TYPES_SLAM3D_LIB
NAMES g2o_types_slam3d g2o_types_slam3d_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
find_library(G2O_SOLVER_CHOLMOD_LIB
NAMES g2o_solver_cholmod g2o_solver_cholmod_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
find_library(G2O_SOLVER_PCG_LIB
NAMES g2o_solver_pcg g2o_solver_pcg_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
find_library(G2O_SOLVER_CSPARSE_LIB
NAMES g2o_solver_csparse g2o_solver_csparse_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
find_library(G2O_INCREMENTAL_LIB
NAMES g2o_incremental g2o_incremental_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
find_library(G2O_CSPARSE_EXTENSION_LIB
NAMES g2o_csparse_extension g2o_csparse_extension_rd
PATHS /usr/local /usr /opt /opt/local
PATH_SUFFIXES lib lib64
)
set(G2O_LIBRARIES
${G2O_CSPARSE_EXTENSION_LIB}
${G2O_CORE_LIB}
${G2O_STUFF_LIB}
${G2O_TYPES_SLAM2D_LIB}
${G2O_TYPES_SLAM3D_LIB}
${G2O_SOLVER_CHOLMOD_LIB}
${G2O_SOLVER_PCG_LIB}
${G2O_SOLVER_CSPARSE_LIB}
${G2O_INCREMENTAL_LIB}
)
if(G2O_LIBRARIES AND G2O_INCLUDE_DIR)
set(G2O_FOUND TRUE)
message(STATUS "Found g2o libraries and headers:")
message(STATUS " include dir: ${G2O_INCLUDE_DIR}")
message(STATUS " libs: ${G2O_LIBRARIES}")
else()
set(G2O_FOUND FALSE)
if(G2O_FIND_REQUIRED)
message(FATAL_ERROR "Could not find g2o libraries or headers!")
else()
message(WARNING "g2o not found, some targets may fail to build.")
endif()
endif()
endif()
# 方便后续引用
mark_as_advanced(G2O_INCLUDE_DIR G2O_LIBRARIES G2O_FOUND)
报错:
Manually-specified variables were not used by the project: CHOLMOD_INCLUDE_DIR CHOLMOD_LIBRARY
解决思路
-
写一个本地的
FindCHOLMOD.cmake文件 (推荐)把一个简单的
FindCHOLMOD.cmake放到 g2o 的cmake_modules/目录(或者你 build 目录下自定义路径),然后用-DCMAKE_MODULE_PATH=...告诉 cmake 去找它。简单版
FindCHOLMOD.cmake如下:放 /home/sukai/3rdparty/g2o/cmake_modules 目录bash# FindCHOLMOD.cmake find_path(CHOLMOD_INCLUDE_DIR NAMES cholmod.h PATHS /usr/include /usr/include/suitesparse ) find_library(CHOLMOD_LIBRARY NAMES cholmod PATHS /usr/lib /usr/lib/x86_64-linux-gnu ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(CHOLMOD DEFAULT_MSG CHOLMOD_INCLUDE_DIR CHOLMOD_LIBRARY) if(CHOLMOD_FOUND) set(CHOLMOD_LIBRARIES ${CHOLMOD_LIBRARY}) set(CHOLMOD_INCLUDE_DIRS ${CHOLMOD_INCLUDE_DIR}) endif()用:
bash用这个 指定 libcholmod 路径 cd ~/g2o rm -rf build mkdir build && cd build cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/usr/local \ -DG2O_USE_CHOLMOD=ON \ -DCMAKE_MODULE_PATH=/home/sukai/3rdparty/g2o/cmake_modules \ -DCHOLMOD_INCLUDE_DIR=/usr/include/suitesparse \ -DCHOLMOD_LIBRARY=/usr/lib/x86_64-linux-gnu/libcholmod.so \ -DG2O_BUILD_APPS=OFF \ -DG2O_BUILD_EXAMPLES=OFF make -j$(nproc) sudo make install sudo ldconfig
如果已经 安装了 g2o:
bash
先彻底卸载你现在的 g2o(非常重要)
# 1. 删头文件
sudo rm -rf /usr/local/include/g2o
# 2. 删库文件
sudo rm -f /usr/local/lib/libg2o*
sudo rm -f /usr/local/lib64/libg2o*
# 3. 删 CMake 配置
sudo rm -rf /usr/local/lib/cmake/g2o
sudo rm -rf /usr/local/share/g2o
sudo rm -rf /usr/local/share/cmake/g2o*
# 4. ⭐ 删 pkg-config(关键),这个可以不删,因为重新安装后还要重新做:g2o.pc 上面有做的教程
sudo rm -f /usr/local/lib/pkgconfig/g2o.pc
sudo rm -f /usr/local/lib64/pkgconfig/g2o.pc
# 5. 更新缓存
sudo ldconfig
确认:
pkg-config --modversion g2o
编译teb_local_planner报错:
CMake Error at CMakeLists.txt:16 (find_package): By not providing "FindCeres.cmake" in CMAKE_MODULE_PATH this project has asked CMake to find a package configuration file provided by "Ceres", but CMake did not find one. Could not find a package configuration file provided by "Ceres" with any of the following names: CeresConfig.cmake ceres-config.cmake Add the installation prefix of "Ceres" to CMAKE_PREFIX_PATH or set "Ceres_DIR" to a directory containing one of the above files. If "Ceres" provides a separate development package or SDK, be sure it has been installed.
✅ 方案 A:直接用 apt 安装(99% 情况够用)
在 Ubuntu 22.04 + ROS 2 Humble 下,直接:
sudo apt update
sudo apt install -y libceres-dev
安装完成后,你应该能看到:
bash
sukai@sukai:~/3rdparty/g2o/cmake_modules$ dpkg -L libceres-dev | grep CeresConfig.cmake
/usr/lib/cmake/Ceres/CeresConfig.cmake
验证:
bash
cmake --find-package \ -DNAME=Ceres \ -DCOMPILER_ID=GNU \ -DLANGUAGE=CXX \ -DMODE=EXIST
如果不报错,说明 Ceres 已被 CMake 正确识别 ✅
报错:
In file included from /home/sukai/workspace/akm_ws/src/teb_local_planner-for-ros2-humble/teb_local_planner/teb_local_planner/src/visualization.cpp:41: /home/sukai/workspace/akm_ws/src/teb_local_planner-for-ros2-humble/teb_local_planner/teb_local_planner/include/teb_local_planner/optimal_planner.h:60:10: fatal error: g2o/solvers/cholmod/linear_solver_cholmod.h: 没有那个文件或目录 60 | #include "g2o/solvers/cholmod/linear_solver_cholmod.h" | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ compilation terminated. gmake[2]: *** [CMakeFiles/teb_local_planner.dir/build.make:121:CMakeFiles/teb_local_planner.dir/src/visualization.cpp.o] 错误 1 gmake[2]: *** 正在等待未完成的任务.... In file included from /home/sukai/workspace/akm_ws/src/teb_local_planner-for-ros2-humble/teb_local_planner/teb_local_planner/src/optimal_planner.cpp:42: /home/sukai/workspace/akm_ws/src/teb_local_planner-for-ros2-humble/teb_local_planner/teb_local_planner/include/teb_local_planner/optimal_planner.h:60:10: fatal error: g2o/solvers/cholmod/linear_solver_cholmod.h: 没有那个文件或目录 60 | #include "g2o/solvers/cholmod/linear_solver_cholmod.h" | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ compilation terminated. gmake[2]: *** [CMakeFiles/teb_local_planner.dir/build.make:93:CMakeFiles/teb_local_planner.dir/src/optimal_planner.cpp.o] 错误 1 gmake[1]: *** [CMakeFiles/Makefile2:153:CMakeFiles/teb_local_planner.dir/all] 错误 2 gmake: *** [Makefile:146:all] 错误 2
一、问题的本质(一句话)
你的 g2o 没有启用 CHOLMOD
但 TEB 源码强制
#include g2o/solvers/cholmod/linear_solver_cholmod.h
所以结果一定是:
bash
fatal error: g2o/solvers/cholmod/linear_solver_cholmod.h: No such file
👉 和 Ceres、SuiteSparse、FindG2O 已经没关系了
二、正确、现实、推荐的解决方案 ✅
👉 禁用 CHOLMOD,使用 g2o 自带的 CSparse / PCG
这是 ROS 社区在 Ubuntu 22.04 + ROS2 下最常用的做法。
✔ 能跑
✔ 稳定
✔ 性能对 Nav2 完全够用
三、一步一步改(照抄即可)
1️⃣ 修改 optimal_planner.h
📍 文件路径
bash
teb_local_planner/include/teb_local_planner/optimal_planner.h
❌ 删除 / 注释这一行(第 60 行左右)
bash
#include "g2o/solvers/cholmod/linear_solver_cholmod.h"
✅ 替换为(CSparse + PCG)
bash
#include <g2o/solvers/csparse/linear_solver_csparse.h>
#include <g2o/solvers/pcg/linear_solver_pcg.h>
2️⃣ 修改 optimal_planner.cpp
📍 文件路径
bash
teb_local_planner/src/optimal_planner.cpp
🔍 找到类似下面这段(创建 solver 的地方)
原来(CHOLMOD)大概是:
bash
typedef g2o::LinearSolverCholmod<g2o::BlockSolverX::PoseMatrixType> LinearSolverType;
✅ 改成 CSparse 版本(推荐)
bash
typedef g2o::LinearSolverCSparse<g2o::BlockSolverX::PoseMatrixType> LinearSolverType;
或者 PCG(更通用):
bash
typedef g2o::LinearSolverPCG<g2o::BlockSolverX::PoseMatrixType> LinearSolverType;
✅ CSparse 是 TEB 最常见替代
PCG 在数值稳定性上稍弱一点,但完全能跑
3️⃣ 确保 CMakeLists.txt 不再强制 CHOLMOD
📍 文件路径
bash
teb_local_planner/CMakeLists.txt
❌ 如果你有这些,删掉 / 注释
bash
find_package(SuiteSparse REQUIRED) find_package(CHOLMOD REQUIRED)
✅ g2o 只需要这些即可
bash
find_package(PkgConfig REQUIRED) pkg_check_modules(G2O REQUIRED g2o)
并确保:
bash
include_directories( include ${G2O_INCLUDE_DIRS} )
4️⃣ 清理 & 重新编译(非常重要)
bash
cd ~/workspace/a_ws rm -rf build install log colcon build --packages-select teb_local_planner --symlink-install
四、为什么这是"正确解法"
✔ ROS2 + Nav2 + TEB 的现实情况
-
Ubuntu 22.04 官方 g2o:无 CHOLMOD
-
自己 patch g2o 启 CHOLMOD:代价巨大
-
TEB 本身并不强依赖 CHOLMOD
👉 90% 的 ROS2 用户都用 CSparse / PCG
五、你现在的状态评估(说实话)
| 项目 | 状态 |
|---|---|
| Ceres | ✅ 已正确 |
| SuiteSparse | ✅ 已正确 |
| g2o | ✅ 正确(无 CHOLMOD) |
| 错误原因 | ❌ TEB 强制 include CHOLMOD |
| 解决方案 | ✅ 禁用 CHOLMOD |
克隆:teb_local_planner
bash
https://github.com/rst-tu-dortmund/teb_local_planner.git