鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    编译cmakelist报错找不到依赖库

    已定时 已固定 已锁定 已移动
    Nav2
    nav2 ros2 缺少依赖
    2
    8
    800
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 2
      2782489573
      最后由 编辑

      编译cmakelist报错找不到依赖库/usr/bin/ld: CMakeFiles/pid_position_follow.dir/src/pid_position_follow.cpp.o: in function TransformPose(std::shared_ptr<tf2_ros::Buffer> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, geometry_msgs::msg::PoseStamped_<std::allocator<void> > const&, geometry_msgs::msg::TransformStamped_<std::allocator<void> >&)': pid_position_follow.cpp:(.text+0xa21): undefined reference to void tf2::fromMsg<geometry_msgs::msg::Pose_<std::allocator<void> >, geometry_msgs::msg::Transform_<std::allocator<void> > >(geometry_msgs::msg::Pose_<std::allocator<void> > const&, geometry_msgs::msg::Transform_<std::allocator<void> >&)'
      /usr/bin/ld: pid_position_follow.cpp:(.text+0xaa2): undefined reference to `void tf2::fromMsg<geometry_msgs::msg::Pose_<std::allocator<void> >, geometry_msgs::msg::Transform_<std::allocator<void> > >(geometry_msgs::msg::Pose_<std::allocator<void> > const&, geometry_msgs::msg::Transform_<std::allocator<void> >&)'
      collect2: error: ld returned 1 exit status
      gmake[2]: *** [CMakeFiles/pid_position_follow.dir/build.make:243:pid_position_follow] 错误 1
      gmake[1]: *** [CMakeFiles/Makefile2:137:CMakeFiles/pid_position_follow.dir/all] 错误 2
      gmake: *** [Makefile:146:all] 错误 2
      但是我加上链接后报错--- stderr: pid_position_follow
      /usr/bin/ld: 找不到 -ltf2: 没有那个文件或目录
      /usr/bin/ld: 找不到 -ltf2_ros: 没有那个文件或目录
      /usr/bin/ld: 找不到 -ltf2_geometry_msgs: 没有那个文件或目录
      collect2: error: ld returned 1 exit status
      很抽象

      1 条回复 最后回复 回复 引用 0
      • 小伊小
        机器人小伊
        最后由 编辑

        这个错误表明你的项目在链接阶段找不到必要的 tf2 及其相关 ROS 库的库文件。这通常是因为这些库没有被正确安装或者它们的安装位置没有被添加到链接器的搜索路径中。以下是一些解决步骤:

        1. 确认库是否已安装:
          确保 tf2 及其相关的 ROS 库(如 tf2_ros, tf2_geometry_msgs)已经正确安装在你的系统上。如果你使用的是 ROS,你可以通过 ROS 的包管理器来安装这些库。例如,在 Ubuntu 上使用 ROS Noetic,你可以通过以下命令安装:

          sudo apt-get install ros-noetic-tf2 ros-noetic-tf2-ros ros-noetic-tf2-geometry-msgs
          

          根据你的 ROS 版本(如 Kinetic, Melodic 等),替换 noetic 为对应的版本名称。

        2. 检查库文件的位置:
          如果库已经安装,检查这些库文件(通常是 .so 文件)位于哪个目录。你可以使用 dpkg -L 命令来查看已安装包的文件列表。例如:

          dpkg -L ros-noetic-tf2
          dpkg -L ros-noetic-tf2-ros
          dpkg -L ros-noetic-tf2-geometry-msgs
          

          查找输出中 .so 文件的路径,通常这些文件位于 /usr/lib/x86_64-linux-gnu/ros-<version>/ 或 /opt/ros/<version>/lib/ 下。

        3. 设置链接器的搜索路径:
          如果库文件存在但不在链接器的默认搜索路径中,你可以通过以下几种方式添加搜索路径:

          • 修改 CMakeLists.txt:在你的 CMakeLists.txt 文件中添加链接库的路径。使用 link_directories() 函数:

            link_directories(/usr/lib/x86_64-linux-gnu/ros-noetic)
            

            替换为实际库文件所在的路径。

          • 设置环境变量:在运行 cmake 或 make 之前,设置 LD_LIBRARY_PATH 环境变量,包括库文件的路径:

            export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/ros-noetic:$LD_LIBRARY_PATH
            

            然后再次运行 cmake 和 make。

        4. 清理并重新构建:
          在做了上述更改后,确保清理旧的构建文件,然后重新运行 cmake 和 make:

          cd your_project_directory
          make clean
          cmake .
          make
          
        5. 检查 ROS 环境:
          确保你的 ROS 环境已经正确设置。这通常涉及到设置 ROS_MASTER_URI 和 ROS_PACKAGE_PATH 环境变量,以及在你的 shell 中 source 正确的 setup.bash 文件。

        如果以上步骤仍然无法解决问题,可能需要检查你的 ROS 安装是否完整或考虑重新安装 ROS 和相关库。


        以上为生成回答,仅供参考~

        我是小伊,已接入ChatGpt,所有回复,仅供参考~

        2 1 条回复 最后回复 回复 引用 0
        • 2
          2782489573 @小伊
          最后由 编辑

          @小伊 cmake_minimum_required(VERSION 3.10)
          project(pid_position_follow)

          Use C++14

          set(CMAKE_CXX_STANDARD 14)
          set(CMAKE_CXX_STANDARD_REQUIRED ON)

          By adding -Wall and -Werror, the compiler does not ignore warnings anymore,

          enforcing cleaner code.

          add_definitions(-Wall -Werror)

          Export compile commands for clangd

          set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

          #######################

          Find dependencies

          #######################

          find_package(ament_cmake_auto REQUIRED)
          ament_auto_find_build_dependencies()

          添加包含目录

          include_directories(
          include/cubic_spline
          include/pid_position_follow
          )

          ###########

          Build

          ###########

          ament_auto_add_executable(${PROJECT_NAME}
          src/pid_position_follow.cpp
          )

          确保链接 tf2 库

          find_package(tf2 REQUIRED)
          find_package(tf2_ros REQUIRED)
          find_package(tf2_geometry_msgs REQUIRED)

          ament_target_dependencies(${PROJECT_NAME}
          tf2
          tf2_ros
          tf2_geometry_msgs
          )

          #############

          Install

          #############

          ament_auto_package(
          INSTALL_TO_SHARE
          launch
          include
          )这个是我的cmakelist

          1 条回复 最后回复 回复 引用 0
          • 小伊小
            机器人小伊
            最后由 编辑

            您的 CMakeLists.txt 文件主要用于配置一个使用 C++14 标准、包含特定编译器标志、依赖项和安装指令的 ROS 2 项目。不过,有几个小问题和改进点需要注意:

            1. 语法错误和拼写错误:

              • Use C++14 应该是一个命令,但 CMake 中没有这样的命令。您已经正确地使用了 set(CMAKE_CXX_STANDARD 14) 和 set(CMAKE_CXX_STANDARD_REQUIRED ON) 来设置 C++ 标准。
              • add_definitions(-Wall -Werror) 应该是 add_compile_definitions(-Wall -Werror)。add_definitions 不是一个 CMake 命令,而 add_compile_definitions 用于添加预处理器定义。
              • find_package 应该是 find_package(PACKAGE_NAME [version] [REQUIRED|OPTIONAL]),但您已经正确使用了它,只是写成了两行(可能是为了解释)。
            2. 改进点:

              • 使用 ament_index_has_component 来检查依赖是否已安装(可选,但有助于调试)。
              • 确保所有路径都是相对于项目根目录的,特别是 include_directories 中的路径。
              • 注释和文档:增加更多的注释来说明每个部分的作用,特别是对于那些可能不熟悉的 CMake 或 ROS 2 的用户。

            下面是修改后的 CMakeLists.txt 文件:

            cmake_minimum_required(VERSION 3.10)
            project(pid_position_follow)
            
            # 设置 C++14 标准
            set(CMAKE_CXX_STANDARD 14)
            set(CMAKE_CXX_STANDARD_REQUIRED ON)
            
            # 添加编译器标志
            add_compile_definitions(-Wall -Werror)
            
            # 导出编译命令供 clangd 使用
            set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
            
            # 查找依赖项
            find_package(ament_cmake_auto REQUIRED)
            ament_auto_find_build_dependencies()
            
            # 添加包含目录
            include_directories(
                ${CMAKE_CURRENT_SOURCE_DIR}/include/cubic_spline
                ${CMAKE_CURRENT_SOURCE_DIR}/include/pid_position_follow
            )
            
            # 构建可执行文件
            ament_auto_add_executable(${PROJECT_NAME}
                src/pid_position_follow.cpp
            )
            
            # 查找 tf2 相关的包
            find_package(tf2 REQUIRED)
            find_package(tf2_ros REQUIRED)
            find_package(tf2_geometry_msgs REQUIRED)
            
            # 添加目标依赖
            ament_target_dependencies(${PROJECT_NAME}
                tf2
                tf2_ros
                tf2_geometry_msgs
            )
            
            # 安装
            ament_auto_package(
                INSTALL_TO_SHARE
                launch
                include
            )
            

            确保您的项目结构正确,特别是 include 和 src 目录的位置,以及 CMakeLists.txt 文件位于项目的根目录。此外,如果您使用的是 ROS 2,确保您的环境已经正确设置,包括 source 了正确的 setup.bash 文件。


            以上为生成回答,仅供参考~

            我是小伊,已接入ChatGpt,所有回复,仅供参考~

            2 1 条回复 最后回复 回复 引用 0
            • 2
              2782489573 @小伊
              最后由 编辑

              @小伊 yzh@yzh:~/PID_Trajectory_Tracking$ colcon build
              Starting >>> rm_decision_interfaces
              Finished <<< rm_decision_interfaces [0.71s]
              Starting >>> pid_position_follow
              --- stderr: pid_position_follow
              /usr/bin/ld: CMakeFiles/pid_position_follow.dir/src/pid_position_follow.cpp.o: in function TransformPose(std::shared_ptr<tf2_ros::Buffer> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, geometry_msgs::msg::PoseStamped_<std::allocator<void> > const&, geometry_msgs::msg::TransformStamped_<std::allocator<void> >&)': pid_position_follow.cpp:(.text+0xa21): undefined reference to void tf2::fromMsg<geometry_msgs::msg::Pose_<std::allocator<void> >, geometry_msgs::msg::Transform_<std::allocator<void> > >(geometry_msgs::msg::Pose_<std::allocator<void> > const&, geometry_msgs::msg::Transform_<std::allocator<void> >&)'
              /usr/bin/ld: pid_position_follow.cpp:(.text+0xaa2): undefined reference to `void tf2::fromMsg<geometry_msgs::msg::Pose_<std::allocator<void> >, geometry_msgs::msg::Transform_<std::allocator<void> > >(geometry_msgs::msg::Pose_<std::allocator<void> > const&, geometry_msgs::msg::Transform_<std::allocator<void> >&)'
              collect2: error: ld returned 1 exit status
              gmake[2]: *** [CMakeFiles/pid_position_follow.dir/build.make:243:pid_position_follow] 错误 1
              gmake[1]: *** [CMakeFiles/Makefile2:137:CMakeFiles/pid_position_follow.dir/all] 错误 2
              gmake: *** [Makefile:146:all] 错误 2

              Failed <<< pid_position_follow [15.5s, exited with code 2]

              Summary: 1 package finished [16.4s]
              1 package failed: pid_position_follow
              1 package had stderr output: pid_position_follow
              还是报错 你看看我的这个#ifndef ROBOMASTER_UTILITY_H
              #define ROBOMASTER_UTILITY_H

              #include <tf2/utils.h>
              #include <tf2_ros/buffer.h>
              #include <tf2_ros/transform_listener.h>
              #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>

              #include <geometry_msgs/msg/pose_stamped.hpp>
              #include <geometry_msgs/msg/quaternion.hpp>
              #include <geometry_msgs/msg/transform_stamped.hpp>

              #include <rclcpp/rclcpp.hpp>

              double GetYawFromOrientation(const geometry_msgs::msg::Quaternion &orientation) {
              tf2::Quaternion q;
              tf2::fromMsg(orientation, q);
              tf2::Matrix3x3 m(q);
              double roll, pitch, yaw;
              m.getRPY(roll, pitch, yaw);
              return yaw;
              }

              double GetEuclideanDistance(const geometry_msgs::msg::PoseStamped &pose_1,
              const geometry_msgs::msg::PoseStamped &pose_2) {
              return hypot(pose_1.pose.position.x - pose_2.pose.position.x,
              pose_1.pose.position.y - pose_2.pose.position.y);
              }

              bool GetGlobalRobotPose(const std::shared_ptr<tf2_ros::Buffer> &tf_buffer,
              const std::string &target_frame,
              geometry_msgs::msg::PoseStamped &robot_global_pose) {
              geometry_msgs::msg::PoseStamped robot_pose;
              robot_pose.header.frame_id = "base_link";
              robot_pose.header.stamp = tf2_ros::toMsg(tf2::TimePointZero);
              robot_pose.pose.orientation.w = 1.0;

              try {
                  tf_buffer->transform(robot_pose, robot_global_pose, target_frame);
              } catch (tf2::TransformException &ex) {
                  RCLCPP_ERROR(rclcpp::get_logger("utility"), "Failed to transform robot pose: %s", ex.what());
                  return false;
              }
              return true;
              

              }

              bool TransformPose(const std::shared_ptr<tf2_ros::Buffer> &tf_buffer,
              const std::string &target_frame,
              const geometry_msgs::msg::PoseStamped &input_pose,
              geometry_msgs::msg::PoseStamped &output_pose) {
              if (target_frame == input_pose.header.frame_id) {
              output_pose = input_pose;
              return true;
              }

              try {
                  tf_buffer->transform(input_pose, output_pose, target_frame);
              } catch (tf2::TransformException &ex) {
                  RCLCPP_ERROR(rclcpp::get_logger("utility"), "Failed to transform pose: %s", ex.what());
                  return false;
              }
              
              return true;
              

              }

              bool TransformPose(const std::shared_ptr<tf2_ros::Buffer> &tf_buffer,
              const std::string &target_frame,
              const geometry_msgs::msg::PoseStamped &input_pose,
              geometry_msgs::msg::TransformStamped &output_pose_tf) {
              if (target_frame == input_pose.header.frame_id) {
              tf2::fromMsg(input_pose.pose, output_pose_tf.transform);
              output_pose_tf.header = input_pose.header;
              return true;
              }

              geometry_msgs::msg::PoseStamped output_pose;
              if (!TransformPose(tf_buffer, target_frame, input_pose, output_pose)) {
                  return false;
              }
              
              tf2::fromMsg(output_pose.pose, output_pose_tf.transform);
              output_pose_tf.header = output_pose.header;
              return true;
              

              }

              void TransformPose(const geometry_msgs::msg::TransformStamped &transform,
              const geometry_msgs::msg::PoseStamped &input_pose,
              geometry_msgs::msg::PoseStamped &output_pose) {
              tf2::Transform input_pose_tf;
              tf2::fromMsg(input_pose.pose, input_pose_tf);
              tf2::Transform transform_tf;
              tf2::fromMsg(transform.transform, transform_tf);
              tf2::Transform output_pose_tf = transform_tf * input_pose_tf;
              // Convert tf2::Transform to geometry_msgs::msg::Pose
              geometry_msgs::msg::Pose output_pose_msg;
              tf2::toMsg(output_pose_tf, output_pose_msg);
              output_pose.pose = output_pose_msg;
              output_pose.header.stamp = transform.header.stamp;
              output_pose.header.frame_id = transform.header.frame_id;
              }

              bool UpdateTransform(const std::shared_ptr<tf2_ros::Buffer> &tf_buffer,
              const std::string &target_frame,
              const std::string &source_frame,
              const rclcpp::Time &source_time,
              geometry_msgs::msg::TransformStamped &target_to_source_transform) {
              try {
              target_to_source_transform = tf_buffer->lookupTransform(target_frame, source_time, source_frame, source_time, source_frame);
              } catch (tf2::TransformException &ex) {
              RCLCPP_ERROR(rclcpp::get_logger("utility"), "Failed to update transform: %s", ex.what());
              return false;
              }

              return true;
              

              }

              #endif // ROBOMASTER_UTILITY_H这个代码有没有问题 改进一下

              1 条回复 最后回复 回复 引用 0
              • 小伊小
                机器人小伊
                最后由 编辑

                从你提供的错误信息来看,链接器在编译 pid_position_follow 包时未能找到 tf2::fromMsg 函数的定义。这通常意味着链接时缺少了某些库文件,或者你的项目中没有正确包含所有需要的头文件。

                首先,确保你的项目中正确链接了 tf2 和 tf2_geometry_msgs 库。这通常在 CMakeLists.txt 文件中设置。以下是一个基本的 CMakeLists.txt 示例,展示了如何链接这些库:

                cmake_minimum_required(VERSION 3.5)
                project(pid_position_follow)
                
                # Find dependencies
                find_package(REQUIRED COMPONENTS
                  rclcpp
                  std_msgs
                  geometry_msgs
                  tf2
                  tf2_geometry_msgs
                  tf2_ros
                )
                
                # Add executable
                add_executable(pid_position_follow src/pid_position_follow.cpp)
                
                # Link libraries
                target_link_libraries(pid_position_follow PRIVATE ${catkin_LIBRARIES})
                

                注意,target_link_libraries 需要包含所有必要的库。这里 ${catkin_LIBRARIES} 会自动包含通过 find_package 找到的依赖库。

                接下来,关于你的头文件 ROBOMASTER_UTILITY_H,有几个小问题和改进建议:

                1. 头文件包含:确保你包含了所有需要的头文件,特别是与 tf2 和 geometry_msgs 相关的。

                2. 命名空间:在函数定义中明确使用 tf2 命名空间可能更清晰,尽管在头文件中已经包含了 tf2/utils.h 和其他相关头文件。

                3. 代码风格:代码整体风格良好,但建议使用 auto 关键字来自动推导变量类型,特别是复杂的类型,如 std::shared_ptr<tf2_ros::Buffer>。

                4. 错误处理:你的错误处理逻辑已经很好,使用了 try-catch 来捕获 tf2::TransformException。

                5. 代码冗余:在 TransformPose 函数中,你重复了 tf2::fromMsg 的调用。考虑是否可以通过重构来减少重复代码。

                6. 使用 C++ 标准库:对于计算欧几里得距离,你已经使用了 hypot,这是正确的。但也可以考虑使用 C++ 标准库中的其他函数,如 std::sqrt 和 std::pow,尽管 hypot 通常是处理这种情况的更好选择。

                7. 宏定义保护:你的头文件使用了 #ifndef, #define, #endif 来防止重复包含,这是良好的实践。

                根据你的错误信息,问题很可能出在 CMakeLists.txt 文件中没有正确链接 tf2 或 tf2_geometry_msgs。请检查并确保这些库被正确链接。如果问题仍然存在,请检查是否有其他库或依赖项缺失。


                以上为生成回答,仅供参考~

                我是小伊,已接入ChatGpt,所有回复,仅供参考~

                2 1 条回复 最后回复 回复 引用 0
                • 2
                  2782489573 @小伊
                  最后由 编辑

                  @小伊 如果我加上target_link_libraries(pid_position_follow PRIVATE ${catkin_LIBRARIES})就会报错/usr/bin/ld: 找不到 -ltf2: 没有那个文件或目录
                  /usr/bin/ld: 找不到 -ltf2_ros: 没有那个文件或目录

                  1 条回复 最后回复 回复 引用 0
                  • 小伊小
                    机器人小伊
                    最后由 编辑

                    错误信息 /usr/bin/ld: 找不到 -ltf2: 没有那个文件或目录 和 /usr/bin/ld: 找不到 -ltf2_ros: 没有那个文件或目录 表明链接器(ld)在尝试链接你的程序时找不到 tf2 和 tf2_ros 这两个库。这通常意味着这些库没有被正确安装在你的系统上,或者它们的安装路径没有被添加到链接器的搜索路径中。

                    解决步骤

                    1. 确认库的安装:

                      • 确保你已经安装了 tf2 和 tf2_ros 库。这些库通常是通过 ROS(Robot Operating System)安装的。
                      • 如果你使用的是 ROS 1,你可以通过以下命令安装这些库(如果它们还未安装):
                        sudo apt-get install ros-<distro>-tf2 ros-<distro>-tf2-ros
                        
                        其中 <distro> 应该替换为你使用的 ROS 发行版,如 melodic、noetic 等。
                    2. 检查库文件:

                      • 安装完成后,你可以使用 find 命令来查找这些库文件(通常是 .so 文件)。例如:
                        sudo find / -name "libtf2*.so*"
                        sudo find / -name "libtf2_ros*.so*"
                        
                      • 这将帮助你确认库文件是否存在于你的系统中,以及它们的位置。
                    3. 设置环境变量:

                      • 如果库文件存在但不在标准路径下,你可能需要设置 LD_LIBRARY_PATH 环境变量来包含这些库的路径。例如:
                        export LD_LIBRARY_PATH=/path/to/your/libs:$LD_LIBRARY_PATH
                        
                      • 替换 /path/to/your/libs 为实际库文件所在的目录。
                    4. CMakeLists.txt 修改:

                      • 确保你的 CMakeLists.txt 文件正确链接了这些库。你已经在使用 target_link_libraries,这是正确的。但确认库名是否正确,有时需要指定完整的库名(包括前缀 lib 和后缀 .so 的版本号,但通常只写基本名即可)。
                      • 确保 find_package 指令包含了 tf2 和 tf2_ros(如果它们是独立的 ROS 包)。
                    5. 重新编译:

                      • 清理你的构建目录(通常是 catkin_ws/build 和 catkin_ws/devel),然后重新编译整个工作空间:
                        cd ~/catkin_ws
                        catkin_make clean
                        catkin_make
                        
                    6. 检查 ROS 环境:

                      • 确保你的 ROS 环境已经正确设置。运行 source ~/catkin_ws/devel/setup.bash(或你的工作空间对应的路径)来设置环境变量。

                    如果以上步骤仍然不能解决问题,可能需要检查你的 ROS 安装是否完整或考虑重新安装 ROS 和相关库。


                    以上为生成回答,仅供参考~

                    我是小伊,已接入ChatGpt,所有回复,仅供参考~

                    1 条回复 最后回复 回复 引用 0
                    • 第一个帖子
                      最后一个帖子
                    皖ICP备16016415号-7
                    Powered by NodeBB | 鱼香ROS