# `Sidereon.GNSS.Positioning.Solution`
[🔗](https://github.com/neilberkman/sidereon-ex/blob/main/lib/sidereon/gnss/positioning.ex#L63)

A single-point-positioning solution at one receive epoch.

`position` is the converged ITRF/IGS ECEF position in meters. `geodetic` is
the same point as `%{lat_rad, lon_rad, height_m}` when geodetic output was
requested (the default), otherwise `nil`. `rx_clock_s` is the reference-system
receiver clock bias in seconds; `system_clocks_s` is a map of GNSS letter
(e.g. `"G"`, `"E"`) to that system's **absolute** receiver clock in seconds (a
single entry for a one-system solve, one per constellation for a mixed solve).
These are per-system clocks, not biases: the inter-system bias of a system is
its clock minus the reference system's (`rx_clock_s`). `dop` carries the
dilution-of-precision scalars for any full-rank geometry; a single-system
solve uses the bit-exact four-state cofactor, a multi-system solve a general
inverse with one clock column per constellation, and is `nil` only when the
geometry is rank-deficient. `system_tdops` is a map of GNSS letter to that
system's time DOP (the square root of its clock cofactor variance), one entry
per constellation in the solve; the reference system's value equals
`dop.tdop`, and the map is empty when the geometry is rank-deficient.
`rx_clock_drift_s_s` is populated by `solve_with_doppler/5` and is `nil` for
pseudorange-only solves. `position_covariance` carries the unit-variance ECEF
and local ENU position covariance blocks in square metres.
`residuals_m` are the post-fit
pseudorange residuals in meters, in `used_sats` order. `used_sats` are the
contributing satellite id strings (e.g. `"G01"`); `rejected_sats` pairs each
excluded satellite id with its reason atom (`:no_ephemeris` or
`:low_elevation`). `metadata` reports solver iterations, convergence, the
corrections applied, and the geometry redundancy: `used_count`, the distinct
`systems`, the `redundancy` (degrees of freedom, `used_count - (3 + systems)`),
`raim_checkable?` (`redundancy >= 1`), and `geometry_quality` with the
core observability tier, rank, condition number, GDOP, RAIM checkability, and
covariance-validation flag. An exactly determined fix has
`redundancy < 1`, forcing the residuals near zero and leaving the fix
unverifiable by RAIM. When the opt-in `:huber` reweighting runs, `metadata`
also carries `:huber` with the `outer_iterations` count and the
`final_scale_m` (the last MAD robust scale in meters); the key is absent on
the default static path.

# `dop`

```elixir
@type dop() :: %{
  gdop: float(),
  pdop: float(),
  hdop: float(),
  vdop: float(),
  tdop: float()
}
```

Dilution-of-precision scalars for the solved geometry.

# `geodetic`

```elixir
@type geodetic() :: %{lat_rad: float(), lon_rad: float(), height_m: float()}
```

Receiver geodetic position in radians and metres.

# `metadata`

```elixir
@type metadata() :: %{
  :iterations =&gt; non_neg_integer(),
  :converged =&gt; boolean(),
  :status =&gt; atom(),
  :ionosphere_applied =&gt; boolean(),
  :troposphere_applied =&gt; boolean(),
  :used_count =&gt; non_neg_integer(),
  :systems =&gt; [String.t()],
  :redundancy =&gt; integer(),
  :raim_checkable? =&gt; boolean(),
  :geometry_quality =&gt; Sidereon.GeometryQuality.t(),
  optional(:fde) =&gt; %{
    excluded: [{String.t(), :raim_excluded}],
    iterations: non_neg_integer()
  },
  optional(:huber) =&gt; %{
    outer_iterations: non_neg_integer(),
    final_scale_m: float()
  }
}
```

Solver metadata and applied correction flags.

# `position`

```elixir
@type position() :: %{x_m: float(), y_m: float(), z_m: float()}
```

Receiver ECEF position in metres.

# `position_covariance`

```elixir
@type position_covariance() :: %{ecef_m2: [[float()]], enu_m2: [[float()]]}
```

Unit-variance receiver position covariance blocks.

# `t`

```elixir
@type t() :: %Sidereon.GNSS.Positioning.Solution{
  dop: dop() | nil,
  geodetic: geodetic() | nil,
  metadata: metadata(),
  position: position(),
  position_covariance: position_covariance(),
  rejected_sats: [{String.t(), :no_ephemeris | :low_elevation}],
  residuals_m: [float()],
  rx_clock_drift_s_s: float() | nil,
  rx_clock_s: float(),
  system_clocks_s: %{required(String.t()) =&gt; float()},
  system_tdops: %{required(String.t()) =&gt; float()},
  used_sats: [String.t()]
}
```

Decoded single-point-positioning receiver solution.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
