mros2-esp32とM5Stackでサンプルプログラムを試す
海洋ロボコンをやってた人です。
今回はesp32系用のmros2であるmros2-esp32を試してみたので、その備忘録として記載していきます。
まとめる理由は以下です。
- 組込み向けのROSを触りながら学びたいため
- 後から使い方を自分で見直せるようにするため
この記事の最終ゴールは以下のようにmros2-esp32のサンプルを動かすことです。
また、本記事に対するコメントも積極的に募集しますので、よろしくお願いいたします。
使用機器と環境は以下です。
- Ubuntu 22.04 Humble
- M5Stack Gray
esp-idfのインストール
では早速mros2-espの準備として、esp-idfのインストールを行っていきます。
mros2-esp32のQuickstart by this repository itself > install esp-idfinstall esp-idf
に書いてある下記を参照して勧めていきます。
また、After install esp-idf, you need to install jinja2 library in esp-idf environment.
とあるようにjinja2
のインストールも必要なので、先にインストールしておきます。
pip install jinja2
Linux Users向けのESP-IDFの準備
上記のespressif.comに飛び、Manual Installation
から各OSごとのインストール手順に従ってIDFのインストールを進めます。
ここではLinuxを想定して進めていきますね。
For Linux Users > Ubuntu and Debian:
より必要なパッケージをインストールします。
sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev libssl-dev dfu-util libusb-1.0-0
Installing Python 3
はPythonのインストールなので割愛します。
Python3系ならよっぽど問題ないと思いますし、Python2.7系は非推奨とありますね。
ESP-IDFのインストール
esp
というフォルダ化を作成し、Gitよりクローンします。
mkdir -p ~/esp
cd ~/esp
git clone --recursive https://github.com/espressif/esp-idf.git
続いて、ESP-IDFとは別にコンパイラ、デバッガ等のインストールも必要なので、下記によりインストールします。
cd ~/esp/esp-idf
./install.sh esp32
サポートしている全てのボードを使う場合は
cd ~/esp/esp-idf
./install.sh all
を実行してください。
ESP-IDFの環境変数設定
ESP-IDFを使用するためには、ターミナルを開くたびに下記を呼び出す必要があります。
. $HOME/esp/esp-idf/export.sh
ESP-IDFを頻繁に使用する予定がある場合は、export.sh を実行するためのエイリアスを作成しておくと便利だと思います。
. $HOME/esp/esp-idf/export.sh
ESP-IDFの動作確認
上記までが完了したら、実際にESP-IDFのHello Worldテストを行っていきます。
cd ~/esp
cp -r $IDF_PATH/examples/get-started/hello_world .
で、hello worldのフォルダをコピーし
cd ~/esp/hello_world
idf.py set-target esp32
idf.py menuconfig
menuconfigを使用して、Wi-Fi ネットワーク名とパスワード、プロセッサ速度などのプロジェクト固有の変数を設定します。
また、開発ボードは40MHzを使用
するため、26MHzは使用しないような設定もしておきましょう。
設定が終わったら、ビルドして実行してみます。
idf.py build
idf.py -p /dev/ttyUSB0 flash
フラッシュ時はポートを指定するので、下記コマンドなどでesp32系の接続ポートを確認してください。
ls /dev/ttyUSB*
モニターで「hello_world」実行を確認します。
idf.py -p /dev/ttyUSB0 monitor
うまく動作していれば
と確認することができます。
プログラムを停止するときは、Ctrl+]
で停止できます。
また、flashとmonitorを一つのコマンドで書きたい場合は下記のようになります。
idf.py -p /dev/ttyUSB0 flash monitor
mros2-esp32のサンプルを試す
esp-idfのインストールが終了したら、ようやくmros2-esp32でmros2のサンプルを動かす準備に入れます。
mros2-esp32パッケージのクローンと設定
まず、mros2-esp32パッケージをgitからクローンします。
git clone --recursive https://github.com/mROS-base/mros2-esp32.git
cd mros2-esp32
/workspace/common/wifi/wifi.h
の ESP_WIFI_SSID
と ESP_WIFI_PASS
を変更します。
-#define ESP_WIFI_SSID "SSID"
-#define ESP_WIFI_PASS "PASS"
-#define NETIF_IPADDR "192.168.11.107"
+#define ESP_WIFI_SSID "Buffalo-XXXXXXXX-XXXXXXXX"
+#define ESP_WIFI_PASS "abcdefg"
+#define NETIF_IPADDR "192.168.11.4"
/include/rtps/config.h
で IP アドレスを変更します。
DHCPを使用する場合は、IPアドレスの指定も必要です。 アプリをフラッシュし、起動ログから IP アドレスを確認します。 その後、config.h の IP アドレスを変更して再構築します。
デフォルトでは、192.168.11.107ですが、192.168.11.4とし上記とIPアドレスをそろえています。
おそらく、このIPアドレスは(上も)他のアドレスと被っていなければ、変えなくても良いと思います。
const std::array<uint8_t, 4> IP_ADDRESS = {
- 192, 168, 11, 107
}; // Needs to be set in lwipcfg.h too.
const std::array<uint8_t, 4> IP_ADDRESS = {
+ 192, 168, 11, 4
}; // Needs to be set in lwipcfg.h too.
mros2-esp32のサンプル実行
上記アドレス設定まで終わったら、いよいよサンプルを実行していきます。
cd ~/mros2-esp32/workspace/pub_float32/
idf.py set-target esp32
idf.py menuconfig
メニューではIPv6を無効にしています。
/* in menuconfig */
Component config -> LWIP -> IPv6 ->
/Disable IPv6/
[ ] IPv6 support (Disable)
/* Save and Quit menuconfig */
↑ [ ] Enable IPv6
どうやら、IPv6が有効になっているとRTPSパケットが飛ばないようです。
mros2-esp32の環境構築について、Ar-Rayさんが詳しくまとめてくださっています。
設定ができたら、下記で起動してみます。
idf.py build
idf.py -p /dev/ttyUSB0 flash
idf.py -p /dev/ttyUSB0 monitor
pub_twistのサンプルを動かす場合は、cd ~/mros2-esp32/workspace/pub_twist/
ディレクトリに移動して、上記のmonitorまでを行えばcmd_velもpubできます。
mros2-esp32サンプルのデータ受信
上記のデータはfloat32なので、別途受信(Subscribe)用のプログラムを準備する必要があります。
そのため、下記を実行しhost用のプログラムを準備します。
git clone https://github.com/mROS-base/mros2-host-examples.git
cd ~/mros2-host-examples
colcon build
ros2 run mros2_sub_float32 sub_node
ros2 run mros2_sub_twist sub_node
うまく通信できていれば、Topicとして/to_linux
が表示され
とSubscribeできます。
うまく通信できない場合は
が考えられるそうですね。こちらは私も勉強になりました。ありがとうございます。
以上。
Discussion