Sidereon.GNSS.PrecisePositioning.MultiEpochSolution (Sidereon v3.0.0)

Copy Markdown View Source

Static multi-epoch float-ambiguity phase positioning solution.

Summary

Types

A phase continuity token: its fields as the core states them and the handle holding the token.

The receiver clock of one solved epoch. epoch_index is the epoch's position in the input arc; an epoch left with no observations by the elevation cutoff, SSR bias exclusion or the residual screen has no clock.

A physical signal: the system letter and band and tracking attribute ("1C").

An observation of the arc: its input epoch index and ambiguity id.

A signal index as its source transmitted it.

One residual row. epoch_index is the input epoch index and ambiguity_id the observation's ambiguity id, which identifies it within its epoch.

The key an SSR bias is stored under.

The iteration and convergence options a float solve ran with.

An observation left out of the solve because an SSR/HAS bias the corrections require was not resolved for it, with every field the core records: transmit_time_failure, why the recorded biases do not hold at the observation's transmission time, and application, the row the bias lookup reported for the observation, with each signal's query result. solve_ppp_fixed/4 takes the record back as it came out. A phase continuity token and a source error, which the core does not let a caller build, carry a handle holding the core value; the fields beside it have to be the value's own. :unrecognized stands for a core value this binding does not know, and a record holding one is refused on the way back.

Provider and solution identity of SSR corrections.

t()

A static float solution. epoch_clocks holds one clock per solved epoch, in the order of solved_epoch_indices. unplaced_observations lists the observations left out because no transmission epoch can be placed from them, and residual_screen_removals the observations the residual screen removed, which solve_ppp_fixed/4 leaves out too, and ssr_bias_exclusions the observations left out for a missing SSR/HAS bias, which the fixed solve starts from.

An observation left out of the solve before it solves because no transmission epoch can be placed from it. :code_not_positive: its code is zero or negative, which RTKLIB satposs reads as no pseudorange. SSR correction-size refusal retains the orbit and clock magnitudes at the rejected transmission epoch.

Types

application_report()

@type application_report() :: %{
  epoch_index: non_neg_integer(),
  sat: String.t(),
  satellite_id: String.t(),
  ambiguity_id: String.t(),
  transmit_time_j2000_s: float() | nil,
  applied_orbit_clock_solution: ssr_solution() | nil,
  observation_signals:
    %{
      code1: String.t(),
      code2: String.t(),
      phase1: String.t(),
      phase2: String.t()
    }
    | nil,
  code_status: if_combination_status(),
  applied_code_if_m: float() | nil,
  code1_report: signal_report(code_bias_query()) | nil,
  code2_report: signal_report(code_bias_query()) | nil,
  phase_status: if_combination_status(),
  applied_phase_if_m: float() | nil,
  phase1_report: signal_report(phase_bias_query()) | nil,
  phase2_report: signal_report(phase_bias_query()) | nil
}

bias_status()

@type bias_status() ::
  :available
  | :missing
  | :unavailable
  | :not_yet_valid
  | :expired
  | :excluded
  | :invalid_epoch
  | :phase_discontinuity_needs_reset
  | :unknown_signal
  | :unrecognized

code_bias_query()

@type code_bias_query() :: %{
  sat: String.t(),
  signal: signal_key(),
  source_signal: raw_signal() | nil,
  status: bias_status(),
  bias_m: float() | nil,
  solution: ssr_solution() | nil,
  iod_ssr: non_neg_integer() | nil,
  ref_epoch_j2000_s: float() | nil,
  lifetime: lifetime() | nil,
  details: resolution_details()
}

continuity_token()

@type continuity_token() :: %{
  satellite: String.t(),
  signal: signal_key(),
  source: :rtcm_ssr | :galileo_has,
  provider_id: non_neg_integer(),
  solution_id: non_neg_integer(),
  continuity_ref_epoch_j2000_s: float(),
  raw_indicator: non_neg_integer(),
  generation: non_neg_integer(),
  handle: reference()
}

A phase continuity token: its fields as the core states them and the handle holding the token.

covariance()

@type covariance() :: %{ecef_m2: [[float()]], enu_m2: [[float()]]}

discontinuity_details()

@type discontinuity_details() ::
  :initial_token_established
  | :continuous
  | {:has_pdi_changed,
     %{previous: non_neg_integer(), current: non_neg_integer()}}
  | {:rtcm_discontinuity_counter_changed,
     %{previous: non_neg_integer(), current: non_neg_integer()}}
  | {:solution_changed, %{previous: ssr_solution(), current: ssr_solution()}}
  | :stale_token
  | :future_token
  | :mismatched_token
  | :unrecognized

epoch_clock()

@type epoch_clock() :: %{
  :epoch => NaiveDateTime.t(),
  :rx_clock_s => float(),
  :rx_clock_m => float(),
  optional(:epoch_index) => non_neg_integer()
}

The receiver clock of one solved epoch. epoch_index is the epoch's position in the input arc; an epoch left with no observations by the elevation cutoff, SSR bias exclusion or the residual screen has no clock.

gnss_signal()

@type gnss_signal() :: %{system: String.t(), code: String.t()}

A physical signal: the system letter and band and tracking attribute ("1C").

if_combination_status()

@type if_combination_status() ::
  :applied
  | :opted_out
  | :signal_unavailable
  | :invalid_frequencies
  | :observation_signals_unknown
  | :carrier_unresolved
  | :observation_frequency_mismatch
  | :incompatible_source_or_solution
  | :incompatible_iod
  | :orbit_clock_solution_unavailable
  | :orbit_clock_solution_mismatch
  | :satellite_excluded
  | :transmit_time_unavailable
  | :phase_discontinuity_needs_reset
  | {:ut1_outside_coverage, :before_coverage | :after_coverage}
  | :unrecognized

lifetime()

@type lifetime() ::
  {:galileo_has_validity_interval, float()}
  | {:rtcm_update_interval, float()}
  | :unrecognized

observation_key()

@type observation_key() :: %{epoch_index: non_neg_integer(), ambiguity_id: String.t()}

An observation of the arc: its input epoch index and ambiguity id.

phase_bias_query()

@type phase_bias_query() :: %{
  sat: String.t(),
  signal: signal_key(),
  source_signal: raw_signal() | nil,
  status: bias_status(),
  bias_m: float() | nil,
  bias_cycles: float() | nil,
  solution: ssr_solution() | nil,
  iod_ssr: non_neg_integer() | nil,
  ref_epoch_j2000_s: float() | nil,
  lifetime: lifetime() | nil,
  continuity_token: continuity_token() | nil,
  discontinuity_indicator:
    {:galileo_has_pdi, non_neg_integer()}
    | {:rtcm_discontinuity_counter, non_neg_integer()}
    | nil,
  discontinuity_details: discontinuity_details() | nil,
  details: resolution_details()
}

position()

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

raw_signal()

@type raw_signal() :: %{
  source: :rtcm_ssr | :galileo_has,
  system: String.t(),
  index: non_neg_integer()
}

A signal index as its source transmitted it.

residual()

@type residual() :: %{
  :epoch => NaiveDateTime.t(),
  :satellite_id => String.t(),
  :code_m => float(),
  :phase_m => float(),
  :ambiguity_id => String.t(),
  optional(:epoch_index) => non_neg_integer(),
  optional(:code_weight) => float(),
  optional(:phase_weight) => float()
}

One residual row. epoch_index is the input epoch index and ambiguity_id the observation's ambiguity id, which identifies it within its epoch.

resolution_details()

@type resolution_details() ::
  :available
  | :no_record
  | :transmitted_unavailable
  | :conversion_unavailable
  | {:epoch_before_reference,
     %{ref_epoch_j2000_s: float(), query_epoch_j2000_s: float()}}
  | {:epoch_expired,
     %{expiry_epoch_j2000_s: float(), query_epoch_j2000_s: float()}}
  | {:excluded_by_do_not_use,
     %{ref_epoch_j2000_s: float(), validity_interval_s: float()}}
  | :invalid_epoch
  | {:phase_discontinuity, discontinuity_details()}
  | {:unknown_signal, raw_signal()}
  | :unrecognized

signal_key()

@type signal_key() :: {:physical, gnss_signal()} | {:unknown, raw_signal()}

The key an SSR bias is stored under.

signal_report(query)

@type signal_report(query) :: %{
  epoch_index: non_neg_integer(),
  sat: String.t(),
  ambiguity_id: String.t(),
  signal: gnss_signal(),
  query_result: query
}

solve_options()

@type solve_options() :: %{
  max_iterations: pos_integer(),
  position_tolerance_m: float(),
  clock_tolerance_m: float(),
  ambiguity_tolerance_m: float(),
  ztd_tolerance_m: float()
}

The iteration and convergence options a float solve ran with.

ssr_bias_exclusion()

@type ssr_bias_exclusion() :: %{
  epoch_index: non_neg_integer(),
  satellite_id: String.t(),
  ambiguity_id: String.t(),
  code_bias_missing: boolean(),
  phase_bias_missing: boolean(),
  transmit_time_failure: transmit_time_failure() | nil,
  application: application_report() | nil
}

An observation left out of the solve because an SSR/HAS bias the corrections require was not resolved for it, with every field the core records: transmit_time_failure, why the recorded biases do not hold at the observation's transmission time, and application, the row the bias lookup reported for the observation, with each signal's query result. solve_ppp_fixed/4 takes the record back as it came out. A phase continuity token and a source error, which the core does not let a caller build, carry a handle holding the core value; the fields beside it have to be the value's own. :unrecognized stands for a core value this binding does not know, and a record holding one is refused on the way back.

ssr_solution()

@type ssr_solution() :: %{
  source: :rtcm_ssr | :galileo_has,
  provider_id: non_neg_integer(),
  solution_id: non_neg_integer()
}

Provider and solution identity of SSR corrections.

t()

@type t() :: %Sidereon.GNSS.PrecisePositioning.MultiEpochSolution{
  ambiguities_m: %{required(String.t()) => float()},
  epoch_clocks: [epoch_clock()],
  epochs: [NaiveDateTime.t()],
  formal_position_covariance: covariance(),
  formal_tropo_gradient_covariance_m2: term(),
  metadata: %{
    iterations: pos_integer(),
    converged: boolean(),
    status: :state_tolerance | :max_iterations,
    residual_screen: boolean(),
    solve_options: solve_options(),
    n_epochs: pos_integer(),
    n_observations: pos_integer(),
    code_rms_m: float(),
    phase_rms_m: float(),
    weighted_rms_m: float(),
    troposphere_applied: boolean(),
    ztd_estimated: boolean()
  },
  position: position(),
  position_covariance: covariance(),
  residual_ionosphere_m: term(),
  residual_screen_removals: [observation_key()],
  residuals_m: [residual()],
  solved_epoch_indices: [non_neg_integer()] | nil,
  ssr_bias_exclusions: [ssr_bias_exclusion()],
  temporal_position_covariance: term(),
  tropo_gradient_covariance_m2: term(),
  tropo_gradient_east_m: term(),
  tropo_gradient_north_m: term(),
  unplaced_observations: [unplaced_observation()],
  used_sats: [String.t()],
  ztd_residual_m: float() | nil
}

A static float solution. epoch_clocks holds one clock per solved epoch, in the order of solved_epoch_indices. unplaced_observations lists the observations left out because no transmission epoch can be placed from them, and residual_screen_removals the observations the residual screen removed, which solve_ppp_fixed/4 leaves out too, and ssr_bias_exclusions the observations left out for a missing SSR/HAS bias, which the fixed solve starts from.

transmit_time_failure()

@type transmit_time_failure() ::
  :source_without_ssr_corrections
  | :transmit_time_unavailable
  | {:orbit_clock_solution,
     %{transmit_time_j2000_s: float(), applied: ssr_solution() | nil}}
  | {:bias_record,
     %{
       transmit_time_j2000_s: float(),
       signal: signal_key(),
       status: bias_status()
     }}
  | {:source,
     %{
       transmit_time_j2000_s: float(),
       error: %{message: String.t(), handle: reference()}
     }}
  | :unrecognized

unplaced_observation()

@type unplaced_observation() :: %{
  epoch_index: non_neg_integer(),
  satellite_id: String.t(),
  ambiguity_id: String.t(),
  reason: unplaced_reason()
}

unplaced_reason()

@type unplaced_reason() ::
  :code_not_positive
  | {:ssr_correction_exceeds_limit, %{orbit_m: float(), clock_m: float()}}

An observation left out of the solve before it solves because no transmission epoch can be placed from it. :code_not_positive: its code is zero or negative, which RTKLIB satposs reads as no pseudorange. SSR correction-size refusal retains the orbit and clock magnitudes at the rejected transmission epoch.