ros noetic中使用了boost::shared_ptr<ros::Subscription>共享指针报错
-
问题
/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,也是一样的问题。
-
在您的代码中,您尝试使用
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
直接管理。解决方案
-
直接使用
ros::Subscriber
和ros::Publisher
对象:
您不需要将ros::Subscriber
和ros::Publisher
封装到shared_ptr
中。这些对象在 ROS 框架的生命周期内是有效的,只要ros::NodeHandle
是活动的,它们就可以被安全使用。 -
修改类定义:
在类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 的设计哲学。
以上为生成回答,仅供参考~
-
-
@小伊 、
如果在头文件a.h中写类成员对象
ros::Subscriber
和ros::Publisher
,在a.cpp中定义的时候,会出现error: field ‘local_list_subscription’ has incomplete type ‘ros::Subscription’ 82 | ros::Subscription local_list_subscription;
的错误。刚开始就这样尝试的,因为出现这个错误,所以想着使用指针来处理。
-
在ROS(Robot Operating System)中,
ros::Subscriber
和ros::Publisher
是用于订阅和发布ROS消息的关键类。当你在头文件中声明这些类型的成员变量时,可能会遇到“incomplete type”错误,这通常是由于缺少相应的头文件包含或包含顺序不正确导致的。解决步骤
-
确保包含必要的ROS头文件:
在你的头文件a.h
中,确保你已经包含了必要的ROS头文件来支持ros::Subscriber
和ros::Publisher
。通常,这些类定义在<ros/subscriber.h>
和<ros/publisher.h>
中,但更常见的做法是直接包含<ros/node_handle.h>
,因为它会间接包含其他必要的头文件。#include <ros/node_handle.h>
-
检查头文件包含顺序:
如果a.h
依赖于其他自定义头文件,并且这些头文件中也可能引用了ROS的类型(或间接地依赖于ROS),确保a.h
中的ROS头文件包含在这些依赖之前。 -
使用指针或引用:
虽然使用指针或引用不是解决“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
)来自动管理内存。 -
检查ROS环境和编译设置:
确保你的ROS环境已经正确设置,并且你的CMakeLists.txt文件已经包含了必要的find_package和target_link_libraries指令来链接ROS库。 -
重新编译:
在做了上述更改后,确保彻底清理你的构建环境(例如,使用catkin_make clean
),然后重新编译你的项目。
通过遵循这些步骤,你应该能够解决关于
ros::Subscriber
和ros::Publisher
的“incomplete type”错误,并成功地在你的类中使用这些ROS组件。如果问题仍然存在,可能需要更详细地检查你的代码和编译设置。
以上为生成回答,仅供参考~
-
-
@小伊 在 ros noetic中使用了boost::shared_ptr<ros::Subscription>共享指针报错 中说:
必要的find_package和target_link_libraries指令来链接ROS库
指的是什么,可否给出具体例子
-
在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的安装和环境配置是否正确。
以上为生成回答,仅供参考~
- 确保你的
-
我发现了,类型名写错了。。。应该是
ros::Subscriber
,不是ros::Subscription
。。 -