(訳注:最新の情報は原文を参照してください.)

Note: This tutorial assumes that you have completed the previous tutorials: 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.

ROSパッケージを作る

Description: このチュートリアルでは,roscreate-pkgやcatkin_create_pkgで新しいパッケージを作る方法やパッケージの依存関係を表示するrospackの使い方を学びます.

Tutorial Level: BEGINNER

Next Tutorial: ROSのパッケージをビルドする

catkinパッケージの必須要素

ROSのcatkin形式のパッケージとしてパッケージを作るには、以下の必要条件を満たす必要があります:

  • パッケージは catkin compliant package.xmllファイルを含むこと

    • package.xmlファイルは、該当パッケージに関するメタ情報を提供します
  • catkinのパッケージはCMakeLists.txtを含まなければならない。Catkin メタパッケージは定型のCMakeLists.txtを保持していなければならない。

  • 1つのフォルダに1つのパッケージだけを構成する
    • これは入れ子状のネストしたパッケージや複数のパッケージが同じディレクトリを共有することが無いという意味です。

もっとも単純なパッケージの構成として可能なのは以下のようなディレクトリになります:

  • my_package/
      CMakeLists.txt
      package.xml

catkinワークスペース内のパッケージ群

catkinパッケージでの作業で推奨されるのはcatkin ワークスペースを使う方法ですが、スタンドアローン(standalone)でcatkinパッケージをビルドすることもできます。よくあるワークスペースは以下のようなものです:

  • workspace_folder/        -- ワークスペース
      src/                   -- ソース領域
        CMakeLists.txt       -- catkinから供給された最上位位置のCMakeファイル
        package_1/
          CMakeLists.txt     -- package_1用のCMakeLists.txtファイル
          package.xml        -- package_1用のパッケージマニフェスト
        ...
        package_n/
          CMakeLists.txt     -- package_n用のCMakeLists.txtファイル
          package.xml        -- Package manifest for package_n

このチュートリアルを続けて進める前に、Creating a workspace for catkinのチュートリアルに従って、空のcatkinワークスペースを作っておきましょう。

catkin形式のパッケージを作る

このチュートリアルは、新しくcatkinパッケージを作るためにcatkin_create_pkgスクリプトをどうやって使うか、そしてパッケージを作った後、それで何が出来るようになるかについて説明します。

まず、Creating a Workspace for catkin tutorialで作ったcatkinワークスペースのソースディレクトリに移動しましょう:

# このワークスペースはthe Creating a Workspace Tutorialで作成済みのはずです
$ cd ~/catkin_ws/src

ここでstd_msgs, roscpp, rospyに依存した新しいパッケージを'beginner_tutorials'という名前で作るために、catkin_create_pkgのスクリプトを使います:

$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp

これでcatkin_create_pkgに添えた情報を元に部分的に記述を補完したpackage.xmlCMakeLists.txtを含んだbeginner_tutorialsフォルダを作っています。

catkin_create_pkgpackage_nameとそのパッケージが依存するライブラリのリストを要求します。

# これは例です。このままで実行しないこと。
# catkin_create_pkg <package_name> [depend1] [depend2] [depend3]

catkin_create_pkgにはより高度な機能があり、詳細はcatkin/commands/catkin_create_pkgにあります。

パッケージの依存

First-order依存

前項で出てきたcatkin_create_pkgを使う時、いくつかの依存パッケージを指定しました。 これらのfirst-order依存(直接的な依存)について、rospackコマンドツールを使って紐解くことができます。

(Jan 9, 2013) バグが報告されており, 既にgroovyのrospackでは修正されているが, コンピュータ上に変更が反映されるまで少し時間がかかるでしょう. もしこれと似たような問題が次のコマンドによって現れる場合は, 次のコマンドを省略することができます.

$ rospack depends1 beginner_tutorials 
  • std_msgs
    rospy
    roscpp

上のように、rospackcatkin_create_pkgを実行した時の引数と同じものを、依存パッケージのリストとして羅列しているのがわかります。 作成したパッケージへの依存についてはpackage.xmlに記述されています。package.xmlの中身を確かめてみましょう:

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

間接的依存

多くの場合、依存関係は依存パッケージのそれぞれの依存についても保持しています。たとえば、rospyは他のパッケージへの依存があります。

(Jan 9, 2013) バグが報告されており, 既にgroovyのrospackでは修正されているが, コンピュータ上に変更が反映されるまで少し時間がかかるでしょう. もしこれと似たような問題が次のコマンドによって現れる場合は, 次のコマンドを省略することができます.

$ rospack depends1 rospy
  • genpy
    rosgraph
    rosgraph_msgs
    roslib
    std_msgs

パッケージは極めて多くの間接的な依存を保持できます。幸いにもrospackは全てのネストされた依存を再帰的に特定することができます。

$ rospack depends beginner_tutorials
cpp_common
rostime
roscpp_traits
roscpp_serialization
genmsg
genpy
message_runtime
rosconsole
std_msgs
rosgraph_msgs
xmlrpcpp
roscpp
rosgraph
catkin
rospack
roslib
rospy

自分のパッケージをカスタマイズする

この項ではcatkin_create_pkgで生成されたそれぞれのファイルを、ファイルの要素の各行ごとに見ていきます。そして自分のパッケージでどうやってそれらをカスタマイズするのかについて説明します。

package.xmlをカスタマイズする

生成されたpackage.xmlが自分の新しいパッケージの中にあるはずです。そして、package.xmlを確認し、注視すべきタグにそれぞれ触れていきましょう。

descriptionタグ

まずdescriptionタグを更新します:

   5   <description>The beginner_tutorials package</description>

description部分を自由に変更しますが、パッケージのスコープがあたっている限りは、慣例的に、最初の文は短くしなければなりません。 一文でパッケージの説明を記述するのが難しい時は、分けて書く必要があるでしょう。

maintainerタグ

次は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>

このmaintainerタグはpackage.xmlで必須で重要なタグです。このタグがあることで、このパッケージについて誰にコンタクトを取ればいいのかをパッケージ利用者が知ることができるからです。少なくとも1人のメンテナを記述するのが必須ですが、複数人設定することもできます。メンテナの名前はタグのbodyに設定しますが、emailのタグ属性もあり、ここにemailを設定しなければなりません。

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

licenseタグ

続いてlicenseタグです。これも以下のような要件があります:

  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>

ライセンス形態を選んで、licenseタグに設定しなければなりません。一般的なオープンソースライセンスはSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3といったものです。これらのいくつかについて、Open Source Initiativeで詳細を読むことができます。このチュートリアルではBSDライセンスを使っていきます。ROSのコアコンポーネント群が以下のようにBSDを使っているからです:

   8   <license>BSD</license>

dependenciesタグ

このタグのセットはパッケージの依存についてについて記述します。dependenciesタグはbuild_depend, buildtool_depend, run_depend, test_dependに分けられています。これらのタグについてのより詳細な説明は、Catkin Dependenciesのドキュメントを参照してください。catkin_create_pkgの引数にstd_msgs, roscpp, rospyを渡したので、このパッケージの依存関係は以下のように見えているでしょう:

  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 run_depend for packages you need at runtime: -->
  35   <!--   <run_depend>python-yaml</run_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>

catkinのデフォルトbuildtool_dependに加えて、自パッケージ用に列記したすべての依存関係はbuild_dependとして追加されています。この場合、指定したパッケージ依存の全てがビルドおよび実行時に利用可能としたいので、それぞれのパッケージついてrun_dependタグを同様に追加しておきます:

  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   <run_depend>roscpp</run_depend>
  19   <run_depend>rospy</run_depend>
  20   <run_depend>std_msgs</run_depend>

最終版のpackage.xml

コメントや未使用タグを除いた、最終版のpackage.xmlは、ずっと簡潔なものになります。

   1 <?xml version="1.0"?>
   2 <package>
   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   <run_depend>roscpp</run_depend>
  19   <run_depend>rospy</run_depend>
  20   <run_depend>std_msgs</run_depend>
  21 
  22 </package>

CMakeLists.txtをカスタマイズする

ここまでで、メタ情報を含んでいるpackage.xmlを自分のパッケージ用に仕立て上げたので、次のチュートリアルに進む準備が出来ました。 catkin_create_pkg によって作られたCMakeLists.txtファイルについては、後に出てくる、ROSコードのビルドに関するチュートリアルで扱います。

ROS パッケージの作成

roscreate の使い方

パッケージを作成する前に roscreate-pkg コマンドラインツールがどのような働きをするのか見てみましょう.ここでは新規に ROS パッケージを作成します.全ての ROS パッケージは manifestsCMakeLists.txt・mainpage.dox・Makefile といった多くの似通ったファイル群で構成されています.roscreate-pkg は手作業で行うパッケージ新規作成において多くの退屈な手間を軽減します.また,ファイルやマニフェストを手作業で作成する上でよくある間違いを防ぎます.

新しいパッケージを現在のディレクトリで作成します:

$ roscreate-pkg [package_name]

パッケージの依存関係についても指定します:

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

あたらしく ROS パッケージを作成する

ここでは ros_tutorials ディレクトリに入って,beginner_tutorials パッケージを作成します.これには一般的な ROS パッケージである std_msgsroscpprospy と関連させます.

まず、~/fuerte_workspace/sandboxに行きます。

$ cd ~/fuerte_workspace/sandbox

もし代わりにfuerteかそれ以降のディストリビューションを使っているなら、単に以下のようにします。

$ roscd
$ cd sandbox

もしsandboxがない場合は、

mkdir sandbox

をして、再度行ってください。

次に以下のように入力してください。

$ roscreate-pkg beginner_tutorials std_msgs rospy roscpp

このように表示されます:

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

あなたは beginner_tutorials/manifest.xml を読みたくなるでしょう.マニフェストはパッケージがどのようにビルドされ・起動し・文書化されるかを定義するという ROS の中で重要な役割を持っています.

さて、ROSが新しく作ったパッケージを見つけることを確認しましょう。新しいディレクトリが発見されるように、新しいパッケージを作った際には、rospack profileを呼ぶのが便利です。

$ rospack profile
$ rospack find beginner_tutorials
  • YOUR_PACKAGE_PATH/beginner_tutorials

もしこれが失敗しているなら、ROS_PACKAGE_PATHに設定が足りなかったためにあなたの新しいパッケージを見つけられなかったと思われます。どのようにインストールしたかでsvnかbinaryから再度インストールの手順を確認してください。もし、現存するROS_PACKAGE_PATHの中にあるパスの中に作ってない場合は、新しいそのディレクトリをROS_PACKAGE_PATHの環境変数に加える必要があります。setup.shをroscdで移動するディレクトリで行ってください。

以下もmkdirを行ったディレクトリに移って、以下を打ってみてください。

$ export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:`pwd`/sandbox

パッケージのディレクトリに移動してみます.

$ roscd beginner_tutorials 
$ pwd
  • YOUR_PACKAGE_PATH/beginner_tutorials

先頭のパッケージの依存関係について

初期に roscreate-pkg を使うとき,少々のパッケージの依存関係が提供されています.

これらの先頭の依存関係は rospack ツールで見ることができます.

$ rospack depends1 beginner_tutorials 
  • std_msgs
    rospy
    roscpp

ここで見られるように,rospackroscreate-pkg を起動するときに使用する引数と同じ依存関係をリスト化します. これらのパッケージの依存関係はマニフェストファイルに補完されます.マニフェストファイルを見てみましょう.

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

間接的なパッケージの依存関係について

多くの場合,1つの依存関係はそれ自身が依存関係を持っています.例を挙げると,rospy は他の依存関係を持っています.

$ rospack depends1 rospy
  • roslib
    roslang

1つのパッケージは間接的な依存関係を持つことができます.幸運なことに rospack は全ての絡み合った依存関係を再帰的に決定することができます.

$ rospack depends beginner_tutorials
  • std_msgs
    roslang
    rospy
    roscpp

ROS クライアント ライブラリ

先ほどの例が rospyroscpp に依存していることが分かるでしょう.rospyroscppROS クライアント ライブラリです.クライアント ライブラリは ROS を通じて他のプログラミング言語とやりとりすることを可能にします.rospy は Python のためのクライアント ライブラリで,roscpp は C++ のためのクライアント ライブラリです.

ここであなたは新しい ROS パッケージを作成しました.次は ROS パッケージをビルドしてみましょう.

roscreate-pkg の周辺

roscreate-pkg が失敗したら,その理由はもしかして同一のディレクトリを2度作成しようとしているのかもしれません.これに対処するには, "roscreate" パッケージ内の "roscreatepkg.py" を編集する必要があります:

$ rosed roscreate roscreatepkg.py

75行目において,同じディレクトリを2度に作成しないようにチェックするようにします.

<<<<<< Old: 
  73    if uses_rospy:
  74        # create package/src/ for python files
  75        py_path = os.path.join(p, 'src')
  76        print "Creating python source directory", py_path
  77        os.makedirs(py_path)
>>>>>> New: 
  73    if uses_rospy:
  74        # create package/src/ for python files
  75        py_path = os.path.join(p, 'src')
  76        if not os.path.exists(py_path):
  77            print "Creating python source directory", py_path
  78            os.makedirs(py_path)

一度このファイルを保存したら,以下のようになっていることでしょう:

$ rm -rf beginner_tutorials/
$ roscreate-pkg beginner_tutorials std_msgs rospy roscpp
Creating package directory ~/ros/ros_tutorials/beginner_tutorials
Creating include directory ~/ros/ros_tutorials/beginner_tutorials/include/
beginner_tutorials
Creating cpp source directory ~/ros/ros_tutorials/beginner_tutorials/src
Creating python source directory ~/ros/ros_tutorials/beginner_tutorials/src/
beginner_tutorials
Creating package file ~/ros/ros_tutorials/beginner_tutorials/Makefile
Creating package file ~/ros/ros_tutorials/beginner_tutorials/manifest.xml
Creating package file ~/ros/ros_tutorials/beginner_tutorials/CMakeLists.txt
Creating package file ~/ros/ros_tutorials/beginner_tutorials/mainpage.dox

Please edit beginner_tutorials/manifest.xml and mainpage.dox to finish creating 
your package.

Review

今まで使用してきたコマンドのいくつかをリストにしましょう。

  • roscreate-pkg = ros+create-pkg : ROSのパッケージを作るのに必要なファイルをすべて生成します。
  • rospack = ros+pack(age) : ROSのパッケージに関係する情報を提供します。
  • rosstack = ros+stack : ROSのスタックに関係する情報を提供します。

これで新規ROSパッケージを作ることが出来ました。次はROSパッケージのビルドに進みましょう.

Wiki: ja/ROS/Tutorials/CreatingPackage (last edited 2015-10-13 13:16:50 by s_ktr)