LoginSignup
4
1

micro-ROS on Wio Terminal with WiFi UDP Transport

Last updated at Posted at 2022-12-19

※2023.06.24更新

※2023.06.17更新

  • micro-ROS for Arduino本家でhumblev2.0.6がリリースされたことにより,今回のWio Terminal対応がリリースバージョンで使用可能となった
    • iron, rollingも同時にリリースされている

※2023.02.23更新

  • micro-ROS for Arduino本家にWio Terminalのサポートがマージされた
  • 最新のfoxyブランチアーカイブをここからダウンロードしてArduino IDEへのインポート手順に則ってインストールすればmicro-ros_publisher_wifiをビルドできるようになった
    • リリースタグはまだ打たれていない
    • Wio Terminal固有のLCDサポートなどは入れていないため,使用する場合は本記事中のexampleを参考にされたい
    • humbleブランチにもバックポートされているのでhumbleでも動作すると思われる

はじめに

ROS2 Advent Calendar 2022の記事として,ROS Japan UG #46 LT大会にてデモンストレーション(飛び込みLT枠のためビデオアーカイブなし)した内容について投稿する.

本記事は,読者がmicro-ROSについての基本的な知識(一部のプラットフォームを除いて,micro-ROS Agentを介してROS2 topicをやり取りすることなど)を持っていることを前提に書かれている.

ライブラリの修正箇所はmicro-ROS for Arduino本家へのPull Requestを予定しており,Seeed Studio Wio Terminal用のサンプルスケッチはそこからforkした筆者のリポジトリで公開予定である.それらの進捗があり次第,本記事も更新していく.

記事概要

Wio TerminalからWiFi経由でROS2 topicをPubするための手順を紹介する.
これにより,ESP32シリーズ以外のMCUでもWirelessでROS2 topicをPub可能であることが示された.

環境

環境構築の詳細な手順は割愛する.

ハードウェア

  • Wio Terminal
  • ホストPC(amd64)
    • 筆者は1台のPCで以下の役割を兼ねさせた
      • ArduinoIDEによる開発
      • Wio TerminalとのUDP通信を受け持つmicro-ROS Agentの実行
      • micro-ROS AgentからのROS2 topicをSubする
  • WiFiルータ
    • Wio Terminal側はDHCPを使用してIPアドレスを取得するので,DHCPサーバ機能を持つこと
    • micro-ROS Agentを実行するホストPC側のIPアドレスはArduinoスケッチに埋め込まれるので,静的IPアドレスを割り振っておくこと

ソフトウェア

ビルド手順

Arduinoの各種ライブラリやスケッチを保存するディレクトリがあるArduinoディレクトリを起点とする.

micro-ROS for Arduinoのヘッダとソースの改変

libraries/micro_ros_arduino-2.0.5-foxy/src/以下にあるmicro_ros_arduino.hwifi_transport.cppの一部を以下のように改変する.

micro_ros_arduino.h
- #if defined(ESP32) || defined(TARGET_PORTENTA_H7_M7) || defined(ARDUINO_NANO_RP2040_CONNECT)
+ #if defined(ESP32) || defined(TARGET_PORTENTA_H7_M7) || defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_WIO_TERMINAL)

#if defined(ESP32) || defined(TARGET_PORTENTA_H7_M7)
#include <WiFi.h>
#include <WiFiUdp.h>
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
#include <SPI.h>
#include <WiFiNINA.h>
+ #elif defined(ARDUINO_WIO_TERMINAL)
+ #include <rpcWiFi.h>
+ #include <WiFiUdp.h>
#endif

wifi_transport.cpp
- #if defined(ESP32) || defined(TARGET_PORTENTA_H7_M7) || defined(ARDUINO_NANO_RP2040_CONNECT)
+ #if defined(ESP32) || defined(TARGET_PORTENTA_H7_M7) || defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_WIO_TERMINAL)

#include <Arduino.h>


#if defined(ESP32) || defined(TARGET_PORTENTA_H7_M7)
#include <WiFi.h>
#include <WiFiUdp.h>
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
#include <SPI.h>
#include <WiFiNINA.h>
+ #elif defined(ARDUINO_WIO_TERMINAL)
+ #include <rpcWiFi.h>
+ #include <WiFiUdp.h>
#endif

ボードの選択とスケッチの作成

ボードとしてWio Terminalを選択する.設定は特に変える必要はない.

スケッチを新規作成,以下のソースで上書きして保存する.

set_microros_wifi_transports("WIFI SSID", "WIFI PASS", "192.168.1.57", 8888);の第1引数と第2引数をWiFiルータの設定に合わせる.第3引数はmiro-ROS Agentを走らせるホストPCのIPアドレスを指定することに注意.

wio_terminal_wifi_publisher.ino
#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <TFT_eSPI.h>

#include <std_msgs/msg/int32.h>

#include "Free_Fonts.h"

rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;

#define LED_PIN 13

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}

TFT_eSPI tft;

void error_loop(){
  while(1){
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  // Setup Wio Terminal's LCD
  tft.begin();
  tft.setRotation(3);
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(FMB12);

  // Show Connecting Message to LCD
  const String connecting_message = "Connecting to WiFi ...";
  tft.setCursor((320 - tft.textWidth(connecting_message))/2, 120);
  tft.print(connecting_message);
  
  set_microros_wifi_transports("WIFI SSID", "WIFI PASS", "192.168.1.57", 8888);

  // Show Connected Message to LCD
  tft.fillScreen(TFT_BLACK);
  const String connected_message = "Connected!";
  tft.setCursor((320 - tft.textWidth(connected_message))/2, 120);
  tft.print(connected_message);
  
  digitalWrite(LED_PIN, HIGH);

  delay(2000);

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_wifi_node", "", &support));

  // create publisher
  RCCHECK(rclc_publisher_init_best_effort(
    &publisher,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "topic_name"));

  msg.data = 0;
}

void loop() {
    delay(1000);
    RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
    msg.data++;
}

フォントファイルのコピー

Wio TerminalのLCDに適合したフォントファイルをダウンロードして,スケッチを保存したディレクトリにコピーする.

スケッチのコンパイルと書き込み

Wio TerminalとホストPCをUSBケーブルで接続し「マイコンボードに書き込む」を実行する.以下のようになればOK.

compile_write.png

動作確認

ホストPCでのmicro-ROS Agentの起動

書き込み終わったWio Terminalの電源スイッチをいったんOFFにしておく.USBケーブルはホストPCに接続したままで良い(後の工程でWio Terminalの電源としてのみ使用するため).

本記事ではDockerを使用したmicro-ROS Agentについて紹介するが,もちろんネイティブ環境でビルドしたものを使用しても良い(むしろより良い).

$ docker pull microros/base:foxy
$ docker run -it --net=host microros/micro-ros-agent:foxy udp4 -p 8888

Wio Terminalの電源スイッチをONにする

LCDにConnecting to WiFi...と表示された後に,WiFiルータやmicro-ROS Agentとの接続に問題なければConnected!と表示される.

micro-ROS Agentを起動した端末では以下のように表示され,接続が確立したことがわかる.

$ docker run -it --net=host microros/micro-ros-agent:foxy udp4 -p 8888
[1671409046.554536] info     | UDPv4AgentLinux.cpp | init                     | running...             | port: 8888
[1671409046.555203] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 4
[1671409057.332292] info     | Root.cpp           | create_client            | create                 | client_key: 0x6FCEB7C8, session_id: 0x81
[1671409057.332937] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x6FCEB7C8, address: 192.168.11.7:47138
[1671409057.371542] info     | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x6FCEB7C8, participant_id: 0x000(1)
[1671409057.382665] info     | ProxyClient.cpp    | create_topic             | topic created          | client_key: 0x6FCEB7C8, topic_id: 0x000(2), participant_id: 0x000(1)
[1671409057.391553] info     | ProxyClient.cpp    | create_publisher         | publisher created      | client_key: 0x6FCEB7C8, publisher_id: 0x000(3), participant_id: 0x000(1)
[1671409057.400132] info     | ProxyClient.cpp    | create_datawriter        | datawriter created     | client_key: 0x6FCEB7C8, datawriter_id: 0x000(5), publisher_id: 0x000(3)

ROS2 topicのSub

$ source /opt/ros/foxy/setup.bash
$ ros2 topic list
/parameter_events
/rosout
/topic_name
$ ros2 topic echo /topic_name 
data: 128
---
data: 129
---
data: 130
---
data: 131
---
data: 132
---

参考資料

  1. ROS2 Advent Calendar 2022
  2. ROS Japan UG #46 LT大会
  3. micro-ROS
  4. micro-ROS for Arduino
  5. Seeed Studio Wio Terminal
  6. Wio Terminalボードライブラリのインストール
  7. Wio TerminalのWiFiを使用するために必要なライブラリのインストール
  8. WiFiコアのファームウェアアップデート手順
  9. Arduino IDEへのインポート手順
  10. Wio TerminalのLCDに適合したフォントファイル
  11. Dockerを使用したmicro-ROS Agent
  12. MAEHARA_Keisukeのポータル記事
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1