Class GnssConstellation

Inheritance Relationships

Base Type

Class Documentation

class GnssConstellation : public lupnt::Constellation

Constellation of GNSS satellites with precomputed ephemerides.

Provides satellite state interpolation plus transmitter antenna/power metadata. Receiver-dependent measurement construction lives in GNSSMeasurements.

Public Functions

GnssConstellation() = default

Construct an empty constellation (no PRNs/ephemerides set).

explicit GnssConstellation(GnssConst gnss_const)

Construct an empty constellation for a given GNSS system, naming it after gnss_const (e.g. “GPS”, “GALILEO”).

Parameters:

gnss_const – GNSS system (GPS, Galileo, BDS, QZSS, …)

GnssConstellation(Config &config)

Construct from a YAML config node specifying gnss_const (and optionally name).

Called by the simulation/application builder when a gnss_const section appears in a scenario config; satellite ephemerides must still be populated afterwards via SetSatelliteStates, LoadEphemeris, or SetupSatelliteStatesFromFiles.

Parameters:

config – YAML config node with a gnss_const key

void SetSatelliteStates(const std::vector<int> &prns, const VecXd &t_tai, const std::vector<MatXd> &rv_eci)

Set precomputed satellite ephemerides directly from already-loaded position/velocity histories.

The primary entry point used by LoadEphemeris and SetupSatelliteStatesFromFiles: stores the raw rv_eci history per PRN and fits a piecewise-Chebyshev model (FitStateHistoryChebyshev) to each, which GetSatelliteStateEci/ComputeRange/ComputeRangeRate then interpolate at arbitrary query epochs.

Parameters:
  • prns – PRNs of the satellites (size N)

  • t_tai – Epochs of the ephemeris samples, in TAI seconds (size M)

  • rv_eci – Per-satellite ECI position/velocity history; each entry is an [M x 6] matrix of [r; v] rows (size N)

void LoadEphemeris(const std::filesystem::path &filepath)

Load precomputed satellite ephemerides from an HDF5 file. Expected layout (see also SaveEphemeris): /prns [N] integer PRNs /t_tai [M] epochs in TAI seconds /rv_eci/<prn> [Mx6] ECI position/velocity history for each PRN This lets ephemerides be precomputed in Python (e.g. via SP3Loader / BRDCLoader, see GNSSMeas.setup_gnss) and consumed directly in C++, avoiding re-implementation of SP3/BRDC parsing.

void SaveEphemeris(const std::filesystem::path &filepath) const

Save the currently-set ephemerides to an HDF5 file using the layout expected by LoadEphemeris.

void SetupSatelliteStatesFromFiles(const std::vector<std::filesystem::path> &sp3_filepaths, const std::filesystem::path &antex_filepath, const VecXd &t_tai, GnssFreq freq, const std::vector<int> &prns = {})

Build precomputed satellite ephemerides directly from SP3 precise-ephemeris and ANTEX antenna files (using Sp3Loader / AntexLoader, see lupnt/interfaces/sp3_loader.h / lupnt/interfaces/antex_loader.h), applying the antenna phase-center-offset (PCO) correction to the SP3 (center-of-mass) ECEF positions before converting to ECI &#8212; mirroring the workflow in projects/Plasmasphere_Delay_Datagen/generate_antenna_pco.ipynb: pos_corrected_ecef = pos_sp3_ecef + Cijk(t_tai, pos_sp3_ecef) @ pco_neu (Cijk = AntexLoader::ComputeIjkToEcefRotation). The (uncorrected) SP3 velocity is retained &#8212; the PCO is constant in the satellite body frame, so its contribution to the ECEF velocity is negligible for link-budget / visibility purposes.

This is an alternative, “from source files”, entry point to SetSatelliteStates / LoadEphemeris that avoids a separate Python preprocessing step.

Parameters:
  • sp3_filepaths – SP3 precise-ephemeris file(s) (e.g. consecutive days)

  • antex_filepath – ANTEX file providing the satellite antenna PCO

  • t_tai – Epochs at which to sample the corrected ephemeris [TAI seconds]

  • freq – Frequency whose phase center (PCO) should be used for the correction (e.g. GnssFreq::L1)

  • prns – PRNs to set up; if empty, every PRN of gnss_const_ found in the SP3 file(s) (and present in the ANTEX file) is used

void SetupTransmitters()

Build a GnssTransmitter device for every PRN currently in the constellation, harvesting its antenna gain pattern(s) and transmit power(s) (reuses GnssTransmitter::InitGps / InitGalileo / InitQzss, which load patterns via gps_table.csv / antenna pattern files).

inline void SetFaultPrns(const std::vector<int> &prns)

Mark the given PRNs as “faulted” so that IsFaultPrn reports them as unavailable, e.g. to simulate a satellite outage for fault-detection / robustness testing.

inline int GetNumSatellites() const

Get the number of satellites (PRNs) currently configured.

inline const std::vector<int> &GetPrns() const

Get the list of PRNs currently configured.

inline GnssConst GetGnssConst() const

Get the GNSS system (GPS, Galileo, BDS, QZSS, …) of this constellation.

inline const std::vector<GnssFreq> &GetFreqList() const

Get the list of frequencies for which transmitter metadata is available (set by SetupTransmitters, taken from PRN 0).

bool IsFaultPrn(int prn) const

Check whether prn has been marked faulted via SetFaultPrns.

Called by GNSSMeasurements::ComputeMeasurements (lupnt/measurements/gnss_measurement.cc) to skip faulted PRNs when building the set of visible/usable measurement channels at an epoch.

Parameters:

prn – PRN to check

Returns:

True if prn is in the fault list

Vec6 GetSatelliteStateEci(int prn, Real t_tai) const

Interpolated ECI state [r; v] of satellite prn at t_tai (linear interpolation over the precomputed ephemeris).

Evaluates the piecewise-Chebyshev model fitted by SetSatelliteStates; called by ComputeRange/ComputeRangeRate and by GNSSMeasurements to get a transmitter’s state at an (iteratively-refined) transmit epoch.

Parameters:
  • prnSatellite PRN

  • t_tai – Query epoch [TAI seconds]

Returns:

ECI state [r; v] [m, m/s]

Real ComputeRange(int prn, const Vec3 &r_rx_eci, Real t_tai) const

Geometric range between satellite prn and a receiver position (ECI) at t_tai [m].

Real ComputeRangeRate(int prn, const Vec6 &rv_rx_eci, Real t_tai) const

Range rate (line-of-sight projection of relative velocity) between satellite prn and receiver state (ECI) at t_tai [m/s].

inline const VecXd &GetEphemerisTimesTai() const

Ephemeris epochs in TAI seconds.

const MatXd &GetSatelliteStateHistoryEci(int prn) const

ECI state history [M x 6] for prn.

const ChebyshevFitModel &GetSatelliteStateChebyshevEci(int prn) const

Piecewise-Chebyshev ECI state model [r; v] for prn.

bool HasTransmitterInfo(int prn, GnssFreq freq) const

Return true if antenna and transmit-power metadata exist for prn and freq.

const Antenna &GetTransmitterAntenna(int prn, GnssFreq freq) const

Transmit antenna pattern for prn and freq.

Real GetTransmitPowerDbw(int prn, GnssFreq freq) const

Transmit power [dB-W] for prn and freq.

Real ComputeSigmaRange(Real cn0_dbhz, GnssFreq freq) const

Pseudorange (DLL/code-tracking) measurement noise std [m]. Mirrors GNSSMeas.compute_gnss_pseudorange_noise.

Real ComputeSigmaRangeRate(Real cn0_dbhz, GnssFreq freq) const

Pseudorange-rate (FLL/frequency-tracking) measurement noise std [m/s]. Mirrors GNSSMeas.compute_gnss_pseudorangerate_noise.

Real ComputeSigmaCarrierPhase(Real cn0_dbhz, GnssFreq freq) const

Carrier-phase (PLL/phase-tracking) measurement noise std [m]. Mirrors GNSSMeas.compute_gnss_carrier_phase_noise.

void Setup()
void Step(Real t)

Public Static Functions

static inline void ComputeAttitude(const Vec3 &r_sat_eci, const Vec3 &r_sun_eci, Vec3 &ex, Vec3 &ey, Vec3 &ez)

Compute the GNSS attitude frame (ex, ey, ez) of a satellite at position r_sat_eci, given the Sun position r_sun_eci (same frame). ez points to nadir (toward the central body), ey is along the cross-track direction (toward the Sun), and ex completes the right -handed triad. Mirrors the attitude computation in GNSSMeas.setup_measurements. Delegates to GnssAttitude::Compute (see lupnt/agents/gnss_attitude.h).

static inline void ComputeAttitude(const Vec3 &r_sat_eci, const Vec3 &v_sat_eci, const Vec3 &r_sun_eci, Vec3 &ex, Vec3 &ey, Vec3 &ez)

Compute the GNSS attitude frame (ex, ey, ez) of a satellite at position r_sat_eci with velocity v_sat_eci, given the Sun position r_sun_eci (all in the same inertial frame), via the documented nominal yaw-steering law (GnssYawSteering::NominalYawAngle; Eq. 1 of Cheng et al., 2025). Numerically identical to the Sun-direction-based ComputeAttitude overload above (both describe the same Sun-pointing nominal attitude), but makes the dependency on the implemented yaw-steering law explicit. Delegates to GnssAttitude::Compute (see lupnt/agents/gnss_attitude.h).