【自分用メモ】ROS2開発＆移行Tips

# はじめに
この記事はROS2のパッケージの作成やROS1パッケージからのROS2移行にあたって私が躓いた点とその解決策を書き残していく備忘メモです。

## 今までに作ったもの
- [ros2_whill](https://github.com/WHILL/ros2_whill)（WHILL Model CR用 ROS2パッケージ）

#以下、雑多なメモ（未整理）
## colconは別インストール
ROS2をソースからビルドするのではなく、debianパッケージからインストールするルートを選んだ時に陥りがちな罠。

```shell-session
sudo apt install python3-colcon-common-extensions
```
参考：
[ubuntu18.04にROS2 crystalをインストールしたがcolconが使えない](https://qiita.com/seshimaru/items/66c64dfe1b807ce7c2b0)

## 命名規則、msg/srvの場所が変わっている
[ROS2.0時代に備えたc++11/14 p.6](https://www.slideshare.net/ogutti/ros20c1114-53507372/6?src=clipshare)に目を通しておきましょう。

## ドキュメントより、サンプルコードや元の実装の方がわかりやすい場面が多々ある。
ドキュメントの整備が間に合ってないんだと思われます。ドキュメント通りにやっても行き詰まるようなら、早々に[examples](https://github.com/ros2/examples/tree/master/rclcpp)や[turtlebot2_demo](https://github.com/ros2/turtlebot2_demo)のコードを読んでみた方が早く解決できることがあります。


## コンパイラはC++14を使う（確定）
公式チュートリアルの[Migration guide from ROS 1](https://index.ros.org/doc/ros2/Contributing/Migration-Guide/)には下記のようにC++11を使うような指示がありますが、おそらくこれは古い記述の名残です。
>In your CMakeLists.txt:
Start by enabling C++11

現行のROS2上でをパッケージをC++11でビルドしようとすると[ROS Answers: rclcpp parameter build fail](https://answers.ros.org/question/294787/rclcpp-parameter-build-fail/)にもあるようにパラメータ関連のビルドが失敗します。
>The CMake code of that package sets the compiler flag -std=c++11. If you are using the current ROS 2 code base you will need C++ 14.

今のところ、私は[ROS2リポジトリにあるExampleコードのCMakeLists.txt](https://github.com/ros2/rclcpp/blob/master/rclcpp/CMakeLists.txt)を参考にして上手く行っています。
この辺りは、`ros2 pkg create [package_name]`で生成される`CMakeLists.txt`は最初からC++14になっているので、一からパッケージ作成する際は特に問題にならないはずです。

```CMake:ros2/examples/rclcpp/minimal_publisher/CMakeLists.txt
# Default to C++14
if(NOT CMAKE_CXX_STANDARD)
  set(CMAKE_CXX_STANDARD 14)
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()
```

## 実行ファイルのインストール先はlib/${PROJECT_NAME}
上記と同じく[Migration guide from ROS 1](https://index.ros.org/doc/ros2/Contributing/Migration-Guide/)の不備（？）ですが、最後の`install`コマンドで`DESTINATION bin`になっていると`ros2 run`から発見されないです。

```CMake: 
install(TARGETS talker RUNTIME DESTINATION bin)
```
↓

```CMake:
install(TARGETS talker RUNTIME DESTINATION lib/${PROJECT_NAME})
```

参考：
[ROS2 Tutorialsをやってみた ~パッケージ作成~](http://robotry.hatenablog.com/entry/2018/09/03/231749)
[ROS2 runコマンドをいじってみた](https://qiita.com/seshimaru/items/4433bde7c43393d00530)


## メッセージ、サービスを定義する場合は別パッケージにする（調査中）
[Introduction to msg and srv interfaces](https://index.ros.org/doc/ros2/Tutorials/Rosidl-Tutorial/)では下記のように書かれているのでカスタムメッセージやカスタムサービスを本体パッケージの中で生成できるはずなのですが、何度やってもうまくいきませんでした。こういう場合、[ros2_whill](https://github.com/WHILL/ros2_whill)に対する[ros2_whill_interfaces](https://github.com/WHILL/ros2_whill_interfaces)のように別パッケージにしておくととりあえず回避できます。

>In order to use the messages generated in the same package we need to use the following cmake code:

```CMake:CMakeLists.txt
get_default_rmw_implementation(rmw_implementation)
find_package("${rmw_implementation}" REQUIRED)
get_rmw_typesupport(typesupport_impls "${rmw_implementation}" LANGUAGE "cpp")

foreach(typesupport_impl ${typesupport_impls})
  rosidl_target_interfaces(publish_address_book
    ${PROJECT_NAME} ${typesupport_impl}
  )
endforeach()
```