ex_drone

View Source

Hex version Hex docs License CI Coverage Status

BEAM-native drone control for Elixir and Erlang. Fly, monitor, and simulate programmable drones 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 before connecting to real hardware
  • 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.2.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.

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, future adapters)
  • Drone.Geometry -- Shared position math (move, rotate, flip deltas)
  • Drone.Safety -- Pure validation module, no side effects
  • Drone.Telemetry -- :telemetry events 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

See the Architecture guide.

Documentation

Guides

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.

  • [x] Drone public API (connect/2, disconnect/1, takeoff/1, move/3, rotate/3, etc.)
  • [x] Drone.Vehicle — one GenServer per drone, supervised
  • [x] Drone.Adapter behaviour — pluggable adapters
  • [x] Drone.Adapters.Sim — in-process simulator with position tracking, battery drain, failure injection
  • [x] Drone.Adapters.Tello — DJI Tello UDP adapter (command encoding, response parsing, state management)
  • [x] Drone.Command — struct constructors for 14 command types
  • [x] Drone.Safety — 8-stage validation pipeline (args, mode, allowlist, flying, altitude, distance, battery, geofence)
  • [x] Drone.Safety.Policy — default, indoor, unrestricted presets
  • [x] Drone.Safety.Geofence — circle and polygon geofencing
  • [x] Drone.Geometry — shared position math (heading-aware movement, rotation, flips)
  • [x] Drone.Telemetry:telemetry events (command start/stop, safety reject, connect, disconnect)
  • [x] Drone.Mission — command sequence DSL with error-early semantics
  • [x] Drone.Error — error type helpers (safety/1, adapter/1, invalid_command/1)
  • [x] Command argument validation per Tello SDK ranges
  • [x] Emergency stop bypassing all safety checks
  • [x] Dry-run mode for validating missions without flying
  • [x] Flight time simulation (query(:time) returns cumulative motor-on seconds)
  • [x] CI/CD — lint, test matrix (1.17-1.20 / OTP 26-29), coverage, sobelow, dialyzer, docs, Hex.pm publish
  • [x] 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.

  • [x] Drone.Swarm — supervised group of drones with fail-fast fan-out
  • [x] Named swarm registry (Drone.Swarm.Registry)
  • [x] Coordinated takeoff / land / emergency
  • [x] Formation planners — front, column, vee, diamond, echelon, circle
  • [x] Swarm.run/2 / run/3 — formations, per-drone missions, or custom functions
  • [x] Simulator initial world offsets for multi-drone layouts
  • [x] Good Advisor / Bad Advisor example
  • [x] Deferred flocking / closed-loop catalogue (docs/design/v0_2_0_deferred.md)

v0.3.0 — Adapters & Resilience

New hardware adapters, command retry, async missions, and reconnect.

  • [ ] Drone.Adapters.Crazyflie — Crazyflie BLE/USB adapter
  • [ ] Drone.Adapters.MAVLink — MAVLink-compatible drones via serial/UDP
  • [ ] Adapter registry — Drone.Adapter.register/2 for third-party adapters
  • [ ] Common adapter test suite — shared Drone.Adapter.Acceptance tests
  • [ ] Command retry with configurable backoff (safe_to_retry?/1 already in Drone.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 UDP
  • [ ] Drone.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
  • [ ] :telemetry analytics 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