Approximate Time Synchronizer callback not working in node member class (sync goes out of scope)
Hi folks,
I've been trying to solve this for a while without success. Basically I have a node with several class members and in one of those classes I need to process data from 3 synced topics. I am using Approximate Time Synchronizer. My problem is that the synced callback only gets called once or twice and then stops (sync goes out of scope).
I'll put a simplified version of the node below. The structure is node.cpp instanciates member class A. Class A has a multi-threaded loop. Inside that loop I instanciate ClassB, declare the subscribers and Approximate synchronizer and set the callback for the synchronizer to point to ClassB's function so I can process that data in class B.
I don't know where to create the synchronizer. First I tried having it directly in class B but declaring it in classB's constructor or one of classB's functions got only 1 successful call before sync was destroyed.
As you see below in classA.cpp, now I have put the sync in the loop function where i get it to successfully callback a few times but it eventually stops. I would like to put it in the main funcion of node.cpp like in this example, but I need to pass to the callback the ClassB environment and I need to do that after a bunch of other things happen in Class A.
I appreciate your advice!
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_B, "topic1", 1);
subscriber_B.subscribe(nh_B, "topic2", 1);
subscriber_C.subscribe(nh_B, "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
}
}
}
class B.h:
#include <message_filters/sync_policies/approximate_time ...
Where does
thread_shutdown_
come from?Suggestion: use fewer raw pointers and
new
. C++ is not Java.It's a bool flag with false by default and it is turned "true" in Class A's destructor. I've updated it in the question to make it clear :)