Rosanswers logo

My ROS rqt plugin now works with single subscription, like

#some lines of plugin initialization from .ui file
self._c.Action_button.clicked.connect(self.visual_callback) #callback started when button is pressed

# other several lines of plugin initialization code
def visual_callback(self):
        self.left_topic = "/my_stereo/left/image_raw"
        try: #Subscription + Callback number 1, with 1 input
            self.bridge0 = CvBridge()
            self.image_sub0 = rospy.Subscriber(self.left_topic,Image,self.left_callback,queue_size=1)
        except ValueError, e:
            rospy.logerr('My Plugin: Error connecting topic (%s)'%e)
        self.right_topic = "/my_stereo/right/image_raw"

        try: #Subscription + Callback number 2, with 1 input
            self.bridge1 = CvBridge()
            self.image_sub1 = rospy.Subscriber(self.right_topic,Image,self.right_callback,queue_size=1)
        except ValueError, e:
            rospy.logerr('My Plugin: Error connecting topic (%s)'%e)

I would like to create a new callback that uses in input both the "left" Image signal and the "right" Image signal. The rospy subscriber structure is fantastic, as it launches the callbacks and spin it automatically. Can I use something similar to subscribe both image topics and launch a single callback with 2 input?

A - I tried this method but I could not make rospy.spin work into a rqt plugin (I hope it would be my fault only, any hints?)

def visual_callback2(self, left, right):
    if True:
        left = message_filters.Subscriber("/my_stereo/left/image_raw", Image)
        right = message_filters.Subscriber("/my_stereo/right/image_raw", Image)
        print "Double subscribe!!"
        ts = message_filters.TimeSynchronizer([left, right], 10) #exact sync
        #ts = message_filters.ApproximateTimeSynchronizer([left, right], 10, 0.1, allow_headerless=True) #approxiamte sync
        #self.maker(left,right) #external function with 2 arguments
        #rospy.spin() #this should update continuously, but it does not work

B - I do not need stereo_image_proc or similar suggestion, that is not my goal. I want to write my personal callback with 2 image inputs in my rqt plugin.

Originally posted by marcoresk on ROS Answers with karma: 76 on 2017-10-17

Post score: 0


1 Answer 1


Rosanswers logo

I think your solution with message filters is pretty close to the solution you need, except that you're putting the subscriber creation inside your callback, and that doesn't make sense.

I think the solution looks something like this:

# some lines of plugin initialization from .ui file
# callback started when button is pressed

def visual_callback(self):
    """ This function is triggered by pressing the connect button."""
    # Create subscribers for each topic
    self.left = message_filters.Subscriber("/my_stereo/left/image_raw", Image)
    self.right = message_filters.Subscriber("/my_stereo/right/image_raw", Image)
    # Create synce filter. Use exact or approximate as appropriate.
    self.ts = message_filters.TimeSynchronizer([left, right], 10)
    # Assuming your object has a method maker(left, right) that takes in two Image objects
    # rospy.spin() is not desired here, as all it does is run an infinite loop

Originally posted by Ed Venator with karma: 1185 on 2017-11-05

This answer was ACCEPTED on the original site

Post score: 1

Original comments

Comment by marcoresk on 2017-11-20:
Thank you for help. It make more sense. However, It still does not work (or, at least, the maker callback seems not to be activated: I commented all the maker callback except for a print instruction). I also tried to set self.left and self.riht as argument of TimeSynchronizer.

Comment by marcoresk on 2017-11-20:
Hold on! The time ApproximateTimeSynchronizer strategy works (not the TimwSynchronizer one)! the parameter allow_headerless is not permitted in ROS Indigo and I was forced to remove it. But your solution now works.


Your Answer

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