Drone.Safety (ex_drone v0.3.0)

View Source

Safety validation for drone commands.

Drone.Safety.check/3 is the primary entry point. It receives a command, a safety policy, and the current vehicle state, and returns either {:ok, command} if the command is approved, {:ok, command, warnings} if approved with warnings, or {:error, :safety, reason} if rejected.

The safety pipeline is a pure function with no side effects. It is called by the Drone.Vehicle GenServer before sending any command to the adapter.

Emergency commands bypass all safety checks.

Summary

Types

Safety rejection reasons (same set as Drone.Error.safety_reason/0).

Vehicle kinematics / mode snapshot used by check/3.

Non-fatal warnings attached to an approved command.

Functions

Validates a command against a safety policy and vehicle state.

Types

rejection_reason()

@type rejection_reason() :: Drone.Error.safety_reason()

Safety rejection reasons (same set as Drone.Error.safety_reason/0).

Examples

:max_altitude
:geofence_violation

vehicle_state()

@type vehicle_state() :: %{
  mode: :idle | :sdk_mode | :flying | :emergency,
  x: integer(),
  y: integer(),
  z: integer(),
  yaw: integer(),
  battery: integer(),
  flying: boolean()
}

Vehicle kinematics / mode snapshot used by check/3.

FieldTypeMeaning
:mode:idle | :sdk_mode | :flying | :emergencyFlight mode
:x, :y, :zinteger()Position in centimeters from launch
:yawinteger()Heading in degrees
:batteryinteger()Percent 0..100
:flyingboolean()Whether airborne

Optional extras used by some policies: :estimator_ready (boolean()), :telemetry_at (integer() monotonic ms).

Example

%{mode: :flying, x: 0, y: 100, z: 50, yaw: 0, battery: 80, flying: true}

warning()

@type warning() :: :low_battery | :no_prop_guards

Non-fatal warnings attached to an approved command.

ValueMeaning
:low_batteryBattery below soft warning threshold
:no_prop_guardsFlip allowed but prop guards are not fitted

Examples

:low_battery

Functions

check(cmd, policy, state)

@spec check(Drone.Command.t(), Drone.Safety.Policy.t(), vehicle_state()) ::
  {:ok, Drone.Command.t()}
  | {:ok, Drone.Command.t(), [warning()]}
  | {:error, :safety, rejection_reason()}

Validates a command against a safety policy and vehicle state.

Parameters

  • command (Drone.Command.t()) — candidate command
  • policy (Drone.Safety.Policy.t()) — active limits and flags
  • state (vehicle_state/0) — current kinematics / mode

Returns

  • {:ok, command} — approved with no warnings
  • {:ok, command, warnings} — approved with warning/0 list
  • {:error, :safety, reason} — rejected (rejection_reason/0)

Emergency commands always pass and bypass other checks.

Examples

policy = Drone.Safety.Policy.new(max_altitude_cm: 100)

{:ok, cmd} =
  Drone.Safety.check(
    Drone.Command.takeoff(),
    policy,
    %{mode: :sdk_mode, x: 0, y: 0, z: 0, yaw: 0, battery: 90, flying: false}
  )

{:error, :safety, :already_flying} =
  Drone.Safety.check(
    Drone.Command.takeoff(),
    policy,
    %{mode: :flying, x: 0, y: 0, z: 50, yaw: 0, battery: 90, flying: true}
  )

{:ok, _cmd} = Drone.Safety.check(Drone.Command.emergency(), policy, %{})