ROS 使用模板 class 成员作为主题订阅的回调
ROS using template class member as callback for topic subscription
我正在尝试创建一个 class,它可以实例化一次,并且可以向其中添加 ros 主题订阅,其中回调是同一成员函数的模板特化。
class ros_topic_subscriber.h 文件是
class ROSTopicSubscriber
{
public:
ROSTopicSubscriber() {}
~ROSTopicSubscriber() {}
template<typename ROSMessageType>
int init
(
const ros::NodeHandle &controller_nh,
const std::string& topic_name,
unsigned int buffer_size
)
{
ros::Subscriber sub = controller_nh.subscribe(
topic_name,
buffer_size,
&ROSTopicSubscriber::topicCallback<ROSMessageType>,
this
);
}
/*! \brief Implement this function for your own message!
*/
template<typename ROSMessageType>
void topicCallback(const typename ROSMessageType::ConstPtr& msg);
private:
// No copying of this class is allowed !
ROSTopicSubscriber(const ROSTopicSubscriber& other) = delete;
ROSTopicSubscriber(ROSTopicSubscriber&& other) = delete;
ROSTopicSubscriber& operator=(const ROSTopicSubscriber& other) = delete;
ROSTopicSubscriber& operator=(ROSTopicSubscriber&& other) noexcept = delete;
};
在我的例子中,topicCallback 的一种可能的模板特化是(在 ros_topic_subscriber.cpp 文件中)
template<>
void ROSTopicSubscriber::topicCallback<geometry_msgs::Pose>
(
const geometry_msgs::Pose::ConstPtr& msg
)
{
std::cout << "msg\n";
}
并利用这个 class 例如可以做
topic_subscriber_.init<geometry_msgs::Pose>
(n, "/wintracker/pose", 100);
现在,我得到的编译器错误是这样的:
ros_topic_subscriber.h:66:3:
error: passing ‘const ros::NodeHandle’ as ‘this’ argument of
‘ros::Subscriber ros::NodeHandle::subscribe(
const string&,
uint32_t,
void (T::*)(const boost::shared_ptr<const M>&),
T*,
const ros::TransportHints&)
[with M = geometry_msgs::Pose_<std::allocator<void> >;
T = hiqp::ROSTopicSubscriber;
std::string = std::basic_string<char>;
uint32_t = unsigned int]’
discards qualifiers [-fpermissive]
为什么在这种情况下会出现此错误消息?
有没有可能实现这种class?
我该如何修复错误?
您的 ROSTopicSubscriber::init
获取 controller_nh
参数作为 const
引用,这意味着它只能调用在常量对象上声明为可调用的方法。但是,您尝试调用未以这种方式声明的 subscribe
方法。
您的代码中的方法声明可能如下所示:
class NodeHandle {
// ...
Subscriber subscribe(/* all the parameters */);
// ...
}
解决方案取决于 subscribe
方法是否需要更改 NodeHandle
对象内部的任何内容。如果不是,则将其标记为可在常量对象上调用:
class NodeHandle {
// ...
Subscriber subscribe(/* all the parameters */) const; // <- notice const!
// ...
}
如果 subscribe
方法更改了 NodeHandle
中的某些内容,那么您需要将 ROSTopicSubscriber::init
方法的 controller_nh
参数更改为可变的(不是常量)参考:
int init
(
ros::NodeHandle &controller_nh, // <- notice const is gone
const std::string& topic_name,
unsigned int buffer_size
)
我正在尝试创建一个 class,它可以实例化一次,并且可以向其中添加 ros 主题订阅,其中回调是同一成员函数的模板特化。
class ros_topic_subscriber.h 文件是
class ROSTopicSubscriber
{
public:
ROSTopicSubscriber() {}
~ROSTopicSubscriber() {}
template<typename ROSMessageType>
int init
(
const ros::NodeHandle &controller_nh,
const std::string& topic_name,
unsigned int buffer_size
)
{
ros::Subscriber sub = controller_nh.subscribe(
topic_name,
buffer_size,
&ROSTopicSubscriber::topicCallback<ROSMessageType>,
this
);
}
/*! \brief Implement this function for your own message!
*/
template<typename ROSMessageType>
void topicCallback(const typename ROSMessageType::ConstPtr& msg);
private:
// No copying of this class is allowed !
ROSTopicSubscriber(const ROSTopicSubscriber& other) = delete;
ROSTopicSubscriber(ROSTopicSubscriber&& other) = delete;
ROSTopicSubscriber& operator=(const ROSTopicSubscriber& other) = delete;
ROSTopicSubscriber& operator=(ROSTopicSubscriber&& other) noexcept = delete;
};
在我的例子中,topicCallback 的一种可能的模板特化是(在 ros_topic_subscriber.cpp 文件中)
template<>
void ROSTopicSubscriber::topicCallback<geometry_msgs::Pose>
(
const geometry_msgs::Pose::ConstPtr& msg
)
{
std::cout << "msg\n";
}
并利用这个 class 例如可以做
topic_subscriber_.init<geometry_msgs::Pose>
(n, "/wintracker/pose", 100);
现在,我得到的编译器错误是这样的:
ros_topic_subscriber.h:66:3:
error: passing ‘const ros::NodeHandle’ as ‘this’ argument of
‘ros::Subscriber ros::NodeHandle::subscribe(
const string&,
uint32_t,
void (T::*)(const boost::shared_ptr<const M>&),
T*,
const ros::TransportHints&)
[with M = geometry_msgs::Pose_<std::allocator<void> >;
T = hiqp::ROSTopicSubscriber;
std::string = std::basic_string<char>;
uint32_t = unsigned int]’
discards qualifiers [-fpermissive]
为什么在这种情况下会出现此错误消息? 有没有可能实现这种class? 我该如何修复错误?
您的 ROSTopicSubscriber::init
获取 controller_nh
参数作为 const
引用,这意味着它只能调用在常量对象上声明为可调用的方法。但是,您尝试调用未以这种方式声明的 subscribe
方法。
您的代码中的方法声明可能如下所示:
class NodeHandle {
// ...
Subscriber subscribe(/* all the parameters */);
// ...
}
解决方案取决于 subscribe
方法是否需要更改 NodeHandle
对象内部的任何内容。如果不是,则将其标记为可在常量对象上调用:
class NodeHandle {
// ...
Subscriber subscribe(/* all the parameters */) const; // <- notice const!
// ...
}
如果 subscribe
方法更改了 NodeHandle
中的某些内容,那么您需要将 ROSTopicSubscriber::init
方法的 controller_nh
参数更改为可变的(不是常量)参考:
int init
(
ros::NodeHandle &controller_nh, // <- notice const is gone
const std::string& topic_name,
unsigned int buffer_size
)