Clojure is fun. Flying AR Parrot Drones are fun. Put them together and there is pure joy.
Ever since I found out that you could program and control your drone over UDP, I couldn’t wait to try it out in Clojure. I had dreams of controlling it with my Emacs REPL. That dream came true and it has been a true joy to fly in a function language. This blog post shows some of the features that the clj-drone project has so far. There is still a bit of work to go to make it complete. But, I wanted to share and hopefully encourage others to start playing with it too.
The Simple Take-off and Landing
(ns clj-drone.example.simple (:require [clj-drone.core :refer :all])) (drone-initialize) ;Use ip and port for non-standard drone ip/port ;(initialize ip port) (drone :take-off) (Thread/sleep 10000) (drone :land)
Here is a video of executing the entire program in nrepl/ emacs
Controlling the Drone with Emacs/ Clojure REPL
Running the program all at once to control the drone is fun. But, I prefer to have more control over it in flight. I find being able to execute commands with keystrokes in emacs, the best way to do it. Here is a short video demonstrating control via the REPL. (Note: I am just doing simple take off / up and landings because of the constraints of flying indoors in my kitchen. There are many more moves you can do if you have more space.)
(ns clj-drone.example.moves (:require [clj-drone.core :refer :all])) (drone-initialize) ;Use ip and port for non-standard drone ip/port ;(initialize ip port) (drone-do-for 4 :take-off) (drone-do-for 2 :up 0.3) (drone-do-for 3.75 :fly 0.2 0 0 0.5) ; sprial (drone :hover) (drone :land)
Looking at the Navigation Data
You can also hook into the navigation feed. There are many drone states and properties to look at. There is a list of all the ones currently available on the github project site. There are also many more, including targeting information, that have yet to be added. There is a logging function that will pair down the navigation properties that you are interested in. The navigation data map as an atom, so it can be de-referenced anywhere in your program. Here is a short video of what the navigation logging data looks like when it is turned on.
(ns clj-drone.example.nav-test (:require [clj-drone.core :refer :all] [clj-drone.navdata :refer :all])) ;; logging is configured to go to the logs/drone.log file (set-log-data [:seq-num :flying :battery-percent :control-state :roll :pitch :yaw :velocity-x :velocity-y :velocity-z]) (drone-initialize) (drone-init-navdata) (drone :take-off) (drone :land) (end-navstream)
Auto-piloting with goals and beliefs
Inspired by reading John McCarthy’s paper on Ascribing Mental Qualities to Machines, the drone can also auto-pilot itself based on goals and beliefs about its streaming navigation data. You define belief-actions and then goals. Finally, you set a vector of the current goals for the drone to process. You can see an example here of the AR drone having three goals: Take off, Get to a cruising altitude, and then land. It does it solely by inspecting and acting on the streaming navigation data.
Code for the program is here: https://github.com/gigasquid/clj-drone/blob/master/examples/nav_goals.clj
I have had a lot of fun so far working on this project. I hope that you get a chance to play with it too. The project is still very young, so stay tuned for updates and, of course, pull requests are always welcome :)