micro-ROSチュートリアル｜ホストPC・マイコン間 ping-pong

micro-ROS のチュートリアルを進め、ホスト PC と STM マイコン間で ping-pong をするまでの記事です。
なるべく docker を利用していますので、手っ取り早く sample を動かしたい方向けです。
詳細は公式のチュートリアル(参考[1])をご覧ください。

記事は 3 つに分けて投稿します。本記事は 3 記事目になります。

 1.  [[ping-pong] ホストPC内 ping-pong](https://qiita.com/hssay/items/322dfd28b4a8a4cbd34d)
 2. [[publisher] ホストPC・マイコン間 pubsub](https://qiita.com/hssay/items/772f3f278124b25b8a2c)
 3. [ping-pong] ホストPC・マイコン間 ping-pong

本記事は ホスト PC 用の ws 上で書かれた ping_pong ノードを STM マイコン用の ws へ移植し、 
ホスト PC と STM マイコン間で ping-pong させます。

## 環境
ホスト PC：Ubuntu 18.04.4 LTS
対象ボード：STM32 Nucleo-144 開発 ボード NUCLEO-F767ZI


## 前提
[ホストPC・マイコン間 pubsub](https://qiita.com/hssay/items/772f3f278124b25b8a2c) を済ませており、
設定済みの `nuttx_nucleo-144_f767-netnsh` がある状態を前提としています。

## 設定
### ホスト PC 用の作業ディレクトリ(ws)の用意
host 用の ws を docker コンテナからコピーしてきます。

```
$ docker run -it --rm --name uros_host microros/micro-ros-demos:dashing /bin/bash
$ ## 別ターミナルで以下を実行。コピーが完了したらコンテナは終了させて良い。

$ cd ~/uros_ws
$ docker cp uros_host:/uros_ws nuttx_host
```

次回以降は `nuttx_host` を編集し、コンテナ起動時は `nuttx_host`をマウントさせて使います。

```
$ docker run -it --rm --net=host -v ~/uros_ws/nuttx_host:/uros_ws \
     --name uros_host microros/micro-ros-demos:dashing /bin/bash
```

### ping_pong プログラムの移植

移植済みのリポジトリを用意してあります。
詳細は [コミットログ](https://github.com/hsgwa/micro-ROS-apps/commit/6d5a162c4f7639bb693a1d9c81fe6662311b50d7) をご覧ください。

以下、移植済みリポジトリを使用方法です

```
$ cd /uros_ws/firmware/apps/
$ git remote set-url origin https://github.com/hsgwa/micro-ROS-apps.git && git pull origin dashing
```

#### 移植作業
（移植済みリポジトリを pull した際は読み飛ばして頂いて大丈夫です）

ホスト用の ws とマイコン用の ws でソースコードの置き場所が異なります。

```
$ ls nuttx_host/src/uros/micro-ROS-demos/rcl/ping_pong/ # nuttx_host の ping_pong
$ ls nuttx_nucleo-144_f767-netnsh/firmware/apps/examples/ # 追加先
```

まずは、ホスト用の ping_pong のソースコードをコピー。

```
$ cp -r nuttx_host/src/uros/micro-ROS-demos/rcl/ping_pong \
        nuttx_nucleo-144_f767-netnsh/firmware/apps/examples/
# CMakeLists.txt は使いません。
```

publisher サンプルを参考に、以下のファイルを追加します。
変更内容は [コミットログ](https://github.com/hsgwa/micro-ROS-apps/commit/6d5a162c4f7639bb693a1d9c81fe6662311b50d7) 参照。

- Makefile
- Kconfig
- Make.defs

main 関数の宣言部のみ変更を加えます。

```
#if defined(BUILD_MODULE)
int main(int argc, char *argv[])
#else
int ping_pong_main(int argc, char* argv[])
#endif
```

#### カーネルの設定

ping_pong を実行可能なプログラムとして追加します。

```
$ docker run -it --rm --privileged -v ~/uros_ws/nuttx_nucleo-144_f767-netnsh:/uros_ws \
  --name uros_nuttx_nucleo-144_f767-netnsh uros_nucleo-144_f767-netnsh:dashing
$ ros2 run micro_ros_setup configure_firmware.sh f767-netnsh # config の再作成
$ cd /uros_ws/firmware/NuttX
$ make menuconfig
Application Configuration > Examples > microROS PingPong # PingPong の有効
```


### ビルド＆書き込み

```
$ cd /uros_ws
$ ros2 run micro_ros_setup build_firmware.sh
$ openocd -f board/st_nucleo_f7.cfg -c "program firmware/NuttX/nuttx.bin exit 0x08000000"
```


### 実行

#### エージェントの起動

```
$ docker run -it --rm --net=host --name uros_agent microros/micro-ros-agent:dashing udp4 --port 8888
```
#### ホスト PC の ping_pong プログラムの起動

ping_pong サンプルがビルド済みの micro-ros-demos イメージを使用します。

```
$ docker run -it --rm --net=host --name uros_nuttx_host \
     microros/micro-ros-demos:dashing ros2 run micro_ros_demos_rcl ping_pong
```

`nuttx_host` 内に変更を加えた場合はビルドしてから実行してください。

```
$ docker run -it --rm --net=host -v ~/uros_ws/nuttx_host:/uros_ws \
    --name uros_nuttx_host --name uros_host microros/micro-ros-demos:dashing /bin/bash
$ ros2 run micro_ros_setup build_firmware.sh
$ ros2 run micro_ros_demos_rcl ping_pong
```



#### nshからping_pongを起動
```
$ sudo minicom -D /dev/ttyACM0
nsh> ping_pong
```

## 実行結果

![host_uc_ping_pong.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62023/92d754a6-b891-2eba-4330-a6edc262a6c3.gif)

上が agent、左下が ホスト ping_pong、右下が マイコンping_pong(nsh)です。
マイコン ping_pong の起動直後、ホストとマイコンの両方が pong を返しています。



-----


今回は Ethernet を使用してますが、 serial を使用する際はビルド時にエラーになります。（2020/07/24現在）
~~github の issue に同様のエラーが報告されているので、 その内解決されそうです。~~
rmw_init.cにfcntl.hとtermios.hをincludeすることで回避できるとのことです。[(コミットログ)](https://github.com/micro-ROS/rmw-microxrcedds/commit/4182dcfba5c20adca0ee2b12b3e396fec28da180) 
[nuttx olimex-stm32-h407 Build using serial protocol · Issue #142](https://github.com/micro-ROS/micro-ros-build/issues/142)

Foxy migration の進み具合や embedded WG での議論内容など、
気になる方は以下もチェックしておくと良さそうです。

- [Foxy migration · Issue #131](https://github.com/micro-ROS/micro-ros-build/issues/131)
- [Latest wg-embedded topics - ROS Discourse](https://discourse.ros.org/tag/wg-embedded)


## 参考

1. [micro-ROS 公式](https://micro-ros.github.io/)
2. [github | micro-ROS_Demo_on_STM32_nucleo-f767zi](https://github.com/maehara-keisuke/micro-ROS_Demo_on_STM32_nucleo-f767zi/blob/master/README.md)