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

How to subscribe for a single message from a topic (receive once and then stop)

asked 2018-05-29 09:56:34 -0500

rahvee gravatar image

I would like to get a single message from a topic. Is there a built-in, simple, elegant way to do this? Currently, I am creating a subscriber, and using a threading.Event object to signal when it receives a message, and automatically unregister itself. It works, but it seems unwieldy for a task that I presume to be fairly common.

class SomeClass:
    def __init__(self):
        self.data = None
        self.get_data_subscriber = None
        self.get_data_event = threading.Event()

    def get_data_callback(self, data):
        self.data = data
        self.get_data_subscriber.unregister()
        self.get_data_subscriber = None
        self.get_data_event.set()

    def run(self):
        rospy.init_node('myNodeName', anonymous=True)

        self.get_data_subscriber = rospy.Subscriber('/sometopic', SomeType, self.get_data_callback)

        while True:
            self.get_data_event.wait(0.1)  # sleep 100ms or wakeup sooner if event was set

            # wait() didn't have a return value until python 2.7, so for compatibility, don't rely on the return val.
            # is_set() method was added in python 2.6, so for compatibility, use isSet() instead.
            if self.get_current_pose_event.isSet():
                self.get_current_pose_event.clear()
                break
            if rospy.is_shutdown():
                return

        rospy.loginfo("data is: {}".format(data))
        return

if __name__ == "__main__":
    foo = SomeClass()
    foo.run()
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
6

answered 2018-05-29 10:04:29 -0500

gvdhoorn gravatar image

updated 2018-05-29 10:13:07 -0500

Please see #q270298.

In Python this should be available through rospy.wait_for_message(..) (docs).

edit flag offensive delete link more

Comments

Perfect, thanks!

rahvee gravatar image rahvee  ( 2018-05-30 17:11:51 -0500 )edit
0

answered 2018-05-29 10:03:52 -0500

simchanu gravatar image

updated 2018-05-29 10:20:47 -0500

You could use the unregister fonction like this :

import rospy
from std_msgs.msg import Int8

class SomeClass:
    def __init__(self):
        self.data = None
        self.sub = None

    def get_data_callback(self, data):
        self.data = data
        print self.data
        self.sub.unregister()

    def run(self):
        rospy.init_node('myNodeName', anonymous=True)
        self.sub = rospy.Subscriber('/sometopic', Int8, self.get_data_callback)

        rospy.spin()

if __name__ == "__main__":
    foo = SomeClass()
    foo.run()
edit flag offensive delete link more

Comments

2

It can work, but there is no need. See the answer I linked. There is API for this.

gvdhoorn gravatar image gvdhoorn  ( 2018-05-29 10:10:44 -0500 )edit

I tried the solution in this way:

from std_msgs.msg import Int8

def callback(data):
 #rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.pose)
 my_data = data.pose
 unregister()

it keeps showing: unregister() NameError: global name 'unregister' is not defined

Tawfiq Chowdhury gravatar image Tawfiq Chowdhury  ( 2019-05-09 13:21:03 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2018-05-29 09:56:34 -0500

Seen: 7,171 times

Last updated: May 29 '18