In today’s video we are going to learn how to compile a ROS Message.
For that we are going to use Robot Ignite Academy, which is the best tool if you want Learn ROS Fast.
Before we start, if you are new to ROS and want to Learn ROS Fast, I highly recommend you to take any of the following courses on Robot Ignite Academy:
We love feedback, so, whether you like the video or not, please share your thoughts on the comments section below.
Step1. Create a project in Robot Ignite Academy(RIA)
We have the best online ROS course available in RIA. It helps you learn ROS in the easiest way without setting up ROS environment locally. The only thing you need is a browser! Create an account here and start to browse the trial course for free now! We’ll use the ROS Basic in 5 days course unit 4 as an example today.
Step2. Create a package
We’ll create a package for our code with the following command.
cd ~/catkin_ws/src
catkin_create_pkg financial_market rospy
We also need one folder for our message definition
cd financial_market
mkdir msg
Let’s call our message SharePrice.msg with the following definition
string name
float32 price
In the package.xml file, please uncomment the following part.
Then we compile the message with the following command
cd ~/catkin_ws
catkin_make
Please source the file after compile.
source devel/setup.bash
You can then check the message with
rosmsg info financial_market/SharePrice
In your python code, you can then add from financial_market.msg import SharePrice to use the message.
Want to learn more?
If you are interested in this topic, please check our ROS Basics In 5 Days (Python) course. You’ll learn how to create service and action message in ROS as well.
In this video we are going to explain and show in a practical way the difference between ROS topics and messages.
We show two nodes running, one publishing to a given topic and another subscribing to this same topic. RQT graph is used to see the big picture of the environment.
Step 0. Create a project in ROS Development Studio(ROSDS)
ROSDS helps you follow our tutorial in a fast pace without dealing without setting up an environment locally. If you haven’t had an account yet, you can create a free account here. Let’s create a new project and call it ros_q_a_topics_messages.
Step 1. Difference between ros topic and ros message
We’ll start by creating a package for the code in catkin_ws
cd catkin_ws/src
catkin_create_pkg my_pkg rospy std_msgs
Let’s also create a scripts folder for our scripts. Then two script called my_subscriber.py and my_publisher.py file in it with the following content.
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def main():
pub = rospy.Publisher('my_topic', String, queue_size=10)
rospy.init_node('my_publisher')
rate = rospy.Rate(1)
while not rospy.is_shutdown():
hello_str = 'hello world %s' % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
main()
except rospy.ROSInterruptExeception:
pass
Basically, a message is data through a channel called topic. In this code, the message is String type and the topic is called my_topic.
#!/usr/bin/env python
import rospy
from std_msgs import String
def main():
pub = rospy.Publisher('my_topic', String, queue_size = 10)
rospy.init_node('my_publisher')
rate = rospy.Rate(1)
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__' :
try:
main()
except rospy.ROSInterruptExeception:
pass
This script established a subscriber for the message through the topic my_topic.
To run the code, we have to give the scripts permission to execute with chmod +x my_publisher.py and chmod +x my_subscriber.py
Then we can run it with
cd catkin_ws
catkin_make
source devel/setup.bash
rosrun my_pkg my_publisher.py
You should see the publisher is publishing message into the topic.
Open another shell and run
rosrun my_pkg my_subscriber.py
Open the third shell and type rqt_graph , then go to Tools->graphical tool to open the GUI.
You should see the nodes are marked with circles. You can find the /my_publisher and /my_subscriber nodes in the graph.
The topic is marked with the square. In this example, the topic is called my_topic. The two node is communicating though this topic.
Want to learn more?
If you are interested in learning ROS, please check our ROS Basics Python course.
Did you like this video? Do you have questions about what is explained? Whatever the case, please leave a comment on the comments section below, so we can interact and learn from each other.
If you want to learn about other ROS topics, please let us know on the comments area and we will do a video about it.
Step 2: Examine the structure of the String message type
In the code, we used a ROS message type called String. Let’s examine the structure of this message.
Pick a Shell from the Tools menu and run the following command:
user:~$ rosmsg show String
[std_msgs/String]:
string data
[roseus/String]:
string data
Pick the IDE from the Tools menu, navigate to catkin_ws/src and open the obiwan_pub.pyprogram. You should see something like:
obiwan_pub.py
#! /usr/bin/env python
import rospy
from std_msgs.msg import String
rospy.init_node("sos_2")
rate = rospy.Rate(2)
help_msg = String()
help_msg.data = "help me Obi-Wan Kenobi, you're my only hope"
pub = rospy.Publisher('/help_msg', String, queue_size = 1)
while not rospy.is_shutdown():
pub.publish(help_msg)
rate.sleep()
We see that the String message is defined in two different packages (roseus and std_msgs), but we used the one defined in the std_msgs package, as can be seen on line 4 of the code block.
We also see that the String message has a single attribute named data, which should be a string. So, when creating a message of type String, we need to set a value for data, and the value must be a string (lines 8-9).
Now also take a look at the obiwan_sub.py program:
We see that on lines 6-7 when accessing a message of type String, we take it for granted that it has an attribute data, therefore we could reference msg.data.
Step 3: Determine the proper ROS message type to use for a given topic
In the obiwan_pub program above, we created a new topic called /help_msg. What if you are trying to publish to an existing topic and you are not sure the kind of message to send over it or you’re trying to subscribe to the topic and want to know what to expect? PS: every topic has a message type you must publish over it, or things will not work properly.
Let’s pretend we didn’t know the kind of message /help_msg uses – we just know the name of the topic. Let’s see how we can find out:
Start the obiwan_pub node, so that the help_msg topic is created.
user:~$ cd catkin_ws/src
user:~/catkin_ws/src$ ./obiwan_pub.py
Now pick another Shell from the Tools menu and run rostopic info /help_msg to find out the type of message it uses:
So now we see that it uses the message std_msgs/String, and we can know about this message by running. Here, we are specifying the package name (std_msgs) also, since we know it for sure:
user:~$ rosmsg show std_msgs/String
string data
Step 4: Wrapping it up
In summary, in order to use a ROS message properly, you need to know its structure. If you are working with an existing ROS topic, you can check what kind of message it uses and then check the structure of that message.
Extra: Video
Prefer to watch a video demonstrating the steps above? We have one for you below!
Related Resources
If you are a ROS beginner and want to learn ROS basics fast, we recommend you take any of the following courses on Robot Ignite Academy:
Head to http://rosds.online and create a project named “ros_message” or whatever you like. Please ensure you select “Ubuntu 16.04 + ROS Kinetic + Gazebo 7” under “Configuration”.
Step 2: Create source files
Pick a Shell from the Tools menu and run the following commands:
user:~$ cd catkin_ws/src
user:~/catkin_ws/src$ touch obiwan.py obiwan_pub.py obiwan_sub.py #create the files
user:~/catkin_ws/src$ chmod +x obiwan.py obiwan_pub.py obiwan_sub.py # make them executable
Pick the IDE from the Tools menu. Locate the folder catkin_ws/src in the IDE’s file navigator, locate the corresponding files and paste the following code into them.
obiwan.py
#! /usr/bin/env python
import rospy
rospy.init_node("sos_1")
rate = rospy.Rate(2)
while not rospy.is_shutdown():
print "Help me Obi-Wan Kenobi, you're my only hope"
rate.sleep()
obiwan_pub.py
#! /usr/bin/env python
import rospy
from std_msgs.msg import String
rospy.init_node("sos_2")
rate = rospy.Rate(2)
help_msg = String()
help_msg.data = "help me Obi-Wan Kenobi, you're my only hope"
pub = rospy.Publisher('/help_msg', String, queue_size = 1)
while not rospy.is_shutdown():
pub.publish(help_msg)
rate.sleep()
First, start the ROS master in the background. Then check the ROS topics currently available:
user:~/catkin_ws/src$ nohup roscore &
user:~/catkin_ws/src$ rostopic list
/rosout
/rosout_agg
obiwan.py
Run this command in the current terminal. You should see the following output:
ser:~/catkin_ws/src$ ./obiwan.py
Help me Obi-Wan Kenobi, you're my only hope
Help me Obi-Wan Kenobi, you're my only hope
...
Pick another Shell from the Tools menu and run the following command. You should see that no additional topic has been created:
user:~$ rostopic list
/rosout
/rosout_agg
obiwan_pub.py
Stop the obiwan.py program in the first terminal by pressing Ctrl + C. Then run the obiwan_pub.py program:
user:~/catkin_ws/src$ ./obiwan_pub.py
Program is doing nothing? Nah, we shall see shortly. In the second terminal, rerun the last command:
user:~$ rostopic list
/help_msg
/rosout
/rosout_agg
Ah, now we have a new topic: help_msg! But where’s the help message? We’ll see that in the third program.
obiwan_sub.py
In the second terminal, run the obiwan_sub program:
user:~$ cd catkin_ws/src
user:~/catkin_ws/src$ ./obiwan_sub.py
SOS received: 'Help me Obi-Wan Kenobi, you're my only hope'!
SOS received: 'Help me Obi-Wan Kenobi, you're my only hope'!
That’s the message being generated by the obiwan_pub.py program.
Now, let’s put everything together.
Step 4: Master the Concept: What is a ROS message?
The obiwan.py and obiwan_pub.py create similar messages. However, the message created by obiwan.py is NOT a ROS message because:
It didn’t use a recognized ROS message type.
It was not sent over a ROS channel (topic).
obiwan_pub.pypublishes a message on the /help_msg topic while obiwan_subsubscribes to that topic and therefore gets the message.
In summary,
ROS nodes communicate with one another through messages.
They communicate over channels called topics.
There are different types of messages for different tasks. For example, a node controlling a drone will tell the drone to take off using a ROS message type Empty over a topic that might be something like /drone/takeoff.
Extra: when you send a message to a robot via the command line, you are a n*** …or at least behaving like one 🙂 .
If you are interested in how this works in detail or even you want to create your own messages, please check our ROS Basics In 5 Days (Python) course!