A message is essentially a datatype that is defined to be used in communication. ROS has a programming language that is used to define messages. It's called Message Description Language (more info here) and it's very simple. All the messages go into a folder named "msg" in your package.
Let us define our own message with the following features:
We'll used the info to send a description and value to send actual floating point value. We'll name it "Equ.msg".
Before defining a message, the following is required:
rosmsg list
command and you'll get a list of messages and packages they're in (package_name/message_name), check it out.This is also the procedure to add dependencies after you've created the package. Here's the CMakeLists.txt file and package.xml file of the package on GitHub. Note that you might not have the lines for Publisher1 and Subscriber1 files (we'll create them later in this tutorial).
Here's the code that we must write in a file named "Equ.msg" in the msg folder of our package intro_pkg1. Write the following into it:
Note that the name of our message here is "Equ.msg". It can virtually be any valid name, just don't name them after keywords like "float" or "char", because even though they might build, they'll give you tremendous problems ahead.
Code hereNow that we've written and saved the files, do the following (open a terminal and run catkin_make
on the workspace):
cd ~/ROS_workspaces/ros_ws/
catkin_make
catkin_make --pkg intro_pkg1
to build the intro_pkg1 package only.You could navigate to the devel folder of the workspace (ros_ws here) and check the following directories:
ros_ws folder on GitHub.
You could also see the output of rosmsg list
command and search for intro_pkg1/Equ in the list. Try other commands to know more about the message using rosmsg
.
Equ.msg file
This finishes the task of creating a message using message description language. You could check the following out as well:
These files show you how to use these custom made messages
A service is a pair of messages, one for request and one for reply. A topic is where some nodes publish data and some nodes read data through subscription. Such a communication form is not apt for a request and response type of communication, thus services. Just like message description language, we have service description language for definition of services (more info here). All services go in a folder named "srv" in your package.
Let's define our own service with the following features:
We'll name the service as FloatIO.srv.
Since a service incorporates the concepts of messages as well, we have to follow similar steps to the prerequisites for messages. You would've already done most of it already, you won't need to change those. You'll need to have the following fone:
Here's the CMakeLists.txt and package.xml file on GitHub. It might have more things than what's given above.
Here's what we must write in the file "FloatIO.srv" in the srv folder of the package intro_pkg1. Write the following into it:
cd ~/ROS_workspaces/ros_ws/
catkin_make
You could navigate to the devel folder and check out the following directories (with respect to the workspace directory):
ros_ws folder on GitHub.
You could also see the output of rossrv list
command and search for intro_pkg1/FloatIO in the list. Try other commands to know more about the service using rossrv
.
A service server is a node that is hosting (or providing) a service. Till now we only defined the structure of the service, not the relation between request and response. A service server does exactly that, defines the service. This is obviously written through C++ or Python code, let's observe how to do that.
We'll take the relation as response (output) is equal to request (input) times 2 plus 1.
Follow this procedure to create a service server (we've named it "ServiceServer1.cpp"):
cd ROS_workspaces/ros_ws/
catkin_make
Now you can run the node using rosrun intro_pkg1 EquationServer
. You can check out the service using the rosservice
command. Try out the following:
rosservice info /equation_service
rosservice call /equation_service "input: 2.5"
Follow this procedure to create a service server:
Run the following commands on a terminal:
roscd intro_pkg1/scripts/
chmod +x *.py
rosrun intro_pkg1 ServiceServer1.py
echo $PYTHONPATH
and source the workspace if the output doesn't have the workspace python source folder.You can check out the service using the rosservice
command. Try out the following:
rosservice info /equation_service
rosservice call /equation_service "input: 2.5"
Service server made using C++
Service server made using Python
A service client is a node that sends requests to a service server. It sends a request and receives a response. Let's program this using C++ and Python. It'll take a number as an argument and print the response received. We can code it using C++ or Python.
Follow the following procedure to create a service client:
Now you can run the node using "rosrun intro_pkg1 EquationClient <Number>". Try out the following:
rosrun intro_pkg1 EquationClient 2
rosrun intro_pkg1 EquationClient 5.5
Make sure the roscore
and the service server is running before calling the client. Try using the service client after killing the service server, you must get an error message
Follow the following procedure to create a service client:
Open a terminal and execute the following commands:
roscd intro_pkg1/scripts/
chmod +x *.py
rosrun intro_pkg1 ServiceClient1.py 5.3
rosrun intro_pkg1 ServiceClient1.py 2.5
Make sure the roscore
and the service server is running before calling the client. Try using the service client after killing the service server, you must get an error message.
Service client made using C++
Service client made using Python