Drone (ex_drone v0.1.0)

View Source

BEAM-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

Functions

Connects to a drone and starts a supervised process.

Sends the SDK mode activation command.

Disconnects from the drone and stops the 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).

Sends a takeoff command.

Retrieves telemetry data from the drone.

Types

connect_result()

@type connect_result() :: {:ok, atom()} | {:error, term()}

drone()

@type drone() :: atom()

Functions

connect(adapter, opts)

@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.

Options

  • :name (required) -- a unique name for this drone process
  • :safety -- keyword list of safety policy options (see Drone.Safety.Policy.new/1)
  • All other options are passed to the adapter

Examples

{:ok, drone} = Drone.connect(:sim, name: :test)
{:ok, drone} = Drone.connect(:tello, name: :tello_1, drone_ip: {192, 168, 10, 1})

connect_sdk(drone)

@spec connect_sdk(drone()) :: :ok | {:error, term()}

Sends the SDK mode activation command.

Required for Tello drones before any other command. The simulator enters SDK mode automatically on connect.

disconnect(drone)

@spec disconnect(drone()) :: :ok | {:error, :not_connected}

Disconnects from the drone and stops the process.

emergency(drone)

@spec emergency(drone()) :: :ok | {:error, term()}

Sends an emergency stop command.

This command bypasses all safety checks and immediately stops the drone's motors. Use only in actual emergencies.

flip(drone, direction)

@spec flip(drone(), Drone.Command.flip_direction()) :: :ok | {:error, term()}

Sends a flip command.

Direction must be one of: :left, :right, :forward, :back. The drone must be flying. A safety warning is emitted if prop guards are not installed.

hover(drone, opts \\ [])

@spec hover(
  drone(),
  keyword()
) :: :ok | {:error, term()}

Sends a hover command.

The drone will hover in place for the specified number of seconds.

land(drone)

@spec land(drone()) :: :ok | {:error, term()}

Sends a land command.

The drone must be flying.

move(drone, direction, distance)

@spec move(drone(), Drone.Command.direction(), pos_integer()) ::
  :ok | {:error, term()}

Sends a movement command.

Direction must be one of: :up, :down, :left, :right, :forward, :back. Distance must be between 20 and 500 cm.

query(drone, type)

@spec query(drone(), Drone.Command.query_type()) :: {:ok, term()} | {:error, term()}

Sends a query command to the drone.

Query type must be one of: :battery, :height, :speed, :time, :wifi, :sdk_version, :serial_number.

Returns {:ok, value} where value depends on the query type.

rotate(drone, direction, degrees)

@spec rotate(drone(), Drone.Command.rotation(), pos_integer()) ::
  :ok | {:error, term()}

Sends a rotation command.

Direction must be :cw (clockwise) or :ccw (counter-clockwise). Degrees must be between 1 and 3600.

set_speed(drone, speed)

@spec set_speed(drone(), pos_integer()) :: :ok | {:error, term()}

Sets the drone speed.

Speed must be between 10 and 100 cm/s.

stop(drone)

@spec stop(drone()) :: :ok | {:error, term()}

Sends a stop command (hover in place).

takeoff(drone)

@spec takeoff(drone()) :: :ok | {:error, term()}

Sends a takeoff command.

The drone must be in SDK mode and not already flying. Safety checks are applied (battery, altitude, geofence, etc.).

telemetry(drone)

@spec telemetry(drone()) :: {:ok, map()} | {:error, term()}

Retrieves telemetry data from the drone.

Returns a map with position, battery, and state information.