📝

micro-ROS for Arduinoを使ってAtom LiteとRaspberry Piで通信してみる

2024/06/05に公開

はじめに

Turtlebot3のようなRaspbeery Piで動くROS2マシンにセンサを載せていろいろやりたいと思ったときにセンサモジュールの開発を簡単にやりたくてGroveで多様なセンサが接続できるM5Stackシリーズを使ったら楽ができるんじゃないかと思いました。中でもAtom Liteは小型安価で個人的によく使うのでこれとラズパイがROS2で会話できればいろいろと便利な気がしました。

というわけでmicro-ROS for Arduinoを使ってAtom LiteとラズパイがROSで喋れるようにしてみます。

材料は以下のとおり

  • Macbook Pro M3
  • Raspberry Pi 4B (Ubuntu Server 22.04 LTS 64bit & ROS2 Hamble)
  • Atom Lite
  • micro-ROS for Arduino

方針

以下のような方針でやります

  • Atom Liteにmicro-ROS for Arduinoを入れてサンプル publisherでデータをpubする
  • Raspberry Pi 側にmicro-ROS-Agentを入れてAtom Liteからpubされるデータを受信する
  • ros2 topic echoで受信されたデータを読む

Raspberry Pi側にmicro-ROS-Agentをセットアップする

以下はRaspberry Pi上で操作します。

Raspberry PiにはあらかじめHambleがセットアップされていることとします。

micro_ros_setupを使ってmicro-ROS-Agentをセットアップします

micro_ros_setupのインストール

cd ros2_ws/src

source /opt/ros/$ROS_DISTRO/setup.bash

git clone -b $ROS_DISTRO https://github.com/micro-
ROS/micro_ros_setup.git

cd ../

rosdep update && rosdep install --from-paths src --ignore-src -y

colcon build

source install/local_setup.bash

micro_ros_Agentのビルド

ros2 run micro_ros_setup create_agent_ws.sh

ros2 run micro_ros_setup build_agent.sh

source install/local_setup.sh

Warningが出るコンパイルがありましたが、正常にセットアップできました。

Atom Liteにmicro-ROSのサンプルpublisherを書き込む

以下はPC(Mac)上で操作します。

micro-ROS for Arduinoのhambleブランチ<> Codeボタンをクリック -> Download ZIP をクリックしてデスクトップ上にmicro_ros_arduino-humble.zipを保存します。

USBケーブルでPCとAtom Liteを接続してArduino IDEを開きます。ボードにM5Stack-Atom、ポートにAtom Liteのシリアルポート(/dev/cu.usebserial-XXXXXX)を指定します。

Arduino IDEのツールバー からスケッチ->ライブラリをインクルード->.Zip形式のライブラリをインストール...を選択してmicro_ros_arduino-humble.zipを選択しインストールします。

ファイル->スケッチ例->micro_ros_arduino->micro-ros_publisher_wifiを選択してソースコードを開きます。

44行目の以下のコードを編集します。

set_microros_wifi_transports("WIFI SSID", "WIFI PASS", "192.168.1.57", 8888);
  • "WIFI SSID" : Raspberry Piが接続しているWiFiのSSID
  • "WIFI PASS" : Raspberry Piが接続しているWiFiのパスワード
  • "192.168.1.57": Raspberry PiのIPアドレス

編集後、書き込みボタンをクリックしてコンパイルして書き込みます。

書き込みが完了したらいったんAtom LiteからUSBケーブルを抜いて電源をオフにしておきます。

micro-ROS-Agentを起動する

以下はRaspberry Pi上での操作です。

cd ~/ros2_ws
source install/local_setup.sh
ros2 run micro_ros_agent micro_ros_agent udp4 --port 8888 -v6

[1717488383.126621] info     | UDPv4AgentLinux.cpp | init                     | running...             | port: 8888
[1717488383.127416] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6

Atom Liteのpublisherを起動する

Atom LiteをUSBケーブルに接続して電源を入れます。

Raspberry Pi側のmicro-ROS-Agentのログを見ると以下のような通信ログが流れてきます。

[1717488633.737107] info     | UDPv4AgentLinux.cpp | init                     | running...             | port: 8888
[1717488633.737884] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1717488670.894897] debug    | UDPv4AgentLinux.cpp | recv_message             | [==>> UDP <<==]        | client_key: 0x00000000, len: 24, data: 
0000: 80 00 00 00 00 01 10 00 58 52 43 45 01 00 01 0F 4E D1 8C 3B 81 00 FC 01
[1717488670.895479] info     | Root.cpp           | create_client            | create                 | client_key: 0x4ED18C3B, session_id: 0x81
[1717488670.895761] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x4ED18C3B, address: 192.168.1.121:47138
[1717488670.896102] debug    | UDPv4AgentLinux.cpp | send_message             | [** <<UDP>> **]        | client_key: 0x4ED18C3B, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00
[1717488670.917654] debug    | UDPv4AgentLinux.cpp | recv_message             | [==>> UDP <<==]        | client_key: 0x4ED18C3B, len: 60, data: 
0000: 81 80 00 00 01 07 32 00 00 0A 00 01 01 03 00 00 24 00 00 00 00 01 FB 3F 1C 00 00 00 6D 69 63 72
0020: 6F 5F 72 6F 73 5F 61 72 64 75 69 6E 6F 5F 77 69 66 69 5F 6E 6F 64 65 00 00 00 00 00
[1717488671.049797] debug    | UDPv4AgentLinux.cpp | recv_message             | [==>> UDP <<==]        | client_key: 0x4ED18C3B, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1717488671.121377] debug    | UDPv4AgentLinux.cpp | recv_message             | [==>> UDP <<==]        | client_key: 0x4ED18C3B, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1717488671.224163] debug    | UDPv4AgentLinux.cpp | recv_message             | [==>> UDP <<==]        | client_key: 0x4ED18C3B, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1717488671.293111] info     | ProxyClient.cpp    | create_participant       | participant created    | client_key: 0x4ED18C3B, participant_id: 0x000(1)
[1717488671.294565] debug    | UDPv4AgentLinux.cpp | send_message             | [** <<UDP>> **]        | client_key: 0x4ED18C3B, len: 14, data: 
0000: 81 80 00 00 05 01 06 00 00 0A 00 01 00 00
[1717488671.294852] debug    | UDPv4AgentLinux.cpp | send_message             | [** <<UDP>> **]        | client_key: 0x4ED18C3B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1717488671.294998] debug    | UDPv4AgentLinux.cpp | send_message             | [** <<UDP>> **]        | client_key: 0x4ED18C3B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80
[1717488671.336318] debug    | UDPv4AgentLinux.cpp | recv_message             | [==>> UDP <<==]        | client_key: 0x4ED18C3B, len: 13, data: 
0000: 81 00 00 00 0B 01 05 00 00 00 00 00 80
[1717488671.336447] debug    | UDPv4AgentLinux.cpp | recv_message             | [==>> UDP <<==]        | client_key: 0x4ED18C3B, len: 13, data: 
0000: 81 00 00 00 0A 01 05 00 01 00 00 00 80

Raspberry Piのターミナルで別タブを開いてトピックリストを参照します

ros2 topic list

/parameter_events
/rosout
/topic_name

topic_name というのがpublisherのトピック名です。Atom Liteに書き込んだサンプルの66行で指定されています。

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

topic_name のデータを出力します

ros2 topic echo /topic_name

data: 466
---
data: 467
---
data: 468
---
data: 469
---
data: 470
---
...

Atom Lite側では下記のようにmsg.dataをカウントアップしたデータが送信されているので、正常に通信できているようです。

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

おわりに

Atom Liteをセンサマイコンとして使うのは多少リッチすぎる気もしますがGrove対応センサでROSにセンサデータを流し込む手段としてはお手軽で良いと思います。

今回はWifi対応publisherのサンプルスケッチを使いましたがmicro-ROS for Arduinoのmicro-ros_publisherのサンプルスケッチと以下のようなmicro-ROS-Agentの起動オプションを使えばRaspberry PiとAtom LiteをUSBシリアル接続で通信することもできます。ROS2マシンにセンサを組み付ける場合はこちらのほうが現実的ですね。

ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyUSB0 -v6

とりあえずAtom Liteが使えることがわかったので何かセンサ制御的なことをやってみようと思います。

Discussion