Acting on information in a custom message on ROS

Question:

I have done the tutorials which shows you how to publish and subscribe to messages in ROS.

I have now set up a message talker and listener in a file, but this is where I am running into some issues. And this may be more of a Python issue than a ROS issue.

My message at the minute publishes a ‘0’. When the one is published, I want my turtle to complete a set action, however, I am having trouble extracting that 1 from the published message.

What I am trying to do is use that 0 in an if-statement. So, if 0, do this, if not, do that.

It was suggested that I make the information in my listener callback function that I want to extract to be global. This doesn’t seem to have worked.

I am hoping someone can point out where I am going wrong, or suggest a path forward.

My code is below:

#!/usr/bin/env python

import rospy
from com760_week4_ws_pkg.msg import CustomChat
from std_msgs.msg import Header
from time import gmtime
from time import strftime

def callback(data):
    global name
    chatter = data.data
    header = data.header
    name = data.name
    timestamp = header.stamp.to_sec()
    rospy.loginfo("The message passed by %s is %s, sent at %s" % (name, chatter, strftime("%H:%M:%S", gmtime(timestamp))))
    
def listener():
    rospy.Subscriber("message_chatter", CustomChat, callback)

def talker(count):
    pub = rospy.Publisher("message_chatter", CustomChat, queue_size=10)
    
    msg = CustomChat()
    msg.name = "The ROS User xxxx"
    

    msg.header.stamp = rospy.Time.now()
    msg.data = "-HELLO, ROS-"
    pub.publish(msg)
    rospy.sleep(2)
    listener()
        
if __name__ == '__main__':
    rospy.init_node("chatter", anonymous=True)
    count = 0
    while not rospy.is_shutdown():
        talker(count)
        print(name)

When I run this I get an error saying

line 42, in <module>
    print(name)
NameError: global name 'name' is not defined

I did try adding name = " " at the top of my code, but when I got to the print at the bottom, all it did was print the empty string.

Asked By: ofithch79

||

Answers:

One major problem you have is recreating the subscriber and publisher every time time you call talker. These should only be created once; preferably when you init the node.

As per your comments a couple more changes are needed. First you’re getting the error because name will only be defined as global when the callback is called first; this is unlikely to happen before your first print so you get the undefined error. To fix this you can simple declare name as a global variable outside of your functions. This will create the variable when your script is loaded and take care of the error. For example:

...
from time import strftime

name = ""    

def callback(data):
    global name
    ...
Answered By: BTables