ROS使用模板类成员作为主题订阅的回调函数

3
我将尝试创建一个类,只能被实例化一次,并且可以向其中添加ROS主题订阅,其中回调是相同成员函数的模板特化。
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";
}

为了使用这个类,可以做如下操作:

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]

这种情况为什么会出现错误信息? 是否可以实现这种类? 如何修复此错误?
1个回答

2

您的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
)

谢谢,我盲目地看了与模板相关的代码! - neckutrek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接