【ROS】C++のパッケージを自作する

#この記事は
ROSを使い始めて、自分でパッケージを作りたくなった人向けです。
ROSのパッケージ作成についてはいくつか記事がありますが、この記事はできるだけ最低限度の構成で説明多めで記述をしています。初学者の助けになれば幸いです。

#環境
Ubuntu 16.04
ROS kinetic

#始める前に
catkin_wsのようなROSのワークスペースを作っておいてください。
以下では、ホームディレクトリ直下にcatkin_wsがあるという前提で記述していきます。

また、説明で{}で囲まれた部分は自分で名前を決めるところです。あとから見てもわかりやすく、覚えやすい名前をつけましょう。

#手順

##step 1. パッケージの作成

以下のようなコマンドを打ちます。

```terminal:説明
$ cd ~/catkin_ws/src
$ catkin_create_pkg {パッケージ名} roscpp std_msgs {その他必要なライブラリ}
```


```terminal:コマンド例
$ cd ~/catkin_ws/src
$ catkin_create_pkg hoge_package roscpp std_msgs
```

roscppとstd_msgsはROSのパッケージを作る上で必要不可欠なライブラリです。他にも必要なライブラリがあればcatkin_create_pkg の最後に追記してから実行してください。
なお、ここでライブラリを追加するのを忘れても、後からCMakeLists.txtというところで追加することができます(step 3 の最後で説明。(補足1))。


```terminal:他のライブラリを追加する場合
$ catkin_create_pkg hoge_package roscpp std_msgs sensor_msgs
```


##step 2. コードを書く

以下のように移動した後、パッケージのノードの本体となるコードを書いていきます。今回は、端末からgeditで新規作成していますが、GUIでディレクトリを開いた後に新しいドキュメントを作成する方法でも構いません。

```terminal:説明
$　cd ~/catkin_ws/src/{さっき作ったパッケージ名}/src
$　gedit {ファイル名}.cpp
```

```terminal:コマンド例
$　cd ~/catkin_ws/src/hoge_package/src
$　gedit fuga.cpp
```

念の為、とても簡単なノードのプログラム例を載せておきます。

```cpp:fuga.cpp
#include <ros/ros.h>

int main(int argc, char **argv)
{
  ros::init(argc, argv, "fuga_node");
  ros::NodeHandle nh;

  ros::Rate rate(10);
  while(ros::ok()){
    ROS_INFO_STREAM("fuga!");
    rate.sleep();
  }
  return 0;
}
```

なお、rqt_graphなどに表示されるノード名はコードの中で

```
  ros::init(argc, argv, "fuga_node");
```
とされている部分で指定されます。



##step 3. CMakeLists.txtの編集

以下のように、ディレクトリ移動後にCMakeLists.txtの編集を行います。

```terminal:説明
$ cd ~/catkin_ws/src/[さっき作ったパッケージ名]
$ gedit CmakeList.txt
```

```terminal:コマンド例
$ cd ~/catkin_ws/src/hoge_package
$ gedit CmakeList.txt
```

geditで開いたら、CmakeList.txtの一番下に以下のような文を記入してください。

```terminal:追加する文の説明
add_executable({実行ファイル名} src/{さっき作ったファイル名}.cpp)
target_link_libraries({実行ファイル名} ${catkin_LIBRARIES})
```

```terminal:追加する文の例
add_executable(piyo src/fuga.cpp)
target_link_libraries(piyo ${catkin_LIBRARIES})
```

ここで、注意が必要なのがOpenCVといったcatkin_LIBRARIES以外のライブラリを使用するときは、上述の文だけでは足りないということです。今回は少し煩雑になるので記載はしませんが、気をつけてください。
このあたりの文法はcatkinやcatkinの元となったCmakeなどを調べると詳しく知ることができると思います。

#####(補足1) step 1 で必要なライブラリを追加し忘れた、新しく追加したい場合 
CMakeLists.txtの最初のように以下のような文があるので、()の中に必要なライブラリの名前を追加しましょう。

```txt:CMakeLists.txtの一部
find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
　# ここに追加する #
)
```


##step 4. catkin_makeする
お疲れ様です。あと少しです。
コード作成とCMakeLists.txtの編集がおわったらcatkin_makeしてください。

```terminal:コマンド例
$　cd ~/catkin_ws
$　catkin_make
```

ここで、エラーが出たら今までのパッケージ作成の手順のどこかか、コードの中でミスしている可能性があります。エラー分を読んだり、ググったりしてもう一度確認してみましょう。私の記事が間違っていたり、古くなっていたらすみません。お知らせいただけると幸いです。


##step 5. 実行してみる
catkin_makeが通ったら、あなたのオリジナルのパッケージが完成したということです。おめでとうございます。ちゃんと動くか確認してみましょう。

まず1つ目の端末でroscoreを立ち上げます。

```terminal:roscore
$ roscore
```

次に、新しい端末を開いてあなたが作ったパッケージを実行します。

```terminal:説明
$　rosrun {パッケージ名} {実行ファイル名}
```

```terminal:コマンド例
$　rosrun hoge_package piyo
```

動きましたか？動いたらおめでとうございます。動かなかったらデバッグ頑張ってください…。


#最後に
今回の記事では詳しく触れませんでしたが、catkin_create_pkgをするとパッケージの中にpackage.xmlというファイルもできます。これは、パッケージの説明や作った人の紹介、ライセンスなどの様々な情報を記述するファイルです。githubなどで公開したりする際にはちゃんと書きましょう(自分含め)。

#参考
[ROS Wiki: ROSパッケージを作る](http://wiki.ros.org/ja/ROS/Tutorials/CreatingPackage)
[wikipedia: メタ構文変数](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BF%E6%A7%8B%E6%96%87%E5%A4%89%E6%95%B0)