
ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

rospy subscriber with multiple input

asked 2017-10-17 04:30:48 -0600

updated 2017-10-17 08:05:57 -0600

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
        ts.registerCallback(self.visual_callback2)
        #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.

edit retag flag offensive close merge delete

3 Answers

Sort by » oldest newest most voted
1

answered 2017-11-05 14:48:17 -0600

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
self._c.Action_button.clicked.connect(self.visual_callback)

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
    self.ts.registerCallback(self.maker)
    # rospy.spin() is not desired here, as all it does is run an infinite loop
edit flag offensive delete link more
0

answered 2017-10-23 06:25:24 -0600

You can use the same callback to subscribe to different topics and check the type of the received message (seeing msg._type) on the callback.

If you are subscribing to two different topics that published messages of types sensor_msgs/LaserScan and nav_msgs/Odometry, for example, then your callback would be something like:

def common_callback(self, msg):

        input_message_type = str(msg._type)

        rospy.logdebug("msg._type: "+input_message_type)

        if input_message_type == "sensor_msgs/LaserScan":
            rospy.loginfo("sub_laserscan called me, with type msg: "+input_message_type)
            # doSomething()

        elif input_message_type == "nav_msgs/Odometry":
            rospy.loginfo("sub_odom called me, with type msg==>"+input_message_type)
            # doSomethingElse()

This callback example I got from this answer.

edit flag offensive delete link more
0

answered 2017-10-17 04:39:56 -0600

updated 2017-10-17 04:57:47 -0600

Hi!

I'm not really sure if I understand the problem fully. But what happens if you follow method A, but omit the rospy.spin()?

rospy.spin() is usually used when you don't want to do nothing more, and just wait for the callbacks to get triggered. This is no te case, as rqt will still need to do things.

EDIT based on on your comment. I do not know what triggers the 'visual_callback' in your code (if that's the one you are stating that runs only once). More code/information is needed to better understand your problem.

edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2017-10-17 04:30:48 -0600

Seen: 1,382 times

Last updated: Nov 05 '17
{"cc_re__cc_re__cc_by_sa_3_0_le": ["ref=\"/question/386628/recursively-get-message-field-names-in-ros2/\">Recursively get message field names in ROS2</a> </p> <p> <a href=\"/question/11488/unknown-error-initiating-tcpip-socket/\">unknown error initiating tcp/ip socket</a> </p> <p> <a href=\"/question/341601/voronoi-map-segmentation-package/\">Voronoi map segmentation package</a> </p> </div> </div> <div class=\"box\"> </div> </div> </div> <!-- template footer.html --> <div id=\"ground\"> <div class=\"content-wrapper\"> <div class=\"copyright\"> <a href=\"http://creativecommons.org/licenses/by-sa/3.0/legalcode\"> <img\n                            class=\"license-logo\"\n                            src=\"/m/default/media/images/cc-by-sa.png?v=28\"\n                            title=\"cc-by-sa\"\n                            alt=\"cc-by-sa\"\n                        /> </a>\n                \n                ROS Answers is licensed under Creative Commons Attribution 3.0 Content on this site is licensed under a <a href=\"http://creativecommons.org/licenses/by-sa/3.0/legalcode\">Creative Commons Attribution Share Alike 3.0</", "ss=\"content-wrapper\"> <div class=\"copyright\"> <a href=\"http://creativecommons.org/licenses/by-sa/3.0/legalcode\"> <img\n                            class=\"license-logo\"\n                            src=\"/m/default/media/images/cc-by-sa.png?v=28\"\n                            title=\"cc-by-sa\"\n                            alt=\"cc-by-sa\"\n                        /> </a>\n                \n                ROS Answers is licensed under Creative Commons Attribution 3.0 Content on this site is licensed under a <a href=\"http://creativecommons.org/licenses/by-sa/3.0/legalcode\">Creative Commons Attribution Share Alike 3.0</a> license.\n\n            </div> <div class=\"footer-links\" > <a href=\"/about/\">about</a><span class=\"link-separator\"> |</span> <a href=\"/faq/\">faq</a><span class=\"link-separator\"> |</span> <a href=\"/help/\" title=\"help\">help</a> <span class=\"link-separator\"> |</span> <a href=\"/privacy/\">privacy policy</a><span class=\"link-separator\"> |</span> <a href=\"/terms/\">terms of service</a> </div> <div class=\"powered-link\"> <a href=\"http://askbot.com\" target=\"_b"], "copyright__copyright__copyright": ["t to do nothing more, and just wait for the callbacks to get triggered. This is no te case, as rqt will still need to do things.\n\nEDIT based on on your comment. I do not know what triggers the 'visual_callback' in your code (if that's the one you are stating that runs only once). More code/information is needed to better understand your problem.\n\nedit flag offensive delete link more\n\nQuestion Tools\n\n2 followers\n\nStats\n\nAsked: 2017-10-17 04:30:48 -0600\n\nSeen: 1,382 times\n\nLast updated: Nov 05 '17"]}