Class GnssAttitude

Class Documentation

class GnssAttitude

GNSS satellite body (attitude) frame.

Defines the orthonormal triad (ex, ey, ez):

  • ez : nadir direction (toward the central body), normalize(-r_sat)

  • ey : cross-track direction (toward the Sun side), normalize(cross(ez, normalize(r_sun - r_sat)))

  • ex : along-track direction, completing the right-handed triad, normalize(cross(ey, ez))

This is the frame in which transmit-antenna gain patterns are defined (theta = azimuth about ez measured from ex, phi = off-boresight angle from ez).

Public Functions

GnssAttitude() = default
GnssAttitude(const Vec3 &r_sat_eci, const Vec3 &r_sun_eci)

Construct and immediately compute the attitude frame.

Convenience constructor wrapping Update(r_sat_eci, r_sun_eci); used where a GnssAttitude instance (rather than raw (ex, ey, ez) out-parameters) is convenient, e.g. in test_gnss_attitude.cc.

Parameters:
  • r_sat_eciSatellite position (ECI or any inertial frame) [m]

  • r_sun_eci – Sun position, in the same frame as r_sat_eci [m]

void Update(const Vec3 &r_sat_eci, const Vec3 &r_sun_eci)

(Re-)compute and cache the attitude triad for this instance.

void Update(const Vec3 &r_sat_eci, const Vec3 &v_sat_eci, const Vec3 &r_sun_eci)

(Re-)compute and cache the attitude triad via the documented nominal yaw-steering law; see Compute(r_sat_eci, v_sat_eci, r_sun_eci, ...).

inline const Vec3 &GetEx() const

Get the cached along-track body axis ex (unit vector, in the same inertial frame as the r_sat_eci/r_sun_eci passed to Update/Compute). Part of this orthonormal, GNSS-attitude-frame triad — distinct from the non-orthonormal ijk PCO frame of AntexLoader::ComputeIjkToEcefRotation.

inline const Vec3 &GetEy() const

Get the cached cross-track (Sun-side) body axis ey (unit vector, same frame as GetEx). Part of this orthonormal, GNSS-attitude-frame triad — distinct from the non-orthonormal ijk PCO frame of AntexLoader::ComputeIjkToEcefRotation.

inline const Vec3 &GetEz() const

Get the cached nadir body axis ez (unit vector, same frame as GetEx). Part of this orthonormal, GNSS-attitude-frame triad — distinct from the non-orthonormal ijk PCO frame of AntexLoader::ComputeIjkToEcefRotation.

Mat3 GetRotationMatrix() const

Body-to-inertial rotation matrix [ex, ey, ez] (columns), assembled from the cached triad. Used to express vectors given in this GNSS-attitude body frame (e.g. antenna boresight/PCO offsets) in the same inertial frame as r_sat_eci.

void GetAngles(const Vec3 &u, Real &theta, Real &phi) const

Off-boresight angle theta (azimuth, about ez measured from ex) and phi (polar angle from ez) of a unit direction u (expressed in the same inertial frame as r_sat_eci/r_sun_eci), as seen from the satellite body frame.

Mirrors the angle computation used by GNSS link-budget and measurement-channel construction: given the line-of-sight direction to a receiver/target, returns the (theta, phi) pair that Antenna::ComputeGain expects to look up the transmit/receive gain pattern.

Parameters:
  • u – Unit direction vector, in the same inertial frame as r_sat_eci/r_sun_eci

  • theta[out] Azimuth angle about ez, measured from ex [rad]

  • phi[out] Polar (off-boresight) angle from ez [rad]

Public Static Functions

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

Compute the canonical GNSS satellite body (attitude) triad (ex, ey, ez) directly from the satellite-to-Sun geometry.

This is the core attitude computation used to evaluate transmit antenna gain patterns: GNSSMeasurements::ComputeCN0 (lupnt/measurements/gnss_measurement.cc) calls the velocity-aware overload below to get the transmitter’s (ex, ey, ez) at the signal-transmission epoch, then projects the transmitter-to-receiver line of sight onto this triad to get the off-boresight angles fed to Antenna::ComputeGain. Mirrors the attitude computation in GNSSMeas.setup_measurements (python/pylupnt/measurements/gnss_meas.py).

Parameters:
  • r_sat_eciSatellite position (ECI or any inertial frame) [m]

  • r_sun_eci – Sun position, in the same frame as r_sat_eci [m]

  • ex[out] Along-track body axis (unit vector)

  • ey[out] Cross-track body axis (unit vector)

  • ez[out] Nadir body axis (unit vector)

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

Compute the attitude triad (ex, ey, ez) via the documented nominal yaw-steering law (GnssYawSteering::NominalYawAngle, Eq. 1 of Cheng et al., 2025), rather than directly from the Sun direction.

Internally computes the Sun-elevation (beta) and orbit (mu) angles via GnssYawSteering::BetaAngle/OrbitAngle, evaluates the nominal yaw angle phi = NominalYawAngle(beta, mu), and builds the frame by rotating the orbital reference frame about the nadir axis by phi (see ComputeFromYawAngle). This is numerically identical to Compute(r_sat_eci, r_sun_eci, ...) — both describe the same Sun-pointing nominal attitude, since the nominal yaw law is, by construction, the angle that keeps the solar panels Sun-pointing — but this overload makes the dependency on the documented yaw-steering law explicit, and ComputeFromYawAngle is the basis for computing the modeled (maneuver/eclipse) attitude from any of GnssYawSteering’s block-specific yaw-steering laws (Eq. 3-7, 12-16). This is the overload called by GNSSMeasurements::ComputeCN0 to get the transmitter’s body frame for antenna-gain lookups.

Parameters:
  • r_sat_eciSatellite position (ECI or any inertial frame) [m]

  • v_sat_eciSatellite velocity, in the same frame [m/s]

  • r_sun_eci – Sun position, in the same frame as r_sat_eci [m]

  • ex[out] Along-track-ish body axis (unit vector)

  • ey[out] Cross-track-ish body axis (unit vector)

  • ez[out] Nadir body axis (unit vector)

static void ComputeFromYawAngle(const Vec3 &r_sat_eci, const Vec3 &v_sat_eci, Real yaw_angle, Vec3 &ex, Vec3 &ey, Vec3 &ez)

Build the attitude triad (ex, ey, ez) from an explicit yaw angle phi, e.g. one produced by any of GnssYawSteering’s nominal or modeled/maneuver yaw-steering laws (Eq. 1, 3-7, 8, 12-16), and the orbital geometry alone (no Sun direction needed): ez = normalize(-r_sat) (nadir) ex_ref = normalize(v_sat), ey_ref = ez x ex_ref (orbital frame, phi = 0) ex = cos(phi) * ex_ref + sin(phi) * ey_ref ey = -sin(phi) * ex_ref + cos(phi) * ey_ref i.e. (ex, ey) are the orbital reference axes (ex_ref, ey_ref) rotated by phi about the nadir axis ez. Supplying phi = GnssYawSteering::NominalYawAngle(beta, mu) reproduces exactly the Sun-pointing nominal frame of Compute (verified in test_gnss_attitude.cc); supplying a modeled yaw angle from one of GnssYawSteering’s maneuver-specific laws instead yields the actual (eclipse-season / midnight-noon-turn) attitude.

Parameters:
  • r_sat_eciSatellite position (ECI or any inertial frame) [m]

  • v_sat_eciSatellite velocity, in the same frame [m/s]

  • yaw_angle – Yaw angle phi [rad]

  • ex[out] Along-track-ish body axis (unit vector)

  • ey[out] Cross-track-ish body axis (unit vector)

  • ez[out] Nadir body axis (unit vector)