ROS2独自メッセージの作成 before Foxy Fitzroy

【[ROS2関係トップページへ](https://qiita.com/NeK/items/7ac0f4ec10d51dbca084)】
【[ROS2レクチャー:初級 -ROS1 style-](https://qiita.com/NeK/items/74e4bb9d1530e22a63fc)】
【[ROS2レクチャー:初級 -class style-](https://qiita.com/NeK/items/14db31ff784a0bfafe3d)】

【前:[ROS2の最小構成publisher:初級 -ROS1 style-]】
【前:[ROS2の最小構成publisher:初級 -class style-]】
【次:[独自メッセージを用いたROS2 publisher/subscriber:初級 -ROS1 style-]】
【次:[独自メッセージを用いたROS2 publisher/subscriber:初級 -class style-]】

[ROS2の最小構成publisher:初級 -ROS1 style-]:https://qiita.com/NeK/items/12faa483de71eb55162f
[ROS2の最小構成publisher:初級 -class style-]:https://qiita.com/NeK/items/3a123fadd8a574b14162
[独自メッセージを用いたROS2 publisher/subscriber:初級 -ROS1 style-]:https://qiita.com/NeK/items/f4f186af2401aa4dc13d
[独自メッセージを用いたROS2 publisher/subscriber:初級 -class style-]:https://qiita.com/NeK/items/cd00705f7e473f83ca44

ROSには沢山の種類のメッセージが用意されている．しかし勿論自分独自のメッセージを作りたくなる．C言語でいうstructのように．
ROS(ROS1)では実行ファイル=nodeでありnodeがメッセージを使用するため，nodeのパッケージの中に独自メッセージが付属的に作成された．
ROS2ではメッセージも独立性を持つようで，それ自体がパッケージとして成り立ち，他のパッケージがメッセージに関するパッケージを利用する形となる．
詳しくは当ページの最後の「参考」を参照のこと．

<details>
<summary>dashingからの変更?</summary>[ROS2インストール・初期設定(for dashing用)](https://qiita.com/NeK/items/d2bdd8798de7cdea1932)の「上記ガイド以外でインストールしたもの」に追加したが，lark-parserとnumpyをちゃんとインストールしないとエラーが出るようになった(2019/6)
</details>

# 作成物
データの基本型は[About ROS 2 Interfaces](https://index.ros.org/doc/ros2/Concepts/About-ROS-Interfaces/)に一覧がある．
独自メッセージはtopic用とService用がある．ここでは
両方つくる.


## topic用メッセージ
int64型のデータを二つ．

## service用メッセージ
service用メッセージは送信と受信がある．送信として二つのfloat64型のデータ，送信し処理した結果受信するデータとして二つのfloat64型のデータ．

# 準備
topic用のメッセージのためにmsgディレクトリをservice用のメッセージのためにsrvディレクトリを作成する．

```Bash:terminal
$ cd ~/ros2_studies_ws/
$ ros2 pkg create my_messages
$ cd my_messages
$ mkdir msg
$ mkdir srv
```

# メッセージ作成
作成物:[github.com](https://github.com/nek009/my_messages)

## topic用メッセージの作成
msgディレクトリ以下に以下のファイルを作成

- TwoInts.msg

```msg/TwoInts.msg
int64 a
int64 b
```

## service用メッセージの作成
srvディレクトリ以下に以下のファイルを作成

- CalcTwoFloats.srv

```srv/CalcTwoFloats.srv
float64 a
float64 b
---
float64 sum
float64 diff
```

## メッセージに関する注意点
メッセージを表すファイル名(\*\*\*.msgや\*\*\*.srv)にはいくつかの制限がある．

### メッセージファイル名に関する制限

- 最初の文字が大文字でなければならない
- _(アンダースコア)を使ってはいけない
- 単語の区切り(意味の区切り)は大文字で行う

OKな例

- Test.msg
- TEST.msg
- TestMessage.msg

NGな例

- test.msg
- test_message.msg

### 制限の理由とメッセージの利用方法

メッセージファイルはcolcon buildによって他のパッケージで利用できるようにビルドされる．この時，***.msgはコンパイルされてクラスになる．この時，二個目の大文字の前に_(アンダースコア)が挿入され全て小文字のヘッダファイルが作成されて，これをインクルードすることで利用できるようにしている．

例

- msgファイル
    - TestMessage.msg
- コンパイル後に作成されるメッセージ利用のためのクラスヘッダファイル
    - test_message.hpp

この変換をスムーズに行うために上記のような制限が行われる．

このように他のパッケージで利用するためには，メッセージファイル名から上記のように変換したヘッダファイルを読み込むことを覚えておくこと．

## package.xmlとCMakeLists.txt
idl(interface description language)という名前を持つライブラリを使用している．interface，つまり他のnodeから使ってもらえるようにするためのもの．

### package.xml

```xml:package.xml
<package format="3">
  <buildtool_depend>rosidl_default_generators</buildtool_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>
  <member_of_group>rosidl_interface_packages</member_of_group>
```

1行目:これまでformat="2"であったが，<member_of_group>タグを利用するためには"3"にしなければならない．
2～4行目:メッセージをビルドするために必要．特に2行目は\<build_depend\>ではなく\<buildtool_depend\>なので注意が必要である．

### CMakeLists.txt

```CMakeLists.txt
find_package(rosidl_default_generators REQUIRED)

set(msg_files
  "msg/TwoInts.msg"
)
set(srv_files
  "srv/CalcTwoFloats.srv"
)
rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files}
  ${srv_files}
)
ament_export_dependencies(rosidl_default_runtime)
```

# ビルト・動作確認

```Bash:terminal
$ cd ~/ros2_studies_ws/
$ colcon build --symlink-install --packages-select my_messages
$ . install/setup.bash
$ ros2 msg list # 全メッセージのリストが表示される．作成したメッセージが存在するか確認
$ ros2 msg show my_messages/TwoInts # [パッケージ名]/[メッセージ]で中身が見えるので確認
$ ros2 srv show my_messages/CalcTwoFloats # [パッケージ名]/[メッセージ]で中身が見えるので確認
```

# 参考
メッセージについて詳しくは以下のページに詳しい

- [Introduction to msg and srv interfaces](https://index.ros.org/doc/ros2/Tutorials/Rosidl-Tutorial/)
- [Defining custom interfaces (msg/srv)](https://index.ros.org/doc/ros2/Tutorials/Defining-custom-interfaces-(msg-srv)/)
- [ROS2の紹介 by gbiggs](https://gbiggs.github.io/rosjp_ros2_intro/ros2_basics.html#%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E5%8F%97%E4%BF%A1%E3%83%8E%E3%83%BC%E3%83%89%E3%81%AE%E4%BD%9C%E6%88%90)

公式の使用例は以下のとおり．

- [ros2/tutorials](https://github.com/ros2/tutorials/tree/rosidl_tutorials/rosidl_tutorials)
    - [ROS互換のスタンダードな例?](https://github.com/ros2/tutorials/tree/rosidl_tutorials/rosidl_tutorials/rosidl_tutorials)．
    - [ROS独自の拡張含めたもの](https://github.com/ros2/tutorials/tree/rosidl_tutorials/rosidl_tutorials/rosidl_tutorials_msgs)．こちら推奨．