0
$\begingroup$

Rosanswers logo

I have been trying to implement a synchronizer with approximate time policy in a class. The following code compiles with no problem. But how should I define the Synchronizer and the registerCallback? (The two commented lines)

#include "header.h"
using namespace message_filters;
typedef control_sys::IntWithHeader myMsg;

class Node
{
    
public:

    Node()
{
    sub1.subscribe(node, "in1", 1);
    sub2.subscribe(node, "in2", 1);
    
}
    void callback(const myMsg &in1, const myMsg &in2)
{
        std::cout << "Synchronization successful" << std::endl;
}   
    
 
private:

    ros::NodeHandle node;
    ros::Publisher pub;
    std_msgs::Int32 out;
    message_filters::Subscriber<myMsg> sub1;
    message_filters::Subscriber<myMsg> sub2;
    typedef sync_policies::ApproximateTime<myMsg, myMsg> MySyncPolicy;
    // This is how I would define them inside main()
    //Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), sub1, sub2);
    //sync.registerCallback(&callback);
};

int main(int argc, char **argv)
{

    ros::init(argc, argv, "synchronizer");
    Node synchronizer;

    ros::spin();

}

Update 1: Headers included:

#include <ros/ros.h>
#include <std_msgs/Int32.h>
#include <iostream>
#include <message_filters/subscriber.h>
#include <message_filters/synchronizer.h>
#include <message_filters/sync_policies/approximate_time.h>
#include "control_sys/IntWithHeader.h"

Update 2: Error output of catkin_make (in terminal)


Originally posted by mohsen on ROS Answers with karma: 249 on 2018-01-25

Post score: 1


Original comments

Comment by Thomas D on 2018-01-25:
What are the includes in header.h?

Comment by Thomas D on 2018-01-26:
One of the errors is /usr/include/boost/bind/mem_fn_template.hpp:299:7: note: no known conversion for argument 1 from ‘Node*’ to ‘Node&’. Can you put an update showing the file as you have it now? That looks suspicious, like a copy-paste error from one of us.

Comment by Vince4396 on 2018-07-31:
I am wondering if your final code is working. I have been trying to implement a similar class as yours but my callback function is never called.

Comment by mohsen on 2018-08-02:
I haven't run this for a while, but I remember that it was working fine. Have a look.

$\endgroup$

2 Answers 2

0
$\begingroup$

Rosanswers logo

Change your commented out lines to:

typedef sync_policies::ApproximateTime<myMsg, myMsg> MySyncPolicy;
typedef Synchronizer<MySyncPolicy> Sync;
boost::shared_ptr<Sync> sync;                                                                 

In your constructor initialize and register:

sync.reset(new Sync(MySyncPolicy(10), sub1, sub2));      
sync->registerCallback(boost::bind(&Node::callback, this, _1, _2));

Update

A couple of other things to keep in mind.

  1. The messages you are subscribing to require a std_msgs/Header field so that message times can be compared.
  2. Change the signature of your callback to void callback(const control_sys::IntWithHeaderConstPtr &in1, const control_sys::IntWithHeaderConstPtr &in2).

With those types of changes I was able to get a node to compile that basically mimics what you have. I had to substitue myMsg for sensor_msgs/Image in order to use a message type I have access to.


Originally posted by Thomas D with karma: 4347 on 2018-01-25

This answer was ACCEPTED on the original site

Post score: 4


Original comments

Comment by mohsen on 2018-01-25:
sync->registerCallback(boost::bind(&Node::callback, this, _1, _2));

The line above causes a wall of error when I compile the package. It's too long to paste but I hope this helps.

error: no match for call to ‘(boost::_mfi::mf2<void, Node,

Comment by Thomas D on 2018-01-25:
That is probably because you have not declared your callback function. After the parts that were commented out try void callback(const myMsg &in1, const myMsg &in2);

Comment by mohsen on 2018-01-25:
It still gives the same error (boost) + new errors caused by (I think) illegal function overload.

 error: ‘void Node::callback(const myMsg&, const myMsg&)’ cannot be overloaded  

 error: with ‘void Node::callback(const myMsg&, const myMsg&)’

Comment by Thomas D on 2018-01-25:
Try making the function definition private.

Comment by Thomas D on 2018-01-25:
Looking at it more, I think I was wrong about needing the extra function declaration in the code as you have it. Sorry about that.

Comment by mohsen on 2018-01-26:
That's alright. This is pretty advanced C++ for me so I really appreciate your help. Making the definition private didn't make a difference.

Comment by Thomas D on 2018-01-26:
I have a gist of the entire package that builds for me at https://gist.github.com/tdenewiler/e2172f628e49ab633ef2786207793336.

Comment by mohsen on 2018-01-27:
Thanks for the update. But myMsgConstPtr is not a valid type so instead I changed the callback to

void callback(const control_sys::IntWithHeaderConstPtr &in1, const control_sys::IntWithHeaderConstPtr &in2)  

and now it compiles and works properly. Would you mind editing your answer?

Comment by Thomas D on 2018-01-27:
To use myMsgConstPtr you would have to add typedef control_sys::IntWithHeaderConstPtr myMsgConstPtr;.

$\endgroup$
0
$\begingroup$

Rosanswers logo

What follows is a correct version of the code:

#include "header.h"
using namespace message_filters;
typedef control_sys::IntWithHeader myMsg;

class Node
{
    
public:

    Node()
{
    sub1.subscribe(node, "in1", 1);
    sub2.subscribe(node, "in2", 1);
    sync.reset(new Sync(MySyncPolicy(10), sub1, sub2));   
    sync->registerCallback(boost::bind(&Node::callback, this, _1, _2));

     
}

    void callback(const control_sys::IntWithHeaderConstPtr &in1, const control_sys::IntWithHeaderConstPtr &in2)
{
         std::cout << "Synchronization successful" << std::endl;
}  

private:

    ros::NodeHandle node;
    ros::Publisher pub;
    std_msgs::Int32 out;

    message_filters::Subscriber<myMsg> sub1;
    message_filters::Subscriber<myMsg> sub2;
    typedef sync_policies::ApproximateTime<myMsg, myMsg> MySyncPolicy;
    typedef Synchronizer<MySyncPolicy> Sync;
    boost::shared_ptr<Sync> sync;
    
};


int main(int argc, char **argv)
{

    ros::init(argc, argv, "synchronizer");

    Node synchronizer;

    ros::spin();

}

Originally posted by mohsen with karma: 249 on 2018-01-27

This answer was NOT ACCEPTED on the original site

Post score: 4


Original comments

Comment by jayess on 2018-01-27:
Is this your solution or an update to your question?

Comment by mohsen on 2018-01-28:
The solution.

Comment by thorper on 2018-09-07:
This helped me!

Comment by mohsen on 2018-09-10:
Glad to hear that!

Comment by apletta on 2019-07-03:
This really helped me too!

Comment by CoffeeKangaroo on 2023-03-23:
This should be marked as accepted answer.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.