rospy Subscriber callback threading test
I try to use rospy Subscriber callback handler to manipulate some object but it doesn't work like i would like to.
In,subscriber handler is look like this :
import rospy from std_msgs.msg import String import time
verboser = True
def counter() :
counter = 0
while(verboser and counter < 20 ):
counter += 1
time.sleep(1)
print(counter)
def callback(data):
print("data INcoming : ",data.data)
if int(data.data) == 1:
counter()
else :
global verboser
verboser = False
def main():
rospy.init_node('listener')
sub = rospy.Subscriber('chatter', String,callback)
if __name__ == '__main__':
main()
rospy.spin()
if i try to command counter() function with code like this :
import rospy
from std_msgs.msg import String
import time
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
hello_str = "1"
pub.publish(hello_str)
time.sleep(5)
hello_str = "0"
pub.publish(hello_str)
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
it produce this output :
data INcoming : 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
data INcoming : 0
but if i change talker to publish only one and re-run it with change variable 'hello_str' it seem counter() function does stop after run the process
import rospy
from std_msgs.msg import String
import time
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
hello_str = "1"
pub.publish(hello_str)
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
ouput :
data INcoming : 1
1
2
3
4
5
6
data INcoming : 0
7
and i try to check if publisher publish after sleep 5 second via 'rostopic echo /chatter' and it seem it does send. so i think the rospy.Subscriber() is refuse to new threading callback that have been publish from the same process until it finish. Is there anyway to config rospy to accept this ?
I think the main problem is that you are not giving the callback enough time to perform its task. The callback, counter funtion will take at least 20 sec to be executed, but if you are publishing again at max rate the callback will be executed again while the other one is still producing.
So in your set up, 1 is published and callback start the loop until a 0 is again published. Then the flag
verboser
is set to False forcing the other thread loop to stop right after receiveng the 0.As a comment: Callbacks in rospy are not threadsafe. You should use locks in any rospy node where multiple callbacks of any kind might interact.
the point in this test is i try to start then stop it by using the same subscriber,but it doesn't work out when i using the same node to publishing to a topic and it work when i run it separately which run one node to publish 1 to start a counter() function and another node to publish 0 the set the
verboser
to stop it.