Sidereon.GNSS.SSR (Sidereon v3.0.0)

Copy Markdown View Source

State-space GNSS corrections.

This module is the Elixir wrapper over the core SSR/HAS correction store and corrected broadcast ephemeris source. It holds decoded corrections in a native resource and evaluates corrected satellite states through the core.

Summary

Functions

Return the latest clock correction for a satellite.

Evaluate an SSR-corrected broadcast satellite state at an epoch.

Evaluate an SSR-corrected state using exact state and record-selection queries.

Read SSR-source position variance at independent exact state and selection queries.

Build a correction store from every readable frame of framed RTCM SSR/HAS bytes, reporting what was not read or not applied.

Build a correction store from framed RTCM bytes, refusing anything it cannot read under the strict RTCM policy and apply in full: bytes outside a frame, a CRC-24Q failure, a trailing partial frame, a frame that does not decode, and a message the store refuses.

Ingest one decoded RTCM message into an existing correction store.

Create an empty correction store.

Return the latest orbit correction for a satellite.

Sample an SSR-corrected broadcast source over a time grid.

Sample SSR states at explicit exact state and selection queries.

Read a selected SSR state with independent exact state and selection queries.

Read the SSR transmission-placement clock at exact state and selection queries.

Return the latest SSR URA index for a satellite.

Types

epoch()

@type epoch() :: NaiveDateTime.t() | tuple() | number()

satellite_attitude()

@type satellite_attitude() :: :unavailable | :nominal_sun_fixed

t()

@type t() :: %Sidereon.GNSS.SSR{handle: reference()}

Functions

clock(ssr, satellite_id)

@spec clock(t(), String.t()) ::
  {:ok, Sidereon.GNSS.SSR.ClockCorrection.t()} | {:error, term()}

Return the latest clock correction for a satellite.

clock!(store, satellite_id)

clock_relativity_for_state_at_epoch_query(broadcast, store, satellite_id, state_query, position_ecef_m, opts \\ [])

@spec clock_relativity_for_state_at_epoch_query(
  Sidereon.GNSS.Broadcast.t(),
  t(),
  String.t(),
  Sidereon.GNSS.Time.ExactEpochQuery.t(),
  {number(), number(), number()},
  keyword()
) :: :not_applicable | :unavailable | {:term, float()} | {:error, term()}

Evaluate SSR-source clock relativity for a state at its exact query.

corrected_position(broadcast, ssr, satellite_id, epoch, opts \\ [])

@spec corrected_position(
  Sidereon.GNSS.Broadcast.t(),
  t(),
  String.t(),
  epoch(),
  keyword()
) ::
  {:ok,
   %{
     position_ecef_m: {float(), float(), float()},
     clock_s: float(),
     oversized_corrections: [Sidereon.GNSS.SSR.OversizedCorrection.t()]
   }}
  | {:error, term()}

Evaluate an SSR-corrected broadcast satellite state at an epoch.

:correction_size_policy accepts :strict (the default) or :lenient. :satellite_antex may be a parsed Sidereon.GNSS.Antex product, and :satellite_attitude may be :unavailable (the default) or :nominal_sun_fixed. These configure the same core source used by the exact-query and sampling routes. A centre-of-mass correction needs both antenna calibration and a usable attitude to convert to the antenna phase centre; absent configuration leaves that correction unavailable. Strict mode returns {:error, {:correction_exceeds_limit, details}} when the applied orbit or clock correction exceeds the RTKLIB limits. This refusal is not replaced by a broadcast fallback.

corrected_position!(broadcast, store, satellite_id, epoch, opts \\ [])

corrected_position_at_epoch_query(broadcast, store, satellite_id, epoch, opts \\ [])

@spec corrected_position_at_epoch_query(
  Sidereon.GNSS.Broadcast.t(),
  t(),
  String.t(),
  Sidereon.GNSS.Time.ExactEpochQuery.t(),
  keyword()
) ::
  {:ok,
   %{
     position_ecef_m: {float(), float(), float()},
     clock_s: float(),
     oversized_corrections: [Sidereon.GNSS.SSR.OversizedCorrection.t()]
   }}
  | {:error, term()}

Evaluate an SSR-corrected state using exact state and record-selection queries.

ephemeris_variance_at_epoch_queries(broadcast, store, satellite_id, state_query, selection_query, opts \\ [])

@spec ephemeris_variance_at_epoch_queries(
  Sidereon.GNSS.Broadcast.t(),
  t(),
  String.t(),
  Sidereon.GNSS.Time.ExactEpochQuery.t(),
  Sidereon.GNSS.Time.ExactEpochQuery.t(),
  keyword()
) :: float() | nil | {:error, term()}

Read SSR-source position variance at independent exact state and selection queries.

from_rtcm(bytes, week, tow_s, opts \\ [])

@spec from_rtcm(binary(), non_neg_integer(), number(), keyword()) ::
  {:ok, t(),
   %{
     diagnostics: Sidereon.GNSS.RTCM.diagnostics(),
     trailing_partial_frame_len: non_neg_integer(),
     ingest_refusals: [%{message_number: integer(), reason: String.t()}]
   }}
  | {:error, term()}

Build a correction store from every readable frame of framed RTCM SSR/HAS bytes, reporting what was not read or not applied.

Frames are read under the lenient RTCM policy, so a frame that departs from the format is read and the departure recorded. Returns {:ok, store, report}, report holding :diagnostics (the stream diagnostics Sidereon.GNSS.RTCM.decode_stream/2 reports: resynchronized bytes, CRC-24Q failures, skipped frames with their reasons, and departures), :trailing_partial_frame_len (the bytes of an unfinished frame at the end) and :ingest_refusals (each message the store refused, as %{message_number, reason}). from_rtcm_strict/4 refuses all of these instead.

week and tow_s are the receiver time, on the scale named by :scale (:gpst by default); each message's time of week is placed in the week nearest it.

from_rtcm!(bytes, week, tow_s, opts \\ [])

@spec from_rtcm!(binary(), non_neg_integer(), number(), keyword()) :: t()

As from_rtcm_strict/4, raising ArgumentError on failure.

from_rtcm_strict(bytes, week, tow_s, opts \\ [])

@spec from_rtcm_strict(binary(), non_neg_integer(), number(), keyword()) ::
  {:ok, t()} | {:error, term()}

Build a correction store from framed RTCM bytes, refusing anything it cannot read under the strict RTCM policy and apply in full: bytes outside a frame, a CRC-24Q failure, a trailing partial frame, a frame that does not decode, and a message the store refuses.

ingest(ssr, message, week, tow_s)

@spec ingest(t(), Sidereon.GNSS.RTCM.message(), non_neg_integer(), number()) ::
  :ok | {:error, term()}

Ingest one decoded RTCM message into an existing correction store.

Non-SSR RTCM messages are ignored by the core store.

new(opts \\ [])

@spec new(keyword()) :: t()

Create an empty correction store.

The reference_point option selects interpretation of incoming orbit corrections: :antenna_phase_center (default) or :center_of_mass.

orbit(ssr, satellite_id)

@spec orbit(t(), String.t()) ::
  {:ok, Sidereon.GNSS.SSR.OrbitCorrection.t()} | {:error, term()}

Return the latest orbit correction for a satellite.

orbit!(store, satellite_id)

sample(broadcast, ssr, satellites, arg, step_s, opts \\ [])

Sample an SSR-corrected broadcast source over a time grid.

Accepts the same :satellite_antex and :satellite_attitude options as corrected_position/5.

sample!(broadcast, store, satellites, window, step_s, opts \\ [])

sample_at_epoch_queries(broadcast, store, satellites, queries, opts \\ [])

Sample SSR states at explicit exact state and selection queries.

selected_state_at_epoch_queries(broadcast, store, satellite_id, state_query, selection_query, opts \\ [])

@spec selected_state_at_epoch_queries(
  Sidereon.GNSS.Broadcast.t(),
  t(),
  String.t(),
  Sidereon.GNSS.Time.ExactEpochQuery.t(),
  Sidereon.GNSS.Time.ExactEpochQuery.t(),
  keyword()
) :: {:ok, map() | nil} | {:error, term()}

Read a selected SSR state with independent exact state and selection queries.

transmit_clock_at_epoch_queries(broadcast, store, satellite_id, state_query, selection_query, opts \\ [])

@spec transmit_clock_at_epoch_queries(
  Sidereon.GNSS.Broadcast.t(),
  t(),
  String.t(),
  Sidereon.GNSS.Time.ExactEpochQuery.t(),
  Sidereon.GNSS.Time.ExactEpochQuery.t(),
  keyword()
) :: {:ok, %{clock_s: float(), degraded: atom() | nil} | nil} | {:error, term()}

Read the SSR transmission-placement clock at exact state and selection queries.

ura_index(ssr, satellite_id)

@spec ura_index(t(), String.t()) :: {:ok, integer()} | {:error, term()}

Return the latest SSR URA index for a satellite.

ura_index!(store, satellite_id)