return value from subscriber callback rospy
For most of my work, I've used the rospy.Subcriber call in this way:
def func():
rospy.Subscriber(topic, msg_type, callback)
print "Let's proceed from where we left"
def callback(data):
foo = data.msg
# and so on
This, however, presents an issue: the value of data.msg
won't be accessible anywhere else, except for storing its value in class / global variables. This isn't always a choice that can be taken.
My question is: how can I continue the program-flow from just after calling the subscriber constructor, having the value of the callback "returned"? Am I forced to have a single-line function func()
whose only purpose is to call the subscriber? I know that I can continue from there, but I won't have the value of the callback
EDIT: As requested, I'll post an extended example:
class Listener(object):
def __init__(self):
self.flag = True
self.sub = rospy.Subscriber('/echo', MyMsg, self.echo)
def echo(self, data): # data.msg can be 'stop' string or any other string
if data.msg == 'stop':
self.flag = False
self.return_value = data.foo
else:
rospy.loginfo(data.msg)
if __name__ == '__main__':
rospy.init_node('listener')
list = Listener()
while list.flag:
rospy.sleep(1)
print 'Value was non-stop'
This is the code I have to circumvent the issue of not being able to "return" a value from a callback function. My goal would be to avoid using the class variable flag
, which I use for this purpose only and is not very meaningful, and to "use" (or, incorrectely, "return") data.foo
at the time needed, being when data.msg == 'stop'
, outside of the callback echo
function.
Pedantic, but: callbacks do not return anything, so the direct answer would be: no, you cannot do this.
This is probably not what you are asking about though.
Could you clarify what the function of
func()
is here? Why do you use it? Also: where do you store the constructedSubscriber
instance?Finally: could you provide an indication of how much experience you have with asynchronous/event based programming? From your description it sounds like you're trying to use callbacks as regular functions which "return a value". That is not how this works.
The code I just provided is just a template, to generalise my question. Not gonna lie, I'm not very familiar with async events, I've had a short practice on the subject so that's why my question might sound off-ROS-topic. I get your point, but still I am asking, is it somehow possible to "wait for the response" of the callback function, having its value "returned" (in its general meaning)?
Ok, but this also makes it harder to answer, as details are missing.
Yes, but please explain why you want to do that, so we can avoid discussing an anti-pattern.
If you want to wait for the response of the callback function, you can use a service, but I agree with @gvdhoorn that this is probably not the right solution for your problem.