Note: This tutorial assumes that you have completed the previous tutorials: Navegando pelo sistema de arquivos do ROS.
(!) 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.

Criando um Pacote ROS

Description: Este tutorial cobre a utilização de roscreate-pkg ou catkin para criar um novo pacote, e rospack para listar dependências de pacotes.

Tutorial Level: BEGINNER

Next Tutorial: Gerando um pacote ROS

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

Do que é feito um pacote catkin?

Para que um pacote seja considerado um pacote catkin, ele deve responder à alguns requerimentos:

  • O pacote deve conter um arquivo package.xml

    • O arquivo package.xml provê meta-informações sobre o pacote
  • O pacote deve conter uma CMakeLists.txt que use catkin.

  • Não pode haver mais de um pacote em cada diretório
    • Isso significa que múltiplos pacotes não podem ficar no mesmo diretório

O pacote mais simples possível poderia ser assim:

  • my_package/
      CMakeLists.txt
      package.xml

Pacotes em um espaço de trabalho catkin

O método recomendado para trabalhar com pacotes catkin é usando um espaço de trabalho catkin, mas você também pode criar pacotes catkin por fora. Um espaço de trabalho trivial poderia ser algo do tipo:

  • espaco_de_trabalho/      -- espaço de trabalho (workspace)
      src/                   -- espaço do código fonte
        CMakeLists.txt       -- arquivo CMake mais acima, provido pelo catkin
        pacote_1/
          CMakeLists.txt     -- arquivo CMake para pacote_1
          package.xml        -- manifesto para pacote_1
        ...
        pacote_n/
          CMakeLists.txt     -- arquivo CMake para pacote_n
          package.xml        -- manifesto para pacote_n

Antes de continuar com este tutorial, crie um espaço catkin vazio seguindo o tutorial sobre criar um espaço de trabalho catkin.

Criando um pacote catkin

Este tutorial vai mostrar como usar o script catkin_create_pkg para criar um novo pacote catkin, e o que você pode fazer com ele depois de ter sido criado.

Primeiro vá para o diretório de código fonte que você criou no tutorial Criando um espaço de trabalho catkin:

# Você já deveria ter criado este diretório no tutorial anterior
$ cd ~/catkin_ws/src

Agora use o script catkin_create_pkg para criar um novo pacote chamado beginner_tutorials, que depende de std_msgs, roscpp, e rospy:

$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

Isso vai criar uma pasta beginner_tutorials que contém os arquivos package.xml e CMakeLists.txt, que já foram parcialmente preenchidos com informações que você deu ao script catkin_create_pkg.

catkin_create_pkg pede que você dê um `nome_do_pacote' e opcionalmente uma lista de dependências para o pacote:

# Isso é um exemplo, não rode
# catkin_create_pkg <nome_do_pacote> [depende1] [depende2] [depende3]

catkin_create_pkg também tem funcionalidades mais avançadas que são descritas em catkin/commands/catkin_create_pkg.

Compilando o espaço catkin e usando o arquivo de setup

Agora você precisa compilar os pacotes no espaço de trabalho catkin:

$ cd ~/catkin_ws
$ catkin_make

Depois do espaço ter sido compilado, ele criou uma estrutura similar na subpasta devel, como geralmente encontrado em /opt/ros/$ROSDISTRO_NAME.

Para adicionar o espaço ao seu ambiente ROS você precisa "source" o arquivo setup gerado com o seguinte comando:

$ . ~/catkin_ws/devel/setup.bash

Dependências do pacote

Dependências de primeira ordem

Quando usamos catkin_create_pkg antes, algumas dependências foram fornecidas. Essas dependências de primeira ordem agora podem ser revisadas com a ferramenta rospack.

$ rospack depends1 beginner_tutorials
  • roscpp
    rospy
    std_msgs

Você pode ver que rospack lista as mesmas dependências que foram usadas como argumentos quando rodamos catkin_create_pkg. Essas dependências de pacote são guardadas no arquivo package.xml:

$ 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>

Dependências indiretas

Em muitos casos, uma dependência também vai ter suas próprias dependências. Por exemplo, rospy tem outras dependências.

$ rospack depends1 rospy
  • genpy
    roscpp
    rosgraph
    rosgraph_msgs
    roslib
    std_msgs

Um pacote pode ter várias dependências. Felizmente, rospack pode determinar recursivamente todas as dependências herdadas.

$ 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

Customizando seu pacote

Esta parte do tutorial vai examinar cada arquivo gerado por catkin_create_pkg e descrever, linha por linha, cada componente desses arquivos e como customizá-los para seu pacote.

Customizando package.xml

O arquivo package.xml gerado deve estar no seu novo pacote. Agora vamos ao novo package.xml e modificar os elementos que precisam de sua atenção.

tag description

Primeiro, atualize a tag:

   5   <description>The beginner_tutorials package</description>

Modifique a descrição para qualquer coisa que você goste, mas por convenção a primeira frase deve ser curta o bastante para abranger o escopo do pacote. Se for difícil descrever o pacote em uma simples frase então ela pode ser quebrada em mais frases.

tag maintainer

Em seguida, vem a tag maintainer:

   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>

Essa é uma tag obrigatória e importante para o package.xml porque ela permite que outras pessoas saibam com quem entrar em contato para saber mais sobre o pacote. Ao menos um mantenedor (maintainer) é necessário, mas se quiser você pode inserir quantos for necessário. O nome do mantenedor vai no corpo da tag, mas também tem um atributo de email que deve ser preenchido:

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

tag license

Próximo é a tag license, que também é obrigatória:

  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>

Você deve escolher uma licença e inseri-la aqui. Algumas licenças comuns são BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, and LGPLv3. Você pode ler sobre algumas delas em Open Source Initiative. Para este tutorial iremos usar a licença BSD porque o restante dos componentes do ROS já utiliza ela:

   8   <license>BSD</license>

tags dependencies

O próximo conjunto de tags descreve as dependências do seu pacote. As dependências são dividas em build_depend, buildtool_depend, exec_depend, test_depend. Para uma explicação mais detalhadas destas tags, veja a documentação Dependências Catkin. Como passamos std_msgs, roscpp, and rospy como argumentos para catkin_create_pkg, as dependências terão essa aparência:

  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>

Todas as nossas dependências listadas foram adicionadas como build_depend, além do padrão buildtool_depend para catkin. Nesse caso, queremos que todas as nossas dependências especificadas estejam disponíveis no tempo de compilação e execução, portanto adicionaremos a tag exec_depend para cada um delas também:

  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

Como você pode ver o package.xml final, sem comentários e sem tags não utilizadas, é muito mais conciso:

   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>

Customizando o CMakeLists.txt

Agora que o package.xml, que contém meta-informação, foi adaptado para o seu pacote, você está pronto para seguir em frente nos tutoriais. O arquivo CMakeLists.txt criado no tutorial catkin_create_pkg será abordado nos próximos tutoriais sobre compilação dos códigos do ROS.

Agora que você já criou um novo pacote ROS, vamos Montar (build) nosso pacote.

Wiki: pt_BR/ROS/Tutorials/CreatingPackage (last edited 2020-04-18 23:08:59 by MateusMenezes)