Orbis.GNSS.Positioning (Orbis v0.9.0)

Copy Markdown View Source

GNSS single-point positioning (SPP): recover a receiver position, clock bias, and geometry diagnostics from one epoch of pseudorange observations against a precise SP3 ephemeris or a broadcast navigation product.

This is the Elixir surface over the astrodynamics-gnss SPP solver. Given an ephemeris source — an Orbis.GNSS.SP3 product or an Orbis.GNSS.Broadcast handle (GPS / Galileo / BeiDou / GLONASS) — a set of single-frequency pseudoranges, the receive epoch, and the broadcast/atmosphere parameters, it runs the transmit-time iteration and trust-region least-squares solve in the crate and returns an Orbis.GNSS.Positioning.Solution. A mixed-constellation set is solved together with one receiver clock per system. No positioning math lives on the Elixir side; this module marshals units and epoch arguments and decodes the result.

Units at the boundary

  • pseudoranges and the initial guess position/clock are meters;
  • the recovered position is ITRF/IGS ECEF meters, matching the SP3 frame;
  • geodetic latitude/longitude are radians and height is meters;
  • rx_clock_s is seconds;
  • pressure is hPa, temperature is kelvin, relative humidity is a fraction in [0, 1];
  • the Klobuchar alpha/beta coefficients are passed in their broadcast units.

The epoch is interpreted in the SP3 product's own time scale (typically GPST); no leap-second shifting is applied. The seconds-since-J2000, second-of-day, and fractional day-of-year arguments the crate needs are derived from the supplied epoch via Orbis.GNSS.Time.

Example

{:ok, sp3} = Orbis.GNSS.SP3.load("igs.sp3")

observations = [{"G01", 2.41e7}, {"G02", 2.49e7}, {"G05", 2.05e7}, {"G07", 2.30e7}]

{:ok, solution} =
  Orbis.GNSS.Positioning.solve(sp3, observations, ~N[2020-06-24 12:00:00],
    ionosphere: true,
    troposphere: true,
    klobuchar_alpha: {1.0e-8, 2.2e-8, -6.0e-8, -1.2e-7},
    klobuchar_beta: {96_256.0, 131_072.0, -65_536.0, -589_824.0}
  )

solution.position.x_m
solution.rx_clock_s

Summary

Types

An epoch as a NaiveDateTime or {{y, m, d}, {h, min, s}} tuple.

A {satellite_id, pseudorange_m} pseudorange observation.

Functions

Solve single-point positioning for one receive epoch.

Types

epoch()

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

An epoch as a NaiveDateTime or {{y, m, d}, {h, min, s}} tuple.

observation()

@type observation() :: {String.t(), number()}

A {satellite_id, pseudorange_m} pseudorange observation.

Functions

solve(source, observations, epoch, opts \\ [])

@spec solve(
  Orbis.GNSS.SP3.t() | Orbis.GNSS.Broadcast.t(),
  [observation()],
  epoch(),
  keyword()
) ::
  {:ok, Orbis.GNSS.Positioning.Solution.t()} | {:error, term()}

Solve single-point positioning for one receive epoch.

source is a loaded ephemeris product — an Orbis.GNSS.SP3 precise product or an Orbis.GNSS.Broadcast broadcast-navigation product. observations is a list of {satellite_id, pseudorange_m} pairs (ids like "G01", pseudoranges in meters), and epoch is a NaiveDateTime or {{y, m, d}, {h, min, s}} tuple in the product's time scale.

Options

  • :ionosphere - apply the broadcast Klobuchar ionosphere correction (default false); the L1 delay is scaled to each satellite's carrier by (f_L1/f)^2, covering GPS L1, Galileo E1, and BeiDou B1I (a system with no modeled single-frequency carrier, e.g. GLONASS, is rejected)
  • :troposphere - apply the Saastamoinen/Niell troposphere correction (default false)
  • :klobuchar_alpha - broadcast alpha coefficients, 4-tuple (default zeros)
  • :klobuchar_beta - broadcast beta coefficients, 4-tuple (default zeros)
  • :pressure_hpa - surface pressure, hPa (default 1013.25)
  • :temperature_k - surface temperature, kelvin (default 288.15)
  • :relative_humidity - relative humidity fraction [0, 1] (default 0.5)
  • :initial_guess - {x_m, y_m, z_m, b_m} start point (default all zeros)
  • :with_geodetic - also return the geodetic position (default true)

A mixed GPS+Galileo+BeiDou+GLONASS observation set is solved together with one receiver clock per GNSS (an inter-system bias is the difference between a system's clock and the reference system's), and dilution of precision is reported for the combined geometry as well.

Returns {:ok, %Orbis.GNSS.Positioning.Solution{}} or {:error, reason}, where reason is one of {:too_few_satellites, used, required} (required is 3 + n_systems), :singular_geometry, {:duplicate_observation, sat}, {:ephemeris_lost, sat}, or {:ionosphere_unsupported, sat} (the ionosphere correction was requested for a system with no modeled single-frequency carrier).