ROS2 Foxy中正确引入Eigen3:解决头文件路径异常问题
在ROS2 Foxy中正确配置并引入Eigen3库
问题背景
我在ROS2 Foxy工作空间开发C++程序,想使用Eigen3库。已经按照官方cmake模块的步骤修改了CMakeLists.txt和package.xml,但代码中引入头文件时,系统只识别我在根目录手动克隆的Eigen3路径,不知道怎么通过ROS2的依赖管理正确引入。
我的CMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(tachimawari) if(NOT CMAKE_C_STANDARD) set(CMAKE_C_STANDARD 99) endif() if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 17) endif() if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic -fPIC) endif() find_package(ament_cmake REQUIRED) find_package(dynamixel_sdk REQUIRED) find_package(kansei_interfaces REQUIRED) find_package(keisan REQUIRED) find_package(rclcpp REQUIRED) find_package(tachimawari_interfaces REQUIRED) find_package(eigen3_cmake_module REQUIRED) find_package(Eigen3 REQUIRED) add_library(${PROJECT_NAME} SHARED "src/${PROJECT_NAME}/control/controller/module/cm740.cpp" "src/${PROJECT_NAME}/control/controller/packet/protocol_1/instruction/bulk_read_packet.cpp" "src/${PROJECT_NAME}/control/controller/packet/protocol_1/instruction/read_packet.cpp" "src/${PROJECT_NAME}/control/controller/packet/protocol_1/instruction/sync_write_packet.cpp" "src/${PROJECT_NAME}/control/controller/packet/protocol_1/instruction/write_packet.cpp" "src/${PROJECT_NAME}/control/controller/packet/protocol_1/model/packet.cpp" "src/${PROJECT_NAME}/control/controller/packet/protocol_1/status/bulk_read_data.cpp" "src/${PROJECT_NAME}/control/controller/packet/protocol_1/status/status_packet.cpp" "src/${PROJECT_NAME}/control/controller/packet/protocol_1/utils/word.cpp" "src/${PROJECT_NAME}/control/controller/platform/linux.cpp" "src/${PROJECT_NAME}/control/controller/utils/timer.cpp" "src/${PROJECT_NAME}/control/manager/control_manager.cpp" "src/${PROJECT_NAME}/control/sdk/module/dynamixel_sdk.cpp" "src/${PROJECT_NAME}/control/sdk/packet/model/group_bulk_read.cpp" "src/${PROJECT_NAME}/control/sdk/packet/protocol_1/group_bulk_read.cpp" "src/${PROJECT_NAME}/control/sdk/packet/protocol_1/group_sync_write.cpp" "src/${PROJECT_NAME}/control/sdk/packet/protocol_2/group_bulk_read.cpp" "src/${PROJECT_NAME}/control/sdk/packet/protocol_2/group_sync_write.cpp" "src/${PROJECT_NAME}/imu/node/imu_node.cpp" "src/${PROJECT_NAME}/imu/node/imu_provider.cpp" "src/${PROJECT_NAME}/joint/model/joint_id.cpp" "src/${PROJECT_NAME}/joint/model/joint.cpp" "src/${PROJECT_NAME}/joint/node/joint_manager.cpp" "src/${PROJECT_NAME}/joint/node/joint_node.cpp" "src/${PROJECT_NAME}/joint/utils/middleware.cpp" "src/${PROJECT_NAME}/joint/utils/node_control.cpp" "src/${PROJECT_NAME}/node/tachimawari_node.cpp") target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) ament_target_dependencies(${PROJECT_NAME} dynamixel_sdk kansei_interfaces keisan rclcpp tachimawari_interfaces Eigen3) install(DIRECTORY "include" DESTINATION ".") install(TARGETS ${PROJECT_NAME} EXPORT export_${PROJECT_NAME} ARCHIVE DESTINATION "lib" LIBRARY DESTINATION "lib" RUNTIME DESTINATION "bin") add_executable(check_joints "src/check_joints_main.cpp") target_include_directories(check_joints PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) target_link_libraries(check_joints ${PROJECT_NAME}) add_executable(init_joints "src/init_joints_main.cpp") target_include_directories(init_joints PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) target_link_libraries(init_joints ${PROJECT_NAME}) add_executable(main "src/tachimawari_main.cpp") target_include_directories(main PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) target_link_libraries(main ${PROJECT_NAME}) add_executable(read_buttons "src/read_buttons_main.cpp") target_include_directories(read_buttons PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) target_link_libraries(read_buttons ${PROJECT_NAME}) add_executable(read_joints "src/read_joints_main.cpp") target_include_directories(read_joints PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) target_link_libraries(read_joints ${PROJECT_NAME}) add_executable(forward_kinematic "src/tachimawari/node/forward_kinematic.cpp") target_include_directories(forward_kinematic PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) target_link_libraries(forward_kinematic ${PROJECT_NAME}) install(TARGETS check_joints init_joints main read_buttons read_joints forward_kinematic DESTINATION lib/${PROJECT_NAME}) if(BUILD_TESTING) find_package(ament_cmake_gtest REQUIRED) find_package(ament_lint_auto REQUIRED) ament_add_gtest(${PROJECT_NAME}_tests "test/joint/joint_test.cpp") target_include_directories(${PROJECT_NAME}_tests PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>) target_link_libraries(${PROJECT_NAME}_tests ${PROJECT_NAME}) ament_lint_auto_find_test_dependencies() endif() ament_export_dependencies( dynamixel_sdk kansei_interfaces keisan rclcpp tachimawari_interfaces Eigen3 eigen3_cmake_module) ament_export_include_directories("include") ament_export_libraries(${PROJECT_NAME}) ament_package()
待修改的C++代码
#include <iostream> #include <stdio.h> #include <eigen3/Dense> // 这里不知道怎么正确引入 using namespace std; using namespace Eigen; typedef Matrix<double, 4, 4> Matrix4D; typedef Matrix<double, 4, 1> Vector4D; typedef Matrix<double, 3, 1> Vector3D;
解决步骤
1. 确认package.xml依赖配置
先检查package.xml是否添加了Eigen相关依赖,没有的话补上:
<depend>eigen3_cmake_module</depend> <depend>Eigen3</depend>
2. 移除手动克隆的Eigen3
删除工作空间根目录下手动克隆的Eigen3文件夹,避免干扰ROS2的依赖查找逻辑。
3. 修改代码中的头文件引入方式
通过ROS2的依赖管理配置后,Eigen的根目录已经被添加到编译器的包含路径中,直接用以下方式引入即可:
#include <Eigen/Dense>
不需要加eigen3前缀,因为Eigen3包会自动把包含Eigen文件夹的路径注入到编译环境里。
4. 清理并重新构建
执行以下命令彻底清理旧构建文件,重新编译:
rm -rf build install log colcon build --packages-select tachimawari source install/setup.bash
完成以上步骤后,编译器就会使用ROS2依赖管理找到的系统Eigen3库,不再依赖手动克隆的版本。
内容的提问来源于stack exchange,提问作者Kuuhaku
相关产品推荐
相关产品推荐

