Tello Low-Level Protocol (Tello 低レベルプロトコル) とは

トイドローン Tello にはSDKドキュメント で公開されている公式の通信仕様とは別にドキュメント化されていない Low-Level Protocol (低レベルプロトコル) と呼ばれる通信仕様が存在します。これはメーカーから公式にアナウンスされたものではなく、TelloPilotsコミュニティが独自に解析したものです。

Low-Level Protocol のメリット

Low-Level Protocol を使用すると、公式の通信仕様には存在しない機能が利用できます。 例えば、公式の通信仕様では写真撮影はサポートされていませんが、Low-Level Protocol を使うとそれが可能になります。 Telloの状態取得に関しても「光量不足」など公式通信仕様では取得できない情報が取得できます。

Low-Level Protocol のデメリット

デメリットは大きく2つあります。

  • 誰も動作保証してくれない。
  • 実装がめちゃくちゃ面倒。

このうち、前者に関してはおそらく半永久的に解決されない問題だとおもうのですが、後者に関してはいくつかの言語では利用を簡単にするためのラッパーが用意されており、デメリットはかなり緩和できます。

例えば Python の場合は TelloPy がそれに該当します。その他の言語に関しても こちらのページ に記載されている Gobot (Go言語) や TelloLib (C#) では低レベルプロトコルを使用しています。

作ってみた

さてここからが本題です。

私の場合、Android OS 上 (もうちょっと具体的に言うと Meta Quest 2 や Lynx R-1 といった MR デバイス) で動くアプリで使ってみたかったので、Java か Kotlin での実装を探したのですが、ざっと見た感じではなさそうでした。ということで「ならばちょっと自作してみるかー」というのが事の始まりです。

結構軽い気持ちで始めたのですが思いのほか面倒で (リトルエンディアンだのビットシフトだの…) 途中ちょっと後悔したりもしましたが、偉大な先人たちの知恵のおかげで何とか完成にこぎつけたので公開します。

使い方

上記リポジトリを git clone して、gradleでビルドすれば利用可能になります。

実際の動かし方に関しては、かなりシンプルなのでリファレンス的な説明よりも、Example.javaを見てもらう方が早いかなという気がします。

ということでまずは Java のユニットテストが実行できる IDE で開いてメソッド単位でテスト実行してみることをお勧めします。

  • 注意: 前述の通り、非公式の通信仕様を使っているため想定通りの動きができるかどうかは保証できません。 想定外の動作等によるドローン・家具・物の破壊やケガなどの可能性は十分ありますが、その点について私が保証できることは一切ありません。 というとこで「おーそれでもいいよ。『何か起こっても自分の責任』でいいから試してみたい」という勇者の方のみお試しください。
  • Example.java には以下のメソッドがあります:
    • testGetStates: Telloの状態を出力する
    • testVideoRecording: ビデオ録画を行う
    • testPicture: 写真撮影を行う
    • testStickCommand: 「離陸 → 移動・回転 → 着陸」という一連の動作を行う

最後の testStickCommand 以外は Tello が動かない (離陸しない) のでわりと気軽に試せます。 ただしどのテストを行う際にも、実行前に Tello と PC との Wi-Fi 接続を済ませておく必要があります。

ソフトウェア構造に関して

今回作成した Java用のソフトウェアですが、こちらで紹介したPython用のTello操作プログラムとほぼ同じ構造になっています。

もちろんこちらもクリーンアーキテクチャになっています。

クリーンアーキテクチャ

今回作成したソフトウェアと Python 用プログラムとの一番大きな違いは「ユーザーインターフェース制御を担当する Dashboard に該当する部分が存在しない」という点です。 ユーザーインターフェース制御部分に関してはこのライブラリの担当範囲外なので、別途自力で実装する必要があります。

Unity 用 Android プラグイン

私の場合は、前述のように MR (Mixed Reality) デバイスでこれを使いたかったため、3Dユーザーインターフェースを比較的容易にできる Unity で画面を作成しています。 そのままでは Unity から直接 Tello Low-Level Protocol Wrapper は呼べないため、間を仲介するソフトウェア (Unity 用 Android プラグイン) も作成しました。こちらは上図の「ドライバ層」をAndroid用のクラス実装に置き換えたものです。

詳細は割愛しますが、README.md に従ってセットアップすると Unity のスクリプトから Java からと同様の呼び出しが可能になります。

注意事項・制限事項など

  • Tello Low-Level Protocol Wrappertydrone-android-plugin は MIT ライセンスですが、Tello Low-Level Protocol Wrapperが内部で利用している JavaCV (の中のFFmpeg) は GPL ライセンスです。従って、これらをご自身で作成したソフトウェアに同梱して再配布する場合は、GPLライセンスでの配布となりますのでご注意ください (そんな奇特な人はいないと思いますが念のため…) 。
  • 動画に関してはブロックノイズがひどくて正直鑑賞に堪えられるレベルではありません。 もうちょっとどうにかならないものかと、結構試行錯誤したのですが力尽きました…。「ひょっとしたら Android の場合は MediaCodec 使えば改善できる?」と考えて実装にチャレンジしてみたのですが、ちょっと難しすぎて無理でした…。現在 JavaCV (FFmepg) を使っている理由はここの実装がうまくできなかったということが大きいので、もしこれができれば GPL の呪縛からも逃れられるのですが… (Pull Request まってます💖)

次回

次回は、Unityで実装した 3Dユーザーインターフェース「バーチャル3Dコントローラ」を紹介します!

Tello 関連記事