Plugins

Plugins exist to extend the functionality of DroneManager in a straightforward way. They define a list of commands that they make available for the user interface, a list of background functions that should run continuously while the plugin is running. They can also have dependencies on other plugins, which are then loaded automatically when the plugin is loaded.

They are implemented as special classes in modules. Each module in the plugins folder is inspected for potential classes. There can one plugin per module. The name of the module defines the name of the plugin. For the command-line, they additionally provide a prefix, which is prepended to the commands to prevent collisions, i.e. multiple plugins can have a connect command. For plugin abc, this command becomes abc-connect.

There are two special types of plugins: Missions and Sensors.

Plugin Base Class

Class for extra, loadable plugins.

Plugins extend the functionality of DroneManager or Drone Classes by providing extra functions. They can also register their own commands to the CLI.

class dronemanager.plugin.Plugin(dm, logger, name, *args, **kwargs)

Bases: ABC

Generic plugin class.

The attribute cli_commands is called by the DroneManager CLI (and could be called by other UIs) to populate their interfaces. This is a dictionary with coroutines as values and human-readable names as keys. In DroneManager the names are used together with the class prefix to determine the command input on the command line, while the signature of the function is used to populate the CLI parser. The attribute background_functions should list coroutines that will run indefinitely, for example those polling for status updates from a camera. They will be started during construction of the class object, usually when the module is loaded. Note that these must be coroutines.

There is a basic dependency structure for plugins. The attribute DEPENDENCIES can be used to list other plugins by their names, on which this plugin depends. These are loaded before this one is. The list supports a single-entry deep dot-notation, i.e. “sensor.ecowitt” specifies that we depend on the ecowitt plugin, which requires the sensor plugin and should be loaded using their loading functions.

A common kwarg is “name”, for plugins of which multiple copies may be loaded, in which case the name acts as the unique identifier.

dm

The DroneManager instance connected to this plugin.

Type:

dronemanager.core.DroneManager

logger

The parent logger. A child logger with the name of the class is created below this.

Type:

logging.Logger

name

The name for this instance of the plugin.

Type:

str

cli_commands

A dictionary with input strings as keys and the associated coroutines as values. The coroutine should be bare, i.e. coro instead of coro(args).

Type:

dict[str, Callable]

background_functions

A list with coroutines which will be launched automatically once the plugin has loaded. These coroutines should be complete, i.e. coro(args) and not coro.

Type:

list[Coroutine]

PREFIX: str = 'abc'

(class attribute) The prefix for the CLI commands.

DEPENDENCIES: list[str] = []

(class attribute) Other plugins that this plugin depends on.

start_background_functions()
async start()

Starts any background functions.

async close()

Ends all running tasks functions.

Plugin list

Camera

Plugin for controlling MAVSDK Cameras

class dronemanager.plugins.camera.CameraPlugin(dm, logger, name)

Bases: Plugin

PREFIX: str = 'cam'

(class attribute) The prefix for the CLI commands.

async start()

Starts any background functions.

async close()

Removes all cameras

check_has_camera(drone)
async add_camera(drone: str, camera_id: int = 100)

Add cameras from/for a given drone to the plugin

async remove_camera(drone: str)

Remove a camera from the plugin

async status(drone: str)
async parameters(drone: str)
async set_parameter(drone: str, param_name: str, param_value: str)
async take_picture(drone: str)
async start_video(drone: str)
async stop_video(drone: str)
async set_zoom(drone: str, zoom: float)
class dronemanager.plugins.camera.ParameterOption(name, value, excludes)

Bases: object

name: str
value: int | float
excludes: list[str]
class dronemanager.plugins.camera.CameraParameter(name, param_type, default, control: bool, description: str, updates: list[str], options: list[ParameterOption], min_value: float | None, max_value: float | None, step_size: float | None)

Bases: object

value: int | float
property is_range
property is_bool
property is_option
check_option_valid(value)
get_current_otion()
get_option_by_name(option_name)
get_option_by_value(option_value)
get_options()
to_json_dict()
classmethod from_json_dict(json_dict)
class dronemanager.plugins.camera.Camera(logger, dm, drone_name: str, camera_id: int = 100)

Bases: object

cam_def_uri: str | None
parameters: dict[str, CameraParameter]
property drone
async start()
async close()
property params_loaded
log_status()
async take_picture()
async start_video()
async stop_video()
async set_zoom(zoom)
async init_cam_info()
async get_cam_param_definition()
async print_parameters()
parse_param_value(param_name: str, param_value: str) bool | int | float | None
async set_parameter(param_name: str, param_value: bool | int | float)

Controllers

Plugin for using controllers and joysticks to control drones with DM

class dronemanager.plugins.controllers.InputMapping

Bases: object

Map actions to controller axis

thrust_axis: int = None
yaw_axis: int = None
forward_axis: int = None
right_axis: int = None
arm_button: int = None
disarm_button: int = None
land_button: int = None
takeoff_button: int = None
control_button: int = None
arm_hold_duration: float = 1.0
extra_button_inputs: dict[int, set[Callable]] = {}
extra_axis_inputs: dict[Callable, list[int]] = {}
classmethod add_method_to_button(button: int, method: Callable)
classmethod add_axis_method(method: Callable, axes: list[int])
classmethod remove_method_from_button(button: int, method: Callable)
classmethod remove_axis_method(method: Callable)
class dronemanager.plugins.controllers.PS4Mapping

Bases: InputMapping

thrust_axis: int = 1
yaw_axis: int = 0
forward_axis: int = -3
right_axis: int = 2
arm_button: int = 0
disarm_button: int = 1
land_button: int = 12
takeoff_button: int = 11
control_button: int = 5
class dronemanager.plugins.controllers.ControllerPlugin(dm, logger, name, auto_set=False, auto_drone=False)

Bases: Plugin

PREFIX: str = 'control'

(class attribute) The prefix for the CLI commands.

controller: Joystick | None
async add_controller(dev_id: int)

Set which controller to use, matching the ID from check.

async remove_controller()

Remove the current controller.

async status()

Log current configuration of the controller plugin.

async set_drone(drone: str)

Set which drone is controlled by the controller.

stick_response(axis: int) float

Linear stick response with -10 to 10% dead zone.

Axis should be the joystick axis. A negative number means that the response is inverted.

async close()

Ends all running tasks functions.

External

Plugins for communication to other software

Currently only features a basic UDP server which sends data on connected drones and running missions in a json format.

class dronemanager.plugins.external.UDPClient(ip, port, frequency, duration)

Bases: object

class dronemanager.plugins.external.UDPPlugin(dm, logger, name, server_port=SERVER_PORT, max_frequency: float = MAX_FREQUENCY, min_frequency: float = MIN_FREQUENCY, max_duration: float = MAX_DURATION)

Bases: Plugin

Communication happens over port 31659. A client will send a json message with the desired frequency and duration (in seconds) to this port and the server starts answering. Frequency is capped between 1/60 and 20Hz.

Example message from client:

{
  "duration": 30,
  "frequency": 5
}
PREFIX: str = 'UDP'

(class attribute) The prefix for the CLI commands.

async close()

Ends all running tasks functions.

Gimbal

class dronemanager.plugins.gimbal.GimbalPlugin(dm, logger, name)

Bases: Plugin

PREFIX: str = 'gimbal'

(class attribute) The prefix for the CLI commands.

async start()

Starts any background functions.

async close()

Removes all gimbals

check_has_gimbal(drone)
async add_gimbals(drone: str, device_id: int = 154)

Add Gimbals from/for a given drone to the plugin

async remove_gimbal(drone: str)

Remove a gimbal from the plugin

async status(drone: str)
async take_control(drone: str)
async release_control(drone: str)
async set_gimbal_angles(drone: str, pitch: float, yaw: float)
async set_gimbal_rate(drone: str, pitch_rate: float, yaw_rate: float)
async point_gimbal_at(drone: str, x1: float, x2: float, x3: float, relative: bool = False)
async set_gimbal_mode(drone: str, mode: str)
class dronemanager.plugins.gimbal.Gimbal(logger, dm, drone, device_id: int = 154)

Bases: object

roll: float
pitch: float
yaw: float
yaw_absolute: float
mode: GimbalMode
primary_control: tuple[float, float]
secondary_control: tuple[float, float]
start()
async close()
property in_control
log_status()
async take_control()
async release_control()
async point_gimbal_at(lat, long, amsl)
async point_gimbal_at_relative(x, y, z)
async set_gimbal_angles(pitch, yaw)
async set_gimbal_rates(pitch_rate, yaw_rate)
async set_gimbal_mode(mode)
class dronemanager.plugins.gimbal.GimbalMulti(logger, dm, drone)

Bases: object

Should work with properly implemented gimbal managers, but those seem rare.

gimbal_list: set[int]
roll: dict[int, float]
pitch: dict[int, float]
yaw: dict[int, float]
mode: dict[int, GimbalMode]
primary_control: dict[int, tuple[float, float]]
secondary_control: dict[int, tuple[float, float]]
async close()
log_status()
in_control(gimbal_id: int | None)
async take_control(gimbal_id: int | None)
async release_control(gimbal_id: int | None)
async point_gimbal_at(gimbal_id: int | None, lat, long, amsl)
async point_gimbal_at_relative(gimbal_id: int | None, x, y, z)
async set_gimbal_angles(gimbal_id: int | None, pitch, yaw)
async set_gimbal_rates(gimbal_id: int | None, pitch_rate, yaw_rate)
async set_gimbal_mode(gimbal_id: int | None, mode)

Mission

Please see the mission documentation page.

Optitrack

Plugin for using controllers and joysticks to control drones with DM

class dronemanager.plugins.optitrack.CoordinateConversion(n_axis: str, e_axis: str, d_axis: str)

Bases: object

convert_euler(tracking_pos, tracking_euler, out_sequence='XYZ', degrees=False, in_degrees=True)
convert_quat(tracking_pos, tracking_quat, out_sequence='XYZ', degrees=False)
make_rotation()
class dronemanager.plugins.optitrack.OptitrackPlugin(dm, logger, name, server_ip: str | None = None, local_ip: str | None = None, axes: list[str] | None = None, log_frames: bool = False)

Bases: Plugin

PREFIX: str = 'opti'

(class attribute) The prefix for the CLI commands.

async connect_server(remote: str = None, local: str = None)

Connect to a NatNet server at the given IP remote and local IP addresses. Localhost by default.

async add_drone(name: str, track_id: int)

Add a drone to the data forwarding system by name and track ID

async remove_drone(name: str)

Remove a drone from the data forwarding system by name

async log_available_bodies()

Print available rigid bodies on the NatNet server

async status()
async close()

Ends all running tasks functions.

Scripts

class dronemanager.plugins.scripts.ScriptsPlugin(dm, logger, name)

Bases: Plugin

PREFIX: str = 'script'

(class attribute) The prefix for the CLI commands.

async start()

Starts any background functions.

async close()

Ends all running tasks functions.

async execute_script(script_name: str)

Run Script in ./Scripts with given Name

dronemanager.plugins.scripts.script_function(script_path)

Sensor

Please see the sensor documentation page.

Stream

class dronemanager.plugins.stream.StreamPlugin(dm, logger, name, ip='127.0.0.1', port=5000, **kwargs)

Bases: Plugin

Plugin to receive video stream from Unity via TCP.

Parameters:
  • ip – Default IP, can be set via config.json ‘plugin_settings’.

  • port – Default Port, can be set via config.json ‘plugin_settings’.

PREFIX: str = 'stream'

(class attribute) The prefix for the CLI commands.

async start_stream(ip: str = None, port: int = None)

Starts the Video Stream.

Parameters:
  • ip – Override the default IP (optional).

  • port – Override the default Port (optional).

async stop_stream()

Stops the running stream and closes the window.

async display()

Toggles the display of the stream.

async close()

Cleanup when plugin is unloaded.

add_callback(callback_function: Callable)
remove_callback(callback_function: Callable)