ROSチュートリアル第五回 - catkinのパッケージをコンパイルしてみる


## catkinのレポジトリを追加する
[前回](http://qiita.com/garaemon/items/e5554d6c03a7d475a682)catkinのワークスペースを`$HOME/ros_catkin_ws/hydro`に作成しました。
ここにソースコードを追加してみます。

今回は[garaemon-catkin-sample-pkg](https://github.com/garaemon/garaemon-catkin-sample-pkg)というレポジトリを追加してみます。中には簡単なサンプルが入っているだけです。

```sh
$ cd ~/ros_catkin_ws/hydro/src
$ wstool set --git garaemon-catkin-sample-pkg https://github.com/garaemon/garaemon-catkin-sample-pkg.git
$ wstool update
```

[`wstool`](http://wiki.ros.org/wstool)というのはcatkinのワークスペース、つまり`$HOME/ros_catkin_ws/hydro/src`を色々といじるときに使うコマンドです。

```sh
$ wstool -h                                                                                                                                                                                                                                                                                                                       
wstool is a command to manipulate ROS workspaces. wstool replaces its predecessor wstool.

Official usage:
  wstool CMD [ARGS] [OPTIONS]

wstool will try to infer install path from context

Type 'wstool help' for usage.

help            provide help for commands
init            set up a directory as workspace

set             add or changes one entry from your workspace config
merge           merges your workspace with another config set
remove (rm)     remove an entry from your workspace config, without deleting files

update (up)     update or check out some of your config elements

info            Overview of some entries
status (st)     print the change status of files in some SCM controlled entries
diff (di)       print a diff over some SCM controlled entries
```

`wstool set`はワークスペースに新しくレポジトリを追加するときのコマンドになっています。

なので、

```sh
$ wstool set --git garaemon-catkin-sample-pkg https://github.com/garaemon/garaemon-catkin-sample-pkg.git
```

はローカルでは`garaemon-catkin-sample-pkg`という名前のディレクトリで`https://github.com/garaemon/garaemon-catkin-sample-pkg.git`をとってきてください、ちなみにgitですという意味です。


`wstool set`をしただけではまだコードはcloneされていません。そのためには`wstool update`を走らせる必要があります。
これは、ワークスペースに`wstool set`で追加したレポジトリを全部アップデートしてくれ、というコマンドです。

パッケージが追加されたことを確認してみましょう

```sh
$ ls ~/ros_catkin_ws/hydro/src
CMakeLists.txt garaemon-catkin-sample-pkg
$ rospack find catkin_roscpp_sample
/home/username/ros_catkin_ws/hydro/src/garaemon-catkin-sample-pkg/catkin_roscpp_sample
```

ここで[`rospack`](http://wiki.ros.org/rospack)という新しいコマンドが出てきました。`rospack`はROSのパッケージに関する情報を提供するためのコマンドです。例えば、

```sh
$ rospack list
actionlib /opt/ros/hydro/share/actionlib
actionlib_msgs /opt/ros/hydro/share/actionlib_msgs
actionlib_tutorials /opt/ros/hydro/share/actionlib_tutorials
(中略)
voxel_grid /opt/ros/hydro/share/voxel_grid
xacro /opt/ros/hydro/share/xacro
xmlrpcpp /opt/ros/hydro/share/xmlrpcpp
```

`rospack list`コマンドを使うとパッケージの一覧が見えます。
`rospack find`はパッケージのパスを返します。

## catkinのパッケージをコンパイルする
`catkin_make`というコマンドを使います

```sh
$ cd ~/ros_catkin_ws/hydro
$ catkin_make
```

`catkin_make`を実行するディレクトリに注意してください。`wstool`は`~/ros_catkin_ws/hydro/src`以下で使いましたが、これはその一つ上です。

`catkin_make`を実行すると`src`ディレクトリと並列に`build`, `devel`というディレクトリが出来ます。

```sh
$ ls ~/ros_catkin_ws/hydro
build  devel  src
```

この`devel`というディレクトリの中にコンパイルしてできたライブラリやバイナリが置かれます。

## コンパイルしてできたサンプルを実行する

今回チェックアウトしたレポジトリには`catkin_roscpp_sample`とういパッケージが有ります。
これには二つのノードの間でtopicを利用した通信を行う最低限のサンプルが含まれています。
これを実行しましょう。

まず一つ目のターミナルで

```sh
$ roscore
```

と実行します。
２つ目のターミナルで

```sh
$ rosrun catkin_roscpp_sample hello_publisher
```
と実行します

最後に3つめのターミナルで

```sh
$ rosrun catkin_roscpp_sample hello_subscriber
```

と実行します。

そうすると3つめのターミナルに以下の様な出力が出るはずです

```sh
$ rosrun catkin_roscpp_sample hello_subscriber
[ INFO] [1390899414.971967414]: subscriber get message: Hello World!!
[ INFO] [1390899414.982323544]: subscriber get message: Hello World!!
[ INFO] [1390899414.992567862]: subscriber get message: Hello World!!
[ INFO] [1390899415.001686398]: subscriber get message: Hello World!!
[ INFO] [1390899415.011823428]: subscriber get message: Hello World!!
[ INFO] [1390899415.021833998]: subscriber get message: Hello World!!
...
```

ちなみに、プログラムを止めるには`Ctrl-C`をしてください。ROSのプログラムは基本的に`Ctrl-C`で止めます。

ここでは二つ新しいコマンドが出てきています, [`roscore`](http://wiki.ros.org/roscore)と[`rosrun`](http://wiki.ros.org/rosbash#rosrun)です

[`roscore`](http://wiki.ros.org/roscore)はROSの通信を管理してくれるマスターです。必ず立ち上げる必要があります。
一つのroscoreが一つのROSネットワークを作ります。

[`rosrun`](http://wiki.ros.org/rosbash#rosrun)はいわば便利スクリプトです。
`rosrun package executable`で`package`というパッケージに含まれる`executable`を実行してくれという意味です。

つまり、`rosrun catkin_roscpp_sample hello_publisher`, `rosrun catkin_roscpp_sample hello_subscriber`の二つは`catkin_roscpp_sample`パッケージの`hello_publisher`と`hello_subscriber`という二つの実行ファイルを実行してくれ、という意味です。

しかし、いちいちプロセスを一つ一つあげていたのでは面倒です。そのため、複数のプロセスをまとめて立ち上げるためのコマンドが用意されています。

## roslaunchでサンプルを実行する
複数のプロセスを一気に立ち上げるには[`roslaunch`](http://wiki.ros.org/roslaunch)というのを利用します。先ほど立ち上げたプログラムを全て終了した後に

```sh
$ roslaunch catkin_roscpp_sample sample.launch
```
と実行すると同じように`Hello World`という文字列がターミナルに見えます。


`roslaunch`はlaunchファイルと呼ばれるxmlにどのようなプロセスを立ち上げるかとずらーっと書いておいて、それでまとめてプロセスを立ち上げるコマンドです。

`sample.launch`の中身を見てみましょう

```sh
$ roscd catkin_roscpp_sample
$ less launch/sample.launch
<launch>
  <node pkg="catkin_roscpp_sample"
        type="hello_publisher"
        name="publisher"
        output="screen">
  </node>
  <node pkg="catkin_roscpp_sample"
        type="hello_subscriber"
        name="subscriber"
        output="screen">
  </node>
</launch>
```

`<node>`タグによって、立ち上げるプロセスを指定しています。`pkg`属性によって実行ファイルが含まれるパッケージ、`type`属性は実行ファイルの名前, `name`属性はROSのネットワークにおける名前、`output`属性は標準出力をどこにPIPEするかを指定しています。

さりげなく登場してる[`roscd`](http://wiki.ros.org/rosbash#roscd)というコマンドはとても便利です。`roscd package`で`package`にcdするということです。
この系統のrosコマンドは、tab補完が効くので便利です。

サンプルの細かい中身は今後見ていきます。

## まとめ
* `wstool`はcatkinのワークスペースをいじるコマンド
* `catkin_make`はcatkinのパッケージをコンパイルする
* `roscore`はネットワークのマスター
* `rospack`はパッケージの情報を見るコマンド
* `rosrun`は実行ファイルを実行するためのコマンド
* `roslaunch`はlaunchファイルでまとめてプロセスを立ち上げる。
* `roscd`はパッケージにcdする
* `Ctrl-C`でROSのプログラムは終了させる