uataq.gps.estimate_speed_course#

uataq.gps.estimate_speed_course(latitude, longitude, time=None, window=1, max_gap='60s')[source]#

Estimate speed and course from a sequence of positions.

Both are centered differences: the sample at position i is described by the displacement from i - window to i + window, so the estimate is symmetric in time and does not lag the track. Speed is the great-circle distance over the elapsed time; course is the bearing along it.

Parameters:
  • latitude (ArrayLike) – Positions in degrees, ordered in time. A pandas Series with a DatetimeIndex supplies time on its own.

  • longitude (ArrayLike) – Positions in degrees, ordered in time. A pandas Series with a DatetimeIndex supplies time on its own.

  • time (ArrayLike | None) – Sample times, convertible by pandas.to_datetime(). Defaults to the index of latitude when that is a Series.

  • window (int) – Number of samples on each side of the centered difference. 1 uses the immediate neighbors. A larger window averages over a longer baseline, which suppresses position noise at the cost of smoothing real accelerations and turns.

  • max_gap (str | Timedelta | None) – Longest interval between consecutive samples that may fall inside the difference. Where a larger gap is spanned the estimate is NaN, because a straight chord across a gap is not the path traveled. None disables the check.

Returns:

Speed_m_s and Course_deg, indexed by time (named Time_UTC). The first and last window samples are NaN, as are samples spanning a gap or a non-increasing time step.

Return type:

DataFrame

Notes

Position noise becomes speed noise: a receiver jittering by a few meters looks like it is moving at a few m/s when differenced over 1 s. Use a longer window (or aggregate first) before thresholding a stationary platform, and treat the course as meaningless wherever the speed is at or below the noise level.