• No results found

3 Catkin Build System

The Catkin Build System is one of the most powerful tools at your disposal for use with ROS. Catkin was established as the primary build tool for ROS, replacing rosbuild, in ROS groovy [11].

3.1 Creating package.xml

In a Catkin package, there are two required files: package.xml and CMake Lists.txt (package.xml replaced manifest.xml in REP-140 [4]). The first file is responsible for identifying a directory as something Catkin needs to build as well as provide information about the order in which the packages should be built.

Consider the following example from ros_threading_example.

<?xml version="1.0"?>

(Example package.xml from ros-threading-example on GitHub [2])

In this example, we create a minimal package.xml file. The required xml tags include package name, version, description, license, maintainer and author. These tags are used to identify the package. The buildtool_depend tag identifies the package as a Catkin package. The build_depend tags are used to establish the topological building of packages: this helps Catkin to build the packages in the correct order (so that dependencies are built before the packages which depend on them). As for run_depend, this identifies the packages with which Catkin needs to link your package dynamically.

3.2 CMake Setup

Next we examine the file CMakeLists.txt from the package ros-threading-example.

cmake_minimum_required(VERSION 2.8.9) project(ros_threading_example)

find_package(catkin REQUIRED COMPONENTS roscpp message_generation

nav_msgs)

(Example CMakeLists.txt from ros_threading_example on GitHub [5])

In this CMakeLists.txt file, we tell Catkin to compile and link the executables with the necessary ROS libraries (as declared in package.xml) and with the necessary Qt libraries. We will discuss only the relevant commands here, and note that information regarding commands out of the scope of this text may be found on the CMake website [6].

We begin by restricting the CMake version to only those that are 2.8.9 or later (for the Qt5-specific Commands). This is handled by the command cmake_minimum_

requiredfollowed by the flag VERSION and a release number.

The project command identifies the name of the project. Here, one can also specify the language or languages in which the particular program was written;

however, it is of the author’s opinion that this information is not relevant in the ROS world (unless you really want to be pedantic).

The find_package command is used to load settings from an external CMake package. Here it is used to set up CMake to work with Catkin and the necessary catkin packages. Successive calls are made to this command to include the Qt5 libraries in the build. The flag REQUIRED tells CMake to exit and throw an error if Catkin

or any necessary ROS components are not found. The COMPONENTS flag lists the specific CMake components to require before building.

Catkin provides the macro catkin_package. This command is used to generate the package configuration and remaining CMake files. There are five arguments, all optional: INCLUDE_DIRS, LIBRARIES, CATKIN_DEPENDS, DEPENDSand CFG_EXTRAS. INCLUDE_DIRS controls the export of the inclusion paths. LIBRARIES declares the libraries that Catkin is exporting from this pack-age. DEPENDS lists the CMake projects to incorporate that are not Catkin libraries (system-lib, for example). CFG_EXTRAS is the catch-all command for Catkin;

with this command, you specify another CMake file to include in the build (for example, this would be a file named extra.cmake).

CMake also has built-in Qt support. It uses the command qt5_wrap_cpp to produce Qt wrappers.1These are the moc files usually generated by the make com-mand in a qmake generated Makefile. In our context, we use this to create a qt-library from the sources command which we identify with QT_MOC_HPP. Had we created a User Interface with a tool such as QtDesigner (generating a .ui file), then we would employ the qt_wrap_ui in a similar fashion.

CMake uses include_directories to identify the directories to include when looking for header files. We use the ones with which Catkin is already famil-iar. It is important to note that, unless otherwise specified, CMake interprets your directory input as relative to the current directory (that is, the one with the file CMakeLists.txt). In particular, we use it to identify the source directories, the Catkin include directories and Qt5Widgets include directories.

The add_executable command identifies the binary to be built and identifies it with the sources with which to build it.

A specified target is linked with the command target_link_libraries.

Such a target must have been produced by an add_executable command or an add_library command. In our example, we link both executables to the Qt5 Widgets library and the Catkin libraries.

Finally, we place the binary (binaries) and or library (libraries) in the appropriate locations with the install command. The flag TARGETS identifies the targets we are installing. There are five types of targets: ARCHIVE, LIBRARY, RUNTIME, FRAMEWORK and BUNDLE. In most ROS applications, you will exclusively use LIBRARYand RUNTIME. The DESTINATION flag identifies the end location of the specified targets.

3.3 Message Generation

Before proceeding into Callback functions, the ability to generate a custom message file with ease is a noteworthy ROS feature. Say, for example, you wanted to create a message that held the robot’s position in only two coordinates. You can create a file

1This command is only found when Qt5Core is in the build environment. This command is also only available in CMake versions 2.8.9 and later.

called Pose2D.msg and in only a few lines implement the message. Below is the message file for the above example.

float64 xPose float64 yPose

The above file is found a in the build path of our example under the directory msg. Messages are included in the CMake file with the following commands.

add_message_files(FILES Pose2D.msg) generate_messages(DEPENDENCIES std_msgs)

Also, it is important to note that these commands must come before the catkin_

package()command appears. Before the targets are linked in CMakeLists.

txt, we add the message as a dependency with the following lines.

add_dependencies(pose_echo ${PROJECT_NAME}_generate_messages_cpp)

add_dependencies(pose_echo_threaded ${PROJECT_NAME}_generate_messages_cpp)

The messages are referenced in the source by including the automatically gener-ated header file $PROJECT_NAME/MessageName.h. In our particular example, we include the message and redefine the type as Pose2D with the following lines.

#include <ros_threading_example/Pose2D.h>

typedef ros_threading_example::Pose2D Pose2D;