ROS Tutorialを追いながらのまとめメモ②【Creating Package】

※IndigoをUbuntu上にインストールし、catkinを利用している前提のメモ ROSは初心者なので、認識が間違っていたらご容赦を

##catkinのパッケージを作成するときに必要なもの/条件
* catkinの規約に準拠したマニフェストファイルであるpackage.xmlが含まれていること。
* catkinによって利用されるCMakeLists.txtファイルが含まれていること。CMakeListsはCMakeでコンパイルをかける際の設定が記述されているファイル。
* 複数のパッケージをまとめて一つの論理的なパッケージとして扱う場合、catkinのmetapackagesの仕組みを使うが、この場合、CMakeListsのひな形が定義
されている必要がある。
* 一つのフォルダが必ず一つのパッケージとなっていること。パッケージのネストや同じフォルダに複数のパッケージが存在していてはいけない。

##catkin workspaceを利用したパッケージの作成
* catkinでパッケージを作成する場合、個々のパッケージを単独のプロジェクトとして個別にビルドする（standalone）こともできるが、依存関係のある
パッケージが複数ある場合は、それらをまとめて一つのプロジェクトとしてビルドすることができる。その場合にworkspaceを利用する。
* workspaceの基本的な構成は以下のような形。

```
workspace/            --任意のworkspace名で作成
  src/                --workspaceに含める各パッケージのソースを配置
    CMakeLists.txt    --トップレベルのCMakeListsファイル
    package_1/        --各パッケージ毎のソース配置ディレクトリ
      CMakeLists.txt  --各パッケージ毎のビルドに必要なCMakeListsファイル
      package.xml     --各パッケージ毎のメタ情報が含まれるマニフェストファイル
      
         ・
         ・
         ・
    package_n/        
      CMakeLists.txt  
      package.xml     
   build/             --ビルド時に利用するディレクトリ
   devel/             --CMakeのCATKIN_DEVEL_PREFIXで指定される開発版のディレクトリ
      bin/            --その他のディレクトリはLinuxなどでは一般的な使い分けがされているのと同等（bin,etc,libなど）
      etc/
      include/
      lib/
      share/
      .catkin
      env.bash
      setup.bash
      setup.sh
   install/           --CMakeのCMAKE_INSTALL_PREFIXで指定されるインストール版のディレクトリ
      bin/
      etc/
      include/
      lib/
      share/
      .catkin
      env.bash
      setup.bash
      setup.sh
      
```

##catkinでの具体的なパッケージの作成
* workspaceは事前に作成しておく。(workspaceの作成方法詳細はTutorialの別項目であるcreate_a_workspaceに記載)

```shell-session
$ mkdir -p ~/projects/spike/ROS/catkin_ws/src   #任意のディレクトリにsrcディレクトリまで作っておく
$ cd ~/projects/spike/ROS/catkin_ws/src         #作成したsrcディレクトリに移動
$ catkin_init_workspace                         #workspaceの初期化コマンドであるcatkin_ini_workspaceコマンドを実行
```

* 上記まで実行して、トップレベルのCMakeListsファイルがsrc下に生成されていることを確認
* workspaceのトップディレクトリまで戻って、この空の状態で一度catkin_makeを実行し、その他のディレクトリと作成するパッケージを環境変数に追加するためのスクリプトを生成する

```shell-session
$ cd ~/projects/spike/ROS/catkin_ws
$ catkin_make
Base path: /home/xxxx/projects/spike/ROS/catkin_ws
Source space: /home/xxxx/projects/spike/ROS/catkin_ws/src
Build space: /home/xxxx/projects/spike/ROS/catkin_ws/build
Devel space: /home/xxxx/projects/spike/ROS/catkin_ws/devel
Install space: /home/xxxx/projects/spike/ROS/catkin_ws/install
####
#### Running command: "cmake /home/xxxx/projects/spike/ROS/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/xxxx/projects/spike/ROS/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/xxxx/projects/spike/ROS/catkin_ws/install -G Unix Makefile
s" in "/home/xxxx/projects/spike/ROS/catkin_ws/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/xxxx/projects/spike/ROS/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/indigo
-- This workspace overlays: /opt/ros/indigo
-- Found PythonInterp: /home/xxxx/.pyenv/shims/python (found version "2.7.6") 
-- Using PYTHON_EXECUTABLE: /home/xxxx/.pyenv/shims/python
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/xxxx/projects/spike/ROS/catkin_ws/build/test_results
-- Found gtest sources under '/usr/src/gtest': gtests will be built
-- Using Python nosetests: /usr/bin/nosetests
-- catkin 0.6.11
-- BUILD_SHARED_LIBS is on
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xxxx/projects/spike/ROS/catkin_ws/build
####
#### Running command: "make -j6 -l6" in "/home/xxxx/projects/spike/ROS/catkin_ws/build"
####
```

* buildとdevelのディレクトリが作成され、devel下にsetup.*が生成されていることを確認できたら、生成されたsetup.*を使ってROS_PACKAGE_PATHに今回作成するパッケージのパスを追加しておく。

```shell-session
$ source devel/setup.bash
```

* ここまででworkspaceが作られた状態なので、src以下に個々のパッケージを作成する
* パッケージの作成はcatkin_create_pkgコマンドを使って行う
* あらかじめsrc以下まで移動しておいて、catkin_create_pkgに作成したいパッケージ名、依存関係のあるパッケージ名を引数に渡して実行

```shell-session
$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp 
Created file beginner_tutorials/CMakeLists.txt
Created file beginner_tutorials/package.xml
Created folder beginner_tutorials/include/beginner_tutorials
Created folder beginner_tutorials/src
Successfully created files in /home/xxxx/projects/spike/ROS/catkin_ws/src/beginner_tutorials. Please adjust the values in package.xml.
```

* 上記実行後にbeginner_tutorialsパッケージのディレクトリが作成されたことと、配下にCMakefileと指定した依存関係が記述済のpackage.xmlが生成されていることを確認。

* パッケージの作成が済んだら、workspaceのルートディレクトリまで移動して、もう一度catkin_makeを実行する

```shell-session
Base path: /home/xxxx/projects/spike/ROS/catkin_ws
Source space: /home/xxxx/projects/spike/ROS/catkin_ws/src
Build space: /home/xxxx/projects/spike/ROS/catkin_ws/build
Devel space: /home/xxxx/projects/spike/ROS/catkin_ws/devel
Install space: /home/xxxx/projects/spike/ROS/catkin_ws/install
####
#### Running command: "cmake /home//projects/spike/ROS/catkin_ws/src -DCATKIN_DEVEL_PREFIX=/home/xxxx/projects/spike/ROS/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/xxxx/projects/spike/ROS/catkin_ws/install -G Unix Makefiles" in "/home/t
ie300657/projects/spike/ROS/catkin_ws/build"
####
-- Using CATKIN_DEVEL_PREFIX: /home/xxxx/projects/spike/ROS/catkin_ws/devel
-- Using CMAKE_PREFIX_PATH: /opt/ros/indigo
-- This workspace overlays: /opt/ros/indigo
-- Using PYTHON_EXECUTABLE: /usr/bin/python
-- Using Debian Python package layout
-- Using empy: /usr/bin/empy
-- Using CATKIN_ENABLE_TESTING: ON
-- Call enable_testing()
-- Using CATKIN_TEST_RESULTS_DIR: /home/xxxx/projects/spike/ROS/catkin_ws/build/test_results
-- Found gtest sources under '/usr/src/gtest': gtests will be built
-- Using Python nosetests: /usr/bin/nosetests-2.7
-- catkin 0.6.11
-- BUILD_SHARED_LIBS is on
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- ~~  traversing 1 packages in topological order:
-- ~~  - beginner_tutorials
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-- +++ processing catkin package: 'beginner_tutorials'
-- ==> add_subdirectory(beginner_tutorials)
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xxxx/projects/spike/ROS/catkin_ws/build
####
#### Running command: "make -j6 -l6" in "/home/xxxx/projects/spike/ROS/catkin_ws/build"
####
```

* 実行ログをみると先ほど作成したbeginner_tutorialsパッケージが追加された状態で諸般コンフィグが生成されているので、再度setup.
*を実行して追加されたパッケージも含めたパスを通しておく

##パッケージの依存関係の確認

* パッケージの依存関係はrospackで確認できる
* 以下を実行するとcatkin_create_pkgで指定していた依存パッケージでpackage.xmlに記述されたパッケージのリストを表示できる

```shell-session
$ rospack depends1 beginner_tutorials
```

* 第１引数のdepends1はパッケージから直接参照されている依存ファイル（パッケージから見て参照順の最初にくるもの）を表示するオプション
* 依存しているパッケージがさらに依存しているパッケージについては、同じオプションで該当のパッケージ名を指定して実行すればよい

```shell-session
$ rospack depends1 rospy
genpy
roscpp
rosgraph
rosgraph_msgs
roslib
std_msgs
```

* 関連する依存パッケージ全てを表示する場合は、オプションとしてdependsを指定して実行

```shell-session
$ rospack depends beginner_tutorials
cpp_common
rostime
roscpp_traits
roscpp_serialization
genmsg
genpy
message_runtime
catkin
gencpp
genlisp
message_generation
rosbuild
rosconsole
std_msgs
rosgraph_msgs
xmlrpcpp
roscpp
rosgraph
rospack
roslib
rospy
```

##パッケージのカスタマイズ
* catkin_create_pkgコマンドで自動生成されたpackage.xmlはデフォルト値のままなので、それぞれ必要な項目を変更する
* チュートリアルで解説されているタグはそれぞれ以下の通り
    * description tag: パッケージの簡潔な説明を記述するタグ。デフォルトでは、パッケージ名が記載されている。
    * maintainer tags: パッケージメンテナを記述するタグ。複数人いる場合は追加記載する。
    * license tags: 公開時に適用するオープンソースライセンスを記載する。BSD、GPL、MITなど一般的なライセンスを指定。
    * dependencies tags: 依存パッケージを記載する。パッケージ作成時に指定したもの以外を追加する場合には追記。依存の適用範囲によって以下のタグを使い分ける。
        * buildtool_depend: パッケージをビルドする際に利用するビルドツールを指定。通常はcatkin。
        * build_depend: パッケージをビルドする際に依存するパッケージを指定。
        * run_depend: 実行時に依存するパッケージ、もしくはパッケージで利用されるシェアードライブラリなどをビルドする際に記載。
        * test_depend: ユニットテスト実行時に依存するパッケージを記載。build_dependとrun_dependにすでに記載されているものを重複して書いてはいけない。