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

How can I subscribers multiple topics to get data at the same time (python)?

asked 2015-10-18 07:54:31 -0500

Ananthakrishnan gravatar image

updated 2018-11-28 13:46:40 -0500

jayess gravatar image

Hi, Am new to ROS and I need a little help. There are 4 topics (robot0/sonar1, robot0/sonar2, ...) of same type (sensor_msgs/Range). I need to process these 4 values together.

#!/usr/bin/env python
import rospy
from sensor_msgs.msg import Range



def callback0(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.range)
    sonar0 = int(data.range)
def callback1(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.range)
    sonar1 = data.range
def callback2(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.range)
    sonar2 = data.range
def callback3(data):
    rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.range)
    sonar3 = data.range
def listener():
    # In ROS, nodes are uniquely named. If two nodes with the same
    # node are launched, the previous one is kicked off. The
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaneously.
    rospy.init_node('listener', anonymous=True)
    rospy.Subscriber("robot0/sonar_0", Range, callback0)
    rospy.Subscriber("robot0/sonar_1", Range, callback1)
    rospy.Subscriber("robot0/sonar_2", Range, callback2)
    rospy.Subscriber("robot0/sonar_3", Range, callback3)
    rospy.loginfo(rospy.get_caller_id() + "I heard %s %s %s %s", sonar0,sonar1,sonar2,sonar3)
    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()

if __name__ == '__main__':
    sonar0=0
    sonar1=0
    sonar2=0
    sonar3=0
    listener()

The line

rospy.loginfo(rospy.get_caller_id() + "I heard %s %s %s %s", sonar0,sonar1,sonar2,sonar3)

is not even executing. But I was able to see the result of individual callback. What is the best way to do this? I need an another function that has to process these 4 values.

Update:

Just like you said I am only getting the

rospy.loginfo(rospy.get_caller_id() + "I heard %s %s %s %s", sonar0,sonar1,sonar2,sonar3)

line executed once. What is the best way to do this? I want to store all the values in an array and process once all the four values are received. Then repeat this process again.

edit retag flag offensive close merge delete

Comments

do you get anything displayed - one set of values (probably all zeros) then nothing else, or nothing at all ?

nickw gravatar image nickw  ( 2015-10-18 10:49:24 -0500 )edit

yes. one set of values... All zero

Ananthakrishnan gravatar image Ananthakrishnan  ( 2015-10-18 12:40:19 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
10

answered 2015-10-18 14:44:17 -0500

Dimitri Schachmann gravatar image

updated 2015-10-18 14:44:51 -0500

You need to use message_filters.TimeSynchronizer for this. Please look at the example code in the documentation: http://wiki.ros.org/message_filters#E...

Please note that there is also the ApproximateTime synchronization, which is often what you want if the sensor time stamps are not exactly in sync.

edit flag offensive delete link more

Comments

Thanks... That worked. I was able to use ApproximateTime synchronization. That solved my issue. But I am not able to use message_filter with cmd_vel bcz it doesn't have any header. Is there any workaround 4 tat? Now am chckng t value of cmd_vel inside the call back function using wait_for_message

Ananthakrishnan gravatar image Ananthakrishnan  ( 2015-10-18 15:11:07 -0500 )edit

a solution would be to make the data source publish messages with a header.

Dimitri Schachmann gravatar image Dimitri Schachmann  ( 2015-10-18 16:22:47 -0500 )edit

a workaround could be to use http://wiki.ros.org/topic_tools/trans... to subscribe to your sensor data and output a new message type with a header. Than your node subscibes to that. You probably have to define that new message type yourself, unless it already exists.

Dimitri Schachmann gravatar image Dimitri Schachmann  ( 2015-10-18 16:23:21 -0500 )edit

I think its easy to use wait_for_message inside the callback function rather than going for republishing the topic. It solved my issue. But thanks for the reply...

Ananthakrishnan gravatar image Ananthakrishnan  ( 2015-10-19 03:14:41 -0500 )edit
2

answered 2015-10-18 11:06:49 -0500

updated 2015-10-20 01:28:59 -0500

I just ran your code, don't have a bunch of nodes publishing to the topics, but I get one line of 4 zeros as I would expect.

The line you say never runs does run, but onlyruns once at the beginning, on the next line it reaches ros.spin(). It stays at that point. The only activity you will then see are from the callbacks being called when messages come in on a topic, so you would see individual values being printed out as they come in on each of the topics.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2015-10-18 07:54:31 -0500

Seen: 29,088 times

Last updated: Nov 28 '18