{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Copyright (c) 2024 Massachusetts Institute of Technology\n", "\n", "SPDX-License-Identifier: MIT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Transformations\n", "\n", "`astroforge` provides a number of utilies that can transform between coordinate frames and between compatible orbital parameters. We highlight a few of these transformations in this example, but the full list can be reviewed in the API documentation for `astroforge.coordinates._transformations`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Coordinate Conversions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Convert between the International Terrestrial Reference System (ITRS) and the Mean Equator Mean Equinox of Date system (MEMED) at a specific time defined as a Modified Julian Date (MJD)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ 4394.69603967 -5881.50950936 3177.18312508]\n", "[-5413.11749016 4960.20830485 3177.18312508]\n" ] } ], "source": [ "import numpy as np\n", "from astroforge.coordinates import ITRSToMEMED, MEMEDToITRS\n", "\n", "MJD = 60197.5\n", "\n", "x_itrs = np.array([-5413.11749016, 4960.20830485, 3177.18312508]) # just a random vector\n", "x_memed = ITRSToMEMED(MJD, x_itrs)\n", "x_itrs_2 = MEMEDToITRS(MJD, x_memed)\n", "\n", "print(x_memed)\n", "print(x_itrs_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Convert between ITRS and Latitude/Longitude/Altitude (degrees and km)." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(23.511926934533797, 137.50000000001472, 1625.2463742566208)\n", "[-5413.11749016 4960.20830485 3177.18312508]\n" ] } ], "source": [ "from astroforge.coordinates import ITRSToLatLonAlt, LatLonAltToITRS\n", "\n", "x_itrs = np.array([-5413.11749016, 4960.20830485, 3177.18312508]) # just a random vector\n", "x_latlonalt = ITRSToLatLonAlt(x_itrs)\n", "x_itrs_2 = LatLonAltToITRS(*x_latlonalt)\n", "\n", "print(x_latlonalt)\n", "print(x_itrs_2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Convert between Keplerian elements and True Equator True Equinox of Date (TETED) carteisan coordinates:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[-371.69607966 7116.79717907 707.23699658]] [[-8.19634168 2.03599094 0.36358961]]\n", "{'inclination_rad': 0.10000000000000056, 'raan_rad': 0.19999999999999946, 'argp_rad': 0.3000000000000009, 'eccentricity': 0.4000000000000004, 'semi_major_axis_km': 10000.000000000005, 'eccentric_anomaly_rad': 0.7818320279930673, 'true_anomaly_rad': 1.1237047648504743, 'mean_anomaly_rad': 0.49999976729035667}\n" ] } ], "source": [ "from astroforge.coordinates import keplerian_to_cartesian, cartesian_to_keplerian\n", "\n", "# All angles are in radians\n", "inclination_rad = 0.1\n", "raan_rad = 0.2\n", "argp_rad = 0.3\n", "ecc = 0.4\n", "semi_major_axis_km = 10000.\n", "mean_anomaly_rad = 0.5\n", "\n", "x_teted, v_teted = keplerian_to_cartesian(inclination_rad=inclination_rad,\n", " raan_rad=raan_rad,\n", " argp_rad=argp_rad,\n", " ecc=ecc,\n", " semi_major_axis_km=semi_major_axis_km,\n", " mean_anomaly_rad=mean_anomaly_rad)\n", "\n", "# Note: The pos/vel arrays need to be converted from shape (1,3) to (3,) for cartesian_to_keplerian\n", "keplerian_elements = cartesian_to_keplerian(pos=x_teted[0], vel=v_teted[0])\n", "\n", "print(x_teted, v_teted)\n", "print(keplerian_elements)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Orbital Element Conversions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Calculate the True Anomaly from the Mean Anomaly.\n", "\n", "Note: You can specify the tolerance and max number of iterations for the underlying numerical solver. By default, they will be set to 1.0e-14 and 100, respectively." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True Anomaly: 0.6595163855574937 radians\n", "Mean Anomaly: 0.2 radians\n" ] } ], "source": [ "from astroforge.coordinates import true_anomaly_from_mean_anomaly, mean_anomaly_from_true_anomaly\n", "\n", "eccentricity = 0.5\n", "mean_anomaly = 0.2\n", "\n", "true_anomaly = true_anomaly_from_mean_anomaly(e=eccentricity, M=mean_anomaly)\n", "mean_anomaly_2 = mean_anomaly_from_true_anomaly(e=eccentricity, v=true_anomaly)\n", "\n", "print(f\"True Anomaly: {true_anomaly} radians\")\n", "print(f\"Mean Anomaly: {mean_anomaly_2} radians\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Calculate the True Anomaly from the Eccentric Anomaly." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True Anomaly: 0.3441325691613769 radians\n", "Eccentric Anomaly: 0.19999999999999996 radians\n" ] } ], "source": [ "from astroforge.coordinates import true_anomaly_from_eccentric_anomaly, eccentric_anomaly_from_true_anomaly\n", "\n", "eccentricity = 0.5\n", "eccentric_anomaly = 0.2\n", "\n", "true_anomaly = true_anomaly_from_eccentric_anomaly(e=eccentricity, E=eccentric_anomaly)\n", "eccentric_anomaly_2 = eccentric_anomaly_from_true_anomaly(e=eccentricity, v=true_anomaly)\n", "\n", "print(f\"True Anomaly: {true_anomaly} radians\")\n", "print(f\"Eccentric Anomaly: {eccentric_anomaly_2} radians\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "maddg", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.7" } }, "nbformat": 4, "nbformat_minor": 2 }