前回の記事のようにTelloのWi-Fiが届く範囲で動かすのが普通の遊び方なのですが、もっと遠く離れたところからTelloを動かしてみたくないですか?
Tello-Videoのサンプルコードを改造し、MQTT通信でTelloの操縦コマンドとカメラ映像を送ることで、インターネット経由でTelloを遠隔操作できるようにしました。
これにより、↓の動画のように2km離れた場所からTelloを動かすことに成功しました!
地球の裏側からでもTelloのカメラ映像を見ながら操縦することができるはずです。
(Tello側でパソコンやTelloのセッティングをしてくれる人が必要ではありますが・・・)
動画ではゲームコントローラF710を使って操作していますが、お持ちでない方はキーボードでも動かせます。
私の通信環境だと、Telloのカメラ映像をフルサイズ(960×720)で送信すると遅延が大きかったので、160×120まで間引いてリアルタイム性を向上させました。
なので、画質は低いです・・・
MQTTブローカーとしては、登録無しで無料で使えるtest.mosquitto.orgを使いました。
ネットワーク遅延に関しては、使用するMQTTブローカーや通信環境にも左右されると思いますので、状況に応じて画素数を調整しても良いと思います。
本記事の方法を実践すると、2台のMacを使って、Telloをインターネット越しに遠隔で操縦することができるようになります。
構成
下図のように2台のPCがクラウドサーバーのMQTTブローカー(mosquitto)を中継して通信し、操縦コマンドと映像を送ることでTelloを遠隔から操作します。
項目 | バージョン |
---|---|
macOS | Catalina 10.15.7 / Big Sur 11.2 |
Anaconda | Anaconda3-2020.11-MacOSX-x86_64 |
python | 3.8.5 / 3.8.8 |
numpy | 1.19.2 |
opencv | 4.5.1 |
paho-mqtt | 1.5.1 |
pygame | 2.0.1 |
環境構築
厳密には2台のPCとも下記環境設定のすべてを行う必要はないのですが、簡単化のために環境構築までは共通のものとして説明します。
前回の記事で作ったAnacondaの仮想環境TelloにMQTTクライアントライブラリpaho-mqttをインストールします。
conda install -c conda-forge paho-mqtt
PY3_Tello_Videop
ディレクトリの下にh264decoder.cpython-38-darwin.so
の実体またはシンボリックリンクが必要ですので、無い場合は前回の記事に従いCMakeを使って作成してください。
この記事に従い、Pygameをインストールします。
pip install pygame
必要なファイルをGitHubからダウンロードします。
前回の記事で作ったTello-Python
ディレクトリに移動し、git clone
します。
cd Tello-Python git clone https://github.com/tak6uch1/PY3_Tello_Videop_MQTT cd PY3_Tello_Videop_MQTT
前回の記事でビルドしたh264decoder.cpython-38-darwin.so
へのシンボリックリンクを作ります。
ln -s ../PY3_Tello_Videop/h264decoder.cpython-38-darwin.so
MQTTのテスト
test.mosquitto.orgから証明書mosquitto.org.crt
をダウンロードし、PY3_Tello_Videop_MQTT以下に移動しておきます。
Anaconda NAVIGATORから仮想環境Telloのターミナルを2つ立ち上げ、一方で以下のSubscriberプログラムを実行します。
python sub-mqtt-enc.py
これの中身は以下です。
# coding=utf8 import paho.mqtt.client as mqtt def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) client.subscribe("Tello-Control/command") def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.tls_set("mosquitto.org.crt") client.connect("test.mosquitto.org", 8883) client.loop_forever()
もう一つのターミナルで以下のPublisherプログラムを実行します。
python pub-mqtt-enc.py
これの中身は以下です。
# coding=utf8 import paho.mqtt.client as mqtt import time def on_connect(client, userdata, flags, rc): print("Connected with result code "+str(rc)) def on_message(client, userdata, msg): print(msg.topic+" "+str(msg.payload)) client = mqtt.Client() client.on_connect = on_connect client.on_message = on_message client.tls_set("mosquitto.org.crt") client.connect("test.mosquitto.org", 8883) while client.loop() == 0: msg = "TIME: "+time.ctime() client.publish("Tello-Control/command", msg, 0, True) print(msg) time.sleep(1.5) pass
これでSubscriber側に以下のように表示されれば成功です。
Connected with result code 0 Tello-Control/command b'TIME: Sat Mar 13 16:10:55 2021' Tello-Control/command b'TIME: Sun Mar 14 02:33:21 2021' Tello-Control/command b'TIME: Sun Mar 14 02:33:23 2021'
Tello-Videoの変更点
環境構築の章でGitHubからダウンロードしたmain.py
, tello_control_ui.py
が改造済みのファイルになります。
main.py
の改造内容をvimdiff
コマンドで表示すると以下となります。(左:改造後、右:改造前)
TelloUIクラスに追加したstart_mqtt_subメソッドを実行し、MQTT Subscribeを開始しています。
tello_control.py
の改造内容は以下です。
画像をPublishする処理とコマンドをSubscribeし、受け取ったコマンドに応じてTelloの操縦コマンドを発する処理を追加しています。
Telloのカメラから取得した画像をMQTTにPublish(送信)するとともに、Tello操縦コマンドをSubscribe(受信)する機能を追加しています。
Telloの遠隔操作実行
Tello側
Telloの電源を入れ、1台目のMacのWi-FiをTelloにつなぎます。
インターネット接続も必要なので有線LANもしくはUSBに差し込むWi-Fiモジュールでインターネットに接続しておきます。
以下でPythonプログラムからTelloの制御を可能な状態にします。
python main.py
以下のようなウィンドウが立ち上がり、Telloのカメラ映像が表示されます。
操縦側
2台目のMacで以下の操作側プログラムを実行します。
python remote_tello.py
これでTelloのカメラ映像が出れば通信はできています。
カメラ映像が小さくて見づらい場合、ウィンドウ枠を引っ張って大きくできます。
(単に引き伸ばすだけで解像度が上がるわけではありまあせん)
remote_tello.py
はTelloのカメラ映像をSubscribeして表示し、ゲームコントローラF710またはキーボードの入力を検知したら操縦コマンドをPublishします。
test.mosqtuitto.orgの混み具合なのか、とても通信が遅くなることがあるようですが、少し時間をおいてから試すと改善することもあります。
終了するにはターミナルを最前面に出して(ターミナルウィンドウをクリック)、Ctrl+Cを押します。
ゲームコントローラで動かす
F710のキーの割当は以下です。
START:離陸
BACK:着陸
十字キー:前後左右移動
LB:左30度回転
RB:右30度回転
Y:30cm上昇
A:30cm下降
X:左回り一回転
B:右回り一回転
LT:後ろ回り一回転
RT:前回り一回転
Telloを離陸させる前に、コントローラのボタン入力に反応するか試します。
十字キーを押してForward, Back, Right, Leftなどと表示されるか、YでUp、AでDown、LB/RBでRotate〜と表示されるかなどを試しておきます。
コントローラ入力が効かない場合は、F710のAボタンなどを押しながら受信機を刺し直します。(参考ページ)
ボタンや十字キーを押したら、カメラ映像で動いたことを確認して次のコマンドを送るようにすると安全に飛行できると思います。
正常に反応しているようなら、STARTボタンを押して離陸させ、Telloを動かしてみましょう!
通信状況によって遅延が発生することもあるので、コマンドは高頻度では送らないようにしてあります。
キーボードで動かす
F710が無い場合、キーボードからも動かせます。
キーの割当は以下です。
T:離陸
L:着陸
矢印キー:前後左右移動
A:左30度回転
D:右30度回転
W:30cm上昇
S:30cm下降
Z:左回り一回転
V:右回り一回転
X:前回り一回転
C:後ろ回り一回転
まとめ
TelloのビデオサンプルTello-Videoを改造して、クラウド上のMQTTブローカーを利用してインターネット経由でTelloを遠隔操作する方法を紹介しました。
ゲームコントローラーF710を使って動かすとゲームのように直感的に動かせるので楽しいです。
F710をお持ちでない場合はキーボードでも動かせます。
離れた場所からTelloを動かしたい方の参考になれば幸いです。
書籍紹介
基礎から応用までわかりやすい説明でコード例も多数載っていて、初学者の入門書としては必要十分と感じています。
さらにPythonらしいコードの書き方も言及されていて、スマートなコードが書けるようになります。
参考文献
- 【Mac】Tello_VideoをAnaconda Python3環境で動かす(2021年版)(https://take6shin-tech-diary.com/tello-video-python3/)
- IoT時代を支えるプロトコル「MQTT」(https://codezine.jp/article/detail/8020)
- mosquitto(https://test.mosquitto.org/)
- Stream live video from client to server using OpenCV and Paho-MQTT(https://medium.com/@pritam.mondal.0711/stream-live-video-from-client-to-server-using-opencv-and-paho-mqtt-674d3327e8b3)