Sidereon.GNSS.RTK.MovingBaseline (Sidereon v0.10.0)

Copy Markdown View Source

Moving-baseline RTK: both receivers move each epoch (RTKLIB "moving-base").

Standard relative RTK positions a moving rover against a base whose ECEF coordinates are fixed for the whole arc. The double-difference cancellation, the iterated float baseline least squares, and the LAMBDA integer fix are all unchanged when the base also moves, so the only difference is that the base ECEF position is supplied per epoch (typically the base receiver's own navigation fix). This module is a thin primitive over sidereon_core::rtk_filter::moving_baseline: it marshals already-prepared double-difference epochs into the core solvers and decodes the per-epoch baseline, its length, and the integer-fix verdict.

This is a traceable primitive, not the high-level Sidereon.GNSS.RTK API: the caller supplies the reference/non-reference satellite measurements and the ambiguity set directly, so no reference selection or cycle-slip preparation happens here.

Epoch shape

%{
  base_position_m: {x, y, z},
  references: [sat_meas],          # one reference per constellation
  nonref: [sat_meas],
  velocity_mps: {x, y, z} | nil,   # optional
  dt_s: 0.0,                        # optional
  ambiguity_ids: ["G02", ...],
  ambiguity_satellites: %{"G02" => "G02", ...},
  wavelengths_m: %{"G02" => 0.19, ...},
  offsets_m: %{"G02" => 0.0, ...},   # optional, default 0 per id
  float_only_systems: []             # optional
}

where each sat_meas is

%{
  sat: "G01", sd_ambiguity_id: "G01",
  base_code_m: _, base_phase_m: _, rover_code_m: _, rover_phase_m: _,
  base_tx_pos: {x, y, z}, rover_tx_pos: {x, y, z}, pos: {x, y, z}
}

Options

%{
  model: %{code_sigma_m: 0.3, phase_sigma_m: 0.003,
           stochastic_model: :simple, elevation_weighting: false, sagnac: false},
  float: %{position_tol_m: 1.0e-4, ambiguity_tol_m: 1.0e-4, max_iterations: 10},
  fixed: %{position_tol_m: 1.0e-4, ambiguity_tol_m: 1.0e-4, max_iterations: 10,
           ratio_threshold: 3.0, partial_ambiguity_resolution: false,
           partial_min_ambiguities: 4},
  initial_baseline_m: {0.0, 0.0, 0.0},
  warm_start: true
}

Summary

Functions

Solve a sequence of moving-baseline epochs, each against its own base position.

Types

solution()

@type solution() :: %{
  base_position_m: vec3(),
  baseline_m: vec3(),
  baseline_length_m: float(),
  status: :fixed | :float,
  float: map(),
  fixed: map()
}

vec3()

@type vec3() :: {number(), number(), number()}

Functions

solve_epochs(epochs, opts)

@spec solve_epochs([map()], map()) :: {:ok, [solution()]} | {:error, term()}

Solve a sequence of moving-baseline epochs, each against its own base position.

With warm_start: true each solved baseline seeds the next epoch's float linearization point. Returns {:ok, [solution]} or {:error, {epoch_index, reason}} for the first failing epoch.