RaspberryPi pico wでmicro-ROSを動かす(WiFi編)

前回までのあらすじ

RaspberryPi pico wにmicro-ROSを組み込み、micro-ROSエージェントとシリアル通信で接続できていることを確認した。

今回のテーマ

シリアル通信ではエッジデバイスとホストマシンが有線接続になってしまい、配置や線の取り回しなどに制約が出てしまう。

RaspberryPi pico wは無線モジュールを搭載しており、WiFi/Bluetoothで他のデバイスと通信が可能である。
ホストマシンに配置されたエージェントと無線で接続できれば、遠隔操作を行うような用途に有利となる。
そこでmicro-ROSの通信処理部をシリアル→WiFiに置き換え、エージェントとの通信を試みる

※現在(2024年1月17日)、エージェントとの接続がうまくいっていません💦💦💦

ソフト変更

以下のサイトを参考にWiFi仕様へ変更していく

platformio.iniの変更

board_microros_transportオプションをWiFiに指定する

board_microros_transport = wifi

このオプションの指定で、いずれかの定義が1となる

  • MICRO_ROS_TRANSPORT_ARDUINO_SERIAL

  • MICRO_ROS_TRANSPORT_ARDUINO_WIFI

  • MICRO_ROS_TRANSPORT_ARDUINO_CUSTOM

  • MICRO_ROS_TRANSPORT_ARDUINO_WIFI_NINA

main.cppの変更

変更点は以下の通り

  • set_microros_serial_transports()→set_microros_wifi_transports()に変更する
    set_microros_wifi_transports()にはSSID、パスワード、エージェント側のIPアドレス、ポート番号の4つのパラメータを渡す

コード(抜粋)

上の方でSS-ID、パスワード、エージェント側のIPアドレスおよびポート番号を定義しておく

#if (MICRO_ROS_TRANSPORT_ARDUINO_WIFI==1)
// Wifi関連
char ssid[] = "xxxxxxxxxxxxxxx";
char psk[] = "xxxxxxxxxxxxxx";
IPAddress agent_ip(192, 168, 11, 112);
size_t agent_port = 8888;
#endif

setup()関数内でコールされているセットアップ関数をWi-Fiのものに切り替える。

#if (MICRO_ROS_TRANSPORT_ARDUINO_SERIAL==1)
  set_microros_serial_transports(Serial); 
#elif (MICRO_ROS_TRANSPORT_ARDUINO_WIFI==1)
  set_microros_wifi_transports(ssid, psk, agent_ip, agent_port);
#else
#endif
ビルド成功
書き込みも成功

エージェントとの接続

今回はUDPv4エージェントを使用する
docker run -it --rm -v /dev:/dev -v /dev/shm:/dev/shm --privileged --net=host microros/micro-ros-agent:rolling udp4 --port 8888 -v6
picoからの送信がない・・・

原因はpico?エージェント?

ということで、picoがUDPを送れているか確認するため、pythonでUDPパケットを拾う簡単なスクリプトを作成した。

from socket import *

##################
# 受信側プログラム#
##################

# 受信側アドレスの設定
# 受信側IP
SrcIP = "192.168.11.112"
# 受信側ポート番号                           
SrcPort = 8888
# 受信側アドレスをtupleに格納
SrcAddr = (SrcIP, SrcPort)
# バッファサイズ指定
BUFSIZE = 1024

# ソケット作成
udpServSock = socket(AF_INET, SOCK_DGRAM)
# 受信側アドレスでソケットを設定
udpServSock.bind(SrcAddr)

# While文を使用して常に受信待ちのループを実行
while True:                                     
  # ソケットにデータを受信した場合の処理
  # 受信データを変数に設定
  data, addr = udpServSock.recvfrom(BUFSIZE) 
  # 受信データと送信アドレスを出力
  #print(data.decode(), addr)
  print(data, addr)
実行結果:送信はできているようである。

WSL2になって、ホストOSとゲストOSでは異なるIPアドレスが割り当てられるようになったそうだ。
なので、外部のデバイスからホストOSへのパケットをゲストOS(Linux)へフォワードする仕掛けが必要になる。(できるのかな…💦)

この記事が気に入ったらサポートをしてみませんか?