ex_drone

Hex versionHex docsLicenseCICoverage Status

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.

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

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.

Roadmap

v0.1.0 — Tello + Simulator Foundation

Public API, supervised processes, safety pipeline, simulator, Tello adapter, missions, telemetry.

v0.2.0 — Swarms and Mission Orchestration

Multi-drone coordination on the v0.1.0 vehicle model.

v0.3.0 — Crazyflie Adapter & Capabilities

Single-drone Crazyflie high-level flight, capability reporting, and shared adapter contracts.

v0.4.0 — Video & Sensors

Video stream handling and real-time sensor data from Tello EDU.

v0.5.0 — Persistence & Analytics

Flight logging, replay, and observability.

v1.0.0 — Stable API

API freeze, production hardening, and deployment guides.

License

MIT