内容が古くなっている可能性がありますのでご注意下さい。
Ryze社の小型ドローン「Tello」は手頃な価格でありながら高性能で、一時は品薄状態となった程の人気機種です。

Telloは専用アプリによる操作のほか、ScratchやPython等のプログラミング言語を使用して制御することができます。
そこで、簡単なプログラムを作成してAndroid端末上のPython環境からTelloを操作してみることにします。今回作成するプログラムは離陸と着陸の機能しかありませんので、飛行の際には充分な安全を確保して下さい。
Tello SDK
ドキュメントによると、Tello SDK 1.0.0.0では以下のコマンドが提供されています。
| コマンド | 説明 | レスポンス |
|---|---|---|
| command | commandモードに入る | OK / FALSE |
| takeoff | 自動離陸 | OK / FALSE |
| land | 自動着陸 | OK / FALSE |
| up xx | 上昇 xx=(20-500cm) | OK / FALSE |
| down xx | 下降 xx=(20-500cm) | OK / FALSE |
| left xx | 左方に飛行 xx=(20-500cm) | OK / FALSE |
| right xx | 右方に飛行 xx=(20-500cm) | OK / FALSE |
| forward xx | 前方に飛行 xx=(20-500cm) | OK / FALSE |
| back xx | 後方に飛行 xx=(20-500cm) | OK / FALSE |
| cw xx | 時計回りにxx°回転 xx=(1-3600°) | OK / FALSE |
| ccw xx | 反時計回りにxx°回転 xx=(1-3600°) | OK / FALSE |
| flip x | フリップ x={l,r,f,b,bl,rb,fl,fr} | OK / FALSE |
| speed xx | 速度をxxに設定 xx=(1-100cm/s) | OK / FALSE |
| speed? | 現在の設定速度を取得 | 1-100cm/s |
| battery? | 現在の充電量を取得 | 0-100% |
| time? | 現在の飛行時間を取得 | xx |
Telloへのコマンド送信には、UDPのポート8889を使用します。今回使用するコマンドは、command、takeoff、landの3つです。
ドキュメントでレスポンスが OK / FALSE となっていても、実際には ERROR や error が返されることがあります。
サンプルプログラム
今回作成したプログラムは以下の通りです。GitHubでMITライセンスで公開しています。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import threading
import socket
import time
import sys
from PyQt5.QtWidgets import *
class TelloController1(QWidget):
def __init__(self):
QWidget.__init__(self)
self.initConnection()
self.initUI()
# 通信の設定
def initConnection(self):
host = ''
port = 9000
locaddr = (host,port)
self.tello = ('192.168.10.1', 8889)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.bind(locaddr)
# 受信スレッド起動
recvThread = threading.Thread(target=self.recvSocket)
recvThread.setDaemon(True)
recvThread.start()
# 最初にcommandコマンドを送信
try:
sent = self.sock.sendto('command'.encode(encoding="utf-8"), self.tello)
except:
pass
# UIの作成
def initUI(self):
self.label = QLabel('')
self.label.setFrameStyle(QFrame.Box | QFrame.Plain)
# 終了ボタン
endBtn = QPushButton("End")
endBtn.clicked.connect(self.endBtnClicked)
# 離着陸ボタン
takeoffBtn = QPushButton("Takeoff")
takeoffBtn.clicked.connect(self.takeoffBtnClicked)
landBtn = QPushButton("Land")
landBtn.clicked.connect(self.landBtnClicked)
# ボタンのレイアウト
layout = QGridLayout()
layout.addWidget(self.label,0,0)
layout.addWidget(endBtn,0,1)
layout.addWidget(takeoffBtn,1,0)
layout.addWidget(landBtn,1,1)
self.setLayout(layout)
# 終了処理
def endBtnClicked(self):
sys.exit()
# takeoffコマンド送信
def takeoffBtnClicked(self):
try:
sent = self.sock.sendto('takeoff'.encode(encoding="utf-8"), self.tello)
except:
pass
# landコマンド送信
def landBtnClicked(self):
try:
sent = self.sock.sendto('land'.encode(encoding="utf-8"), self.tello)
except:
pass
# Telloからのレスポンス受信
def recvSocket(self):
while True:
try:
data, server = self.sock.recvfrom(1518)
self.label.setText(data.decode(encoding="utf-8"))
except:
pass
if __name__ == '__main__':
app = QApplication(sys.argv)
window = TelloController1()
window.show()
sys.exit(app.exec_())
Android端末にPython環境を構築
Pythonで開発したプログラムをAndroid端末で動作させるために、Pydroid 3を使用します。

Pydroid 3をインストールして起動すると、以下のような画面が表示されます。

次に、Pythonの拡張ライブラリをインストールします。
左上の「≡」をタップしてメニューを表示させます。

メニューにある「Pip」をタップします。

リストにある「PyQt5」の「INSTALL」ボタンをタップしてインストールします。「PyQt」は、GUIツールキット「Qt」をPython言語で使用するためのものです。
Pythonプログラムの起動と追加インストール
TelloにWiFi接続し、Pydroidの画面上部にあるフォルダのアイコンをタップしてメニューを表示させます。

「Open」をタップし、端末にコピーしておいたPythonプログラムを開きます。

右下の実行ボタン「▶」をタップするとプログラムが起動しますが、初回の起動時には以下のような画面が表示されます。

MinistroはPyQtの実行環境として必要ですので、OKをタップします。

「インストール」をタップしてMinistroをインストールします。
正常に起動すると、以下のような画面が表示されます。

左上に「OK」と表示されているのは、Telloに最初に送信した「command」コマンドの実行結果です。Telloとの通信ができていないと、ここに何も表示されません。
あとは、「Takeoff」ボタンで離陸し、「land」ボタンで着陸します。「End」ボタンはプログラムを終了します。必ず、着陸してからプログラムを終了して下さい。飛行中に「Takeoff」ボタンをタップすると、「ERROR」と表示されます。
