W. Files Conspiracy vol. 2: Spy drones over UDP

How I analyze drone's flight data gathered over UDP with Warp 10 and use a dashboard as code to display it.

A couple of years ago I've bought a small low-cost drone: Tello. You can pilot it with your smartphone through Wi-Fi connection and UDP protocol. I decided to hack it and to analyze the data that is emitted by the drone.

After the very serious post about chemtrails, it's time to open the second W. Files chapter!

So, I've developed a small NodeJS lib in order to programmatically pilot the drone, fetch its flights' telemetry, and stream its video on my laptop. After a couple of coffee and hours, I achieved it. You can find it here.

I have children and the main goal of this dev was to make them develop and have fun. In fact, they never gave a buck about that project, I am the only child who plays with it.

picture of the Tello drone
Tello is watching you

If you own a Tello, you can of course use this lib. But the main aim of this blog post is not really the drone but to manage its flight data.

This little drone communicates over UDP and regularly push its telemetry which contains :

tofcmto floor distance
templ°Cmin temperature
temph°Cmax temperature
pitch°attitude pitch
roll°attitude roll
yaw°attitude yaw
agx0.001gacceleration x
agy0.001gacceleration y
agz0.001gacceleration z
vgxcm/sspeed x
vgycm/sspeed y
vgzcm/sspeed z
Flight data

Nice. Here, we will transmit the flight data through UDP to Warp 10.

Warp 10

The Warp 10 Platform has a lot of functionalities. In particular for our usage here, you can use the built-in UDPPlugin to start a UDP server.

Warp 10 is an open source platform designed to collect, store, and analyze sensor / IoT data.

Assuming Warp 10 is installed in /opt/warp10, activate it by editing the file /opt/warp10/etc/conf.d/80-udp-plugin.conf:

// activate the UDP plugin
warp10.plugin.udp = io.warp10.plugins.udp.UDPWarp10Plugin
udp.dir = ${standalone.home}/udp
udp.period = 5000

You may also activate the Debug Extension:

warpscript.extension.debug = io.warp10.script.ext.debug.DebugWarpScriptExtension

Then, create a new directory /opt/warp10/udp and create a new file called tello.mc2 in it:

Analyze drone’s flight data gathered over UDP with Warp 10 Click To Tweet

And then restart Warp 10. Connect the drone to your Wi-Fi local card and launch this JavaScript which plays a small scenario:

import {Tello} from "@giwisoft/ryze-tello-sdk";
const tello = new Tello();
(async () => {  
  // Start the engine and play "Ride Of The Valkyries"
  await tello.start();  await tello.takeoff();
  // Go up
  await tello.up(50);
  // Perform a forward flip
  await tello.flip("f");
  // Go forward
  await tello.forward(50);
  await tello.right(20);
  // Go backward
  await tello.backward(100);
  await tello.rotateCW(360);
  // Finally land
  await tello.land();
  // And then shut down the engine
})().then(() => tello.stop());

If you tail /opt/warp10/logs/warp10.log you will see the flight data:

[1616403713307] UDP: line from IP: port:8889 content=pitch:0;roll:0;yaw:-156;vgx:0;vgy:0;vgz:0;templ:79;temph:81;tof:10;h:0;bat:82;baro:-99.61;time:31;agx:1.00;agy:-10.00;agz:-998.00;
[1616403713409] UDP: line from IP: port:8889 content=pitch:0;roll:0;yaw:-156;vgx:0;vgy:0;vgz:0;templ:79;temph:81;tof:10;h:0;bat:82;baro:-99.83;time:31;agx:1.00;agy:-10.00;agz:-1002.00;
[1616403713511] UDP: line from IP: port:8889 content=pitch:0;roll:0;yaw:-156;vgx:0;vgy:0;vgz:0;templ:79;temph:81;tof:10;h:0;bat:82;baro:-99.87;time:31;agx:1.00;agy:-11.00;agz:-1003.00;
[1616403713613] UDP: line from IP: port:8889 content=pitch:0;roll:0;yaw:-156;vgx:0;vgy:0;vgz:0;templ:79;temph:81;tof:10;h:0;bat:82;baro:-99.86;time:31;agx:2.00;agy:-9.00;agz:-1001.00;
[1616403713714] UDP: line from IP: port:8889 content=pitch:0;roll:0;yaw:-156;vgx:0;vgy:0;vgz:0;templ:79;temph:81;tof:10;h:0;bat:82;baro:-99.80;time:31;agx:0.00;agy:-9.00;agz:-1002.00;

Huh, what an ugly CSV, yes it is. Ok, let's parse it with our previous WarpScript tello.mc2:

Now, wait 5 seconds (Warp 10 put the mc2 in a cache, which TTL was set by udp.period = 5000) and re-launch the previous JavaScript. In the log file you will see something like that:

[1616403713714] {"pitch":0,"roll":0,"yaw":-156,"vgx":0,"vgy":0,"vgz":0,"templ":79,"temph":82,"tof":10,"h":0,"bat":82,"baro":-99.66,"time":31,"agx":0,"agy":-9,"agz":-998}

It is time to persist data into the Warp 10 storage engine. You could either use a multivariate model or a GTS per metric model. To keep things simple I will use the second one (but the first one would be more optimized).

Modify tello.mc2:

Then, wait 5 seconds and re-launch the previous JavaScript.

This drone produces 10 metrics per second for 15 metrics, so we insert 150 points per second. To optimize the ingestion you may use SHM extension to build a buffer and flush it periodically.

First analysis

Now open WarpStudio (https://studio.senx.io) and let's see the distance to floor:

chart representing the distance to floor of the drone
Distance to the floor

If we look at the roll (tello.telemetry.roll), the flip appears clearly:

chart presenting the flip of the drone
The flip

Now, we can try to detect when comes the flip with GRUBBSTEST for example:

chart presenting the flip detection
We detected the flip

The dashboard

After that, we can use Discovery (a dashboarding solution to create highly dynamic Dashboards as Code) to build a dashboard:

Dashboard of the tutorial, presenting 8 tiles, and created thanks to Discovery.
My mission control

Et voilà! As you can see in the code, I used LTTB to subsample while keeping the shape of the plot, it's a handy function when doing dataviz.

Going further

As you can see, it is really easy to fetch and store data coming from a UDP source.

Of course, we can extract a lot of KPIs from this dataset as we detect outliers. We could also develop an alerting system for low batteries or a dynamic dashboard with an auto-refresh feature in order to have a real-time dashboard. It's up to you to build your application.

If you want, we can share this dataset to you if you explain us your use-case. It's always interesting for us to knows what our users are building around Warp 10. Tell us on Twitter or Slack.