Geometry

Classes:

Distance(pairwise, n_dim, metric, …)

Given an n_samples x n_dimensions array, compute pairwise or mean distances

Angle([abs, degrees])

Get angle between line formed by two points and horizontal axis

IMU_Orientation(use_kalman, invert_gyro, …)

Compute absolute orientation (roll, pitch) from accelerometer and gyroscope measurements (eg from hardware.i2c.I2C_9DOF )

Rotate([dims, rotation_type, degrees, …])

Rotate in 3 dimensions using scipy.spatial.transform.Rotation

Spheroid([target])

Fit and transform 3d coordinates according to some spheroid.

Functions:

_ellipsoid_func(fit, a, b, c, x, y, z)

Ellipsoid equation for use with Ellipsoid.fit()

class Distance(pairwise: bool = False, n_dim: int = 2, metric: str = 'euclidean', squareform: bool = True, *args, **kwargs)[source]

Bases: autopilot.transform.transforms.Transform

Given an n_samples x n_dimensions array, compute pairwise or mean distances

Parameters
  • pairwise (bool) – If False (default), return mean distance. if True, return all distances

  • n_dim (int) – number of dimensions (input array will be filtered like input[:,0:n_dim]

  • metric (str) – any metric acceptable to :func:`scipy.spatial.distance.pdist

  • squareform (bool) – if pairwise is True, if True return square distance matrix, otherwise return compressed distance matrix (dist(X[i], X[j] = y[i*j])

  • *args

  • **kwargs

Attributes:

format_in

format_out

Methods:

process(input)

format_in = {'type': <class 'numpy.ndarray'>}
format_out = {'type': <class 'numpy.ndarray'>}
process(input: numpy.ndarray)[source]
class Angle(abs=True, degrees=True, *args, **kwargs)[source]

Bases: autopilot.transform.transforms.Transform

Get angle between line formed by two points and horizontal axis

Attributes:

format_in

format_out

Methods:

process(input)

format_in = {'type': <class 'numpy.ndarray'>}
format_out = {'type': <class 'float'>}
process(input)[source]
class IMU_Orientation(use_kalman: bool = True, invert_gyro: bool = False, *args, **kwargs)[source]

Bases: autopilot.transform.transforms.Transform

Compute absolute orientation (roll, pitch) from accelerometer and gyroscope measurements (eg from hardware.i2c.I2C_9DOF )

Uses a timeseries.Kalman filter, and implements [PPT+18] to fuse the sensors

Can be used with accelerometer data only, or with combined accelerometer/gyroscope data for greater accuracy

Parameters
  • invert_gyro (bool) – if the gyroscope’s orientation is inverted from accelerometer measurement, multiply gyro readings by -1 before using

  • use_kalman (bool) – Whether to use kalman filtering (True, default), or return raw trigonometric transformation of accelerometer readings (if provided, gyroscope readings will be ignored)

Variables

kalman (transform.timeseries.Kalman) – If use_kalman == True , the Kalman Filter.

References

[PPT+18] [ABCO15]

Methods:

process(accelgyro)

Parameters

accelgyro (tuple, numpy.ndarray) – tuple of (accelerometer[x,y,z], gyro[x,y,z]) readings as arrays, or

process(accelgyro: Union[Tuple[numpy.ndarray, numpy.ndarray], numpy.ndarray]) numpy.ndarray[source]
Parameters

accelgyro (tuple, numpy.ndarray) – tuple of (accelerometer[x,y,z], gyro[x,y,z]) readings as arrays, or an array of just accelerometer[x,y,z]

Returns

filtered [roll, pitch] calculations in degrees

Return type

numpy.ndarray

class Rotate(dims='xyz', rotation_type='euler', degrees=True, inverse='', rotation=None, *args, **kwargs)[source]

Bases: autopilot.transform.transforms.Transform

Rotate in 3 dimensions using scipy.spatial.transform.Rotation

Parameters
  • dims (“xyz”) – string specifying which axes the rotation will be around, eg "xy" , "xyz"`

  • rotation_type (str) – Format of rotation input, must be one available to the Rotation class (but currently only euler angles are supported)

  • degrees (bool) – whether to output rotation in degrees (True, default) or radians

  • inverse (“xyz”) – dimensions in the “rotation” input to Rotate.process() to inverse before applying rotation

  • rotation (tuple, list, numpy.ndarray, None) – If supplied, use the same rotation for all processed data. If None, Rotate.process() will expect a tuple of (data, rotation).

Methods:

process(input)

Parameters

input (tuple, numpy.ndarray) – a tuple of (input[x,y,z], rotation[x,y,z]) where input is to be rotated

process(input)[source]
Parameters

input (tuple, numpy.ndarray) – a tuple of (input[x,y,z], rotation[x,y,z]) where input is to be rotated according to the axes in rotation (indicated in Rotate.dims ). If only an input array is provided, a static rotation array must have been provided in the constructor (otherwise the most recent rotation will be used)

Returns

numpy.ndarray - rotated input array

class Spheroid(target=(1, 1, 1, 0, 0, 0), source: tuple = (None, None, None, None, None, None), fit: Optional[numpy.ndarray] = None, *args, **kwargs)[source]

Bases: autopilot.transform.transforms.Transform

Fit and transform 3d coordinates according to some spheroid.

Eg. for calibrating accelerometer readings by transforming them from their uncalibrated spheroid to the expected sphere with radius == 9.8m/s/s centered at (0,0,0).

Does not estimate/correct for rotation of the spheroid.

Examples

# Calibrate an accelerometer by transforming readings to a 9.8-radius sphere centered at 0 >>> sphere = Spheroid(target=(9.8,9.8,9.8,0,0,0)) # take some readings… # imagine we’re taking them from some sensor idk # say our sensor slightly exaggerates gravity in the z-axis… >>> readings = np.array((0.,0.,10.5)) # fit our object (need >>1 sample) >>> sphere.fit(readings) # transform to proper gravity >>> sphere.process(readings) [0., 0., 9.8]

Parameters
  • target (tuple) – parameterization of spheroid to transform to, if none is passed, transform to unit circle centered at (0,0,0). parameterized as:

    (a, # radius of x dimension
    

    b, # radius of y dimension c, # radius of z dimension x, # x-offset y, # y-offset z) # z-offset

  • source (tuple) – parameterization of spheroid to transform from in the same 6-tuple form as target, if None is passed, assume we will use Spheroid.fit()

  • fit (None, numpy.ndarray) – Initialize with values to fit, if None assume fit will be called later.

References

Methods:

fit(points, **kwargs)

Fit a spheroid from a set of noisy measurements

process(input)

Transform input (x,y,z) points such that points in source are mapped to those in target

generate(n[, which, noise])

Generate random points from the ellipsoid

fit(points, **kwargs)[source]

Fit a spheroid from a set of noisy measurements

updates the _scale and _offset private arrays used to manipulate input data

Note

It’s usually important to pass bounds to scipy.optimize.curve_fit() !!! passed as a 2-tuple of ((min_a, min_b, ...), (max_a, max_b...)) In particular such that a, b, and c are positive. If no bounds are passed, assume at least that much.

Parameters
Returns

parameters of fit ellipsoid (a,b,c,x,y,z)

Return type

tuple

process(input: numpy.ndarray)[source]

Transform input (x,y,z) points such that points in source are mapped to those in target

Parameters

input (numpy.ndarray) – x, y, and z coordinates

Returns

coordinates transformed according to the spheroid requested

Return type

numpy.ndarray

generate(n: int, which: str = 'source', noise: float = 0)[source]

Generate random points from the ellipsoid

Parameters
  • n (int) – number of points to generate

  • which (‘str’) – which spheroid to generate from? (‘source’ - default, or ‘target’)

  • noise (float) – noise to add to points

Returns

(n, 3) array of generated points

Return type

numpy.ndarray

_ellipsoid_func(fit, a, b, c, x, y, z)[source]

Ellipsoid equation for use with Ellipsoid.fit()

Parameters
  • fit (numpy.ndarray) – (M, 3) array of x,y,z points to fit

  • a (float) – X-scale parameter to fit

  • b (float) – Y-scale parameter to fit

  • c (float) – Z-scale parameter to fit

  • x (float) – X-offset parameter to fit

  • y (float) – Y-offset parameter to fit

  • z (float) – Z-offset parameter to fit

Returns

result of ellipsoid function, minimize parameters to == 1

Return type

float