Sidereon.GNSS.Broadcast (Sidereon v2.1.0)

Copy Markdown View Source

A parsed RINEX broadcast-navigation product (GPS LNAV, Galileo I/NAV+F/NAV, BeiDou D1/D2, GLONASS).

Holds the broadcast Keplerian elements and clock terms as a resource handle, the broadcast-ephemeris counterpart to Sidereon.GNSS.SP3. Pass a handle to Sidereon.GNSS.Positioning.solve/4 to position from broadcast ephemeris instead of a precise SP3 product. The navigation file is parsed exactly once; the parsed product is held as a reference, not re-parsed per call.

Parsing covers RINEX 3.x and 4.xx files: GPS, Galileo, and BeiDou records (including BeiDou geostationary satellites), GPS/QZSS CNAV-family records, and GLONASS (a PZ-90.11 state-vector model propagated by Runge-Kutta integration rather than Keplerian elements). Other constellations in a mixed file are skipped.

The orbit and clock models follow IS-GPS-200 (GPS LNAV), the Galileo OS-SIS-ICD (I/NAV + F/NAV), and the BeiDou BDS-SIS-ICD (D1/D2), parsed from RINEX 3.x/4.xx navigation records.

The handle API applies the core store's default usability policy. The direct parse_rinex_nav_records/1, parse_rinex_nav_lenient/1, parse_rinex_glonass_records/1, parse_rinex_glonass_lenient/1, and encode_rinex_nav/1 routes expose the caller-owned raw record-list contracts without that filtering.

Epochs

position/3 interprets the query epoch in GPS time (GPST). A NaiveDateTime or {{year, month, day}, {hour, minute, second}} is converted to a continuous second-of-J2000 via Sidereon.GNSS.Time; the crate maps that onto each system's own time scale (BDT for BeiDou, UTC-referenced for GLONASS) before selecting the governing record. No leap-second shifting is applied to the supplied epoch.

Summary

Functions

Time-dependent CNAV URA_NED bound in metres.

Nominal CNAV URA in metres for a URA ED/NED0 index.

Serialize the usable GPS, Galileo, and BeiDou broadcast records to RINEX 3 navigation text.

Encode a caller-supplied list of full broadcast records to canonical RINEX NAV text.

Number of healthy GLONASS state-vector records held by the parsed product.

Healthy GLONASS broadcast state-vector records in file order.

Broadcast ionosphere coefficients parsed from the NAV header.

GPS minus UTC leap seconds from the NAV header, if present.

Parse a RINEX 3.x or 4.xx navigation file from disk.

Like load/1 but raises on failure.

GPS/QZSS record-family preference used by mixed LNAV/CNAV selection.

Parse an in-memory RINEX 3.x or 4.xx navigation text buffer into a handle.

Parse raw GLONASS RINEX NAV records while retaining skipped slot identities.

Parse every representable GLONASS state-vector record from RINEX NAV text.

Parse supported RINEX NAV records leniently.

Parse all supported RINEX NAV records in file order without the broadcast store's health, message-family, or CNAV usability filters.

Evaluate the broadcast state of satellite sat_id at epoch.

Number of usable GPS, Galileo, and BeiDou records held by the parsed product.

Usable GPS, Galileo, and BeiDou broadcast records in file order.

Detailed GPS, Galileo, BeiDou, and CNAV-family records in file order.

Types

message_preference()

@type message_preference() :: :legacy | :modern

nav_message()

@type nav_message() ::
  :gps_lnav
  | :gps_cnav
  | :gps_cnav2
  | :qzss_lnav
  | :qzss_cnav
  | :qzss_cnav2
  | :galileo_inav
  | :galileo_fnav
  | :beidou_d1
  | :beidou_d2

t()

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

Functions

cnav_ura_ned(cnav, time)

Time-dependent CNAV URA_NED bound in metres.

cnav_ura_nominal(index)

@spec cnav_ura_nominal(integer()) :: float() | nil

Nominal CNAV URA in metres for a URA ED/NED0 index.

encode_nav(broadcast)

@spec encode_nav(t()) :: String.t()

Serialize the usable GPS, Galileo, and BeiDou broadcast records to RINEX 3 navigation text.

Round-trips with parse/1: re-parsing the output reconstructs the same records. The text covers the records held by the parsed product (the default SPP policy output exposed by records/1); GLONASS state-vector records are not serialized.

encode_rinex_nav(records)

@spec encode_rinex_nav([Sidereon.GNSS.Broadcast.DetailedRecord.t()]) ::
  {:ok, String.t()} | {:error, term()}

Encode a caller-supplied list of full broadcast records to canonical RINEX NAV text.

This is independent of a parsed Broadcast handle and does not apply the store's default filtering policy. Pass DetailedRecord values such as those returned by parse_rinex_nav_records/1; the list may be reordered or reduced by the caller.

glonass_record_count(broadcast)

@spec glonass_record_count(t()) :: non_neg_integer()

Number of healthy GLONASS state-vector records held by the parsed product.

glonass_records(broadcast)

@spec glonass_records(t()) :: [Sidereon.GNSS.Broadcast.GlonassRecord.t()]

Healthy GLONASS broadcast state-vector records in file order.

iono_corrections(broadcast)

@spec iono_corrections(t()) :: Sidereon.GNSS.Broadcast.IonoCorrections.t()

Broadcast ionosphere coefficients parsed from the NAV header.

Returns GPS and BeiDou Klobuchar-8 coefficient sets when present, otherwise nil for each missing set.

leap_seconds(broadcast)

@spec leap_seconds(t()) :: float() | nil

GPS minus UTC leap seconds from the NAV header, if present.

load(path)

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

Parse a RINEX 3.x or 4.xx navigation file from disk.

Returns {:ok, %Sidereon.GNSS.Broadcast{}} or {:error, reason}. The file is read and parsed once; the parsed product is held as a resource handle.

load!(path)

@spec load!(String.t()) :: t()

Like load/1 but raises on failure.

message_preference(broadcast)

@spec message_preference(t()) :: message_preference()

GPS/QZSS record-family preference used by mixed LNAV/CNAV selection.

parse(text, opts \\ [])

@spec parse(
  String.t(),
  keyword()
) :: {:ok, t()} | {:error, term()}

Parse an in-memory RINEX 3.x or 4.xx navigation text buffer into a handle.

parse_rinex_glonass_lenient(text)

@spec parse_rinex_glonass_lenient(String.t()) ::
  {:ok, Sidereon.GNSS.Broadcast.GlonassParse.t()} | {:error, term()}

Parse raw GLONASS RINEX NAV records while retaining skipped slot identities.

The core parser returns representable records and the source token of every unrepresentable GLONASS slot. Both lists preserve source order. Malformed representable records remain errors.

parse_rinex_glonass_records(text)

@spec parse_rinex_glonass_records(String.t()) ::
  {:ok, [Sidereon.GNSS.Broadcast.GlonassRecord.t()]} | {:error, term()}

Parse every representable GLONASS state-vector record from RINEX NAV text.

Unlike glonass_records/1, this direct parser returns records before the broadcast store's healthy-satellite filter, in file order.

parse_rinex_nav_lenient(text)

@spec parse_rinex_nav_lenient(String.t()) ::
  {:ok, Sidereon.GNSS.Broadcast.RinexNavParse.t()} | {:error, term()}

Parse supported RINEX NAV records leniently.

Header errors remain {:error, reason}. Malformed supported body blocks are omitted from records and reported in skipped; valid records remain in file order.

parse_rinex_nav_records(text)

@spec parse_rinex_nav_records(String.t()) ::
  {:ok, [Sidereon.GNSS.Broadcast.DetailedRecord.t()]} | {:error, term()}

Parse all supported RINEX NAV records in file order without the broadcast store's health, message-family, or CNAV usability filters.

The returned DetailedRecord values retain the full core record needed by encode_rinex_nav/1, including issue/time tags, group delays, and CNAV parameters.

position(broadcast, sat_id, epoch)

@spec position(t(), String.t(), NaiveDateTime.t() | tuple()) ::
  {:ok, Sidereon.GNSS.Broadcast.State.t()} | {:error, term()}

Evaluate the broadcast state of satellite sat_id at epoch.

sat_id is the canonical RINEX token, e.g. "G01" (GPS PRN 1), "E12", "C30", "R07". epoch is a NaiveDateTime or a {{year, month, day}, {hour, minute, second}} tuple, interpreted in GPS time.

Returns {:ok, %Sidereon.GNSS.Broadcast.State{}} with the ECEF position (meters) and satellite clock offset (seconds), {:error, :no_ephemeris} when no broadcast record covers that satellite at that epoch (the validity window has no match; this is not extrapolated), or {:error, reason} for a malformed satellite token or a non-integer-second tuple epoch.

Evaluating the same satellite across a window reuses the parsed handle; the navigation file is never re-read.

record_count(broadcast)

@spec record_count(t()) :: non_neg_integer()

Number of usable GPS, Galileo, and BeiDou records held by the parsed product.

records(broadcast)

@spec records(t()) :: [Sidereon.GNSS.Broadcast.Record.t()]

Usable GPS, Galileo, and BeiDou broadcast records in file order.

The returned records are the core store's default SPP policy output: healthy GPS LNAV, Galileo I/NAV, and BeiDou D1/D2 records. Galileo F/NAV and unhealthy satellites are not included in this accessor.

records_detailed(broadcast)

@spec records_detailed(t()) :: [Sidereon.GNSS.Broadcast.DetailedRecord.t()]

Detailed GPS, Galileo, BeiDou, and CNAV-family records in file order.