gcc4mbedとrosserial_mbedでmbedオフライン開発環境を構築する話

# はじめに
基本的にリンク先の「Using the offline compiler」の手順を踏むだけ
http://wiki.ros.org/rosserial_mbed/Tutorials/rosserial_mbed%20Setup

mbed OS 5を使用する際はmbed CLIを使うと良いらしいが，私はmbed CLI上でrosserial_mbedを使おうとしてエラーが出まくり，断念した．
今回はgcc4mbedとrosserial_mbedを組み合わせてオフラインの環境構築を行う．

# gcc4mbedのインストール
①gcc4mbedをクローン
パッケージをクローンします．

```bash
$ git clone https://github.com/adamgreen/gcc4mbed
```
(場所はどこでも良いと思います．自分はホームディレクトリに保存しました)

「~/gcc4mbed」に入り，「linux_install」を実行
「./linux_install」

すると必要なものが色々インストールされる．

ここで，ちゃんとインストールされたかを確認するために「~/gcc4mbed/samples/HelloWorld」をコンパイル・実行して確認してみることにする．

「~/gcc4mbed/samples/HelloWorld/Makefile」を以下のように編集．

``` Makefile:~/gcc4mbed/samples/HelloWorld/Makefile
PROJECT         := Blink
DEVICES         := NUCLEO_F303K8\  # ココを編集
                   NUCLEO_F446RE  # ココを編集
GCC4MBED_DIR    := ../..
NO_FLOAT_SCANF  := 1
NO_FLOAT_PRINTF := 1

include $(GCC4MBED_DIR)/build/gcc4mbed.mk"
```

そして，そのディレクトリで```$ make```を実行して実行ファイルを生成．(デバイス名)のフォルダが生成されます．
（私の場合はNUCLEO_F303K8とNUCLEO_F446RE）
![Screenshot from 2020-10-22 12-04-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320997/23a57154-c495-fa46-a5c0-9549582d31f9.png)

あとは，この中にある「HelloWorld.bin」を自分のNucleoボードにD&Dで書き込み，LEDが光るか確認する．

確認できたら，~/.bashrcにgcc4mbedへの環境変数を設定する．

```
$ echo "export GCC4MBED_DIR=~/gcc4mbed" >> ~/.bashrc
```
(gcc4mbedのファイル名やファイル場所を別の場合にしている場合は適宜読み替えてください)

以上でgcc4mbedのインストールは終了．


# rosserial_mbedのインストール
※ROSを使わない方はココを飛ばして構いません．

rosserialを自分のROS_workspaceにgit cloneする．
catkin_ws/src内でターミナルを開いて，

```:~/catkin_ws/src
$ git clone https://github.com/ros-drivers/rosserial
```
を実行．

そのあとコンパイルをして再読込を行う．

```:~/catkin_ws/src/
$ catkin build rosserial_mbed
$ source ../devel/setup.bash
```

そして，以下を実行して既存のROSライブラリのmbed版を生成する．このときの生成先は「~/ros/lib」とした．

```:
$ rosrun rosserial_mbed make_libraries.py ~/ros/lib
```

すると，~/ros/lib内にros_libというmbed用のROSライブラリが生成される．

最後に，gcc4mbedと同様に~/ros/libを環境変数で定義しておく．

```:
$ echo "export ROS_LIB_DIR=~/ros/lib/ros_lib" >> ~/.bashrc
```

これでrosserial_mbedの導入は完了．
最後にrosserial_mbed内のexampleを用いて動作確認を行う．

#rosserial_mbedの動作確認
「~/catkin_ws/src/rosserial/rosserial_mbed/src/examples/HelloWorld」にあるMakefileを開く．

DEVICESの部分を自分の所有するボードに書き換える．

``` Makefile:~/catkin_ws/src/rosserial/rosserial_mbed/src/examples/HelloWorld/makefile
PROJECT         := rosserial_mbed_HelloWorld
DEVICES         := NUCLEO_F303K8 NUCLEO_F446RE
GCC4MBED_DIR    := $(GCC4MBED_DIR)
USER_LIBS       := !$(ROS_LIB_DIR) $(ROS_LIB_DIR)/BufferedSerial
NO_FLOAT_SCANF  := 1
NO_FLOAT_PRINTF := 1

include $(GCC4MBED_DIR)/build/gcc4mbed.mk
```
先程と同様にボードに書き込み，動作確認を行う．

今回の例ではNucleo側がchatterというトピック名のString型メッセージをPublishするので，PC側のrostopicで受信することにする．（詳細なコードはHelloWorld.cppを参照）

```:1つ目のターミナル
$ roscore
```
```:2つ目のターミナル
$ sudo chmod 666 /dev/ttyACM0
$ rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0 _baud:=57600
```
```:3つ目のターミナル
rostopic echo /chatter
```
3つ目のターミナルで受信できていたら成功．


必要に応じて，pythonパッケージをインストールします．

```bash
$ pip3 install pyserial
```

# Nucleo側で自作msg/srvファイルを使用したい場合

```
$ rosrun rosserial_mbed make_libraries.py ~/ros/lib
```
上記のコマンドは，PC側のROSmsg/srvをmbed版に変換するコマンドなので，PC側で自作msg/srvのヘッダファイルを生成したあとにもう一度コマンドを実行するとmbed版のヘッダファイルが生成される．





# 任意のディレクトリで作業する場合
自分の好きなディレクトリで開発を行いたい場合について説明する．

仮にワークスペースを「~/my_ws」と仮定する．
このとき，「~/catkin_ws/rosserial/rosserial_mbed/src/examples/」にあるmakefileとHelloWorldファイルを
「~/my_ws」にコピーする．

```
$ cp ~/catkin_ws/src/rosserial/rosserial_mbed/src/examples/makefile ~/my_ws/
$ cp -r ~/catkin_ws/src/rosserial/rosserial_mbed/src/examples/HelloWorld ~/my_ws/
```
あとはmakefileのDIRS等を書き換えることで自由にオフラインコンパイルをすることができる．

一例として，自分のworkspaceを公開しておきます．
https://github.com/Hayabusa6863/mbed_ROS_ws