HoloLens1 UWPでTello EDUとUDP連携をして操作するメモです。
やりたいこと
今回は、このように、同じネットワーク内のHoloLensからTello EDUを動かします。
下準備
Tello EDUの下準備です。
Tello EDUをNode-REDから station mode にして操作するメモ をベースに、同じネットワーク上にHoloLensとTello EDUがいる状況を作ります。
無印TelloでもHoloLensから直接つなげてしまえば同じことは出来るのですが、外部の情報と連携させるのであれば、Tello EDUの station mode のほうが扱いやすいです。
HoloLensのソースコード
以下の記事を参考にしました。
- ファイルの作成、書き込み、および読み取り – Windows UWP applications | Microsoft Docs
- Unity UdpClient and UWP DatagramSocket for receiving UDP broadcasts.
Untyの場合はUdpClientというクラスでサクッとやれるのですが、UWPの場合、DatagramSocketを使う必要があるということが分かって、なんとか実装することができました。
このように、Unityでボタンを作成します。InteractionReceiverで受け取る仕組みです。
HoloLensで実際に表示してみるとこのように見えます
以下がソースコードです。適当なGameObjectに割り当てます。
using HUX.Interaction; using HUX.Receivers; using UnityEngine; #if UNITY_UWP using System; using System.IO; using Windows.Networking; using Windows.Networking.Sockets; using Windows.Storage.Streams; #endif public class ButtonManager : InteractionReceiver { #if UNITY_UWP DatagramSocket socket; private HostName Host = new HostName("192.168.XX.YY"); private string Port = "8889"; #endif async void Start() { #if UNITY_UWP Debug.Log("Connecting TelloEDU..."); socket = new DatagramSocket(); socket.MessageReceived += Socket_MessageReceived; await socket.BindServiceNameAsync(Port); #endif } async public void SendDataMessage(string data) { #if UNITY_UWP Debug.LogFormat("SendDataMessage {0}", data); var telloOutputStream = await socket.GetOutputStreamAsync(Host, Port); DataWriter telloDataWriter = new DataWriter(telloOutputStream); telloDataWriter.WriteString(data); await telloDataWriter.StoreAsync(); await telloOutputStream.FlushAsync(); #endif } protected override void OnTapped(GameObject obj, InteractionManager.InteractionEventArgs eventArgs) { base.OnTapped(obj, eventArgs); Debug.LogFormat("{0} button tapped", obj.name); if (obj) { if (obj.name != null) { if (obj.name == "ButtonCommand") { SendDataMessage("command"); } if (obj.name == "ButtonTakeoff") { SendDataMessage("takeoff"); } if (obj.name == "ButtonLand") { SendDataMessage("land"); } } } } #if UNITY_UWP private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args) { Stream streamReadData = args.GetDataStream().AsStreamForRead(); StreamReader reader = new StreamReader(streamReadData); string message = await reader.ReadLineAsync(); Debug.Log("TELLO MESSAGE : " + message); } #endif }
Start 時に、Tello EDUからHoloLens受信するDatagramSocket周りの設定を行っています。
private HostName Host = new HostName("192.168.XX.YY");
の、192.168.XX.YYの部分は、自分のTello EDUのIPに合わせて設定しましょう。
SendDataMessageによってTello EDUにコマンドを送っています。IPさえ合っていれば、起動時につなぎにいって、SendDataMessageで命令を出し返答としてSocket_MessageReceivedで受け取っています。
動かしてみる
実際の動きです。
HoloLensからはこのように見えます。
無事動いていますね!
Socket_MessageReceivedはこのように受信しています。
ButtonTakeoff button tapped (Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51) SendDataMessage takeoff (Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51) TELLO MESSAGE : ok (Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51) ButtonLand button tapped (Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51) SendDataMessage land (Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51) TELLO MESSAGE : ok (Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51)
操作後にTELLO MESSAGEが出力されてますね。
他の方からみるとこのように見えています。
今回はHoloLensとTello EDUだけの連携でしたが、IoTのセンサーデータなどと協調したり、Tello EDUの見ている画像を転送してHoloLensに表示したりと色々と用途がありそうですね。
引き続き、進めていきます!