compute_angular_time_derivative#

movement.kinematics.compute_angular_time_derivative(data, order, window=None)[source]#

Compute the time-derivative of a 2D orientation.

The orientation is given as 2D vectors. Its rate of change is estimated from the signed angles between nearby orientation vectors, which avoids the spurious jumps that occur when angles wrap around at \(\pm\pi\) (see Notes).

Parameters:
  • data (DataArray) – The input orientation vectors, containing time and space as dimensions. space must have exactly the coordinates ["x", "y"]. The vectors need not be of unit length.

  • order (int) – The order of the time-derivative. Use 1 for angular velocity and 2 for angular acceleration. Must be a positive integer.

  • window (int | None) – If None (default), the derivative is computed with central differences (one-sided at the first and last observations). Otherwise, the size of the centred rolling window, representing the fixed number of observations to which a least-squares polynomial is fitted (see Notes). Must be an odd integer greater than order, and requires a uniformly sampled time coordinate.

Returns:

The time-derivative of the orientation, in radians per unit of time (raised to the power of order). It has the dimensions of the input, without space.

Return type:

DataArray

See also

compute_angular_velocity

Wrapper for order=1.

compute_angular_acceleration

Wrapper for order=2.

Notes

Wrap-around. Differentiating angles directly produces spurious spikes wherever they wrap around at \(\pm\pi\). Instead, this function uses the signed angles between nearby orientations vectors. Without window, order=1 is a central-difference estimate built from the angles between consecutive observations. As with numpy.gradient(), it stays centred on each observation even when time steps are irregular. Higher orders differentiate that result further with compute_time_derivative(). With window, the angles are measured from the window’s centre orientation (see Windowed estimate). This assumes rotations of less than \(\pi\) between consecutive observations (or across half a window). Undefined orientations (NaNs or zero-length vectors) are treated as NaN.

Sign. Positive values are rotations from the positive x-axis towards the positive y-axis. In image coordinates (y pointing down) with a top-down camera, this is clockwise on screen.

Windowed estimate. With window, the angles of the orientations in the window, relative to the centre one, are differentiated with Savitzky-Golay coefficients (scipy.signal.savgol_coeffs()). For order=1, this is the slope of a least-squares line over the window centred on each time point. It uses every observation in the window. The first and last window // 2 values are NaN, as are all outputs whose window contains a NaN. For a window ending on each time point, shift the result by window // 2 time steps.

Preprocessing. Smooth, interpolate, or resample the orientation vectors, not their angles, since angle averages are wrong near \(\pm\pi\). Windowed estimates require uniform sampling, so make sure to resample irregularly sampled data onto a uniform time grid first, e.g. with xarray.DataArray.interp() on the vectors.