With a bit more work, I’ve created a companion iOS app for the Drone and also given it WiFi capabilities (it formerly ran on ethernet).

The iOS App

The PiDrone’s iOS app is completely written in Swift and retrieves live data from the drone by fetching JSON data from a webpage every quarter second.  Download it: PiDrone

Screen Shot 2015-04-25 at 4.02.00 PM

Current Features Include:

  • Altitude, Speed, Yaw, Pitch, and Roll measurements displayed
  • Displays WiFi speed (amount of time it takes for the request to be made)
  • Arming and Disarming
  • Taking a Picture and saving it to the camera roll
  • Live Stream displayed in a Web View

I currently have two classes, WebModel.swift for accessing the JSON web page, and ViewController.swift to display the stats in a UI from the WebModel

Inside WebModel.swift

Here is the code for synchronously (doesn’t need to be asynchronous since it only takes <0.1 seconds) retrieving the JSON text:

The code for parsing the JSON in to a more accessible swift dictionary:

To invoke some action, such as arming the quadcopter, the code simply access a specific URL on the Pi’s CherryPy web server, which then causes the python code to use the DroneKit libraries to set the quadcopter as armed. I made a simple request method that makes a request to any url asynchronously:

The code for downloading the picture asynchronously and saving it to the Photos library:

To save the picture to the camera roll, I am downloading a still shot provided by the MJPG web application. This process needs to be asynchronous since downloading images takes a significant amount of time and downloading in synchronously causes the button press animation to hang up.

Inside ViewController.swift

The code for displaying the live stream video:

I haven’t quite figured out yet how to center the video feed perfectly with no white space on the screen, so I’m now stuck with having to using the pinch and pan gestures to manually arrange the stream.

To create the nice rounded rect effect around each of the label/buttons, I created outlets to each of the UI elements and a method named roundView which rounds the UIView it receives.

I then individually call roundView on all of the different UIViews I want rounded on the storyboard. I could have also subclassed UILabel and UIButton as UIRoundedLabel and UIButton for cleaner code.

To update the statistics live, I set a NSTimer that “rings” every 0.25 seconds by calling the method update.

A quick look at the Storyboard

Screen Shot 2015-04-25 at 4.03.22 PM

Since none of the Apple UI objects were perfect, I made my own combobox type object for selecting the Flight mode. Its very simple and there is a just a group of other possible flight modes to choose hanging under the current flight mode that are usually hidden.

Screen Shot 2015-04-29 at 5.42.51 PM

When the current flight mode is clicked, the other flight modes unhide themselves, When one of these alternate flight modes are chosen, the group hides again. Instead of updating the current flight mode immediately after the new flight mode is chosen, the program instead waits for the next time update() is called to update the current flight mode when the drone’s flight mode has already been changed.

Next Up:

  • Maps integration with MapKit
    • Location of Drone
    • Location of User
  • Signal Strength