Drone (ex_drone v0.2.0)
View SourceBEAM-native drone control for Elixir.
ex_drone provides a supervised, safety-first API for controlling programmable drones. It supports pluggable adapters (simulator, Tello, and more in the future), a safety pipeline that validates every command, and telemetry events for observability.
Getting Started
# Connect to the simulator (no hardware needed)
{:ok, drone} = Drone.connect(:sim, name: :test)
# Enter SDK mode (required for Tello, automatic for sim)
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)Safety
All commands pass through a safety pipeline before reaching the drone. Safety policies can be configured at connection time:
{:ok, drone} = Drone.connect(:sim,
name: :classroom,
safety: [indoor: true, prop_guards: true]
)See Drone.Safety.Policy for all safety options.
Safety warning: Drones are physical devices that can cause injury. Always test in the simulator first. Use prop guards. Do not fly near faces. Have an emergency stop ready. Understand local laws and regulations.
Summary
Types
Result of flight / control commands that go through the safety pipeline.
Result of connect/2.
Registered name of a connected drone vehicle.
Functions
Connects to a drone and starts a supervised process.
Sends the SDK mode activation command.
Disconnects from the drone and stops the vehicle process.
Sends an emergency stop command.
Sends a flip command.
Sends a hover command.
Sends a land command.
Sends a movement command.
Sends a query command to the drone.
Sends a rotation command.
Sets the drone speed.
Sends a stop command (hover in place / cancel velocity).
Sends a takeoff command.
Retrieves telemetry data from the drone.
Types
Result of flight / control commands that go through the safety pipeline.
:ok— success with no payload{:ok, term()}— success with a value (rare for flight cmds; used when the adapter returns a non-:okreply){:error, :safety, term()}— rejected byDrone.Safety{:error, term()}— adapter / connectivity failure
Examples
:ok
{:error, :safety, :max_altitude}
{:error, :not_connected}
Result of connect/2.
{:ok, atom()}— connected; value is the drone name{:error, :name_already_taken}— name already registered{:error, term()}— adapter or supervisor failure
Examples
{:ok, :demo}
{:error, :name_already_taken}
@type drone() :: atom()
Registered name of a connected drone vehicle.
Always an atom looked up via Drone.Vehicle.Registry (pids are not accepted
by the public API).
Examples
:my_drone
:tello_1
:good_advisor
Functions
@spec connect( atom() | module(), keyword() ) :: connect_result()
Connects to a drone and starts a supervised process.
Accepts an adapter identifier (:sim or :tello) or a module that
implements Drone.Adapter. Options are passed to the adapter and
safety policy.
Parameters
adapter(atom() | module()) —:sim,:tello, or adapter moduleopts(keyword()) — connection options::name(atom(), required) — unique vehicle name:safety(keyword() | Drone.Safety.Policy.t()) — safety policy- remaining keys — forwarded to the adapter (e.g.
:initial_x,:drone_ip,:battery)
Returns
Examples
{:ok, drone} = Drone.connect(:sim, name: :test)
{:ok, drone} = Drone.connect(:tello, name: :tello_1, drone_ip: {192, 168, 10, 1})
{:ok, drone} = Drone.connect(:sim, name: :left, initial_x: -50, safety: [indoor: true])
@spec connect_sdk(drone()) :: command_result()
Sends the SDK mode activation command.
Required for Tello drones before any other command. The simulator enters SDK mode automatically on connect but still accepts this command.
Parameters
drone(drone/0) — registered vehicle name
Returns
Example
:ok = Drone.connect_sdk(:my_drone)
@spec disconnect(drone()) :: :ok | {:error, :not_connected}
Disconnects from the drone and stops the vehicle process.
Parameters
drone(drone/0)
Returns
:ok{:error, :not_connected}
Example
:ok = Drone.disconnect(:my_drone)
Sends an emergency stop command.
Bypasses all safety checks and immediately stops the drone's motors. Use only in actual emergencies.
Parameters
drone(drone/0)
Returns
:ok{:error, term()}
Example
:ok = Drone.emergency(:my_drone)
@spec flip(drone(), Drone.Command.flip_direction()) :: command_result()
Sends a flip command.
Parameters
drone(drone/0)direction(Drone.Command.flip_direction()) —:left|:right|:forward|:back
Returns
command_result/0 (may include a prop-guards warning path via telemetry)
Example
:ok = Drone.flip(:my_drone, :left)
@spec hover( drone(), keyword() ) :: command_result()
Sends a hover command.
Parameters
drone(drone/0)opts(keyword()) —:seconds(pos_integer(), default1)
Returns
Example
:ok = Drone.hover(:my_drone, seconds: 5)
@spec land(drone()) :: command_result()
Sends a land command.
The drone must be flying.
Parameters
drone(drone/0)
Returns
Example
:ok = Drone.land(:my_drone)
@spec move(drone(), Drone.Command.direction(), pos_integer()) :: command_result()
Sends a movement command.
Parameters
drone(drone/0)direction(Drone.Command.direction()) —:up|:down|:left|:right|:forward|:backdistance(pos_integer()) — centimeters (20..500)
Returns
Example
:ok = Drone.move(:my_drone, :forward, 100)
@spec query(drone(), Drone.Command.query_type()) :: {:ok, term()} | {:error, term()}
Sends a query command to the drone.
Parameters
drone(drone/0)type(Drone.Command.query_type()) —:battery,:height,:speed,:time,:wifi,:sdk_version, or:serial_number
Returns
{:ok, term()}— query value{:error, :safety, term()}{:error, term()}
Example
{:ok, percent} = Drone.query(:my_drone, :battery)
@spec rotate(drone(), Drone.Command.rotation(), pos_integer()) :: command_result()
Sends a rotation command.
Parameters
drone(drone/0)direction(Drone.Command.rotation()) —:cwor:ccwdegrees(pos_integer()) — 1..3600
Returns
Example
:ok = Drone.rotate(:my_drone, :cw, 90)
@spec set_speed(drone(), pos_integer()) :: command_result()
Sets the drone speed.
Parameters
drone(drone/0)speed(pos_integer()) — cm/s (10..100)
Returns
Example
:ok = Drone.set_speed(:my_drone, 50)
@spec stop(drone()) :: command_result()
Sends a stop command (hover in place / cancel velocity).
Parameters
drone(drone/0)
Returns
Example
:ok = Drone.stop(:my_drone)
@spec takeoff(drone()) :: command_result()
Sends a takeoff command.
The drone must be in SDK mode and not already flying. Safety checks are applied (battery, altitude, geofence, etc.).
Parameters
drone(drone/0)
Returns
Example
:ok = Drone.takeoff(:my_drone)
{:error, :safety, :low_battery} = Drone.takeoff(:low_bat)
Retrieves telemetry data from the drone.
Parameters
drone(drone/0)
Returns
{:ok, map()}— includes:x,:y,:z,:yaw,:battery,:flying,:mode, ...{:error, term()}
Example
{:ok, tel} = Drone.telemetry(:my_drone)
tel.z
#=> 30