ROS Kinetic: Publisher and Subscriber in Python

The first time I started reading about ROS was last year. Also at that time, I made the decision to learn as much about ROS and make as many projects as possible based on it. After reading the first tutorials, I was sure it would be painful until I’ll build the first robot based on ROS. And I was right.

The first step in ROS begins with this tutorial. Or better, everything starts with two nodes, the so-called basic elements. A node to publish data, and a node to read and display the data received. As an autodidact, I know how hard it is to learn things that are not explained in detail. In this tutorial, I put a lot of attention on resources and the steps needed to write and run two nodes: a Publisher node and a Subscriber node.

Read now the best books to learn ROS:

Note: I have written with capital letters the Publisher and Subscriber to highlight the two ROS concepts.

What you find in this tutorial
  1. Resources needed
  2. A short description of the Publisher and Subscriber nodes
  3. A schema of the nodes
  4. Creating the workspace and the package that will contain the nodes
  5. The Publisher
  6. The Subscriber
  7. Run nodes with an automatic launch file
  8. Helpful commands
  9. Statistics
  10. Conclusion

1. Resources needed

To write the two ROS nodes you need hardware and software resources. Below I made a list of mandatory resources, and in the end, I added an optional resource that can be helpful in developing complex projects.

Further reading on IntoRobotics:
  1. A Raspberry Pi 3 board connected to a monitor, a keyboard, and a mouse. In addition to these, you can use the SSH (Secure Shell) option or the graphical interface option. One of the applications that allow Pi control from another computer is Remote Desktop Connection. Here is a tutorial where you can find the settings to control Pi remotely.
  2. Ubuntu MATE installed on Raspberry Pi 3. There is a version of Ubuntu MATE specifically designed for Raspberry Pi.
  3. ROS Kinetic installed on Raspberry Pi 3. I explained the steps necessary to install the full version of ROS Kinetic in this tutorial.
  4. Optionally, you can install an IDE for Python. I use IDLE.

2. A short description of the Publisher and Subscriber nodes

The idea is to simulate the data transfer between a sensor (for example, it can be an ultrasonic sensor) and a program that commands the direction of the robot. An ultrasonic sensor such as HC-SR04 returns information as a numeric string. The string of numbers returned by the sensor will be read by the Subscriber node for the calculation and decision-making of the robot navigation.

To simulate such a simple scenario for sending and reading data, I’ve created two nodes. The Publisher node will generate a random number, while the Subscriber node will display the random number received from the Publisher node.

Below I draw the schema of the nodes, how the data will flow, the data type used to send the information from one node to the other, and the rate of data transmission.

3. A schema of the nodes

A node scheme that contains the names of the two nodes, the type of data sent / received, and the data sending rate.

A node scheme that contains the names of the two nodes, the type of data sent / received, and the data sending rate.

4. Creating the workspace and the package that will contain the nodes

This step is only valid if you have not already created a workspace. If the workspace is created, then you can skip the step 4.1 and jump directly to the following commands – section 4.2 – to create the package.

4.1 The commands to create the workspace
mkdir -p ~/your_workspace_name_here/src 
cd ~/ your_workspace_name_here/src
catkin_init_workspace
catkin_make
source devel/setup.bash

The above commands create a set of directories that will host all ROS nodes.

If the first two commands should be familiar, the following two commands are ROS-specific. Both commands are designed to create meta data for ROS. The “catkin_init_workspace” command creates the CmakeLists.txt file. The “catkin_make” command generates a series of directories to host files, libraries, or executable programs.

4.2 Commands for creating the ROS package

It is necessary that the ROS package containing the two nodes to be included in the workspace directory. In addition, each package will contain two files: CmakeLists.txt and package.xml.

The commands for creating the package are:

cd ~/your_workspace_name_here/src
catkin_create_pkg your_package_name rospy

‘catkin_create_pkg’ is the command for creating the new package.
‘rospy’ is the dependency of the new package created by the rospy package.

5. The Publisher

Below is the code for the Publisher node. This node will generate a random number between 0 and 5000 every 2 seconds. The file must be executable.

#!/usr/bin/env python
import rospy

from std_msgs.msg import Int32
from random import randint

//define the random_number Publisher
def random_number_publisher():
    rospy.init_node('random_number')
    pub=rospy.Publisher('rand_no', Int32, queue_size=10)
    rate= rospy.Rate(2)
//generate a random number at every 2 seconds
    while not rospy.is_shutdown():
        random_msg=randint(0,5000)
        rospy.loginfo(random_msg)
        pub.publish(random_msg)
        rate.sleep()

if __name__=='__main__':
    try:
        random_number_publisher()
    except rospy.ROSInterruptException:
        pass

To make an executable file, run the command:

chmod u+x the_file.py

6. The Subscriber

The Subscriber node will display all the random numbers sent by the Subscriber node. The display rate is the same as the Publisher node transmission rate. The file must also be executable.

#!/usr/bin/env python

import rospy

from std_msgs.msg import Int32
//define the display text
def callback(data):
    rospy.loginfo("I receive %s", data.data)

//define the subscriber
def random_subscriber():
    rospy.init_node('random_subscriber')
    rospy.Subscriber('rand_no',Int32, callback)
    rospy.spin()

if __name__=='__main__':
    random_subscriber()

7. Run nodes with an automatic launch file

To run the two files, you must run three shell commands in different terminals. The first terminal belongs to the roscore command. The second command belongs to the Publisher node, and the third is the Subscriber command. In order not to open a terminal and run the controls manually one by one, ROS provides us a tool that automatically runs all these commands. It’s about roslaunch.

To launch all files automatically, we need a file with the extension ‘.launch’. Our file contains the lines in the image below and will be saved in the Publisher and Subscriber package. The file must be executable, just like the other Publisher and Subscriber files.

The content of the file with the '.launch' extension

The content of the file with the ‘.launch’ extension

Running the roslaunch file

Running the roslaunch file

8. Helpful commands

  • rostopic info rand_no – displays information about the topic, in my case the topic name is rand_no
  • rostopic hz rand_no – displays the rate of posting
  • rostopic type rand_no – displays the topic type
  • rqt_graph – displays a window with the nodes and links between them

9. Statistics

The Raspberry Pi 3 board has limited memory and processing resources. That is why it is necessary to know at any moment the resources consumed by the ROS nodes. Below I monitored the Raspberry Pi load while running the two nodes. Depending on the applications turned on, the data below may differ. The capture below is done while running only the two ROS nodes.

The Raspberry Pi 3 statistics

The Raspberry Pi 3 statistics

10. Conclusion

This tutorial is for beginners, for those who want to learn to work with ROS. The two above mentioned nodes are a kind of “Hello World” in programming. If you went through the tutorial and put it into practice, you just took the first step in the ROS. It’s the first step in advanced robotics.

Commerce Content is independent of articles and advertising, and if you buy something through our posts, I may get a small share of the sale.

Leave a Reply

Required fields are marked *.