Skip to content

Controller Types

control

Manual flight controller package for closed-loop PD control.

ManualFlightController

Closed-loop PD controller using manual control inputs.

This controller enables simultaneous position (XYZ) and yaw control, which is not possible with the blocking move_to() + rotate() commands.

The control loop runs at a configurable rate (default 20Hz) and uses PD control to smoothly reach the target state.

Coordinate Frame (World-Frame):

  • +X = East (right on QR mat)
  • +Y = North (forward on QR mat)
  • +Z = Up
  • +yaw = CCW rotation

Example:

from droneapi import DroneAPI

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

    # Create controller
    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")

    drone.land()

drone property

drone: DroneAPI

Get underlying DroneAPI instance for direct access if needed.

config property

Get current controller configuration.

configure

configure(**kwargs: Any) -> ManualFlightController

Fluent configuration of controller parameters.

Parameters:

Name Type Description Default
**kwargs Any

Any ControllerConfig attribute to override. Common: kp_xy, kd_xy, kp_z, kd_z, kp_yaw, kd_yaw, position_tolerance_cm, yaw_tolerance_deg

{}

Returns:

Type Description
ManualFlightController

Self for method chaining.

Example:

ctrl.configure(kp_xy=2.5, position_tolerance_cm=3.0)

set_target

set_target(x: float, y: float, z: float, yaw: float | None = None) -> None

Set target state for the controller.

Parameters:

Name Type Description Default
x float

Target X position in cm (East on QR mat).

required
y float

Target Y position in cm (North on QR mat).

required
z float

Target altitude in cm.

required
yaw float | None

Target heading in degrees (0-360). None = maintain current heading.

None

update

update() -> bool

Execute one control iteration.

Computes PD control outputs and sends manual control command.

Returns:

Type Description
bool

True if update succeeded, False on telemetry error.

has_converged

has_converged() -> bool

Check if drone has reached target within tolerance.

Returns:

Type Description
bool

True if position and yaw errors are within configured tolerances.

stop

stop() -> None

Send zero control inputs to stop all movement.

fly_to

fly_to(x: float, y: float, z: float, yaw: float | None = None, timeout: float | None = None) -> ControllerResult

Blocking fly to target position and heading.

Runs the control loop until convergence or timeout.

Parameters:

Name Type Description Default
x float

Target X position in cm.

required
y float

Target Y position in cm.

required
z float

Target altitude in cm.

required
yaw float | None

Target heading in degrees. None = maintain current heading.

None
timeout float | None

Maximum time in seconds. Uses config default if None.

None

Returns:

Type Description
ControllerResult

ControllerResult with success status and final state.

move_to

move_to(x: float, y: float, z: float, speed: VelocityLevel | int = ZOOM) -> bool

Move to absolute position (cm).

DroneInterface-compatible method. Speed parameter affects P-gain scaling.

Parameters:

Name Type Description Default
x float

X position in cm.

required
y float

Y position in cm.

required
z float

Z position (altitude) in cm.

required
speed VelocityLevel | int

Speed level (affects gains). Higher = more aggressive.

ZOOM

Returns:

Type Description
bool

True if movement succeeded.

get_position

get_position() -> tuple[float, float, float]

Get current (x, y, z) position in cm.

Returns:

Type Description
tuple[float, float, float]

Tuple of (x, y, z) in cm.

get_yaw

get_yaw() -> float

Get current heading in degrees.

Returns:

Type Description
float

Yaw angle in degrees (0-360).

get_obstacles

get_obstacles() -> Obstacles

Get obstacle readings from barrier sensors.

Returns:

Type Description
Obstacles

Obstacles with forward, back, left, right, down flags.

rotate

rotate(degrees: float) -> bool

Rotate by degrees using the flight controller.

Parameters:

Name Type Description Default
degrees float

Rotation angle. Positive = CCW, negative = CW.

required

Returns:

Type Description
bool

True if rotation succeeded.

takeoff

takeoff(height_cm: int = 100) -> bool

Take off to specified height.

Delegates to underlying DroneAPI.

Parameters:

Name Type Description Default
height_cm int

Target altitude in cm.

100

Returns:

Type Description
bool

True if takeoff succeeded.

land

land() -> bool

Land the drone.

Delegates to underlying DroneAPI.

Returns:

Type Description
bool

True if landing succeeded.

hover

hover(duration_sec: float = 1.0) -> bool

Hover in place using the controller.

Parameters:

Name Type Description Default
duration_sec float

Hover duration in seconds.

1.0

Returns:

Type Description
bool

True if hover completed.

ControllerConfig dataclass

Configuration for the PD flight controller.

Attributes:

Name Type Description
kp_xy float

Proportional gain for horizontal (X, Y) control

kd_xy float

Derivative gain for horizontal control

kp_z float

Proportional gain for altitude (Z) control

kd_z float

Derivative gain for altitude control

kp_yaw float

Proportional gain for yaw control

kd_yaw float

Derivative gain for yaw control

max_horizontal_output float

Max output for X/Y axes (0-1000)

max_vertical_output float

Max output for Z axis (0-1000)

max_yaw_output float

Max output for yaw axis (0-1000)

position_tolerance_cm float

Position convergence tolerance

yaw_tolerance_deg float

Yaw convergence tolerance

control_rate_hz float

Control loop frequency

timeout_sec float

Maximum time for a fly_to operation

min_altitude_cm float

Minimum allowed altitude (safety)

max_altitude_cm float

Maximum allowed altitude (safety)

kp_xy class-attribute instance-attribute

kp_xy: float = kp_xy

kd_xy class-attribute instance-attribute

kd_xy: float = kd_xy

kp_z class-attribute instance-attribute

kp_z: float = kp_z

kd_z class-attribute instance-attribute

kd_z: float = kd_z

kp_yaw class-attribute instance-attribute

kp_yaw: float = kp_yaw

kd_yaw class-attribute instance-attribute

kd_yaw: float = kd_yaw

max_horizontal_output class-attribute instance-attribute

max_horizontal_output: float = max_horizontal_output

max_vertical_output class-attribute instance-attribute

max_vertical_output: float = max_vertical_output

max_yaw_output class-attribute instance-attribute

max_yaw_output: float = max_yaw_output

position_tolerance_cm class-attribute instance-attribute

position_tolerance_cm: float = position_tolerance_cm

yaw_tolerance_deg class-attribute instance-attribute

yaw_tolerance_deg: float = yaw_tolerance_deg

control_rate_hz class-attribute instance-attribute

control_rate_hz: float = control_rate_hz

timeout_sec class-attribute instance-attribute

timeout_sec: float = fly_to_timeout_sec

min_altitude_cm class-attribute instance-attribute

min_altitude_cm: float = min_altitude_cm

max_altitude_cm class-attribute instance-attribute

max_altitude_cm: float = max_altitude_cm

dt property

dt: float

Control loop period in seconds.

from_drone_config classmethod

from_drone_config(config: DroneConfig) -> ControllerConfig

Create controller defaults from a runtime drone config.

ControllerResult dataclass

Result of a fly_to operation.

Attributes:

Name Type Description
success bool

True if target was reached within tolerance

final_state FlightState | None

Drone state at completion

error_position_cm float

Final position error in cm

error_yaw_deg float

Final yaw error in degrees

elapsed_sec float

Time taken for the operation

reason str

Human-readable result description

success instance-attribute

success: bool

final_state class-attribute instance-attribute

final_state: FlightState | None = None

error_position_cm class-attribute instance-attribute

error_position_cm: float = 0.0

error_yaw_deg class-attribute instance-attribute

error_yaw_deg: float = 0.0

elapsed_sec class-attribute instance-attribute

elapsed_sec: float = 0.0

reason class-attribute instance-attribute

reason: str = ''

FlightState dataclass

Represents drone position and orientation state.

Attributes:

Name Type Description
x float

X position in cm (East on QR mat)

y float

Y position in cm (North on QR mat)

z float

Z position/altitude in cm

yaw float

Heading in degrees (0-360, CCW positive)

timestamp float

Monotonic time for derivative calculation

x instance-attribute

x: float

y instance-attribute

y: float

z instance-attribute

z: float

yaw instance-attribute

yaw: float

timestamp class-attribute instance-attribute

timestamp: float = field(default_factory=monotonic)

from_telemetry classmethod

from_telemetry(datacenter: DataCenter) -> FlightState | None

Create FlightState from DataCenter telemetry.

Parameters:

Name Type Description Default
datacenter DataCenter

DataCenter instance with drone telemetry

required

Returns:

Type Description
FlightState | None

FlightState if telemetry available, None otherwise

distance_to

distance_to(other: FlightState) -> float

Compute 3D Euclidean distance to another state.

Parameters:

Name Type Description Default
other FlightState

Target FlightState

required

Returns:

Type Description
float

Distance in cm

yaw_error_to

yaw_error_to(target_yaw: float) -> float

Compute yaw error with wraparound handling.

Computes the shortest angular distance from current yaw to target.

Parameters:

Name Type Description Default
target_yaw float

Target heading in degrees

required

Returns:

Type Description
float

Error in degrees (-180 to +180). Positive = CCW rotation needed.