Skip to content

DroneAPI

DroneAPI

DroneAPI

Type-safe API for F09-lite drone control.

Wraps the legacy Controlserver with proper types, validation, and error handling. All telemetry methods return immediately without artificial delays.

is_connected property

is_connected: bool

Check if connected to drone.

config property

config: DroneConfig

Resolved runtime configuration for this API instance.

default_ip property

default_ip: str

Configured default drone IP address.

connect

connect(ip: str | None = None, timeout: float = 5.0) -> None

Connect to drone.

Parameters:

Name Type Description Default
ip str | None

Drone IP address. Uses the configured default if None.

None
timeout float

Connection timeout in seconds (unused currently).

5.0

Raises:

Type Description
DroneConnectionError

If connection fails.

disconnect

disconnect() -> None

Disconnect from drone and release resources.

robust_connect

robust_connect(ip: str | None = None, timeout: float = 5.0, verbose: bool = True) -> bool

Connect to drone with robust error handling and diagnostics.

Unlike connect(), this method doesn't raise exceptions on failure. Instead, it prints diagnostic information and returns a boolean.

Parameters:

Name Type Description Default
ip str | None

Drone IP address. Uses the configured default if None.

None
timeout float

Connection timeout in seconds (unused currently).

5.0
verbose bool

Print diagnostic messages.

True

Returns:

Type Description
bool

True if connection successful, False otherwise.

Example:

if not drone.robust_connect("192.168.100.1"):
    print("Check WiFi connection")
    sys.exit(1)

move

move(direction: Direction, distance_cm: float, led: LEDConfig | None = None, blocking: bool = True, speed: VelocityLevel | int = ZOOM) -> CommandResult

Move drone in specified direction.

This is the unified movement API replacing separate forward/back/left/right methods.

Parameters:

Name Type Description Default
direction Direction

Movement direction (FORWARD, BACK, LEFT, RIGHT, UP, DOWN)

required
distance_cm float

Distance in centimeters (positive value)

required
led LEDConfig | None

Optional LED configuration during movement

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True
speed VelocityLevel | int

Movement speed - VelocityLevel.SLOW, MEDIUM, ZOOM, or TURBO. Controls position controller P-gain (lower value = higher gain = faster). Default is ZOOM (100).

ZOOM

Returns:

Type Description
CommandResult

CommandResult indicating success/failure

Raises:

Type Description
NotReady

If drone not connected or not ready

LowBattery

If battery below threshold

Example:

drone.move(Direction.FORWARD, 100)  # Move forward 100cm (default ZOOM speed)
drone.move(Direction.FORWARD, 100, speed=VelocityLevel.TURBO)  # Very fast
drone.move(Direction.LEFT, 50, speed=VelocityLevel.SLOW)  # Slow, smooth

rotate

rotate(angle_degrees: float, led: LEDConfig | None = None, blocking: bool = True) -> CommandResult

Rotate drone by specified angle.

Parameters:

Name Type Description Default
angle_degrees float

Rotation angle in degrees. Positive = counter-clockwise (left) Negative = clockwise (right)

required
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

move_to

move_to(x: float, y: float, z: float, led: LEDConfig | None = None, blocking: bool = True, speed: VelocityLevel | int = ZOOM) -> CommandResult

Move to position via straight line flight.

Position interpretation depends on QR localization mode:

  • QR localization ENABLED (set_qr_localization(True)): Coordinates are ABSOLUTE positions in the QR code coordinate system. The drone flies to the exact (x, y, z) position on the QR mat.

  • QR localization DISABLED (default): Coordinates are relative to the takeoff position (which is 0, 0, 0). Effectively works as absolute positioning from the takeoff origin.

Parameters:

Name Type Description Default
x float

X position in cm (right is positive)

required
y float

Y position in cm (forward is positive)

required
z float

Z position in cm (up is positive, relative to ground)

required
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True
speed VelocityLevel | int

Movement speed - VelocityLevel.SLOW, MEDIUM, ZOOM, or TURBO. Controls position controller P-gain (lower value = higher gain = faster). Default is ZOOM (100).

ZOOM

Returns:

Type Description
CommandResult

CommandResult

Example:

# With QR localization - fly to absolute position on QR mat
drone.set_qr_localization(enabled=True)
drone.move_to(x=200, y=350, z=120)  # Fly to (200, 350, 120) cm

# Without QR localization - position relative to takeoff point
drone.move_to(x=100, y=100, z=0)  # Fly to 100cm right, 100cm forward

# With speed control
drone.move_to(x=100, y=100, z=50, speed=VelocityLevel.TURBO)  # Very fast
drone.move_to(x=100, y=100, z=50, speed=VelocityLevel.SLOW)  # Slow, smooth

curve_to

curve_to(x: float, y: float, z: float, ccw: bool = True, led: LEDConfig | None = None, blocking: bool = True) -> CommandResult

Move to position along curved path.

Like move_to(), position interpretation depends on QR localization mode:

  • QR enabled: Absolute position on QR mat
  • QR disabled: Position relative to takeoff origin (0, 0, 0)

Parameters:

Name Type Description Default
x float

X position in cm

required
y float

Y position in cm

required
z float

Z position in cm

required
ccw bool

Counter-clockwise curve (True) or clockwise (False)

True
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

circle

circle(radius_cm: float, led: LEDConfig | None = None, blocking: bool = True) -> CommandResult

Fly in a circle around current position.

Parameters:

Name Type Description Default
radius_cm float

Circle radius in cm. Positive = counter-clockwise Negative = clockwise

required
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

takeoff

takeoff(height_cm: int = 100, led: LEDConfig | None = None, blocking: bool = True, flags: TakeoffFlags | int = NONE) -> CommandResult

Take off to specified hover height.

Parameters:

Name Type Description Default
height_cm int

Target hover height in centimeters (default 100)

100
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True
flags TakeoffFlags | int

Takeoff behavior flags (TakeoffFlags enum or int bitmask):

  • TakeoffFlags.NONE (0): Normal takeoff (default)
  • TakeoffFlags.RESET_YAW (1): Reset yaw orientation on takeoff
  • TakeoffFlags.WITH_LOAD (2): Takeoff with load/clamp - may have different dynamics Flags can be combined: TakeoffFlags.RESET_YAW | TakeoffFlags.WITH_LOAD
NONE

Returns:

Type Description
CommandResult

CommandResult

Raises:

Type Description
NotReady

If drone not in ready state

Example:

drone.takeoff()  # Normal takeoff to 100cm
drone.takeoff(height_cm=80, flags=TakeoffFlags.WITH_LOAD)  # With load mode
drone.takeoff(flags=TakeoffFlags.RESET_YAW | TakeoffFlags.WITH_LOAD)  # Combined

land

land(led: LEDConfig | None = None, blocking: bool = True) -> CommandResult

Land the drone.

Parameters:

Name Type Description Default
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

hover

hover(duration_seconds: float, led: LEDConfig | None = None, blocking: bool = True) -> CommandResult

Hover in place for specified duration.

Parameters:

Name Type Description Default
duration_seconds float

Hover duration

required
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

flip

flip(direction: FlipDirection, led: LEDConfig | None = None, blocking: bool = True) -> CommandResult

Perform a flip/somersault maneuver.

Parameters:

Name Type Description Default
direction FlipDirection

Flip direction (FORWARD, BACK, LEFT, RIGHT)

required
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

bounce

bounce(frequency: int, height_cm: float, led: LEDConfig | None = None, blocking: bool = True) -> CommandResult

Perform bouncing motion.

Parameters:

Name Type Description Default
frequency int

Bounce frequency

required
height_cm float

Bounce height in cm

required
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

spin

spin(rotations: float, led: LEDConfig | None = None, blocking: bool = True) -> CommandResult

Perform 360-degree rotation(s).

Parameters:

Name Type Description Default
rotations float

Number of rotations. Positive = counter-clockwise Negative = clockwise

required
led LEDConfig | None

Optional LED configuration

None
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

arm

arm() -> CommandResult

Arm motors (low speed rotation).

Returns:

Type Description
CommandResult

CommandResult

disarm

disarm() -> CommandResult

Disarm motors.

Returns:

Type Description
CommandResult

CommandResult

get_state

get_state() -> DroneState

Get complete drone state snapshot.

Returns:

Type Description
DroneState

DroneState with all telemetry data

get_position

get_position() -> Vector3

Get current position.

Returns:

Type Description
Vector3

Position vector in cm

Raises:

Type Description
TelemetryUnavailable

If no telemetry data

get_orientation

get_orientation() -> Orientation

Get current orientation (yaw, pitch, roll).

Returns:

Type Description
Orientation

Orientation in degrees

Raises:

Type Description
TelemetryUnavailable

If no telemetry data

get_battery

get_battery() -> int

Get battery percentage.

Returns:

Type Description
int

Battery level (0-100)

Raises:

Type Description
TelemetryUnavailable

If no telemetry data

get_altitude

get_altitude() -> float

Get ToF altitude.

Returns:

Type Description
float

Altitude in cm

Raises:

Type Description
TelemetryUnavailable

If no telemetry data

get_velocity

get_velocity() -> Vector3

Get current velocity.

Returns:

Type Description
Vector3

Velocity vector in cm/s

Raises:

Type Description
TelemetryUnavailable

If no telemetry data

get_acceleration

get_acceleration() -> Vector3

Get current acceleration.

Returns:

Type Description
Vector3

Acceleration vector in cm/s^2

Raises:

Type Description
TelemetryUnavailable

If no telemetry data

get_obstacles

get_obstacles() -> Obstacles

Get obstacle detection state.

Returns:

Type Description
Obstacles

Obstacles indicating which directions are blocked

get_flight_data

get_flight_data() -> FlightData

Get complete flight telemetry snapshot.

Returns:

Type Description
FlightData

FlightData with all sensor values

Raises:

Type Description
TelemetryUnavailable

If no telemetry data

get_drone_id

get_drone_id() -> int | None

Get drone ID.

Returns:

Type Description
int | None

Drone ID as integer, or None if not connected

recognize_target

recognize_target(target: AIRecognitionTarget | int) -> AIResult

Attempt to recognize a visual target (digit, arrow, letter).

Parameters:

Name Type Description Default
target AIRecognitionTarget | int

Target type to recognize. Use AIRecognitionTarget enum:

  • AIRecognitionTarget.DIGIT_0 through DIGIT_9 for digits
  • AIRecognitionTarget.ARROW_LEFT/RIGHT/UP/DOWN for arrows
  • AIRecognitionTarget.END_TASK for end marker
  • Integer 65-90 for letters A-Z (ASCII codes)
required

Returns:

Type Description
AIResult

AIResult with recognition data

Example:

result = drone.recognize_target(AIRecognitionTarget.DIGIT_5)
result = drone.recognize_target(AIRecognitionTarget.ARROW_LEFT)
result = drone.recognize_target(65)  # Letter 'A'

recognize_qr

recognize_qr(qr_id: int, mode: VisionMode = OPTICAL_FLOW, timeout: float = 10.0, search_radius: int = 0) -> AIResult

Recognize and align to QR code.

Parameters:

Name Type Description Default
qr_id int

QR code ID to find

required
mode VisionMode

Camera mode (optical flow or front camera)

OPTICAL_FLOW
timeout float

Search timeout in seconds

10.0
search_radius int

Search radius

0

Returns:

Type Description
AIResult

AIResult with QR position data

track_qr

track_qr(qr_id: int, duration: float, mode: VisionMode = OPTICAL_FLOW) -> AIResult

Track QR code for specified duration.

Parameters:

Name Type Description Default
qr_id int

QR code ID to track

required
duration float

Tracking duration in seconds

required
mode VisionMode

Camera mode

OPTICAL_FLOW

Returns:

Type Description
AIResult

AIResult with tracking data

detect_qr

detect_qr(qr_id: int, mode: VisionMode = OPTICAL_FLOW) -> AIResult

Detect and recognize QR code without alignment.

Unlike recognize_qr() which aligns the drone to the QR code, this method only detects and returns position information.

Parameters:

Name Type Description Default
qr_id int

QR code ID to detect (0-9)

required
mode VisionMode

Camera mode (OPTICAL_FLOW for downward, FRONT_CAMERA for forward)

OPTICAL_FLOW

Returns:

Type Description
AIResult

AIResult with:

  • success: Whether QR was detected
  • position: Distance from drone to QR (x, y, z in cm)
  • angle: Yaw angle between drone and QR
  • qr_id: ID of detected QR code

Example:

# Detect QR code 5 using optical flow camera
result = drone.detect_qr(5, VisionMode.OPTICAL_FLOW)
if result.success:
    print(f"QR {result.qr_id} at {result.position}")

get_color

get_color(mode: int = 1) -> ColorResult

Get dominant color from camera.

Parameters:

Name Type Description Default
mode int

Color recognition mode

1

Returns:

Type Description
ColorResult

ColorResult with RGB values

set_led

set_led(led_or_r: LEDConfig | int, g: int = 0, b: int = 0, mode: LEDMode = CONSTANT, duration: float = 0) -> CommandResult

Set LED color and mode.

Can be called with LEDConfig or individual RGB values:

drone.set_led(LEDColor.RED)
drone.set_led(LEDConfig.rgb(255, 128, 0, LEDMode.BLINK))
drone.set_led(255, 0, 0)  # Legacy: r, g, b

Parameters:

Name Type Description Default
led_or_r LEDConfig | int

LEDConfig object, or red channel (0-255) for legacy usage

required
g int

Green channel (0-255) - only used if led_or_r is int

0
b int

Blue channel (0-255) - only used if led_or_r is int

0
mode LEDMode

LED mode - only used if led_or_r is int

CONSTANT
duration float

Effect duration in seconds (0 = indefinite)

0

Returns:

Type Description
CommandResult

CommandResult

Example:

# Using LEDConfig (preferred)
drone.set_led(LEDColor.BLUE)
drone.set_led(LEDColor.RED.with_mode(LEDMode.BLINK))
drone.set_led(LEDConfig.rgb(128, 64, 255))

# Using individual values (legacy)
drone.set_led(255, 0, 0, LEDMode.CONSTANT)

enable_led

enable_led(blocking: bool = True) -> CommandResult

Enable LEDs.

Re-enables LEDs after they have been disabled with disable_led(). Does not change the current LED color/mode - just makes them visible.

Parameters:

Name Type Description Default
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

Example:

drone.set_led(255, 0, 0)  # Set red
drone.disable_led()       # Turn off
drone.enable_led()        # Red is back

disable_led

disable_led(blocking: bool = True) -> CommandResult

Disable LEDs.

Turns off all LEDs without clearing the color/mode settings. Use enable_led() to turn them back on.

Parameters:

Name Type Description Default
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

Example:

drone.set_led(0, 255, 0)  # Set green
drone.disable_led()       # LEDs off
# ... later ...
drone.enable_led()        # Green is back

cancel_rgb_animation

cancel_rgb_animation(blocking: bool = True) -> CommandResult

Cancel current RGB animation.

Stops any running LED animation/effect and returns LEDs to static state. Useful for interrupting breathing, blinking, or other animated effects.

Parameters:

Name Type Description Default
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

Example:

drone.set_led(255, 0, 0, mode=LEDMode.BREATHING)  # Start breathing
time.sleep(5)
drone.cancel_rgb_animation()  # Stop animation

set_rgb_brightness

set_rgb_brightness(brightness: int, blocking: bool = True) -> CommandResult

Set RGB LED brightness.

Parameters:

Name Type Description Default
brightness int

Brightness level (firmware-dependent range)

required
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

vertical_circle

vertical_circle(radius_cm: int, blocking: bool = True) -> CommandResult

Perform vertical circle maneuver.

Parameters:

Name Type Description Default
radius_cm int

Circle radius in cm (positive=CCW, negative=CW)

required
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

Note

Requires minimum altitude of 0.35m

set_avoidance_direction

set_avoidance_direction(direction: Direction, distance_cm: int = 0, barrier_mask: BarrierMask | int = ALL, blocking: bool = True) -> CommandResult

Set conditional avoidance behavior with directional control.

When obstacle is detected (checked against barrier_mask), drone moves in the specified direction. This is a conditional move, it only executes if an obstacle is actually detected by the IR/ToF sensors.

Parameters:

Name Type Description Default
direction Direction

Direction to move when obstacle detected (FORWARD, BACK, LEFT, RIGHT, UP, DOWN)

required
distance_cm int

Avoidance distance in cm

0
barrier_mask BarrierMask | int

Which sensors trigger avoidance. Use BarrierMask enum:

  • BarrierMask.FRONT, BACK, LEFT, RIGHT, UP, DOWN
  • BarrierMask.HORIZONTAL (front + back + left + right)
  • BarrierMask.ALL (default, all sensors)
  • Combine with |: BarrierMask.FRONT | BarrierMask.BACK
ALL
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

Example:

# Move back 50cm if obstacle detected in front
drone.set_avoidance_direction(Direction.BACK, 50, BarrierMask.FRONT)

# Move left 30cm if front or right obstacle detected
drone.set_avoidance_direction(Direction.LEFT, 30, BarrierMask.FRONT | BarrierMask.RIGHT)

# Move up if any horizontal obstacle
drone.set_avoidance_direction(Direction.UP, 20, BarrierMask.HORIZONTAL)

get_product_id

get_product_id() -> CommandResult

Request product ID / autopilot version from drone.

Triggers the drone to send autopilot version information.

Returns:

Type Description
CommandResult

CommandResult

set_velocity_level

set_velocity_level(level: VelocityLevel | int, horizontal_vel: int = 0, blocking: bool = True) -> CommandResult

Set manual/RC control velocity level.

IMPORTANT

This command sets the velocity limit for MANUAL RC/joystick control only. It does NOT affect the speed of API movement commands like move() or move_to().

To control the speed of API movement commands, use the speed parameter directly:

drone.move(Direction.FORWARD, 100, speed=VelocityLevel.TURBO)
drone.move_to(x=100, y=100, z=50, speed=VelocityLevel.ZOOM)

This command affects:

- RC/joystick manual control speed limits
- manual_vel_max, manual_vel_z_up_max, manual_vel_z_down_max in firmware

Parameters:

Name Type Description Default
level VelocityLevel | int

Velocity in cm/s (0-300). Use integer values directly:

  • 100 = 1.0 m/s (slow RC)
  • 200 = 2.0 m/s (medium RC)
  • 300 = 3.0 m/s (fast RC) NOTE: Do NOT use VelocityLevel enum here - it's designed for move() P-gain control, not RC velocity mapping.
required
horizontal_vel int

Optional horizontal velocity override in cm/s (firmware-specific)

0
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

See Also

move() and move_to() - use their speed parameter for API movement speed control

set_yaw_rate_level

set_yaw_rate_level(level: int, blocking: bool = True) -> CommandResult

Set yaw rotation rate level.

Parameters:

Name Type Description Default
level int

Yaw rate level

required
blocking bool

If True (default), wait for command completion. If False, return immediately.

True

Returns:

Type Description
CommandResult

CommandResult

enable_battery_failsafe

enable_battery_failsafe() -> CommandResult

Enable battery failsafe.

When enabled, drone will auto-land when battery reaches critical level.

Returns:

Type Description
CommandResult

CommandResult

disable_battery_failsafe

disable_battery_failsafe() -> CommandResult

Disable battery failsafe.

WARNING

Disabling battery failsafe may cause drone to fall if battery is depleted during flight.

Returns:

Type Description
CommandResult

CommandResult

set_parameters

set_parameters(velocity: int = 0, yaw_rate: int = 0, brightness: int = 0, avoidance: bool = False, battery_failsafe: bool = False, fast_land: bool = False) -> CommandResult

Set multiple drone parameters in a single command.

This is more efficient than calling individual setters when configuring multiple parameters at once.

Parameters:

Name Type Description Default
velocity int

Velocity level (0-3, where 0=no change)

0
yaw_rate int

Yaw rate level

0
brightness int

RGB brightness level

0
avoidance bool

Enable obstacle avoidance

False
battery_failsafe bool

Enable battery failsafe

False
fast_land bool

Enable fast landing speed

False

Returns:

Type Description
CommandResult

CommandResult

set_operate_status

set_operate_status(status: int) -> CommandResult

Set formation operate status.

Used for formation flight coordination.

Parameters:

Name Type Description Default
status int

Operate status value

required

Returns:

Type Description
CommandResult

CommandResult

set_land_speed

set_land_speed(fast: bool = False) -> CommandResult

Set landing speed.

Parameters:

Name Type Description Default
fast bool

True for fast landing, False for slow/safe landing

False

Returns:

Type Description
CommandResult

CommandResult

Note

Fast landing descends more quickly but may be less stable. Use slow landing for precision or when carrying payload.

set_electromagnet

set_electromagnet(on: bool) -> CommandResult

Control electromagnet.

Parameters:

Name Type Description Default
on bool

True to activate, False to deactivate

required

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_CLAMP_ELECTROMAGNET (cmd=26)

  • type=3: OFF
  • type=4: ON

set_clamp

set_clamp(is_open: bool | None = None, angle: int | None = None) -> CommandResult

Control gripper/clamp (servo/steering engine).

Can be used in two modes: 1. Simple open/close: set_clamp(is_open=True) or set_clamp(is_open=False) 2. Angle control: set_clamp(angle=45) sets specific angle (0-180)

Parameters:

Name Type Description Default
is_open bool | None

True to open, False to close (uses type 0/1)

None
angle int | None

Specific angle to set (0-180, uses type 2)

None

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_CLAMP_ELECTROMAGNET (cmd=26)

  • type=0: close
  • type=1: open
  • type=2: set angle

take_photo

take_photo(download: bool = True, timeout: float = 5.0, save_path: Path | str | None = None) -> Path | None

Capture photo and optionally download it.

Note: The RTP video stream must be enabled before taking photos. Call set_video_stream(True) first if photos aren't being captured.

Parameters:

Name Type Description Default
download bool

If True, wait for photo and download to media/photos/

True
timeout float

Max seconds to wait for photo to appear on drone

5.0
save_path Path | str | None

Optional directory or exact file path for the downloaded photo. If a directory is given, the drone's filename is preserved.

None

Returns:

Type Description
Path | None

Path to downloaded photo if download=True and successful, None otherwise.

Path | None

If download=False, returns None but photo is still captured on drone.

Example:

# Enable video stream first (required for photo capture)
drone.set_video_stream(True)

# Capture and download
photo_path = drone.take_photo()
print(f"Photo saved to {photo_path}")

# Capture only (manual download later)
drone.take_photo(download=False)
photos = drone.list_photos()

# Capture and save to a custom path
drone.take_photo(save_path="captures/latest.jpg")

set_video

set_video(recording: bool) -> CommandResult

Start or stop video recording to SD card.

Parameters:

Name Type Description Default
recording bool

True to start, False to stop

required

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_TAKE_VIDEO (cmd=6)

  • type=0: Begin recording
  • type=1: End recording

set_barrier_mode

set_barrier_mode(enabled: bool) -> CommandResult

Enable or disable obstacle avoidance.

Parameters:

Name Type Description Default
enabled bool

True to enable, False to disable

required

Returns:

Type Description
CommandResult

CommandResult

follow_line

follow_line(distance_cm: float, line_color: LineColor = BLACK) -> LineFollowResult

Follow a line for specified distance.

The drone follows a colored line on the ground using optical flow camera. Returns when distance is reached or an intersection is detected.

Parameters:

Name Type Description Default
distance_cm float

Distance to follow in centimeters

required
line_color LineColor

Color of line to follow (BLACK or WHITE)

BLACK

Returns:

Name Type Description
LineFollowResult LineFollowResult
  • FAILED (0): Line following failed
  • SUCCESS (1): Successfully followed line for distance
  • INTERSECTION (2): Encountered intersection before reaching distance

Example:

result = drone.follow_line(100, LineColor.BLACK)
if result == LineFollowResult.INTERSECTION:
    # Handle intersection - check for arrows, decide direction
    pass

fire_laser

fire_laser(mode: LaserMode = SINGLE_SHOT, frequency: int = 10, ammo: int = 100) -> CommandResult

Control laser firing.

Parameters:

Name Type Description Default
mode LaserMode

Laser mode (SINGLE_SHOT, BURST, CONTINUOUS, OFF, etc.)

SINGLE_SHOT
frequency int

Firing frequency in shots/second (1-14), only for BURST mode

10
ammo int

Ammo capacity (1-255), only for BURST mode

100

Returns:

Type Description
CommandResult

CommandResult

Example:

# Single shot
drone.fire_laser(LaserMode.SINGLE_SHOT)

# Burst fire at 10 shots/sec with 50 ammo
drone.fire_laser(LaserMode.BURST, frequency=10, ammo=50)

# Stop firing
drone.fire_laser(LaserMode.OFF)

is_laser_hit

is_laser_hit() -> bool

Check if laser receiver detected a hit.

Returns:

Type Description
bool

True if hit detected, False otherwise

Note

Requires laser receiver to be enabled first with: drone.fire_laser(LaserMode.RECEIVER_ON)

set_camera_angle

set_camera_angle(mode: CameraPitchMode, angle: int = 0) -> CommandResult

Control main camera pitch angle.

Parameters:

Name Type Description Default
mode CameraPitchMode

Pitch control mode (UP_ABSOLUTE, DOWN_ABSOLUTE, etc.)

required
angle int

Target angle in degrees (0-90)

0

Returns:

Type Description
CommandResult

CommandResult

Example:

# Look down at 45 degrees
drone.set_camera_angle(CameraPitchMode.DOWN_ABSOLUTE, 45)

# Look straight ahead (0 degrees)
drone.set_camera_angle(CameraPitchMode.UP_ABSOLUTE, 0)

# Calibrate camera
drone.set_camera_angle(CameraPitchMode.CALIBRATE)

set_video_stream

set_video_stream(enabled: bool) -> CommandResult

Enable or disable video stream.

Parameters:

Name Type Description Default
enabled bool

True to enable, False to disable

required

Returns:

Type Description
CommandResult

CommandResult

flip_video

flip_video() -> CommandResult

Flip video stream orientation.

Returns:

Type Description
CommandResult

CommandResult

set_qr_localization

set_qr_localization(enabled: bool) -> CommandResult

Enable or disable QR code localization.

When enabled, the drone uses QR codes on a mat for absolute position tracking. This significantly changes how positioning works:

Effects when ENABLED:

  • get_position() returns absolute coordinates in the QR mat coordinate system
  • move_to(x, y, z) flies to absolute position (x, y, z) on the QR mat
  • curve_to() uses absolute target coordinates
  • Enables QR-based features: recognize_qr(), track_qr(), QR landing
  • Required for accurate multi-drone formation flight

Effects when DISABLED (default):

  • Position starts at (0, 0, 0) on takeoff
  • get_position() returns position relative to takeoff point
  • move_to(x, y, z) flies to position relative to takeoff origin
  • Position tracking uses optical flow (less accurate, may drift)

Parameters:

Name Type Description Default
enabled bool

True to enable, False to disable

required

Returns:

Type Description
CommandResult

CommandResult

Example:

# Enable QR localization for absolute positioning
drone.set_qr_localization(enabled=True)

# Now move_to uses absolute QR mat coordinates
drone.move_to(x=200, y=350, z=120)  # Fly to exact position

# Position reports are now absolute
pos = drone.get_position()  # Returns absolute QR coordinates

set_video_resolution

set_video_resolution(resolution: VideoResolution | int) -> CommandResult

Set video resolution for RTP streaming and recording.

Controls the video encoder resolution. Lower resolution reduces encoder CPU load, which may allow the QR localization camera to run at a higher update rate when RTP streaming is active.

By default, enabling RTP streaming causes QR updates to drop to 5 Hz. Using a lower resolution may help mitigate this (needs testing).

Parameters:

Name Type Description Default
resolution VideoResolution | int

Resolution level - use VideoResolution enum or int:

  • VideoResolution.HIGH (0): 1920x1080 - Best quality
  • VideoResolution.MEDIUM (1): 1280x720 - Balanced
  • VideoResolution.LOW (2): 640x480 or lower - AI/programming mode
required

Returns:

Type Description
CommandResult

CommandResult

Example:

# Set low resolution before enabling RTP for object detection
from pypack.core import VideoResolution

drone.set_video_resolution(VideoResolution.LOW)
drone.enable_rtp()  # Now streaming at lower resolution
# ... capture frames for object detection

Note:

- Should be set BEFORE enabling RTP streaming for best results
- May need to disable/re-enable RTP after changing for effect
- Firmware handler: HandleMsgSelectRecordResolution @ avmanager

get_firmware_version

get_firmware_version() -> CommandResult

Request firmware version from the drone.

Sends VERSION command (cmd=21) to query the avmanager firmware version. The response is received asynchronously via plane_ack message.

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_VERSION (cmd=21) Version info may be available in telemetry after this call.

get_mcu_version

get_mcu_version() -> CommandResult

Request STM51 MCU firmware version.

Sends 51VERSION command (cmd=27) to query the flight controller MCU firmware version.

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_51VERSION (cmd=27)

shutdown

shutdown() -> CommandResult

Shutdown the drone.

WARNING

This will power off the drone. Use with caution.

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_SHUTDOWN_REBOOT (cmd=24) with type=0

reboot

reboot() -> CommandResult

Reboot the drone.

WARNING

This will restart the drone. Connection will be lost.

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_SHUTDOWN_REBOOT (cmd=24) with type=1

get_storage_capacity

get_storage_capacity() -> CommandResult

Request SD card storage capacity information.

Sends STORAGE_CAPACITY command (cmd=2) to query available and total storage space on the drone's SD card.

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_STORAGE_CAPACITY (cmd=2) Storage info may be available in telemetry after this call.

set_anti_flicker

set_anti_flicker(hz_50: bool = True) -> CommandResult

Set anti-flicker mode for indoor lighting.

Adjusts camera exposure to reduce flickering under artificial lights. Use 50Hz for most of Europe/Asia, 60Hz for Americas.

Parameters:

Name Type Description Default
hz_50 bool

True for 50Hz (default), False for 60Hz

True

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_RESIST_SCREEN_FLICKER (cmd=23)

  • type=0: 50Hz
  • type=1: 60Hz

sync_time

sync_time() -> CommandResult

Synchronize drone clock with current time.

Sends SYNC_TIME command (cmd=25) to update the drone's internal clock.

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_SYNC_TIME (cmd=25)

set_wifi_mode

set_wifi_mode(mode: 'WiFiMode', channel_id: int = 0) -> CommandResult

Set WiFi configuration mode.

Low-level method to configure WiFi settings. For common operations, prefer using the convenience methods (set_wifi_band, set_wifi_power, etc.).

Parameters:

Name Type Description Default
mode 'WiFiMode'

WiFiMode enum value

required
channel_id int

Channel ID for manual channel mode (WiFiMode.CHANNEL_MANUAL)

0

Returns:

Type Description
CommandResult

CommandResult

Note

Uses MAV_PLANE_CMD_WIFI_MODE (cmd=4)

set_wifi_band

set_wifi_band(band_5ghz: bool = False) -> CommandResult

Switch WiFi band between 2.4GHz and 5GHz.

Parameters:

Name Type Description Default
band_5ghz bool

True for 5GHz, False for 2.4GHz (default)

False

Returns:

Type Description
CommandResult

CommandResult

set_wifi_power

set_wifi_power(high: bool = True) -> CommandResult

Set WiFi transmission power.

Parameters:

Name Type Description Default
high bool

True for high power (default), False for low power

True

Returns:

Type Description
CommandResult

CommandResult

set_wifi_broadcast

set_wifi_broadcast(enabled: bool = True) -> CommandResult

Enable or disable WiFi broadcast.

Parameters:

Name Type Description Default
enabled bool

True to enable broadcast (default), False to disable

True

Returns:

Type Description
CommandResult

CommandResult

set_wifi_channel

set_wifi_channel(manual: bool = False, channel_id: int = 0) -> CommandResult

Set WiFi channel mode.

Parameters:

Name Type Description Default
manual bool

True for manual channel selection, False for auto (default)

False
channel_id int

Channel ID for manual mode

0

Returns:

Type Description
CommandResult

CommandResult

set_wifi_ap_mode

set_wifi_ap_mode() -> CommandResult

Switch WiFi to Access Point mode.

Returns:

Type Description
CommandResult

CommandResult

start_video_stream

start_video_stream(display: bool = True, web_server: bool = False, web_port: int | None = None) -> VideoStream

Start video stream with optional display and web server.

Enables the drone's RTP video stream and returns a VideoStream instance for frame processing and object detection.

Parameters:

Name Type Description Default
display bool

Show OpenCV window with video

True
web_server bool

Start web server for browser viewing

False
web_port int | None

Web server port. Defaults to config network web port.

None

Returns:

Type Description
VideoStream

VideoStream instance for adding detection callbacks

Example:

# Basic display
stream = drone.start_video_stream()

# With object detection
def detect(frame):
    frame.detections = my_model.detect(frame.image)
    return frame

stream = drone.start_video_stream()
stream.add_callback(detect)

# With web streaming
stream = drone.start_video_stream(web_server=True)
print("Open http://localhost:5000 in browser")

create_video_stream

create_video_stream() -> VideoStream

Create a video stream without starting it.

Use this when you want full control over the stream configuration and callback pipeline before starting.

Returns:

Type Description
VideoStream

VideoStream instance (not started)

Example:

stream = drone.create_video_stream()

# Add callbacks
stream.add_callback(my_detector)
stream.add_callback(my_display)

# Enable stream on drone and start
drone.set_video_stream(True)
stream.start()

list_photos

list_photos(page: int = 0) -> list[MediaFile]

List photos stored on drone.

Parameters:

Name Type Description Default
page int

Page number for pagination (0-indexed)

0

Returns:

Type Description
list[MediaFile]

List of MediaFile objects sorted by date (newest first)

Example:

photos = drone.list_photos()
for photo in photos:
    print(f"{photo.name} - {photo.size} - {photo.date}")

list_videos

list_videos(page: int = 0) -> list[MediaFile]

List videos stored on drone.

Parameters:

Name Type Description Default
page int

Page number for pagination (0-indexed)

0

Returns:

Type Description
list[MediaFile]

List of MediaFile objects sorted by date (newest first)

list_logs

list_logs(page: int = 0) -> list[MediaFile]

List log files stored on drone.

Parameters:

Name Type Description Default
page int

Page number for pagination (0-indexed)

0

Returns:

Type Description
list[MediaFile]

List of MediaFile objects sorted by date (newest first)

download_photo

download_photo(photo: MediaFile | str, save_dir: Path | str | None = None) -> Path | None

Download a photo from drone.

Parameters:

Name Type Description Default
photo MediaFile | str

MediaFile object or filename string

required
save_dir Path | str | None

Directory to save to (default: media/photos/)

None

Returns:

Type Description
Path | None

Path to downloaded file, or None if download failed

Example:

# Download by MediaFile
photos = drone.list_photos()
path = drone.download_photo(photos[0])

# Download by filename
path = drone.download_photo("20251111_102056_1.jpg")

download_video

download_video(video: MediaFile | str, save_dir: Path | str | None = None) -> Path | None

Download a video from drone.

Parameters:

Name Type Description Default
video MediaFile | str

MediaFile object or filename string

required
save_dir Path | str | None

Directory to save to (default: media/videos/)

None

Returns:

Type Description
Path | None

Path to downloaded file, or None if download failed

download_log

download_log(log: MediaFile | str, save_dir: Path | str | None = None) -> Path | None

Download a log file from drone.

Parameters:

Name Type Description Default
log MediaFile | str

MediaFile object or filename string

required
save_dir Path | str | None

Directory to save to (default: media/logs/)

None

Returns:

Type Description
Path | None

Path to downloaded file, or None if download failed

download_all_photos

download_all_photos(save_dir: Path | str | None = None) -> list[Path]

Download all photos from drone.

Parameters:

Name Type Description Default
save_dir Path | str | None

Directory to save to (default: media/photos/)

None

Returns:

Type Description
list[Path]

List of paths to downloaded files

download_all_videos

download_all_videos(save_dir: Path | str | None = None) -> list[Path]

Download all videos from drone.

Parameters:

Name Type Description Default
save_dir Path | str | None

Directory to save to (default: media/videos/)

None

Returns:

Type Description
list[Path]

List of paths to downloaded files

download_all_logs

download_all_logs(save_dir: Path | str | None = None) -> list[Path]

Download all log files from drone.

Parameters:

Name Type Description Default
save_dir Path | str | None

Directory to save to (default: media/logs/)

None

Returns:

Type Description
list[Path]

List of paths to downloaded files

delete_photo

delete_photo(photo: MediaFile | str) -> bool

Delete a photo from drone.

Parameters:

Name Type Description Default
photo MediaFile | str

MediaFile object or filename string

required

Returns:

Type Description
bool

True if deletion successful

Example:

# Delete by MediaFile
photos = drone.list_photos()
drone.delete_photo(photos[0])

# Delete by filename
drone.delete_photo("20251111_102056_1.jpg")

delete_video

delete_video(video: MediaFile | str) -> bool

Delete a video from drone.

Parameters:

Name Type Description Default
video MediaFile | str

MediaFile object or filename string

required

Returns:

Type Description
bool

True if deletion successful

delete_log

delete_log(log: MediaFile | str) -> bool

Delete a log file from drone.

Parameters:

Name Type Description Default
log MediaFile | str

MediaFile object or filename string

required

Returns:

Type Description
bool

True if deletion successful

delete_all_photos

delete_all_photos() -> tuple[int, int]

Delete all photos from drone SD card.

Returns:

Type Description
tuple[int, int]

Tuple of (deleted_count, failed_count)

Example:

deleted, failed = drone.delete_all_photos()
print(f"Deleted {deleted} photos, {failed} failed")

delete_all_videos

delete_all_videos() -> tuple[int, int]

Delete all videos from drone SD card.

Returns:

Type Description
tuple[int, int]

Tuple of (deleted_count, failed_count)

Example:

deleted, failed = drone.delete_all_videos()
print(f"Deleted {deleted} videos, {failed} failed")

delete_all_logs

delete_all_logs() -> tuple[int, int]

Delete all log files from drone SD card.

Returns:

Type Description
tuple[int, int]

Tuple of (deleted_count, failed_count)

Example:

deleted, failed = drone.delete_all_logs()
print(f"Deleted {deleted} logs, {failed} failed")

delete_all_media

delete_all_media() -> dict[str, tuple[int, int]]

Delete all media (photos, videos, logs) from drone SD card.

Returns:

Type Description
dict[str, tuple[int, int]]

Dict with keys 'photos', 'videos', 'logs', each containing

dict[str, tuple[int, int]]

(deleted_count, failed_count) tuple

Example:

results = drone.delete_all_media()
for media_type, (deleted, failed) in results.items():
    print(f"{media_type}: {deleted} deleted, {failed} failed")

get_photo_url

get_photo_url(photo: MediaFile | str) -> str

Get direct HTTP URL for a photo.

Parameters:

Name Type Description Default
photo MediaFile | str

MediaFile object or filename string

required

Returns:

Type Description
str

HTTP URL for downloading the photo

Example:

url = drone.get_photo_url("20251111_102056_1.jpg")
# http://192.168.100.1:12346/picture/20251111_102056_1.jpg

get_video_url

get_video_url(video: MediaFile | str) -> str

Get direct HTTP URL for a video.

Parameters:

Name Type Description Default
video MediaFile | str

MediaFile object or filename string

required

Returns:

Type Description
str

HTTP URL for downloading the video

send_manual_control

send_manual_control(forward: float = 0.0, right: float = 0.0, up: float = 0.0, rotate: float = 0.0) -> bool

Send a single manual control frame for joystick-style flight.

This sends a MANUAL_CONTROL MAVLink message via UDP, allowing simultaneous position and yaw control. Call this at ~20Hz for smooth control (like a joystick).

Unlike move() and rotate() which are blocking commands that complete a specific movement, this provides continuous real-time control.

Parameters:

Name Type Description Default
forward float

Forward/back input, -1.0 to +1.0. Positive = forward.

0.0
right float

Left/right input, -1.0 to +1.0. Positive = right.

0.0
up float

Up/down input, -1.0 to +1.0. Positive = up.

0.0
rotate float

Rotation input, -1.0 to +1.0. Positive = CCW (left turn).

0.0

Returns:

Type Description
bool

True if message was sent successfully.

Example:

# Move forward while rotating left
for _ in range(40):  # 2 seconds at 20Hz
    drone.send_manual_control(forward=0.5, rotate=0.3)
    time.sleep(0.05)
drone.send_manual_control()  # Stop

manual_fly

manual_fly(duration_sec: float, forward: float = 0.0, right: float = 0.0, up: float = 0.0, rotate: float = 0.0, rate_hz: int = 20, on_frame: ManualFlyFrameCallback | None = None) -> bool

Fly with manual control inputs for a specified duration.

This provides simultaneous position and yaw movement - unlike the standard move() and rotate() commands which must be called separately.

Velocity is controlled by the manual velocity level set via set_velocity_level(). Default levels:

  • Level 1 (SLOW): 1.0 m/s horizontal, 0.5 m/s vertical
  • Level 2 (MEDIUM): 2.0 m/s horizontal, 0.8-1.0 m/s vertical
  • Level 3 (FAST): 3.0 m/s horizontal, 1.0-1.2 m/s vertical

Parameters:

Name Type Description Default
duration_sec float

How long to fly with these inputs (seconds).

required
forward float

Forward/back input, -1.0 to +1.0. Positive = forward.

0.0
right float

Left/right input, -1.0 to +1.0. Positive = right.

0.0
up float

Up/down input, -1.0 to +1.0. Positive = up.

0.0
rotate float

Rotation input, -1.0 to +1.0. Positive = CCW (left turn).

0.0
rate_hz int

Control loop rate (default 20 Hz = 50ms interval).

20
on_frame ManualFlyFrameCallback | None

Optional callback(x, y, z, r, frame_index, success) called after each frame.

None

Returns:

Type Description
bool

True if all messages were sent successfully.

Example:

# Arc movement: forward + rotation for 3 seconds
drone.manual_fly(3.0, forward=0.6, rotate=0.4)

# Diagonal strafe while climbing
drone.manual_fly(2.0, forward=0.5, right=0.5, up=0.3)

# Orbit-like: rotate while moving right
drone.manual_fly(5.0, right=0.3, rotate=0.5)

# With frame logging callback
def log_frame(x, y, z, r, idx, ok):
    print(f"Frame {idx}: x={x}, y={y}, z={z}, r={r}, ok={ok}")
drone.manual_fly(2.0, forward=0.5, on_frame=log_frame)

send_app_heartbeat

send_app_heartbeat(user_mode: int = 1) -> bool

Send APP_HEARTBEAT message to set the app control mode.

The drone requires periodic heartbeats to accept certain control modes. This is called automatically by manual_fly(), but can be called directly for custom control loops using manual_control_frame().

User mode values

0 = Other 1 = Aerial (manual flight mode) - required for MANUAL_CONTROL 2 = Program (autonomous flight mode) 3 = Battle 4 = Formation

Parameters:

Name Type Description Default
user_mode int

App mode (0-4). Default 1 for manual flight.

1

Returns:

Type Description
bool

True if message was sent successfully.

Example:

# Custom control loop with manual heartbeat management
drone.send_app_heartbeat(user_mode=1)  # Enter Aerial mode
for _ in range(100):
    drone.manual_control_frame(forward=0.5)
    if iteration % 20 == 0:  # Every ~1 second at 20Hz
        drone.send_app_heartbeat(user_mode=1)
    time.sleep(0.05)

set_app_mode

set_app_mode(mode: int) -> None

Set the app mode for background heartbeat messages.

This changes the user_mode sent in periodic APP_HEARTBEAT messages. The background heartbeat thread sends this mode every second.

IMPORTANT

Call this BEFORE takeoff when you want to use manual control.

The drone needs to receive Aerial mode (1) heartbeats to accept MANUAL_CONTROL messages.

Mode values:

  • 0 = Other
  • 1 = Aerial (manual flight mode) - required for MANUAL_CONTROL
  • 2 = Program (autonomous flight mode) - default
  • 3 = Battle
  • 4 = Formation

Parameters:

Name Type Description Default
mode int

App mode (0-4).

required

Example:

drone.connect("192.168.100.1")
drone.set_app_mode(1)  # Switch to Aerial mode for manual control
drone.takeoff()
drone.manual_fly(duration_sec=5, up=0.5)

get_app_mode

get_app_mode() -> int

Get the current app mode for background heartbeat messages.

Returns:

Type Description
int

Current app mode (0-4).

stop_manual_control

stop_manual_control() -> bool

Send zero inputs to stop manual movement.

Call this after manual control to ensure the drone stops any ongoing movement from manual inputs.

Returns:

Type Description
bool

True if message was sent successfully.

create_flight_controller

create_flight_controller(config: ControllerConfig | None = None) -> ManualFlightController

Create a closed-loop PD flight controller.

The controller uses MANUAL_CONTROL messages to provide continuous joystick-style inputs, enabling simultaneous position (xyz) and yaw control - something the blocking move_to() + rotate() commands cannot do.

The controller runs at 20Hz (configurable) and uses PD control to smoothly reach target positions while maintaining heading.

Parameters:

Name Type Description Default
config ControllerConfig | None

Controller configuration. Uses this API instance's runtime config defaults if None. See FlightControllerConfig for tunable parameters.

None

Returns:

Type Description
ManualFlightController

ManualFlightController instance ready for use.

Raises:

Type Description
NotReady

If not connected to drone.

Example:

with DroneAPI() as drone:
    drone.connect("192.168.100.1")
    drone.takeoff()

    # Create controller with custom gains
    ctrl = drone.create_flight_controller()
    ctrl.configure(kp_xy=2.5, position_tolerance_cm=3.0)

    # Fly to target with simultaneous yaw
    result = ctrl.fly_to(x=100, y=200, z=120, yaw=90)
    print(f"Arrived: {result.success}, error: {result.error_position_cm}cm")

    # Manual control loop
    ctrl.set_target(x=50, y=50, z=100, yaw=180)
    while not ctrl.has_converged():
        ctrl.update()
        time.sleep(0.05)
    ctrl.stop()

    drone.land()

Re-Exported Types

The droneapi module re-exports these types for convenience. Their canonical reference pages live elsewhere in the docs: