ROS C++近似时间同步器回调在节点成员类中不工作(同步超出范围)。

问题描述 投票:0回答:1

我已经尝试解决这个问题一段时间了,但没有成功。基本上,我有一个有几个类成员的节点,在其中一个类中,我需要处理3个同步主题的数据。我使用的是近似时间同步器。我的问题是,同步的回调只被调用一两次,然后就停止了(同步超出了范围)。

我在下面放一个简化版的节点。结构是node.cpp实例化成员类A,类A有一个多线程循环。在这个循环中,我实例化了ClassB,声明了订阅者和近似同步器,并设置同步器的回调指向ClassB的函数,这样我就可以在类B中处理这些数据。

我不知道在哪里创建同步器。首先,我试过直接在类B中让它存在,但在classB的构造函数或classB的一个函数中声明它,只得到1次成功的调用,然后同步就被销毁了。

正如你在classA.cpp中看到的那样,现在我把同步器放在循环函数中,在那里我让它成功地回调了几次,但它最终停止了。我想把它放在node.cpp的主函数中,就像这个例子一样,但是我需要把ClassB的环境传递给回调,而且我需要在ClassA中发生了一堆其他事情之后再进行回调。

我很感激你的建议

node.cpp。

#include <ros/ros.h>
#include <node/ClassA.h>
#include <tf2_ros/transform_listener.h>
int main(int argc, char** argv){
   ros::init(argc, argv, "node");
   tf2_ros::Buffer buffer(ros::Duration(10));
   tf2_ros::TransformListener tf(buffer);
   node::ClassA lcr("node", buffer);
   ros::spin();
   return (0);
}

Class A. h:

#include <node/classB.h>
#include <message_filters/sync_policies/approximate_time.h>
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <msgs/msgType.h>

using namespace message_filters;

namespace node
{
    Class A
   {
    public: 
        ClassA();
       ~ClassA();
    protected:
        Object* b_;
    private:
        void loop(node::Config &config, double frequency);
        ClassB * b_;
        message_filters::Subscriber<msgs::msgType> subscriber_A;
        message_filters::Subscriber<msgs::msgType> subscriber_B;
        message_filters::Subscriber<msgs::msgType> subscriber_C;
        typedef sync_policies::ApproximateTime<msgs::msgType, msgs::msgType, msgs::msgType> MySyncPolicy;
        typedef Synchronizer<MySyncPolicy> Sync;
        boost::shared_ptr<Sync> sync;
    };
}

ClassA. cpp:

#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>

using namespace message_filters;

namespace node
{
    ClassA::ClassA():
         thread_shutdown_(false)
    { // Constructor for classA
    }
     ClassA::~ClassA(){
          thread_shutdown_ = true;
    }

    objectB_ = new Object ();
    function1();
   }

   void ClassA::function1(){
       // ...
        thread_ = new boost::thread(boost::bind(&ClassA::loop, this, config, loop_frequency));
   }

   void ClassA::loop(node::NodeConfig &config, double frequency){
       ros::NodeHandle nh;

       ros::NodeHandle nh_B("~/" + name_);
       ClassB * b_ = new ClassB(&nh_B, objectB_); // Initialize ClassB instance

       subscriber_A.subscribe(nh_v2x, "topic1", 1);
       subscriber_B.subscribe(nh_v2x, "topic2", 1);
       subscriber_C.subscribe(nh_v2x, "topic3", 1);
       sync.reset(new Sync(MySyncPolicy(20), subscriber_A, subscriber_B, subscriber_C));
       sync->registerCallback(boost::bind(&ClassB::subscribe_synced_callback, b_, _1, _2, _3)); // this gets callback called twice

       while (nh.ok() && !thread_shutdown_)
       {
           //sync->registerCallback(boost::bind(&ClassB::subscribe_synced_callback, b_, _1, _2, _3)); // this gets callback called a few times and then stops
        // do stuff
       }
   }
}

ClassB.h:

#include <message_filters/sync_policies/approximate_time.h>
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>

using namespace message_filters;

namespace node
{
    class ClassB
    {
    //...
    public:
        ClassB();
        ~ClassB();
        void subscribe_synced_callback(const msgs::msgType::ConstPtr& msgA, const msgs::msgType::ConstPtr& msgB, const msgs::msgType::ConstPtr& msgC);
        //...
    };
}

ClassB. cpp:

#include <node/classB.h>

namespace node
{
   ClassB::ClassB(){ // Constructor for classB
    // ...
   }

   void ClassB::subscribe_synced_callback(const msgs::msgTpye::ConstPtr& msgA, const msgs::msgType::ConstPtr& msgB, const msgs::msgType::ConstPtr& msgC)
   {
       // Do stuff with Time synced data
   }
}
c++ callback ros synchronized
1个回答
0
投票

好的,首先,我想说,作为一种风格,你应该试着把你的ros代码和你的类真实的代码分开。你应该把所有真正的工作都放在你的类中,然后从一个节点可执行文件中调用它们,这个可执行文件包裹着它们,并与其他节点进行io。另外,你不需要让一个节点成为一个类,你可以把它变成一个单独的文件。这有助于简化&把你所有的ros定义集中在一个地方。

// ROS Includes
#include <ros/ros.h>
#include <sensor_msgs/Image.h>
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>

// Custom Includes
#include <my_pkg/classA.h>

// Subscribers
//   left_img (sensor_msgs/Image): "camera/left"
//   right_img (sensor_msgs/Image): "camera/right"

// ROS Handles and Publishers
ros::NodeHandle* nh;
ros::NodeHandle* pnh;

// ROS Callbacks
static void img_cb(const sensor_msgs::Image::ConstPtr& left_img_msg, const sensor_msgs::Image::ConstPtr& right_img_msg);

int main(int argc, char **argv){
  ros::init(argc, argv, "synchronizer");
  nh = new ros::NodeHandle();
  pnh = new ros::NodeHandle("~");

  // Subscribers
  message_filters::Subscriber<sensor_msgs::Image> left_img_sub(*nh, "camera/left", 10);
  message_filters::Subscriber<sensor_msgs::Image> right_img_sub(*nh, "camera/right", 10);
  typedef message_filters::sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image> MySyncPolicy;
  message_filters::Synchronizer<MySyncPolicy> img_sync(MySyncPolicy(10), left_img_sub, right_img_sub);
  img_sync.registerCallback(boost::bind(&img_cb, _1, _2));
  ros::spin();
}

static void img_cb(const sensor_msgs::Image::ConstPtr& left_img_msg, const sensor_msgs::Image::ConstPtr& right_img_msg){
  ROS_INFO("Synchronization successful");
  // Real code from classes here
}

这是我从你的代码中所能看到的最好的,但似乎你已经看到了你的代码。相关的ROS维基.

© www.soinside.com 2019 - 2024. All rights reserved.