How to create a ROS node that can start and stop counting based on what message the other node its subscribed to sends
Hello, I am basically trying to get a node that both publishes and subscribes. Imagine I have two nodes, node1 publishes and count_node subscribes and publishes as well. When node1 publishes "start count" I want count_node to start counting and publish the count value. If node1 publishes to "stop count" while count_node is counting, I want count_node to stop the active count. My attempt is below in code. I use ROS Melodic on Ubuntu 18.04
My attempt thus far fails because when I receive the message to start the count the callback function calls a function (startCount) that uses a while loop to increment. Thus until the count it finished, count_node cannot process the message to stop the count and the stopCount function is called AFTER the count is finished, not while its counting.
Is there a way to do what I want?
Here is my attempt at count_node:
import rospy
from std_msgs.msg import String
from std_msgs.msg import Int32
def callback(data):
rospy.loginfo(rospy.get_caller_id() + ' I heard: %s', data.data)
if (data.data=="start count"):
startSanitization()
elif (data.data=="stop count"):
stopSanitization()
def startCount():
percent = 0
while percent < 101 :
rospy.loginfo(percent)
pub.publish(percent)
percent = percent + 1
rate.sleep()
def stopCount():
percent = 0
rospy.loginfo(percent)
pub.publish(percent)
def listener():
# In ROS, nodes are uniquely named. If two nodes with the same
# name 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.
#check for message on Topic
rospy.Subscriber('brwsrButtons', String, callback)
rospy.loginfo("hello")
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
#create a unique node
rospy.init_node('count_node', anonymous=True)
#create a publisher object
pub = rospy.Publisher('progress', Int32, queue_size=10)
rate = rospy.Rate(10) #10Hz
#start the subscribing and publishing process
listener()
*New Updated code:
import rospy
from std_msgs.msg import String
from std_msgs.msg import Int32
from multiprocessing import Process, Pipe
import thread
keepCounting = 0
percent = 0
def callback(data,keepCounting):
# rospy.loginfo(rospy.get_caller_id() + ' I heard: %s', data.data)
if (data.data=="Started Sanitizing the Room"):
rospy.loginfo(rospy.get_caller_id() + ' I heard: %s', data.data)
keepCounting = 1
elif (data.data=="Stopped Sanitizing the Room"):
keepCounting = 0
def countingProc(percent, keepCounting):
while percent < 101 and keepCounting==0 :
rospy.loginfo(percent)
pub.publish(percent)
percent += 1
rate.sleep()
# elif keepCounting==0 :
def listener(percent, keepCounting):
# In ROS, nodes are uniquely named. If two nodes with the same
# name 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.
#check for message on Topic
rospy.Subscriber('brwsrButtons', String, callback,(keepCounting))
rospy.loginfo("hello")
thread.start_new_thread (countingProc, (percent, keepCounting,))
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
#create a unique node
rospy ...