Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Hi @Cry-A-Lot,

The main problem here is that you want to use rospy beyond its limitations. I will explain myself:

In rospy, for a particular topic, there is only one thread that all the subscribers share. Hence, when your node publish 1 and after 5 sec publish 0, it is the same connection/subscriber and the thread is blocked, thus not setting the verbose flag to False.

Your other method works exactly for this reason, when you publish 1 and then exits the program and relaunch again publishing 0, the subscriber connection is new and the callback is called in another thread changing the value of the flag and stopping the other loop thread.

For this reason why you want to do cannot be done if not using tricks to be able to not block your processing, and one of those tricks is unregistering the subscriber for each callback called. It will look something like:

#!/usr/bin/env python
import rospy
from std_msgs.msg import String
import time

verboser = True
sub = None

def counter() :
    counter = 0
    while(verboser and counter < 20 ):
        counter += 1
        time.sleep(1)
        print(str(counter) + ". Verbose is: " + str(verboser))

def callback(data):
    global sub
    sub.unregister()
    sub = rospy.Subscriber('chatter', String, callback)
    print("data INcoming : ",data.data)
    if int(data.data) == 1:
        counter()
    else:
        global verboser
        verboser = False

def main():
    global sub
    rospy.init_node('listener')
    sub = rospy.Subscriber('chatter', String, callback)

if __name__ == '__main__':
    main()
    rospy.spin()

If someone came up with a more elegant solution rather than this I would glad to discuss it here, however, and that is my opinion, if you want to have more control about threats and synchronization I will try to use roscpp. But as I said that is my personal preference to deal with this kind of things.

Hope that helps you.

Regards!