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

    ros noetic中使用了boost::shared_ptr<ros::Subscription>共享指针报错

    已定时 已固定 已锁定 已移动 已解决
    综合问题
    ros noetic c++
    2
    7
    526
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • A
      admin_
      最后由 编辑

      问题

      /usr/include/boost/smart_ptr/make_shared_object.hpp: In instantiation of ‘class boost::detail::sp_ms_deleter<ros::Subscription>’:
      /usr/include/boost/smart_ptr/make_shared_object.hpp:254:21:   required from ‘typename boost::detail::sp_if_not_array<T>::type boost::make_shared(Args&& ...) [with T = ros::Subscription; Args = {ros::Subscriber}; typename boost::detail::sp_if_not_array<T>::type = boost::shared_ptr<ros::Subscription>]’
      /home/wd/cpp_proj/red_car_ros1/src/platooning_logic/src/trans_core.cpp:24:85:   required from here
      /usr/include/boost/smart_ptr/make_shared_object.hpp:44:42: error: invalid application of ‘sizeof’ to incomplete type ‘ros::Subscription’
         44 |     typedef typename sp_aligned_storage< sizeof( T ), ::boost::alignment_of< T >::value >::type storage_type;
      

      背景

      操作系统Ubuntu20,ROS1(noetic)。

      涉及到的文件有以下两个,可以保证类成员函数A::localListCallBack和发布者类型platooning_msgs::PlatoonManagement是没有问题的。在工作空间目录下通过catkin_make运行后出现以上错误,说ros::Subscription不是完整类型。

      以下是两个涉及到文件:
      a.h

      #include <ros/ros.h>
      #include <boost/shared_ptr.hpp>
      
      class A{
      public:
          boost::shared_ptr<ros::NodeHandle> nh = boost::make_shared<ros::NodeHandle>();
          boost::shared_ptr<ros::Subscription> local_list_subscription;
          boost::shared_ptr<ros::Publisher> outer_publisher;
      }
      

      a.cpp

      void A::func() {
          // 创建订阅者
          local_list_subscription = boost::make_shared<ros::Subscription>(
              nh->subscribe("LocalMemberList", 1, &A::localListCallBack, this));
      
          // 创建发布者
          outer_publisher =
              boost::make_shared<ros::Publisher>(nh->advertise<platooning_msgs::PlatoonManagement>("OuterMemberList", 10));
      }
      

      已尝试办法

      刚开始并没有使用boost::shared_ptr的共享指针,使用的是std::shared_ptr,出现的问题基本相同,然后换成了boost::shared_ptr,也是一样的问题。

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

        在您的代码中,您尝试使用 boost::shared_ptr 来管理 ros::Subscription 和 ros::Publisher 对象,但遇到了编译错误。这是因为 ros::Subscription 和 ros::Publisher 并不是可以直接实例化的类型,它们是 ROS 框架内部通过特定方式管理的对象,通常通过 ros::NodeHandle 的成员函数 subscribe 和 advertise 返回的。

        在 ROS 中,ros::NodeHandle::subscribe 返回一个 ros::Subscriber 对象,而 ros::NodeHandle::advertise 返回一个 ros::Publisher 对象。这些对象实际上是封装了底层通信机制的句柄,并且它们的设计并不支持被 boost::shared_ptr 或 std::shared_ptr 直接管理。

        解决方案

        1. 直接使用 ros::Subscriber 和 ros::Publisher 对象:
          您不需要将 ros::Subscriber 和 ros::Publisher 封装到 shared_ptr 中。这些对象在 ROS 框架的生命周期内是有效的,只要 ros::NodeHandle 是活动的,它们就可以被安全使用。

        2. 修改类定义:
          在类 A 中,直接使用 ros::Subscriber 和 ros::Publisher 类型的成员变量。

        修改后的 a.h 文件应该如下所示:

        #include <ros/ros.h>
        
        class A {
        public:
            ros::NodeHandle nh;
            ros::Subscriber local_list_subscription;
            ros::Publisher outer_publisher;
        
            void localListCallBack(const YourMessageTypeConstPtr& msg);  // 确保这个函数声明匹配您的回调函数
        
            void func();
        };
        

        修改后的 a.cpp 文件应该如下所示:

        #include "a.h"
        #include <platooning_msgs/PlatoonManagement.h>  // 确保包含正确的消息头文件
        
        void A::localListCallBack(const YourMessageTypeConstPtr& msg) {
            // 处理消息
        }
        
        void A::func() {
            // 创建订阅者
            local_list_subscription = nh.subscribe("LocalMemberList", 1, &A::localListCallBack, this);
        
            // 创建发布者
            outer_publisher = nh.advertise<platooning_msgs::PlatoonManagement>("OuterMemberList", 10);
        }
        

        注意:

        • 确保 YourMessageTypeConstPtr 是正确的消息类型指针(例如,如果消息类型是 platooning_msgs::SomeMessage,则应为 platooning_msgs::SomeMessageConstPtr)。
        • 确保所有必要的 ROS 消息和服务的头文件都已正确包含。

        通过这种方式,您可以避免尝试将不适合的对象封装到 shared_ptr 中,同时保持代码清晰和符合 ROS 的设计哲学。


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

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

        A 1 条回复 最后回复 回复 引用 1
        • A
          admin_ @小伊
          最后由 编辑

          @小伊 、

          如果在头文件a.h中写类成员对象 ros::Subscriber 和 ros::Publisher ,在a.cpp中定义的时候,会出现error: field ‘local_list_subscription’ has incomplete type ‘ros::Subscription’ 82 | ros::Subscription local_list_subscription;的错误。

          刚开始就这样尝试的,因为出现这个错误,所以想着使用指针来处理。

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

            在ROS(Robot Operating System)中,ros::Subscriber 和 ros::Publisher 是用于订阅和发布ROS消息的关键类。当你在头文件中声明这些类型的成员变量时,可能会遇到“incomplete type”错误,这通常是由于缺少相应的头文件包含或包含顺序不正确导致的。

            解决步骤

            1. 确保包含必要的ROS头文件:
              在你的头文件 a.h 中,确保你已经包含了必要的ROS头文件来支持 ros::Subscriber 和 ros::Publisher。通常,这些类定义在 <ros/subscriber.h> 和 <ros/publisher.h> 中,但更常见的做法是直接包含 <ros/node_handle.h>,因为它会间接包含其他必要的头文件。

              #include <ros/node_handle.h>
              
            2. 检查头文件包含顺序:
              如果 a.h 依赖于其他自定义头文件,并且这些头文件中也可能引用了ROS的类型(或间接地依赖于ROS),确保 a.h 中的ROS头文件包含在这些依赖之前。

            3. 使用指针或引用:
              虽然使用指针或引用不是解决“incomplete type”错误的直接方法(这通常是由于头文件缺失或包含顺序错误),但它们在某些情况下可以提供灵活性,特别是在涉及到复杂的依赖关系时。然而,首先你应该尝试解决根本的包含问题。

              如果你决定使用指针,确保在类定义中正确地声明和初始化它们。例如:

              class MyClass {
              public:
                  MyClass(ros::NodeHandle& nh);
                  ~MyClass();
              
              private:
                  ros::Subscriber* local_list_subscription_;
                  ros::Publisher* my_publisher_;
              };
              
              MyClass::MyClass(ros::NodeHandle& nh) :
                  local_list_subscription_(nh.subscribe("topic_name", 10, callbackFunction)),
                  my_publisher_(nh.advertise<MessageType>("another_topic", 10))
              {}
              
              MyClass::~MyClass() {
                  delete local_list_subscription_;
                  delete my_publisher_;
              }
              

              注意,使用裸指针需要小心管理内存(如上例中的 delete 语句),或者使用智能指针(如 std::unique_ptr 或 std::shared_ptr)来自动管理内存。

            4. 检查ROS环境和编译设置:
              确保你的ROS环境已经正确设置,并且你的CMakeLists.txt文件已经包含了必要的find_package和target_link_libraries指令来链接ROS库。

            5. 重新编译:
              在做了上述更改后,确保彻底清理你的构建环境(例如,使用 catkin_make clean),然后重新编译你的项目。

            通过遵循这些步骤,你应该能够解决关于 ros::Subscriber 和 ros::Publisher 的“incomplete type”错误,并成功地在你的类中使用这些ROS组件。如果问题仍然存在,可能需要更详细地检查你的代码和编译设置。


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

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

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

              @小伊 在 ros noetic中使用了boost::shared_ptr<ros::Subscription>共享指针报错 中说:

              必要的find_package和target_link_libraries指令来链接ROS库

              指的是什么,可否给出具体例子

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

                在ROS Noetic中使用boost::shared_ptr<ros::Subscription>时,如果遇到了关于链接ROS库的报错,这通常意味着你的CMakeLists.txt文件可能没有正确配置来找到和链接ROS相关的库。

                在ROS中,find_package和target_link_libraries是两个关键的CMake指令,用于指定你的项目依赖哪些ROS包,以及链接到哪些库。下面是一个基本的例子,展示如何在一个ROS节点或库中配置这些指令。

                1. find_package

                find_package指令用于告诉CMake你的项目依赖于哪些ROS包。这个指令应该在CMakeLists.txt文件的顶部附近。

                find_package(CATKIN REQUIRED COMPONENTS
                  roscpp
                  std_msgs
                )
                

                在这个例子中,roscpp和std_msgs是依赖的包。roscpp是ROS C++客户端库的包,而std_msgs是一个包含标准消息类型的包。你需要根据你项目的具体依赖来修改这个列表。

                2. target_link_libraries

                target_link_libraries指令用于指定链接到哪些库。在ROS中,通常不需要手动指定链接到ROS的库,因为catkin_make或colcon build会自动处理这些依赖。但是,如果你确实需要手动链接到某些特定的库(虽然这在ROS项目中不常见),你可以这样做:

                target_link_libraries(your_target_name ${catkin_LIBRARIES})
                

                其中your_target_name是你通过add_executable或add_library创建的目标名称。${catkin_LIBRARIES}是一个变量,它包含了所有通过find_package找到的ROS包所需的库。

                完整示例

                下面是一个完整的CMakeLists.txt文件示例,用于一个简单的ROS节点,它依赖于roscpp和std_msgs:

                cmake_minimum_required(VERSION 3.0.2)
                project(your_project_name)
                
                ## Find catkin macros and libraries
                find_package(CATKIN REQUIRED COMPONENTS
                  roscpp
                  std_msgs
                )
                
                ## Declare a C++ executable
                add_executable(your_node_name src/your_node.cpp)
                
                ## Specify libraries to link a target against
                target_link_libraries(your_node_name ${catkin_LIBRARIES})
                
                ## Add cmake target dependencies of the executable/library
                ## as an example, message headers also have to be generated before nodes
                add_dependencies(your_node_name ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
                
                ## Specify include directories
                include_directories(
                  ${catkin_INCLUDE_DIRS}
                )
                

                在这个例子中,your_node_name是你的节点的名字,your_node.cpp是节点的源代码文件。your_project_name是你的ROS项目的名字。

                注意

                • 确保你的CMakeLists.txt文件和源代码文件(如your_node.cpp)位于正确的位置,通常是你的ROS包的src目录下。
                • 如果你使用的是colcon而不是catkin_make来构建你的ROS项目,CMakeLists.txt的配置方式基本相同,但构建过程会有所不同。

                通过这些步骤,你应该能够解决关于链接ROS库的报错问题。如果仍然遇到问题,请检查ROS的安装和环境配置是否正确。


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

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

                1 条回复 最后回复 回复 引用 0
                • A
                  admin_
                  最后由 编辑

                  我发现了,类型名写错了。。。应该是ros::Subscriber,不是ros::Subscription。。

                  1 条回复 最后回复 回复 引用 0
                  • A admin_ 将这个主题标记为已解决,在
                  • 第一个帖子
                    最后一个帖子
                  皖ICP备16016415号-7
                  Powered by NodeBB | 鱼香ROS