ex_drone
BEAM-native drone control for Elixir and Erlang. Fly, monitor, and simulate programmable drones — including Tello, Crazyflie (mock or Crazyradio), and multi-drone swarms — using supervised processes, telemetry, and missions.
Safety Warning
Drones are physical devices that can cause injury or property damage.
- Do not fly near faces or people
- Use prop guards at all times
- Test in the simulator (or Crazyflie
mock://) before connecting to real hardware - Crazyflie high-level flight requires a working positioning system (Flow, Lighthouse, or Loco)
- Use open indoor spaces or outdoor areas with clear lines of sight
- Have an emergency stop ready at all times
- Understand and follow local laws and regulations
Installation
Add ex_drone to your list of dependencies in mix.exs:
def deps do
[
{:ex_drone, "~> 0.3.0"}
]
end
Quick Start
# Connect to the simulator (no hardware needed)
{:ok, drone} = Drone.connect(:sim, name: :my_drone)
# Enter SDK mode
Drone.connect_sdk(drone)
# Fly
Drone.takeoff(drone)
Drone.move(drone, :up, 40)
Drone.move(drone, :forward, 100)
Drone.rotate(drone, :cw, 90)
Drone.land(drone)
# Disconnect
Drone.disconnect(drone)
Swarms
Coordinate multiple simulated drones with Drone.Swarm:
{:ok, swarm} =
Drone.Swarm.start([
{:good, adapter: :sim, initial_x: -50},
{:bad, adapter: :sim, initial_x: 50}
])
Drone.Swarm.connect_sdk(swarm)
{:ok, _} = Drone.Swarm.takeoff(swarm)
{:ok, _} = Drone.Swarm.run(swarm, :front)
{:ok, _} = Drone.Swarm.land(swarm)
:ok = Drone.Swarm.stop(swarm)
See Swarms, Formations, and
examples/good_bad_advisor.exs.
Safety Policies
All commands pass through a safety pipeline before reaching the drone:
# Indoor flight with tight limits
{:ok, drone} = Drone.connect(:sim, name: :classroom, safety: [indoor: true])
# Custom safety limits
{:ok, drone} = Drone.connect(:sim, name: :safe,
safety: [
max_altitude_cm: 200,
max_distance_cm: 500,
prop_guards: true
]
)
# Dry-run mode (validates commands without sending)
{:ok, drone} = Drone.connect(:sim, name: :test, safety: [dry_run: true])
See Drone.Safety.Policy and the Safety guide.
Tello Connection
{:ok, drone} = Drone.connect(:tello, name: :tello_1)
Drone.connect_sdk(drone)
Drone.takeoff(drone)
Drone.land(drone)
Drone.disconnect(drone)
See the Tello guide.
Crazyflie Connection
{:ok, drone} =
Drone.connect(:crazyflie,
name: :cf_1,
uri: "mock://ready",
positioning: :flow
)
Drone.connect_sdk(drone)
Drone.takeoff(drone)
Drone.move(drone, :forward, 50)
Drone.land(drone)
Drone.disconnect(drone)
Use mock:// without hardware. Real Crazyradio links need a usb_backend
implementing Drone.Adapters.Crazyflie.USB. See the Crazyflie guide
and examples/crazyflie_mock_flight.exs.
mix run examples/crazyflie_mock_flight.exs
Mission Scripts
mission =
Drone.Mission.new()
|> Drone.Mission.sdk_mode()
|> Drone.Mission.takeoff()
|> Drone.Mission.move(:up, 40)
|> Drone.Mission.rotate(:cw, 90)
|> Drone.Mission.land()
{:ok, results} = Drone.Mission.run(mission, :my_drone)
Architecture
- Drone.Vehicle -- One GenServer per drone, supervised
- Drone.Adapter -- Behaviour for drone communication (Sim, Tello, Crazyflie)
- Drone.Geometry -- Shared position math (move, rotate, flip deltas)
- Drone.Safety -- Pure validation module, no side effects
- Drone.Telemetry --
:telemetryevents for observability - Drone.Mission -- Command sequence DSL
- Drone.Swarm -- Multi-drone coordinator (
start/1, fan-out,run/2/run/3) - Drone.Formation -- One-shot geometric formation planners
- Drone.Adapter.Capabilities -- Per-adapter capability metadata
See the Architecture guide.
Documentation
Guides
- Getting Started
- Safety
- Simulator
- Tello
- Crazyflie
- Swarms
- Formations
- Architecture
- Adapter Authoring
- Further Reading
Design
Research
On HexDocs these pages appear under Guides, Design, and Research.
Further Reading
Short starter set; the full annotated list is in docs/further_reading.md.
- Tello:DJI Tello SDK 2.0 User Guide (PDF)
- Swarm behaviour: Reynolds, C. W. "Flocks, Herds, and Schools: A Distributed Behavioral Model." SIGGRAPH, 1987
- Formation control: Balch, T., and Arkin, R. C. "Behavior-based formation control for multirobot teams." IEEE TRA, 1998
- Swarm robotics survey: Brambilla, M. et al. "Swarm robotics: a review from the swarm engineering perspective." Swarm Intelligence, 2013
- Motion planning: LaValle, S. M. Planning Algorithms
- Safety: Leveson, N. G. Engineering a Safer World. MIT Press, 2011
- OTP:OTP Design Principles
- Other platforms:Crazyflie, MAVLink, PX4, ArduPilot, Nerves
Roadmap
v0.1.0 — Tello + Simulator Foundation
Public API, supervised processes, safety pipeline, simulator, Tello adapter, missions, telemetry.
Dronepublic API (connect/2,disconnect/1,takeoff/1,move/3,rotate/3, etc.)Drone.Vehicle— one GenServer per drone, supervisedDrone.Adapterbehaviour — pluggable adaptersDrone.Adapters.Sim— in-process simulator with position tracking, battery drain, failure injectionDrone.Adapters.Tello— DJI Tello UDP adapter (command encoding, response parsing, state management)Drone.Command— struct constructors for 14 command typesDrone.Safety— 8-stage validation pipeline (args, mode, allowlist, flying, altitude, distance, battery, geofence)Drone.Safety.Policy— default, indoor, unrestricted presetsDrone.Safety.Geofence— circle and polygon geofencingDrone.Geometry— shared position math (heading-aware movement, rotation, flips)Drone.Telemetry—:telemetryevents (command start/stop, safety reject, connect, disconnect)Drone.Mission— command sequence DSL with error-early semanticsDrone.Error— error type helpers (safety/1,adapter/1,invalid_command/1)- Command argument validation per Tello SDK ranges
- Emergency stop bypassing all safety checks
- Dry-run mode for validating missions without flying
- Flight time simulation (
query(:time)returns cumulative motor-on seconds) - CI/CD — lint, test matrix (1.17-1.20 / OTP 26-29), coverage, sobelow, dialyzer, docs, Hex.pm publish
- 291+ tests, credo --strict clean, --warnings-as-errors clean
v0.2.0 — Swarms and Mission Orchestration
Multi-drone coordination on the v0.1.0 vehicle model.
Drone.Swarm— supervised group of drones with fail-fast fan-out- Named swarm registry (
Drone.Swarm.Registry) - Coordinated takeoff / land / emergency
- Formation planners — front, column, vee, diamond, echelon, circle
Swarm.run/2/run/3— formations, per-drone missions, or custom functions- Simulator initial world offsets for multi-drone layouts
- Good Advisor / Bad Advisor example
- Deferred flocking / closed-loop catalogue (
docs/design/v0_2_0_deferred.md)
v0.3.0 — Crazyflie Adapter & Capabilities
Single-drone Crazyflie high-level flight, capability reporting, and shared adapter contracts.
Drone.Adapters.Crazyflie— Crazyradio / mock high-level position flight- CRTP logging subscribe — battery (
pm.batteryLevel/pm.vbat) +sys.canfly - Optional SafeLink negotiation (
?safelink=1) - Pluggable
usb_backend(Drone.Adapters.Crazyflie.USB) - Adapter capabilities — optional
capabilities/1+Drone.capabilities/1 - Common adapter acceptance tests — shared Sim / Crazyflie contract checks
- Capability-aware mission validation before takeoff
- Estimator / stale-telemetry safety options (fail closed)
- Deferred catalogue (
docs/design/v0_3_0_deferred.md) Drone.Adapters.MAVLink— MAVLink-compatible drones via serial/UDP- Adapter registry —
Drone.Adapter.register/2for third-party adapters - Command retry with configurable backoff (
safe_to_retry?/1already inDrone.Command) Mission.run_async/2— fire-and-forget mission execution with progress events- Reconnect on adapter failure — Vehicle auto-reconnects after network errors
Drone.Adapters.Tello— state recovery on reconnect (re-query SDK mode, battery, position)- Configurable command timeout per-vehicle (default 10s)
v0.4.0 — Video & Sensors
Video stream handling and real-time sensor data from Tello EDU.
Drone.Adapters.Tello.Stream— receive H.264 video stream via UDPDrone.Adapters.Tello.State— subscribe to real-time telemetry (100ms interval)Drone.Telemetry.stream/1— stream telemetry events as Elixir Stream- Video frame extraction — decode keyframes to JPEG for snapshot API
Drone.query(:wifi_signal)— WiFi signal quality from state stream
v0.5.0 — Persistence & Analytics
Flight logging, replay, and observability.
- Ecto-backed persistence — mission logs, flight history, anomaly tracking
- Mission replay — replay a recorded mission against a simulator for regression testing
:telemetryanalytics dashboard — LiveDashboard plugin with real-time charts- Flight log query API — filter by drone, date, safety rejections, battery level
- Live flocking / neighbor-aware collision avoidance (see deferred swarm catalogue)
v1.0.0 — Stable API
API freeze, production hardening, and deployment guides.
- API stability guarantee — no breaking changes within 1.x
- Fly.io deployment guide — run command relay in the cloud
- Nerves integration guide — run on Raspberry Pi with Tello
- Comprehensive property-based testing (
StreamData) - Performance benchmarks and soak tests
License
MIT