Note: This tutorial assumes that you have completed the previous tutorials: navigating the ROS filesystem.
(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Creating a ROS Package

Description: This tutorial covers using roscreate-pkg or catkin to create a new package, and rospack to list package dependencies.

Tutorial Level: BEGINNER

Next Tutorial: Building a ROS package

Using roscreate

Before we create a package, let's see how the roscreate-pkg command-line tool works. This creates a new ROS package. All ROS packages consist of the many similar files : manifests, CMakeLists.txt, mainpage.dox, and Makefiles. roscreate-pkg eliminates many tedious tasks of creating a new package by hand, and eliminates common errors caused by hand-typing build files and manifests.

To create a new package in the current directory:

# roscreate-pkg [package_name]

You can also specify dependencies of that package:

# roscreate-pkg [package_name] [depend1] [depend2] [depend3]

Creating a New ROS Package

Now we're going to go into your home or project directory and create our beginner_tutorials package. We are going to make it depend on std_msgs, roscpp, and rospy, which are common ROS packages.

Now go into the ~/fuerte_workspace/sandbox directory:

$ cd ~/fuerte_workspace/sandbox

Alternatively, if you use Fuerte or later release, you can simply do:

$ roscd
$ cd sandbox

Then create your package:

$ roscreate-pkg beginner_tutorials std_msgs rospy roscpp

You will see something similar to:

  • Creating package directory ~/fuerte_workspace/sandbox/beginner_tutorials
    Creating include directory ~/fuerte_workspace/sandbox/beginner_tutorials/include/beginner_tutorials
    Creating cpp source directory ~/ros/ros_tutorials/beginner_tutorials/src
    Creating python source directory ~/fuerte_workspace/sandbox/beginner_tutorials/src/beginner_tutorials
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/Makefile
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/manifest.xml
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/CMakeLists.txt
    Creating package file ~/fuerte_workspace/sandbox/beginner_tutorials/mainpage.dox
    
    Please edit beginner_tutorials/manifest.xml and mainpage.dox to finish creating your package

You're going to want to spend some time looking at beginner_tutorials/manifest.xml. manifests play an important role in ROS as they define how Packages are built, run, and documented.

Now lets make sure that ROS can find your new package. It is often useful to call rospack profile after making changes to your path so that new directories will be found:

$ rospack profile
$ rospack find beginner_tutorials 
  • YOUR_PACKAGE_PATH/beginner_tutorials

If this fails, it means ROS can't find your new package, which may be an issue with your ROS_PACKAGE_PATH. Please consult the installation instructions for setup from SVN or from binaries, depending how you installed ROS. If you've created or added a package that's outside of the existing package paths, you will need to amend your ROS_PACKAGE_PATH environment variable to include that new location. Try re-sourcing your setup.sh in your fuerte_workspace.

Try moving to the directory for the package.

$ roscd beginner_tutorials 
$ pwd
  • YOUR_PACKAGE_PATH/beginner_tutorials

First-order package dependencies

When using roscreate-pkg earlier, a few package dependencies were provided. These first-order dependencies can now be reviewed with the rospack tool.

(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy; it may take some time to be reflected in the packages. If you see an issue similar to this with the next command, you can skip to the following command.

$ rospack depends1 beginner_tutorials 
  • std_msgs
    rospy
    roscpp

As you can see, rospack lists the same dependencies that were used as arguments when running roscreate-pkg. These dependencies for a package are stored in the manifest file. Take a look at the manifest file.

$ roscd beginner_tutorials
$ cat manifest.xml
  • <package>
    
    ...
    
      <depend package="std_msgs"/>
      <depend package="rospy"/>
      <depend package="roscpp"/>
    
    </package>

Indirect package dependencies

In many cases, a dependency will also have its own dependencies. For instance, rospy has other dependencies.

(Jan 9, 2013) There is a bug reported and already fixed in rospack in groovy; it may take some time to be reflected in the packages. If you see an issue similar to this with the next command, you can skip to the following command.

$ rospack depends1 rospy
  • roslib
    roslang

A package can have quite a few indirect dependencies. Luckily rospack can recursively determine all nested dependencies.

$ rospack depends beginner_tutorials
  • rospack
    roslib
    std_msgs
    rosgraph_msgs
    rosbuild
    roslang
    rospy
    cpp_common
    roscpp_traits
    rostime
    roscpp_serialization
    xmlrpcpp
    rosconsole
    roscpp

Note: in Fuerte, the list is much shorter:

  • std_msgs
    roslang
    rospy
    roscpp

ROS Client Libraries

You may be wondering what rospy and roscpp dependencies are from the previous examples. rospy and roscpp are Client Libraries. The client libraries allow different programming languages to communicate through ROS. rospy is the client library for Python. roscpp is the client library for C++.

Review

Lets just list some of the commands we've used so far:

  • roscreate-pkg = ros+create-pkg : generates all the files needed to create a ROS package
  • rospack = ros+pack(age) : provides information related to ROS packages
  • rosstack = ros+stack : provides information related to ROS stacks

What makes up a catkin Package?

For a package to be considered a catkin package it must meet a few requirements:

  • The package must contain a catkin compliant package.xml file.

    • That package.xml file provides meta information about the package.
  • The package must contain a CMakeLists.txt which uses catkin.

  • Each package must have its own folder
    • This means no nested packages nor multiple packages sharing the same directory.

The simplest possible package might have a structure which looks like this:

  • my_package/
      CMakeLists.txt
      package.xml

Packages in a catkin Workspace

The recommended method of working with catkin packages is using a catkin workspace, but you can also build catkin packages standalone. A trivial workspace might look like this:

  • 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
        ...
        package_n/
          CMakeLists.txt     -- CMakeLists.txt file for package_n
          package.xml        -- Package manifest for package_n

Before continuing with this tutorial create an empty catkin workspace by following the Creating a workspace for catkin tutorial.

Creating a catkin Package

This tutorial will demonstrate how to use the catkin_create_pkg script to create a new catkin package, and what you can do with it after it has been created.

First change to the source space directory of the catkin workspace you created in the Creating a Workspace for catkin tutorial:

# You should have created this in the Creating a Workspace Tutorial
$ cd ~/catkin_ws/src

Now use the catkin_create_pkg script to create a new package called 'beginner_tutorials' which depends on std_msgs, roscpp, and rospy:

$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

This will create a beginner_tutorials folder which contains a package.xml and a CMakeLists.txt, which have been partially filled out with the information you gave catkin_create_pkg.

catkin_create_pkg requires that you give it a package_name and optionally a list of dependencies on which that package depends:

# This is an example, do not try to run this
# catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

catkin_create_pkg also has more advanced functionalities which are described in catkin/commands/catkin_create_pkg.

Building a catkin workspace and sourcing the setup file

Now you need to build the packages in the catkin workspace:

$ cd ~/catkin_ws
$ catkin_make

After the workspace has been built it has created a similar structure in the devel subfolder as you usually find under /opt/ros/$ROSDISTRO_NAME.

To add the workspace to your ROS environment you need to source the generated setup file:

$ . ~/catkin_ws/devel/setup.bash

package dependencies

First-order dependencies

When using catkin_create_pkg earlier, a few package dependencies were provided. These first-order dependencies can now be reviewed with the rospack tool.

$ rospack depends1 beginner_tutorials 
  • roscpp
    rospy
    std_msgs

As you can see, rospack lists the same dependencies that were used as arguments when running catkin_create_pkg. These dependencies for a package are stored in the package.xml file:

$ roscd beginner_tutorials
$ cat package.xml
  • <package format="2">
    ...
      <buildtool_depend>catkin</buildtool_depend>
      <build_depend>roscpp</build_depend>
      <build_depend>rospy</build_depend>
      <build_depend>std_msgs</build_depend>
    ...
    </package>

Indirect dependencies

In many cases, a dependency will also have its own dependencies. For instance, rospy has other dependencies.

$ rospack depends1 rospy
  • genpy
    roscpp
    rosgraph
    rosgraph_msgs
    roslib
    std_msgs

A package can have quite a few indirect dependencies. Luckily rospack can recursively determine all nested dependencies.

$ rospack depends beginner_tutorials
cpp_common
rostime
roscpp_traits
roscpp_serialization
catkin
genmsg
genpy
message_runtime
gencpp
geneus
gennodejs
genlisp
message_generation
rosbuild
rosconsole
std_msgs
rosgraph_msgs
xmlrpcpp
roscpp
rosgraph
ros_environment
rospack
roslib
rospy

Customizing Your Package

This part of the tutorial will look at each file generated by catkin_create_pkg and describe, line by line, each component of those files and how you can customize them for your package.

Customizing the package.xml

The generated package.xml should be in your new package. Now lets go through the new package.xml and touch up any elements that need your attention.

description tag

First update the description tag:

   5   <description>The beginner_tutorials package</description>

Change the description to anything you like, but by convention the first sentence should be short while covering the scope of the package. If it is hard to describe the package in a single sentence then it might need to be broken up.

maintainer tags

Next comes the maintainer tag:

   7   <!-- One maintainer tag required, multiple allowed, one person per tag --> 
   8   <!-- Example:  -->
   9   <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  10   <maintainer email="user@todo.todo">user</maintainer>

This is a required and important tag for the package.xml because it lets others know who to contact about the package. At least one maintainer is required, but you can have many if you like. The name of the maintainer goes into the body of the tag, but there is also an email attribute that should be filled out:

   7   <maintainer email="you@yourdomain.tld">Your Name</maintainer>

license tags

Next is the license tag, which is also required:

  12   <!-- One license tag required, multiple allowed, one license per tag -->
  13   <!-- Commonly used license strings: -->
  14   <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  15   <license>TODO</license>

You should choose a license and fill it in here. Some common open source licenses are BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, and LGPLv3. You can read about several of these at the Open Source Initiative. For this tutorial we'll use the BSD license because the rest of the core ROS components use it already:

   8   <license>BSD</license>

dependencies tags

The next set of tags describe the dependencies of your package. The dependencies are split into build_depend, buildtool_depend, exec_depend, test_depend. For a more detailed explanation of these tags see the documentation about Catkin Dependencies. Since we passed std_msgs, roscpp, and rospy as arguments to catkin_create_pkg, the dependencies will look like this:

  27   <!-- The *_depend tags are used to specify dependencies -->
  28   <!-- Dependencies can be catkin packages or system dependencies -->
  29   <!-- Examples: -->
  30   <!-- Use build_depend for packages you need at compile time: -->
  31   <!--   <build_depend>genmsg</build_depend> -->
  32   <!-- Use buildtool_depend for build tool packages: -->
  33   <!--   <buildtool_depend>catkin</buildtool_depend> -->
  34   <!-- Use exec_depend for packages you need at runtime: -->
  35   <!--   <exec_depend>python-yaml</exec_depend> -->
  36   <!-- Use test_depend for packages you need only for testing: -->
  37   <!--   <test_depend>gtest</test_depend> -->
  38   <buildtool_depend>catkin</buildtool_depend>
  39   <build_depend>roscpp</build_depend>
  40   <build_depend>rospy</build_depend>
  41   <build_depend>std_msgs</build_depend>

All of our listed dependencies have been added as a build_depend for us, in addition to the default buildtool_depend on catkin. In this case we want all of our specified dependencies to be available at build and run time, so we'll add a exec_depend tag for each of them as well:

  12   <buildtool_depend>catkin</buildtool_depend>
  13 
  14   <build_depend>roscpp</build_depend>
  15   <build_depend>rospy</build_depend>
  16   <build_depend>std_msgs</build_depend>
  17 
  18   <exec_depend>roscpp</exec_depend>
  19   <exec_depend>rospy</exec_depend>
  20   <exec_depend>std_msgs</exec_depend>

Final package.xml

As you can see the final package.xml, without comments and unused tags, is much more concise:

   1 <?xml version="1.0"?>
   2 <package format="2">
   3   <name>beginner_tutorials</name>
   4   <version>0.1.0</version>
   5   <description>The beginner_tutorials package</description>
   6 
   7   <maintainer email="you@yourdomain.tld">Your Name</maintainer>
   8   <license>BSD</license>
   9   <url type="website">http://wiki.ros.org/beginner_tutorials</url>
  10   <author email="you@yourdomain.tld">Jane Doe</author>
  11 
  12   <buildtool_depend>catkin</buildtool_depend>
  13 
  14   <build_depend>roscpp</build_depend>
  15   <build_depend>rospy</build_depend>
  16   <build_depend>std_msgs</build_depend>
  17 
  18   <exec_depend>roscpp</exec_depend>
  19   <exec_depend>rospy</exec_depend>
  20   <exec_depend>std_msgs</exec_depend>
  21 
  22 </package>

Customizing the CMakeLists.txt

Now that the package.xml, which contains meta information, has been tailored to your package, you are ready to move on in the tutorials. The CMakeLists.txt file created by catkin_create_pkg will be covered in the later tutorials about building ROS code.

Now that you've made a new ROS package, let's build our ROS package.

Wiki: vn/ROS/Hướng dẫn/CreatingPackage (last edited 2017-03-30 07:36:11 by HoangGiang88)