Skip to content

ECI-RTN

ECI to RTN frame transformations for relative satellite motion.

Provides rotation matrices and state-vector transformations between the Earth-Centered Inertial (ECI) frame and the Radial, Along-Track, Cross-Track (RTN) frame attached to a chief satellite.

The RTN frame (also called LVLH) is defined as:

  • R (Radial): from Earth's center toward the satellite position.
  • T (Along-track): in the orbital plane, completing the right-handed triad (N x R).
  • N (Cross-track / Normal): along the angular-momentum vector, perpendicular to the orbital plane.

All inputs and outputs use SI base units (metres, metres/second).

References
  1. H. Schaub and J. Junkins, Analytical Mechanics of Space Systems, 2nd ed., AIAA, 2009.
  2. K. Alfriend et al., Spacecraft Formation Flying, Elsevier, 2010, eq. 2.16.

rotation_eci_to_rtn(x_eci)

Compute the 3x3 rotation matrix from the ECI frame to the RTN frame.

This is the transpose of :func:rotation_rtn_to_eci.

Parameters:

Name Type Description Default
x_eci ArrayLike

6-element ECI state [x, y, z, vx, vy, vz]. Units: m, m/s.

required

Returns:

Type Description
Array

3x3 rotation matrix (ECI -> RTN).

Examples:

import jax.numpy as jnp
from astrojax.relative_motion import rotation_eci_to_rtn
from astrojax.constants import R_EARTH, GM_EARTH
sma = R_EARTH + 500e3
v_circ = jnp.sqrt(GM_EARTH / sma)
x = jnp.array([sma, 0.0, 0.0, 0.0, v_circ, 0.0])
R = rotation_eci_to_rtn(x)
R.shape

rotation_rtn_to_eci(x_eci)

Compute the 3x3 rotation matrix from the RTN frame to the ECI frame.

The columns of the returned matrix are the RTN unit vectors expressed in ECI coordinates: [r_hat | t_hat | n_hat].

Parameters:

Name Type Description Default
x_eci ArrayLike

6-element ECI state [x, y, z, vx, vy, vz]. Units: m, m/s.

required

Returns:

Type Description
Array

3x3 rotation matrix (RTN -> ECI).

Examples:

import jax.numpy as jnp
from astrojax.relative_motion import rotation_rtn_to_eci
from astrojax.constants import R_EARTH, GM_EARTH
sma = R_EARTH + 500e3
v_circ = jnp.sqrt(GM_EARTH / sma)
x = jnp.array([sma, 0.0, 0.0, 0.0, v_circ, 0.0])
R = rotation_rtn_to_eci(x)
R.shape

state_eci_to_rtn(x_chief, x_deputy)

Transform absolute ECI states to a relative RTN state.

Computes the position and velocity of x_deputy relative to x_chief expressed in the chief's rotating RTN frame, accounting for the Coriolis effect due to the frame's angular velocity.

Parameters:

Name Type Description Default
x_chief ArrayLike

6-element ECI state of the chief satellite [x, y, z, vx, vy, vz]. Units: m, m/s.

required
x_deputy ArrayLike

6-element ECI state of the deputy satellite [x, y, z, vx, vy, vz]. Units: m, m/s.

required

Returns:

Type Description
Array

6-element relative state in RTN [rho_R, rho_T, rho_N, rho_dot_R, rho_dot_T, rho_dot_N]. Units: m, m/s.

Examples:

import jax.numpy as jnp
from astrojax.relative_motion import state_eci_to_rtn
from astrojax.constants import R_EARTH, GM_EARTH
sma = R_EARTH + 500e3
v_circ = jnp.sqrt(GM_EARTH / sma)
chief = jnp.array([sma, 0.0, 0.0, 0.0, v_circ, 0.0])
deputy = chief + jnp.array([100.0, 0.0, 0.0, 0.0, 0.0, 0.0])
rel = state_eci_to_rtn(chief, deputy)
float(rel[0])  # ~100 m radial offset

state_rtn_to_eci(x_chief, x_rel_rtn)

Transform a relative RTN state back to an absolute ECI state.

Given the chief's ECI state and the deputy's relative state in the chief's RTN frame, reconstruct the deputy's absolute ECI state.

Parameters:

Name Type Description Default
x_chief ArrayLike

6-element ECI state of the chief satellite [x, y, z, vx, vy, vz]. Units: m, m/s.

required
x_rel_rtn ArrayLike

6-element relative state in RTN [rho_R, rho_T, rho_N, rho_dot_R, rho_dot_T, rho_dot_N]. Units: m, m/s.

required

Returns:

Type Description
Array

6-element absolute ECI state of the deputy [x, y, z, vx, vy, vz]. Units: m, m/s.

Examples:

import jax.numpy as jnp
from astrojax.relative_motion import state_rtn_to_eci
from astrojax.constants import R_EARTH, GM_EARTH
sma = R_EARTH + 500e3
v_circ = jnp.sqrt(GM_EARTH / sma)
chief = jnp.array([sma, 0.0, 0.0, 0.0, v_circ, 0.0])
rel_rtn = jnp.array([100.0, 0.0, 0.0, 0.0, 0.0, 0.0])
deputy = state_rtn_to_eci(chief, rel_rtn)
float(deputy[0] - chief[0])  # ~100 m radial offset