安装g2o,编译teb_local_planner报错:CHOLMODConfig.cmake

编译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

解决思路

  1. 写一个本地的 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

四、为什么这是"正确解法"

  • 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
相关推荐
gxt_kt2 年前
TEB (Timed Elastic Band)
路径规划·teb