Giter Club home page Giter Club logo

astrodynamics's Introduction

Astrodynamics

Table of Contents

Table of contents generated with markdown-toc

Astrodynamics is a small, self-contained set of objects and functions specifically designed for the exploration and modeling of various orbital trajectories and their interactions. Particularly intended for use in a notebook environment, Astrodynamics is especially useful for defining different kinds of orbital trajectories and simulation of the motion of both planets and arbitrary spacecraft. This collection of Python functions and classes contains numerous useful methods for modeling different trajectories and associated variables, descriptors, constants, and more.

This project was first embarked on in the spring of 2022 as part of a final project for one of my physics courses. Having long been curious about the physical mechanics of a spacecraft undergoing a gravity assist (like Voyager, MESSENGER, and Cassini-Huygens, to name a few), I wanted to try my hand at modeling the counter-intuitive phenomenon for myself. The very first iteration of this project was a simplified look into the very basics of a gravity assist and thus only considered two dimensions.

While two dimensions sufficed for a simple examination of a complex phenomenon and demonstrated a gravity assist even better than I had initially hoped, it just wasn't good enough for me. So, I started from scratch, and changed my whole approach toward an object-oriented model.

For cases where a satellite enters or exits the gravitational sphere of influence of another satellite, the new trajectory of the satellite will be assessed using a patched conic approximation.

Astrodynamics' only dependencies are standard Python libraries like NumPy, SciPy, and Matplotlib, so installation is pretty straightforward. Just download Astrodynamics.py to the root of your project or use git commands in a terminal. All that's left is to import it into a project.

The easiest way to get started with Astrodynamics is closest to home, with the Earth, Moon, and Sun:

There are four shortcut functions to create a system: solar_system(), inner_planets(), outer_planets(), and earth_moon(). Each has an optional keyword argument inclination for defining a reference plane for the inclination angles1.

from Astrodynamics import earth_moon
import Astrodynamics as adx

# Create a System object with the Earth, Sun, and Moon
ems = earth_moon(inclination="ecliptic")

One can alter any orbital property by using any of the class methods of a Satellite object:

# Change Earth's true anomaly
ems.satellites["Earth"].set_true_anomaly(45)

Now we can simulate the Earth-Moon system for 23 days and plot the motion of the Moon around the Earth:

ems.satellites["Earth"].plot_simulation("planar", scale="Mm")

earth_moon_planar

Starting from scratch is understandably more involved than what was discussed in the previous section.

import Astrodynamics as adx

sun = {"name": "Sun",
       "color": "yellow", # Not required, but nice to have for plotting
       "radius": 6.957e+8,
       "mass": 1.98847e+30}
earth = {"name": "Earth", 
         "color": "g",
         "e": 0.0167086,
         "a": 149598023000, 
         "inc": {"sun_eq": 7.155,
                 "ecliptic": 0.00005,
                 "invariable_plane": 1.57869},
         "long_asc_node": -11.26064, 
         "arg_periapsis": 114.20783, 
         "radius": 6371000, 
         "mass": 5.97217e+24}
moon = {"name": "Moon",
        "color": "grey",
        "e": 0.0549, 
        "a": 384399000, 
        "inc": {"sun_eq": 0,
                "ecliptic": 5.145,
                "invariable_plane": 0},
        "radius": 1737400,
        "mass": 7.342e22}
        
# Create a System object with the Earth, Sun, and Moon
Sun = adx.Body(sun)
ems = adx.System(Sun, sun, inclination="ecliptic")
ems.add_satellite(adx.Body(earth), earth)
ems.satellites["Earth"].add_satellite(adx.Body(moon), moon)

While the arguments for Body and add_satellite must be dictionaries, they are not required to contain all of the information in the dictionaries seen above, but name and mass must be defined. Unspecified elements are generally defaulted to zero. Again, we can simulate the trajectory of the Moon for 23 days and instead display a 3d plot, again with the Earth's gravitational sphere of influence:

ems.satellites["Earth"].simulate(23)
ems.satellites["Earth"].plot_simulation("3d", scale="Mm")

earth_moon_3d

"sun_eq" for inclination relative to the Sun's equator (default)
"ecliptic" for inclination relative to the ecliptic
"invariable_plane" for inclination relative to the invariable plane

To demonstrate how Astrodynamics works with interplanetary encounters, I have manufactured an encounter between Jupiter and an arbitrary probe object with negligible mass.

import numpy as np
import Astrodynamics as adx
from Astrodynamics import inner_planets, encounter, escape

AU = 149597871000
pos = np.array([-7.86614423e+11+AU/2, -2.01278847e+11+AU , 8.64304557e+10])
vel = np.array([3074.33691241, 12052.98083353, -89.00020202])

enc = inner_planets()
enc.add_satellite(adx.Body({"name":"Probe", "mass":543}, negligible=True), {"position":pos, "velocity":-vel})
enc.add_satellite(adx.Body(jupiter), jupiter)
enc.satellites["Probe"].set_true_anomaly(187.8)
enc.satellites["Jupiter"].set_true_anomaly(220)
enc.satellites["Probe"].set_velocity(np.array([ 8660.62219213, -4696.66266911, 18.9300877 ]))
enc.simulate(30, timestep="days")
enc.plot_simulation('3d')

Encounter found between Jupiter and Probe at time 28.064806480648063 days samp_enc_3d

With the knowledge that the probe enters Jupiter's sphere of influence shortly after 28 days of simulation time, the simulation automatically stops as soon as there is an encounter, impact, or escape detected (provided all check_ keyword arguments are True). The next step then is to make the patched conic approximation and simulate the hyperbolic trajectory the probe takes around Jupiter:

probe, jupiter = enc.satellites["Probe"], enc.satellites["Jupiter"]
hyp = encounter(jupiter, probe)
hyp.simulate(315)
hyp.satellites["Jupiter"].plot_simulation("3d")

Satellite Probe escapes primary Jupiter at time 312.2277227722772 days samp_hyp_3d

Adjusting the angle of the 3D plot can better display the change in trajectory relative to the Sun:

samp_hyp_other

An equivalent visualization of this trajectory can be displayed by changing the argument in the plot_simulation method:

hyp.satellites["Jupiter"].plot_simulation("planar")

samp_hyp_planar

Given that the probe escapes Jupiter's SOI, the new trajectory is again determined by making the patched conic approximation:

probe, jupe = hyp.satellites["Jupiter"].satellites["Probe"], hyp.satellites["Jupiter"]
esc = escape(jupe, probe)
esc.simulate(400)
esc.plot_simulation("3d")

samp_esc_3d

The difference in the probe's trajectory probably isn't too apparent, considering the initial trajectory was only simulated for a short time and the awkward 3d plot angle from earlier, so here's a comparison of the pre- and post-assist trajectories:

Element Pre-assist Post-assist Difference
semi-major axis 3.99396 AU 8.79155 AU 4.79759 AU
eccentricity 0.39671194 0.41555246 0.01884052
inclination 2.6278306° 3.8009806° 1.1731499°
arg periapsis 257.78166° 109.95140° -147.83026°
long. asc. node 153.92832° 162.03471° 8.1063864°
true anomaly 185.93823° 352.03689° 166.09866°

To add, the effective potential of any orbital trajectory can also be visualized with plotting the orbit's effective potential. While this is technically not part of the same example, I'm just going to toss it in here using the example of the trajectory of Voyager 1 en-route to Jupiter:

import Astrodynamics as adx
from Astrodynamics import earth_moon

voyager1 = {"a": 745761e6, 
            "e": 0.797783}
solsys = earth_moon()
solsys.add_satellite(adx.Body({"name": "Voyager1", "mass": 123}, negligible=True), voyager1)
solsys.satellites["Voyager1"].plot_potential(y_window=[-4e8, 1e8])

effective_potential

Astrodynamics has several noteworthy limitations:

  • Any change in trajectory (with the exception of escape and encounter trajectories) is considered to be instantaneous, and thus the Oberth effect and other specific phenomena are not accounted for.
  • It is assumed that the relationship between the masses of a primary body and a satellite are significantly different and distant enough that a two-body system has a barycenter effectively located at the position of the primary. Thus, Astrodynamics is not suited for modeling systems like the Pluto-Charon system, binary star systems, and the N-body problem.
  • For large systems (those with many satellites), predicting the trajectory of many satellites can take a bit of time, depending on both the type of trajectory being simulated and the resolution of the time frame being simulated.
  • It is assumed that trajectories are on a scale where relativistic effects are negligible. Therefore, velocities in excess of the speed of light are technically allowed to occur.
  • Trajectories do not yet take into consideration reference epochs, though the included data for the planets of the Solar System is assumed to be with respect to epoch J2000.

Most goals for the future are related to the above section.

  • Runtime optimization for systems with many satellites. Depending on both the resolution of a simulation and the number of satellites being simulated, computations can take a few seconds. There is most likely a way to perform some computations in parallel or through vectorization and avoiding loops where possible.
  • Astrodynamics currently has no solid method for setting both Keplerian orbital elements and a state vector simultaneously. Furthermore, I don't yet know of a good way to ensure certain elements can carry-over to precise element changes, particularly verifying whether certain existing and desired elements lie along the same plane formed by the Euler angles. Currently an original position vector can be reused only when the semi-major axis and/or eccentricity is changed, but only if the original position is possible given the new apsides.
  • Problems with inclination being tied to the values of other Euler angles (argument of periapsis, longitude of ascending node) means flipping the inclination of one orbit to invert the direction of the specific angular momentum vector (and thereby making a defined clockwise orbit instead move counter-clockwise) can sometimes produce unexpected results.
  • In the future, I hope to implement some method for keeping track of delta-v considerations at various points along a trajectory. Moreover, this should coincide with more precise editing of an object's trajectory (plane changes, Hohmann transfers, etc.).
  • Maybe create another markdown file detailing the physics and calculations involved in determining Kepelrian elements, state vectors, and predicting satellite motion?

Footnotes

astrodynamics's People

Contributors

evan-bauer avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.