はじめに
Arduino (ESP-WROOM-32; ESP32) + ROSでchatterサンプルを動かすところまでを構築した。
その実績メモを残す。
ググれば類似記事はたくさん出てくるので差別化のため本記事の特徴を書いておく。
- ROSのバージョンがMelodic Morenia
- ROS環境をDocker上で構築した
- ROSのArduino用シリアル通信ライブラリの抽出をビルドなしで行える
動作環境
- Windows 10 1809
- Docker Desktop Community 2.0.0.3
- Arduino IDE 1.8.9
手元に手頃なデスクトップPCがなかったのでOSはWindowsを使うことにし、Docker Desktopを使用してコンテナ内にROS環境を構築することにした。
Gazeboなどシミュレータ(GUI)を使う予定があるならこの方法は使えないことに注意。
ESP32とWindowsはUSBで接続し、Arduinoプログラムのコーディング・ビルド・書き込みはホストOS(Windows)上にインストールしたArduino IDEで行う。
ESP32と通信するROSはDockerコンテナ上に構築する。
上述のとおり、ESP32とWindowsは物理的に接続されているがこれは単に電源供給のためであり、ESP32とROSの間の通信はWiFiによる無線通信で行う。
セットアップ
Docker Desktopのインストールは省略する。
rosserial
入りDockerイメージの作成
ROSのイメージファイルはros:melodic-robot
として配布されているが、
今回やろうとしているArduiono(ESP32)との通信にはrosserial
パッケージを別途インストールする必要がある。
ros:melodic-robot
をrunしてからインストールしてもよいが、せっかくなのでDockerfileを作ってrosserial
のインストールまでイメージ化しておく。
- 適当な空フォルダを用意する
- 以降では
C:\tmp\ros_env
を用意したものとする
- 以降では
- 本節下部に示すDockerfileを
C:\tmp\ros_env\Dockerfile
として置く - コマンドプロンプトやPowerShell上で
docker build -t local_ros/rosserial .\
を実行してイメージを作成する
Dockerfile
FROM ros:melodic-robot
# install packages
RUN apt update && apt install -y \
ros-melodic-rosserial \
ros-melodic-rosserial-arduino \
&& \
apt clean && \
rm -rf /var/lib/apt/lists/*
Arduino IDEのインストール
(1)本体のインストール
公式ページからダウンロード・インストールする。
2019年5月現在なら「Windows Installer, for Windows XP and up」か「Windows app Requires Win 8.1 or 10」がいいと思う。
(2)ESP32用プラグインのインストール
こちらの記事を参考にした。
上記記事の「ESP32-WROOM-32」-「セットアップ」-「ソフトウェア」-「[Arduino core for the ESP3 のインストール (ライブラリマネージャ使用)]」を参照。
(3)ros_lib
の抽出とインストール
ArduinoからROSを使うためには専用のC++ライブラリが必要になる(ライブラリとはいっても実体はヘッダファイルなのでビルドは不要)。
今回の構成ではROSをコンテナ上に構築したので、コンテナ上のファイルをホストにコピーする。
通常はgitリポジトリをcloneしビルド・インストールしてパスを通したところでライブラリを抽出するスクリプトを実行するのが正規の手順であるが、いちいちビルドするのは面倒なので自前でコピーする。
-
cd C:\tmp
でカレントディレクトリを移動する -
mkdir docker
で作業用フォルダを作成する -
docker run -it --rm -v C:\tmp\docker:/root/host local_ros/rosserial
を実行してDockerコンテナを起動する -
cp -R /opt/ros/melodic/share/rosserial_arduino/src/ros_lib ~/host
を実行してライブラリをコピーする -
exit
を実行してコンテナを終了する -
C:\tmp\Docker\ros_lib
フォルダを<Arduinoのインストールフォルダ>\libraries\ros_lib
として移動する
ビルド
Arduino IDEを開き、以下のプログラムをESP32に書き込む。
プログラムにはWiFiルータのSSIDおよびパスワード、接続先となるIPアドレスが必要になる。
接続先となるIPアドレスについてはホストであるWindowsのIPアドレスでよい。後述のとおりコンテナの起動時にポートフォワーディングオプションをつけるためである。
//
// このソースコードは以下の記事を参考にさせていただきました。
// https://gist.github.com/KobayashiRui/094ac01d9d3cd2445faa2a1ef103646f
//
# include <ros.h>
# include <std_msgs/String.h>
# include <WiFi.h>
const char SSID[] = "<ここにWiFiルータのSSIDを書く>";
const char PASSWORD[] = "<ここにWiFiルータのパスワードを書く>";
IPAddress server(<ここにWindowsのIPアドレスを書く>); // e.g.: IPAddress server(192, 168, 1, 3);
const uint16_t serverPort = 11411;
WiFiClient client;
class WiFiHardware {
public:
WiFiHardware() {};
void init() {
client.connect(server, serverPort);
}
int read() {
return client.read();
}
void write(uint8_t* data, int length) {
for(int i=0; i<length; i++)
client.write(data[i]);
}
unsigned long time() {
return millis();
}
};
ros::NodeHandle_<WiFiHardware> nh;
std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);
char hello[13] = "hello world!";
void setup()
{
Serial.begin(115200);
WiFi.begin(SSID,PASSWORD);
Serial.print("WiFi connecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println(" connected");
nh.initNode();
nh.advertise(chatter);
delay(10);
}
void loop()
{
str_msg.data = hello;
chatter.publish( &str_msg );
nh.spinOnce();
delay(1000);
}
実行
コンテナを起動してROSマスターを起動し、subscribeする。
前述のとおり接続先としてホストのIPアドレスを指定したため、コンテナの起動においてはポートフォワーディングオプションをつけていることに注意する。
-
docker run -it --rm -p 11411:11411 -v C:\tmp\docker:/root/host local_ros/rosserial
を実行してコンテナを起動する -
roscore &
を実行してROSマスターを起動する -
rosrun rosserial_python serial_node.py tcp &
を実行してTCP/IPによるシリアル通信をsubscribeする - ESP32のUSBケーブルを差し直して電源を入れ直す
- subscribeに成功したメッセージが表示されたのを確認する
-
rostopic echo chatter
を実行して"hello world!"
を受信していることを確認する
以上。