Skip to content

Lab 5.3. ROS Package, msg, srv

Estimated time to complete this lab: 1 hour

Objectives

At the end of this self-learning lab, you should be able to:

  • recognize the workspace-package-node file structure in ROS
  • create a package in ROS
  • know the function of catkin_make, CMakeLists.txt and package.xml
  • create your own msg and srv

Preparations

There are no preparations needed! In this lab, you will create a package, node, msg and srv from scratch.


Section 1. What is a package?

Recommended reading: m2_wiki – ROS (II: Package):

  • Software in ROS is organized in packages.
  • A package may contain whatever what constitutes a useful module, such as:
    • ROS nodes
    • ROS-independent library
    • dataset, configuration files

When should I create a new package?

Create a package if your functionality doesn't fit into any of the existing packages!

  • Packages should contain enough functionality to be useful and easy-to-consume, but not too much that the package is heavyweight and difficult to use.
    • Functions in a package should be independent and similar.
  • Ideally, one package maps to one Git repository, and only 1 or 2 developers are working on a package at any time.

Workspace-package structure

  • A workspace contains multiple packages. For example, catkin_ws is a workspace that contains packages named package_1 and package_2.
  • Packages are usually placed under the /src directory of a catkin workspace.
  • Each package must have its own folder.
workspace_folder/        -- WORKSPACE
  src/                   -- SOURCE SPACE
    CMakeLists.txt       -- 'Toplevel' CMake file, provided by catkin
    package_1/
      CMakeLists.txt     -- CMakeLists.txt file for package_1
      package.xml        -- Package manifest for package_1
      src/               -- Source files for pakcage_1
      msg/               -- Message files for package_1
      srv/               -- Service files for package 1
    ...
    package_n/
      CMakeLists.txt     -- CMakeLists.txt file for package_n
      package.xml        -- Package manifest for package_n
      src/               -- Source files for pakcage_n
      msg/               -- Message files for package_n
      srv/               -- Service files for package n

Try it yourself: Creating a package

  • Change to the source space directory of your catkin workspace.
    • $ cd ~/catkin_ws/src
  • Now use the catkin_create_pkg command to create a new package called pack1 which has the dependencies of std_msgs, roscpp, and rospy:
$ cd ~/catkin_ws/src
$ catkin_create_pkg pack1 std_msgs roscpp rospy
- This will create a `pack1` folder under `catkin_ws/src/`
- `pack1` now contains a `package.xml` and `CMakeLists.txt`, which have been generated with the `catkin_create_pkg` command arguments.
  • Now, navigate to your workspace root (catkin_ws/) and run catkin_make
    • This will build the packages in the catkin workspace, and let ROS recognize that there is a new package in the workspace.
    • We will further elaborate on catkin_make later this lab.
$ cd ~/catkin_ws/
$ catkin_make
  • You can also verify that ROS recognizes the new package using rospack list:
$ rospack list | grep pack1
pack1 /home/m2/catkin\_ws/src/pack1
  • If you see pack1 in the list of packages, then you have successfully created a new package! We will put some useful codes in it later on.

In the following sections, we will (very) briefly introduce CMakeLists.txt and package.xml. You are recommended to open up these files while you read this lab. If you find it confusing, feel free to skip to Section 2, you can still create a msg/srv later on.

CMakeLists.txt

  • The build system of ROS is catkin.
  • We are referring to the CMakeLists.txt inside a package (pack1/CMakeLists.txt),
    Don't mix it up with the CMakeLists.txt in the root of the ROS workspace (catkin_ws/CMakeLists.txt)! Leave the workspace root CMakeLists.txt alone.

  • This file is a CMake file for everything that needs to be compiled in this ROS package, including:

    • programs written in C++
      • note that Python nodes do NOT need to be compiled.
    • messages, services, actions
      • even if you are using Python, some code is needed to be generated for msg and srv, which is built via CMake.
    • exported dependencies.

ROS package dependencies (more advanced, optional)

  • A package dependency is some external package that is required in order for the current package to be able to be compiled.
  • All ROS packages used must be declared in CMakeLists.txt and package.xml.
  • For example, if std_msgs is to be used, the line
find_package(catkin REQUIRED)

Should be changed to:

find_package(catkin REQUIRED COMPONENTS std_msgs)

If another package called m2_umd is needed, append it to the end of this line like:

find_package(catkin REQUIRED COMPONENTS std_msgs m2_umd)

catkin_make

  • This is the command to rebuild a ROS workspace.
  • Run this command at the root of the ROS workspace (NOT the root of a ROS package).
  • The rebuild process will throw weird warnings and errors if package.xml or CMakeLists.txt of any package in the workspace is not configured correctly.

You need to catkin_make when:

  • Adding/removing a package
  • Editing C++ code/headers
  • Editing dependencies (package.xml or CMakeLists.txt)
  • Editing messages/services/actions.

Note that editing Python codes does not need a catkin_make. That's why we like Python as we don't have to deal with as many issues in the build system. Also, when program running time is not a critical concern, we can afford to use Python, which allows us to skip the build process when testing programs, enabling faster development speed.

package.xml

  • This file includes all information readable by catkin and humans about the package.

ROS package dependencies

  • Add <depend>rospy</depend> if you are writing Python.
  • Add <depend>roscpp</depend> if you are writing C++.
  • Add <depend>[package_name]</depend> if you are using that package.
    • E.g. if you are using std_msgs, add <depend>std_msgs</depend>
    • E.g. if you are using m2_umd, add <depend>m2_umd</depend>

Milestone

Now that we know what these "package configuration files" do, we can add our own msg and srv!


Section 2. Creating a msg and srv

  • msg: a text file that describes the fields of a ROS message.
  • srv: a text file that describes a services. It is split into two parts: request and response.
  • msg files are stored in the msg directory of a package, and srv files are stored in the srv directory.

Field types (for both msg and srv)

For details, see http://wiki.ros.org/msg

  • bool
  • int8, int16, int32, int64, float32, float64
    • Signed numbers should be used in most general cases.
  • string
  • time, duration, Header
  • variable length array[] and fixed-length array[len]
  • other msg files

Try it yourself: Create a new msg

Let's create a new message type that can be used to handle the output of a distance sensor. In Robocon, the distance sensor is often used to find the distance between the robot and a fence or obstacle.

  • Create a new directory named msg under pack1, and under pack1/msg/, create a new text file named DistanceSensorStatus.msg
$ roscd pack1
$ mkdir msg && cd msg
$ touch DistanceSensorStatus.msg
  • Type the following inside DistanceSensorStatus.msg
    • For each message field, you should add a line [type] [name]

DistanceSensorStatus.msg

int32 status
float32 distance

- E.g. The first line: there is a field named `status` whose data type is `int32`.

You have already created a new message file! However, some changes are needed to be made in CMakeLists.txt and package.xml in order for the message to be useable by packages in ROS. Before that, let's create a srv which has a similar structure!

Try it yourself: Create a new srv

Let's create a new service type that can be used to handle the output shifted value of a distance sensor. In Robocon, even if the robot is fully touching a wall, a distance sensor pointed in the normal direction to the wall may not be reading 0 value due to the placement of sensor. Output shift eliminates such inconvenience.

  • Create a new directory named srv under pack1, and under pack1/srv/, create a new text file named SetDistanceSensorShift.srv
    • By ROS coding convention, service file names should be in CamelCase.
$ roscd pack1
$ mkdir srv && cd srv
$ touch SetDistanceSensorShift.srv
  • Type the following inside SetDistanceSensorShift.srv
    • Same as msg, for each service field, you should add [type] [name]
    • For a srv, you must add the line ---
      You must do this even if the Request and/or Response part of the service are empty.
    • The fields above --- are the Request part, while those below --- are the Response part.

SetDistanceSensorShift.srv

float32 distance
---
bool success
string message

I just want to use my own msg and srv, how come I need to learn about CMakeLists.txt?

You need to make modifications to those files in order for them to be used in ROS!


CMakeLists.txt: Modifications for message and service

  • add message_generation to the list of COMPONENTS in find_package:
# Do not just add this to your CMakeLists.txt, modify the
existing text to add message_generation before the closing
parenthesis
find_package(catkin REQUIRED COMPONENTS
 roscpp
 rospy
 std_msgs
 message_generation
)
  • add message_runtime to the list of CATKIN_DEPENDS in catkin_package
    Make sure CATKIN_DEPENDS is uncommented (remove the first #) as well:
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES pack1
 CATKIN_DEPENDS roscpp rospy message_runtime
# DEPENDS system_lib
)
  • uncomment generate_messages
generate_messages( # uncommented!
 DEPENDENCIES
 std_msgs
)
  • messages: uncomment the block of add_message_files, replace the list of .msg files with the .msg files in your package
add_message_files(
 FILES
# Message1.msg
# Message2.msg
 DistanceSensorStatus.msg
)
  • services: uncomment the block of add_service_files, replace the list of .srv files with the .srv files in your package
add_service_files(
 FILES
 SetDistanceSensorShift.srv
)

package.xml: Modifications for message and service

  • Open package.xml, and make sure these two lines are in it and uncommented: Uncomment a line in xml by removing the <!-- at the front and --> at the back.
 <build_depend>message_generation</build_depend>
 <exec_depend>message_runtime</exec_depend>

catkin_make: build the package again, and verify your msg/srv has been generated

  • We need to run catkin_make in order for the msg and srv code to be generated.
$ cd ~/catkin_ws/
$ catkin_make
  • You can verify that ROS has seen your msg/srv by using rosmsg list/rossrv list
$ rosmsg list | grep "pack1"
pack1/DistanceSensorStatus
$ rossrv list | grep "pack1"
pack1/SetDistanceSensorShift
  • You can even see the fields of a msg/srv in the command line using rosmsg show/rossrv show
$ rosmsg show pack1/DistanceSensorStatus
int32 status
float32 distance
$ rossrv show pack1/SetDistanceSensorShift
float32 distance
---
bool success
string message

Checklist and Assignment

Completion

Congratulations! You have successfully create a msg and srv in ROS!

You can even test the msg and srv with a node. The example package created in this lab is stored in m2cs_ros_tutorial/pack1/, and the nodes are stored in pack1/src. You should find the nodes similar to those introduced in Lab 5.1 and 5.2.

Now, you should have enough knowledge to finish Assignment 2 (Automatic path)

  • Understand CMakeLists.txt, package.xml, catkin_make
  • Create a msg and srv

References