astrodynx.rv2coe

Contents

astrodynx.rv2coe#

astrodynx.rv2coe(pos_vec, vel_vec, mu=1)[source]#

Transfer position and velocity vectors to classical orbital elements.

Parameters:
  • pos_vec (ArrayLike) – (…, 3) position vector of the object in the two-body system.

  • vel_vec (ArrayLike) – (…, 3) velocity vector of the object in the two-body system, which shape broadcast-compatible with pos_vec.

  • mu (ArrayLike) – Gravitational parameter of the central body; shape broadcast-compatible with pos_vec and vel_vec.

Return type:

tuple[Array, Array, Array, Array, Array, Array]

Returns:

(p, e, incl, raan, argp, true_anom) The classical orbital elements of the object in the two-body system.

Notes

The classical orbital elements are calculated using the following equations:

\[\begin{split} \begin{aligned} \boldsymbol{h} &= \boldsymbol{r} \times \boldsymbol{v} \\ p &= \frac{h^2}{\mu} \\ \boldsymbol{e} &= \frac{\boldsymbol{v} \times \boldsymbol{h}}{\mu} - \frac{\boldsymbol{r}}{r} \\ i &= \arccos(h_z / h) \\ \boldsymbol{N} &= \boldsymbol{k} \times \boldsymbol{h} \\ \Omega &= \arctan2(N_y, N_x) \\ \omega &= \arctan2(\|\boldsymbol{N}\times \boldsymbol{e}\|, \boldsymbol{N} \cdot \boldsymbol{e}) \\ f &= \arctan2(\|\boldsymbol{e}\times \boldsymbol{r}\|, \boldsymbol{e} \cdot \boldsymbol{r}) \end{aligned} \end{split}\]
where \(p\) is the semiparameter, \(e\) is the eccentricity vector, \(i\) is the inclination, \(\Omega\) is the right ascension of the ascending node, \(\omega\) is the argument of periapsis, and \(f\) is the true anomaly.

References

Vallado, 2013, pp.114.

Examples

A simple example:

>>> import jax.numpy as jnp
>>> import astrodynx as adx
>>> pos_vec = jnp.array([1.0, 0.0, 0.0])
>>> vel_vec = jnp.array([0.0, 1.0, 0.0])
>>> mu = 1.0
>>> p, e, incl, raan, argp, true_anom = adx.rv2coe(pos_vec, vel_vec, mu)
>>> print(p, e, incl, raan, argp, true_anom)
1.0 0.0 0.0 0.0 0.0 0.0

With broadcasting, you can calculate the classical orbital elements for multiple position and velocity vectors:

>>> pos_vec = jnp.array([[-4039.8965, 4814.5605, 3628.625], [6525.3677, 6861.5317, 6449.117]])
>>> vel_vec = jnp.array([[-10.385988, -4.771922, 1.7438745], [4.902279, 5.5331397, -1.9757109]])
>>> mu = jnp.array([[398600],[398600.4418]])
>>> p, e, incl, raan, argp, true_anom = adx.rv2coe(pos_vec, vel_vec, mu)
>>> assert jnp.allclose(p, jnp.array([16056.1966,11067.79]))
>>> assert jnp.allclose(e, jnp.array([1.4,0.83285]))
>>> assert jnp.allclose(incl, jnp.array([jnp.deg2rad(30),jnp.deg2rad(87.87)]))
>>> assert jnp.allclose(raan, jnp.array([jnp.deg2rad(40),jnp.deg2rad(227.89)]))
>>> assert jnp.allclose(argp, jnp.array([jnp.deg2rad(60),jnp.deg2rad(53.38)]))
>>> assert jnp.allclose(true_anom, jnp.array([jnp.deg2rad(30),jnp.deg2rad(92.335)]))