View Source SpaceDust.State.Transforms (Space Dust v0.3.0)
High-performance state vector transformations using Nx.
Provides coordinate frame transformations between:
- TEME (True Equator Mean Equinox) - SGP4 output frame
- ECI J2000 (Earth-Centered Inertial) - Standard inertial frame
- ECEF (Earth-Centered Earth-Fixed) - Rotating with Earth
Also provides conversions between:
- Cartesian state vectors and Keplerian elements
Summary
Functions
Apply a rotation matrix to a vector.
Convert Cartesian state to Keplerian elements using Nx.
Convert an ECEF state to ECI J2000.
Perform ECEF to ECI transformation on position/velocity tensors.
Convert an ECEF state to TEME.
Convert an ECI J2000 state to ECEF.
Build the full W * R * N * P rotation taking an ECI J2000 vector to ECEF.
The W * R * N * P ECI J2000 to ECEF rotation matrix at an epoch, as a tensor.
Perform ECI to ECEF transformation on position/velocity tensors. Accounts for Earth rotation and velocity contribution from rotation.
Convert an ECI J2000 state to TEME.
Perform the full ECI J2000 to TEME transformation on position/velocity tensors.
Build the equation of equinoxes rotation, from TEME to True of Date.
Convert Keplerian elements to Cartesian state using Nx.
Convert Keplerian elements to an ECI state.
Convert Keplerian elements to a TEME state.
Multiply two 3x3 rotation matrices.
Build the IAU 1980 nutation matrix.
Build the polar motion matrix from the IERS pole offsets, in radians.
Build the IAU 1976 precession matrix.
Build a rotation matrix about the X-axis.
Build a rotation matrix about the Y-axis.
Build a rotation matrix about the Z-axis.
Build the nutation matrix in SGP4's TEME convention.
Convert a TEME state to ECEF.
Convert a TEME state to ECI J2000.
Perform the full TEME to ECI J2000 transformation on position/velocity tensors.
Convert a Cartesian state (ECI) to Keplerian elements.
Functions
Apply a rotation matrix to a vector.
Convert Cartesian state to Keplerian elements using Nx.
Degenerate geometry is handled by falling back to a reference direction that is still defined, rather than by reporting zero and losing the information:
- equatorial - the ascending node is undefined, so the argument of perigee is measured from the vernal equinox and the RAAN reported as zero
- circular - perigee is undefined, so the true anomaly is measured from whatever the argument of perigee was measured from
Both keep the round trip through keplerian_to_eci/1 exact. Reporting zero
for all three angles instead, as an equatorial orbit would otherwise get,
puts the reconstructed position a full orbit radius away.
@spec ecef_to_eci(SpaceDust.State.ECEFState.t()) :: SpaceDust.State.ECIState.t()
Convert an ECEF state to ECI J2000.
Parameters
- ecef_state: ECEFState struct with position/velocity in ECEF frame
Returns
- ECIState struct with position/velocity in ECI J2000 frame
Perform ECEF to ECI transformation on position/velocity tensors.
@spec ecef_to_teme(SpaceDust.State.ECEFState.t()) :: SpaceDust.State.TEMEState.t()
Convert an ECEF state to TEME.
Parameters
- ecef_state: ECEFState struct with position/velocity in ECEF frame
Returns
- TEMEState struct with position/velocity in TEME frame
@spec eci_to_ecef(SpaceDust.State.ECIState.t()) :: SpaceDust.State.ECEFState.t()
Convert an ECI J2000 state to ECEF.
Parameters
- eci_state: ECIState struct with position/velocity in ECI J2000 frame
Returns
- ECEFState struct with position/velocity in ECEF frame
Build the full W * R * N * P rotation taking an ECI J2000 vector to ECEF.
Four rotations, in this order applied to a J2000 vector:
P- precession, J2000 to mean of dateN- nutation, mean of date to true of dateR- Earth rotation through the Greenwich apparent sidereal timeW- polar motion, pseudo-earth-fixed to ECEF
Skipping N and P and applying R alone to a J2000 vector leaves the
result short by the accumulated precession - roughly 0.4 degrees, or 645 km
at geostationary radius.
@spec eci_to_ecef_matrix_at(DateTime.t()) :: Nx.Tensor.t()
The W * R * N * P ECI J2000 to ECEF rotation matrix at an epoch, as a tensor.
Exposed for callers that need to rotate a bare direction, where the
omega x r velocity coupling in eci_to_ecef/1 would be meaningless.
Perform ECI to ECEF transformation on position/velocity tensors. Accounts for Earth rotation and velocity contribution from rotation.
@spec eci_to_teme(SpaceDust.State.ECIState.t()) :: SpaceDust.State.TEMEState.t()
Convert an ECI J2000 state to TEME.
Parameters
- eci_state: ECIState struct with position/velocity in ECI J2000 frame
Returns
- TEMEState struct with position/velocity in TEME frame
Perform the full ECI J2000 to TEME transformation on position/velocity tensors.
r_teme = N_teme * P * r_j2000.
Build the equation of equinoxes rotation, from TEME to True of Date.
Retained for callers working in TOD. It is deliberately not part of the
TEME transform below, which uses teme_nutation_matrix/2 instead.
Convert Keplerian elements to Cartesian state using Nx.
@spec keplerian_to_eci(SpaceDust.State.KeplerianElements.t()) :: SpaceDust.State.ECIState.t()
Convert Keplerian elements to an ECI state.
Parameters
- elements: KeplerianElements struct
Returns
- ECIState struct with position/velocity in ECI J2000 frame
@spec keplerian_to_teme(SpaceDust.State.KeplerianElements.t()) :: SpaceDust.State.TEMEState.t()
Convert Keplerian elements to a TEME state.
Parameters
- elements: KeplerianElements struct
Returns
- TEMEState struct with position/velocity in TEME frame
Multiply two 3x3 rotation matrices.
Build the IAU 1980 nutation matrix.
Transforms from Mean of Date (MOD) to True of Date (TOD), as
ROT1(-eps_true) ROT3(-delta_psi) ROT1(eps_mean). Transpose it for TOD to MOD.
Build the polar motion matrix from the IERS pole offsets, in radians.
Transforms from the pseudo-earth-fixed frame (PEF) to ECEF, as
ROT2(xp) ROT1(yp).
Build the IAU 1976 precession matrix.
Transforms from J2000 to Mean of Date (MOD). Transpose it for the other
direction. rotation_x/y/z here are passive (frame) rotations, so this is
Vallado's ROT3(-z) ROT2(theta) ROT3(-zeta).
Build a rotation matrix about the X-axis.
Build a rotation matrix about the Y-axis.
Build a rotation matrix about the Z-axis.
Build the nutation matrix in SGP4's TEME convention.
Transforms from Mean of Date (MOD) to TEME. TEME is not true-of-date: it uses the mean obliquity on both sides of the nutation rotation and carries no separate equation-of-equinoxes step. That is SGP4's own convention and it has to be matched exactly, or a TLE-derived state lands kilometres off.
@spec teme_to_ecef(SpaceDust.State.TEMEState.t()) :: SpaceDust.State.ECEFState.t()
Convert a TEME state to ECEF.
Parameters
- teme_state: TEMEState struct with position/velocity in TEME frame
Returns
- ECEFState struct with position/velocity in ECEF frame
@spec teme_to_eci(SpaceDust.State.TEMEState.t()) :: SpaceDust.State.ECIState.t()
Convert a TEME state to ECI J2000.
Parameters
- teme_state: TEMEState struct with position/velocity in TEME frame
Returns
- ECIState struct with position/velocity in ECI J2000 frame
Perform the full TEME to ECI J2000 transformation on position/velocity tensors.
r_teme = N_teme * P * r_j2000, so the inverse applied here is
P^T * N_teme^T.
@spec to_keplerian( SpaceDust.State.ECIState.t() | SpaceDust.State.TEMEState.t(), keyword() ) :: SpaceDust.State.KeplerianElements.t()
Convert a Cartesian state (ECI) to Keplerian elements.
Parameters
- state: ECIState, TEMEState, or ECEFState struct
- opts: Options including :mu for gravitational parameter
Returns
- KeplerianElements struct