2km離れた場所からTelloを動かす MQTTで映像とコマンドを送信

スポンサーリンク
Control Tello remotely

前回の記事のように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を遠隔から操作します。

Tello側のPCはTelloとWi-Fi接続するとともに、インターネットにも接続する必要があるので、有線LANもしくはUSBに差し込む追加のWi-Fiモジュールが必要になりますのでご注意ください。

項目バージョン
macOSCatalina 10.15.7 / Big Sur 11.2
AnacondaAnaconda3-2020.11-MacOSX-x86_64
python3.8.5 / 3.8.8
numpy1.19.2
opencv4.5.1
paho-mqtt1.5.1
pygame2.0.1

環境構築

厳密には2台のPCとも下記環境設定のすべてを行う必要はないのですが、簡単化のために環境構築までは共通のものとして説明します。

具体的には操縦側のPCではTello-Videoの内容は不要で、Anaconda環境にnumpy, opencv, paho-mqtt, pygameをインストールし、git cloneで必要なファイルのダウンロードを行えば実践できます。

ただし、まず1台のPCでTello側と操縦側の両方を実行して動作確認し、うまく行ったら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を開始しています。

Modifications of main.py

tello_control.pyの改造内容は以下です。

画像をPublishする処理とコマンドをSubscribeし、受け取ったコマンドに応じてTelloの操縦コマンドを発する処理を追加しています。

Modification2 of tello_control.py (1)
Modifications of tello_control.py (2)

Telloのカメラから取得した画像をMQTTにPublish(送信)するとともに、Tello操縦コマンドをSubscribe(受信)する機能を追加しています。

もし複数の方が同じ時間帯にこのプログラムを実行するとMQTTの通信内容がかぶってしまうので、tello_control.pyremote_tello.py中に含まれる"Tello-Video/jpg-image""Tello-Control/command"の部分を他の人とかぶらないような名前に変更してお使いになることをオススメします。

Telloの遠隔操作実行

Tello側

Telloの電源を入れ、1台目のMacのWi-FiをTelloにつなぎます。

インターネット接続も必要なので有線LANもしくはUSBに差し込むWi-Fiモジュールでインターネットに接続しておきます。

以下でPythonプログラムからTelloの制御を可能な状態にします。

python main.py

以下のようなウィンドウが立ち上がり、Telloのカメラ映像が表示されます。

Tello Controller

操縦側

2台目のMacで以下の操作側プログラムを実行します。

python remote_tello.py

これでTelloのカメラ映像が出れば通信はできています。

Remote Tello

カメラ映像が小さくて見づらい場合、ウィンドウ枠を引っ張って大きくできます。
(単に引き伸ばすだけで解像度が上がるわけではありまあせん)

Big Remote 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を動かしてみましょう!

一回転を試す場合は、Telloの回りに十分なスペース(前後左右、上下に1m程度)がある場合のみ試すようにしましょう。
天井や壁などに衝突すると緊急停止して墜落するので、機体の損傷につながります。
ご注意ください。

通信状況によって遅延が発生することもあるので、コマンドは高頻度では送らないようにしてあります。

キーボードで動かす

F710が無い場合、キーボードからも動かせます。

キーの割当は以下です。

T:離陸
L:着陸
矢印キー:前後左右移動
A:左30度回転
D:右30度回転
W:30cm上昇
S:30cm下降
Z:左回り一回転
V:右回り一回転
X:前回り一回転
C:後ろ回り一回転

まとめ

TelloのビデオサンプルTello-Videoを改造して、クラウド上のMQTTブローカーを利用してインターネット経由でTelloを遠隔操作する方法を紹介しました。

ゲームコントローラーF710を使って動かすとゲームのように直感的に動かせるので楽しいです。

F710をお持ちでない場合はキーボードでも動かせます。

離れた場所からTelloを動かしたい方の参考になれば幸いです。

書籍紹介

入門 Python 3

基礎から応用までわかりやすい説明でコード例も多数載っていて、初学者の入門書としては必要十分と感じています。

さらにPythonらしいコードの書き方も言及されていて、スマートなコードが書けるようになります。

参考文献

タイトルとURLをコピーしました