Skip to content

Week 1 Subscriber Node

tom-howard edited this page Feb 15, 2022 · 11 revisions

Week 1 Subscriber Node

The Code

Copy all of the code below into your subscriber.py file. Then, review the explainer (below) to understand how this all works.

#!/usr/bin/env python3
# A simple ROS subscriber node in Python

import rospy
from std_msgs.msg import String

class Subscriber():

    def callback(self, topic_message):
        print(f"The '{self.node_name}' node obtained the following message: '{topic_message.data}'")

    def __init__(self):
        self.node_name = "simple_subscriber"
        topic_name = {BLANK}

        rospy.init_node(self.node_name, anonymous=True)
        self.sub = rospy.Subscriber(topic_name, String, self.callback)
        rospy.loginfo(f"The '{self.node_name}' node is active...")

    def main_loop(self):
        rospy.spin()

if __name__ == '__main__':
    subscriber_instance = Subscriber()
    subscriber_instance.main_loop()

FILL IN THE {BLANK}! Replace the {BLANK} in the code above with the name of the topic that our publisher.py node was set up to publish to!

The Code Explained:

First, don't forget the shebang!

#!/usr/bin/env python3

As with our publisher node, we need to import the rospy client library and the String message type from the std_msgs.msg library in order to write a Python ROS Node and use the relevant ROS messages:

import rospy
from std_msgs.msg import String

Next, we create a Subscriber class:

class Subscriber():

Within our class, we firstly create a callback function, for the rospy.Subscriber method to use later. Within this function, we define what we want to do with the messages that we obtain from the topic we are listening to:

def callback(self, topic_message):
    print(f"Subscriber obtained the following message: '{topic_message.data}'")

In this case, we simply want to format the String message and print it out to the terminal.

Next, we define our initialisation operations for the class:

def __init__(self):
    node_name = "simple_subscriber"
    topic_name = {BLANK}

    rospy.init_node(node_name, anonymous=True)
    self.sub = rospy.Subscriber(topic_name, String, self.callback)

Here, we firstly initialise a rospy node with a custom name (in the same way as we initialised the publisher node earlier). Then, we create a rospy.Subscriber object, set this to listen to the topic that we want to receive messages from, specify message type used by this topic, and then define the function which will be called when a message is received. The received message will automatically be set as the first input to this function, so we need to make sure that the self.callback() function is configured to accept the message (or "data") as its first input (after self).

Then, we send a message to the terminal to indicate that our node is active:

rospy.loginfo(f"The '{node_name}' node is active...")

Then, we define the functionality of the main loop, which will run continuously until the node is shut down:

def main_loop(self):
    rospy.spin()

rospy.spin() simply keeps the node running until it is shutdown externally (i.e. by a user entering Ctrl+C).

Finally, the code is executed by again performing the standard Python name check, creating an instance of the Subscriber class and calling the main_loop() class method:

if __name__ == '__main__':
    subscriber_instance = Subscriber()
    subscriber_instance.main_loop()

An Alternative Implementation

The above code uses a Python Class structure. This approach will be very useful when we start to do more complex things later in the course, but for this exercise you could also achieve the same using the following simplified approach:

#!/usr/bin/env python3

import rospy
from std_msgs.msg import String

node_name = "simple_subscriber"
topic_name = {BLANK}

def callback_function(topic_message):
    print(f"The '{node_name}' node obtained the following message: '{topic_message.data}'")

rospy.init_node(node_name, anonymous=True)
sub = rospy.Subscriber(topic_name, String, callback_function)
rospy.loginfo(f"The '{node_name}' node is active...")

rospy.spin()
Clone this wiki locally