Utility functions

This module contains generic utility functions used throughout the software, mostly relating to GPS and NED positions.

Unless stated otherwise, a GPS coordinate is any indexable sequence with the latitude, longitude and AMSL in that order.

dronemanager.utils.COMMON_FORMATTER

The common formatter string for the loggers.

dronemanager.utils.CACHE_DIR

The directory for any information that might be worth caching. Currently only used for camera definition information.

dronemanager.utils.LOG_DIR

The directory where all the log files are saved.

dronemanager.utils.EARTH_RADIUS = 6371000

Used to compute an approximate NED distance between two GPS coordinates

dronemanager.utils.dist_ned(pos1: ndarray, pos2: ndarray) float

The euclidian distance between two cartesian points.

For n-dimensional points, the arrays should have shape (n,).

Parameters:
  • pos1 – First position, as a numpy array

  • pos2 – Second position, as a numpy array

Returns:

The distance between the two points as a float.

dronemanager.utils.dist_gps(gps1: Sequence[float], gps2: Sequence[float]) float

Approximate euclidian distance between two GPS coordinates.

Haversine functions with WGS84 are used to compute the horizontal component of the distance.

Parameters:
  • gps1 – GPS coordinates of first point

  • gps2 – GPS coordinates of second point

Returns:

Approximate distance between the two points as a float.

dronemanager.utils.heading_ned(pos1: Sequence[float], pos2: Sequence[float]) float

The heading from one position to another, in degrees.

This is the angle from north, such that moving in that direction from the first point will cross the second point. The range is from -180 to +180 with 0 north and +90 east. The two positions must be given as NED. Assumes flat earth.

Parameters:
  • pos1 – The first position

  • pos2 – The second position

Returns:

The heading in degrees, as a float.

dronemanager.utils.heading_gps(gps1: Sequence[float], gps2: Sequence[float]) float

The heading from one GPS position to another, in degrees.

This is the angle from north, such that moving in that direction from the first point will cross the second point. The range is from -180 to +180 with 0 north and +90 east. The two positions must be given as GPS coordinates with latitude first and longitude second.

Parameters:
  • gps1 – The first position

  • gps2 – The second position

Returns:

The heading in degrees, as a float.

dronemanager.utils.relative_gps(gps: Sequence[float], offset: Sequence[float]) tuple[float, float, float]

Create a GPS coordinate that is shifted from the input GPS by a NED input offset.

Uses haversine functions.

Parameters:
  • gps – Initial GPS coordinate

  • offset – NED offset

Returns:

The new, offset GPS coordinate as a tuple (latitude, longitude, amsl)

dronemanager.utils.offset_from_gps(origin: Sequence[float], gps1: Sequence[float], gps2: Sequence[float]) tuple[float, float, float]

Given two GPS points, computes the heading and distance between them and then creates a new point separated fom a third GPS point by the same heading and distance.

Uses haversine functions.

Parameters:
  • origin – The GPS point from which the new offset point will be created

  • gps1 – The starting GPS point for determining the offset

  • gps2 – The ending GPS point for determining the offset

Returns:

The new, offset point as a tuple (latitude, longitude, amsl)

dronemanager.utils.ned_from_gps(gps1: Sequence[float], gps2: Sequence[float]) tuple[float, float, float]

Given two GPS points, compute the NED difference between the two positions. Utilizes the same algorithm as PX4 http://mathworld.wolfram.com/AzimuthalEquidistantProjection.html

Parameters:
  • gps1 – GPS coordinates of first point

  • gps2 – GPS coordinates of second point

Returns:

A tuple with the north, east, down offset between the two GPS coordinates.

dronemanager.utils.get_free_port() int

Get a free network port.

The port is not guaranteed to be free once the function returns, but they usually are.

Returns:

The free port

dronemanager.utils.parse_address(string: str) tuple[str, str, int]

Parses a connection string of the form schema://host:appendix.

Also used to ensure that udp://:14540, udp://localhost:14540 and udp://127.0.0.1:14540 are recognized as equivalent.

Missing elements from the string or the other entries are replaced with defaults. These are “udp”, an empty host “”, and 50051 for the scheme, host and appendix, respectively.

Parameters:

string – A connection string.

Returns:

A tuple with the parsed schema, host and appendix.

async dronemanager.utils.coroutine_awaiter(task: Future, logger: Logger)

Awaits the provided coroutine, logging any exceptions.

In DroneManager, there are many functions that run indefinitely without a concrete return value. These functions are not “naturally” awaited at any point in the code, which can lead to exceptions being silently dropped. This function is used to catch these scenarios, by creating an extra task that awaits the actually interesting task. This task does not need to be explicitly awaited itself.

Parameters:
  • task – The task or future to await.

  • logger – This logger will be used for any exception logging.