def plot_solar_system(outer=True, epoch=None, use_3d=False): """ Plots the whole solar system in one single call. .. versionadded:: 0.9.0 Parameters ------------ outer : bool, optional Whether to print the outer Solar System, default to True. epoch : ~astropy.time.Time, optional Epoch value of the plot, default to J2000. use_3d : bool, optional Produce 3D plot, default to False. """ bodies = [Mercury, Venus, Earth, Mars] if outer: bodies.extend([Jupiter, Saturn, Uranus, Neptune]) if use_3d: op = OrbitPlotter3D() # type: Union[OrbitPlotter3D, OrbitPlotter2D] else: op = OrbitPlotter2D() op.set_frame(*Orbit.from_body_ephem(Earth, epoch).pqw()) # type: ignore for body in bodies: orb = Orbit.from_body_ephem(body, epoch) op.plot(orb, label=str(body)) return op
def test_from_ephem_raises_warning_if_time_is_not_tdb_with_proper_time(recwarn): body = Earth epoch = Time("2017-09-29 07:31:26", scale="utc") expected_epoch_string = "2017-09-29 07:32:35.182" # epoch.tdb.value Orbit.from_body_ephem(body, epoch) w = recwarn.pop(TimeScaleWarning) assert expected_epoch_string in str(w.message)
def test_from_ephem_raises_warning_if_time_is_not_tdb_with_proper_time(recwarn): body = Earth epoch = time.Time("2017-09-29 07:31:26", scale="utc") expected_epoch_string = "2017-09-29 07:32:35.182" # epoch.tdb.value Orbit.from_body_ephem(body, epoch) w = recwarn.pop(TimeScaleWarning) assert expected_epoch_string in str(w.message)
def hill_radius(body, a=None, e=None): """Approximated radius of the Hill Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). e : float, optional Eccentricity of the body's orbit, default to 0 (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor and eccentricity axis at epoch J2000 for the body if it was not # introduced by the user if a is None or e is None: ss = Orbit.from_body_ephem(body, J2000_TDB) a = a if a is not None else ss.a e = e if e is not None else ss.ecc mass_ratio = body.k / (3 * body.parent.k) r_SOI = a * (1 - e) * (mass_ratio**(1 / 3)) return r_SOI.decompose()
def compute_soi(body, a=None): """Approximated radius of the Laplace Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor axis at epoch J2000 for the body if it was not # introduced by the user if a is None: try: a = Orbit.from_body_ephem(body, J2000).a except KeyError: raise RuntimeError( """To compute the semimajor axis for Moon and Pluto use the JPL ephemeris: >>> from astropy.coordinates import solar_system_ephemeris >>> solar_system_ephemeris.set("jpl")""") r_SOI = a * (body.k / body.parent.k)**(2 / 5) return r_SOI.decompose()
def do_GET(self): self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() epoch_now = time.Time(datetime.datetime.now()) res = { "earth": str(Orbit.from_body_ephem(Earth, epoch_now)), "mars": str(Orbit.from_body_ephem(Mars, epoch_now)) } self.wfile.write(json.dumps(res).encode("utf-8")) return
def compute_soi(body, a=None): """Approximated radius of the Laplace Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor axis at epoch J2000 for the body if it was not # introduced by the user if a is None: try: a = Orbit.from_body_ephem(body, J2000).a except KeyError: raise RuntimeError( """To compute the semimajor axis for Moon and Pluto use the JPL ephemeris: >>> from astropy.coordinates import solar_system_ephemeris >>> solar_system_ephemeris.set("jpl")""") r_SOI = a * (body.k / body.parent.k) ** (2 / 5) return r_SOI.decompose()
def hill_radius(body, a=None, e=None): """Approximated radius of the Hill Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). e : float, optional Eccentricity of the body's orbit, default to 0 (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor and eccentricity axis at epoch J2000 for the body if it was not # introduced by the user if a is None or e is None: ss = Orbit.from_body_ephem(body, J2000_TDB) a = a if a is not None else ss.a e = e if e is not None else ss.ecc mass_ratio = body.k / (3 * body.parent.k) r_SOI = a * (1 - e) * (mass_ratio ** (1 / 3)) return r_SOI.decompose()
def _plot_bodies(orbit_plotter, outer=True, epoch=None): bodies = [Mercury, Venus, Earth, Mars] if outer: bodies.extend([Jupiter, Saturn, Uranus, Neptune]) for body in bodies: orb = Orbit.from_body_ephem(body, epoch) orbit_plotter.plot(orb, label=str(body))
def optimal_transit(date, transit_min, transit_max, planet1, planet2, vs0, step): date_arrival = date + transit_min # minimalna data wykonania tranzytu date_max = date + transit_max # maksymalna data wykonania, zakonczenie petli date_arrival_final = date_arrival vs_temp = 0 * u.km / u.s dv_final = 0 * u.km / u.s step_first = True # petla idaca po datach z okreslonym krokiem while date_arrival < date_max: tof = date_arrival - date # tof - time of flight date_iso = time.Time(str(date.iso), scale='utc') # data startu date_arrival_iso = time.Time(str(date_arrival.iso), scale='utc') # data przylotu r1 = Orbit.from_body_ephem(planet1, date_iso) r2 = Orbit.from_body_ephem(planet2, date_arrival_iso) r_1, v_1 = r1.rv() # pozycja i predkosc planety poczatkowej r_2, v_2 = r2.rv() # pozycja i predkosc planety koncowej (vs1, vs2), = iod.lambert(Sun.k, r_1, r_2, tof) # rozwiazanie zagadnienia lamberta dv_vector = vs1 - ( vs0 + (v_1 / (24 * 3600) * u.day / u.s) ) # zmiana predkosci niezbedna do udanego wykonania manewru dv = np.linalg.norm( dv_vector / 10) * u.km / u.s # modul wektora zmiany predkosci if step_first: # zapis wynikow z pierwszego kroku dv_final = dv vs_temp = vs2 step_first = False else: if dv < dv_final: # sprawdzenie czy kolejny krok jest bardziej korzystna dv_final = dv date_arrival_final = date_arrival vs_temp = vs2 date_arrival += step * u.day return dv_final, date_arrival_final, vs_temp # funkcja zwraca niezbedny przyrost predkosci, date przybycia
def total_delta_v(launch, arrival): """Calculate the total delta v for specific combination of launch date and arrival date :param launch: launch time in isoformat string :param arrival: desired arrival time in isoformat string """ date_launch = time.Time(launch, scale="utc") date_arrival = time.Time(arrival, scale="utc") ss_earth = Orbit.from_body_ephem(Earth, date_launch) ss_mars = Orbit.from_body_ephem(Mars, date_arrival) man_lambert = Maneuver.lambert(ss_earth, ss_mars) return { 'delta_v': man_lambert.get_total_cost().value, 'total_seconds': man_lambert.get_total_time().value }
def _plot_solar_system_2d(outer=True, epoch=None, interactive=False): pqw = Orbit.from_body_ephem(Earth, epoch).pqw() if interactive: orbit_plotter = (OrbitPlotter2D() ) # type: Union[OrbitPlotter2D, StaticOrbitPlotter] orbit_plotter.set_frame(*pqw) else: orbit_plotter = StaticOrbitPlotter() orbit_plotter.set_frame(*pqw) _plot_bodies(orbit_plotter, outer, epoch) return orbit_plotter
def set_body_frame(self, body, epoch=None): """Sets perifocal frame based on the orbit of a body at a particular epoch if given. Parameters ---------- body : poliastro.bodies.SolarSystemPlanet Body. epoch : astropy.time.Time, optional Epoch of current position. """ from poliastro.twobody import Orbit with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) orbit = Orbit.from_body_ephem(body, epoch).change_plane(self.plane) # type: ignore self.set_orbit_frame(orbit)
def orbit_check(date, v, m, Isp): # sprawdzenie czy orbita została osiągnieta date_iso = time.Time(str(date.iso), format='iso', scale='utc') r_out = Orbit.from_body_ephem(Jupiter, date_iso) # polozenie Jowisza po asyscie r_out1, vp_out1 = r_out.rv() v_exit = v + (vp_out1 / (24 * 3600) * u.day / u.s) # predkosc satelity po manewrach epoch_out = date.jyear ss_out = Orbit.from_vectors(Sun, r_out1, v_exit, epoch=epoch_out) # wyjsciowe parametry orbity print('Sprawdzanie osiągnięcia orbity ...') print() if ss_out.ecc >= 1: # ekscentrycznosc orbity print('Predkosc jest okej') else: print('Predkosc jest za mała') print() print('Dostosuj się do minimalnej orbity wyjściowej ') # minimalna orbita wyjsciowa paraboliczna: ss_out_new = Orbit.parabolic(Sun, ss_out.p, ss_out.inc, ss_out.raan, ss_out.argp, ss_out.nu, epoch=epoch_out) v_out_new = ss_out_new.rv()[1] - v_exit # obliczenia nowej predkosci dv_out_new = np.linalg.norm(v_out_new) * u.km / u.s m_p_new = m * (math.exp(dv_out_new / Isp) - 1 ) # obliczenia brakujace masy paliwa # Odpowiedz: print('Potrzebna delta V: %.3f km/s' % float(dv_out_new / u.km * u.s)) print('Potrzebna dod. masa paliwa: %i kg' % int(m_p_new / u.kg))
def plot_body_orbit(self, body, epoch=None, label=None): """Plots complete revolution of body and current position if given. Parameters ---------- body : poliastro.bodies.SolarSystemBody Body. epoch : astropy.time.Time, optional Epoch of current position. label : str, optional Label of the orbit, default to the name of the body. """ from poliastro.twobody import Orbit with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) orbit = Orbit.from_body_ephem(body, epoch) self.plot(orbit, label=label or str(body))
def _plot_body_orbit( self, body, epoch, *, label=None, color=None, trail=False, ): if color is None: color = BODY_COLORS.get(body.name) from poliastro.twobody import Orbit with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) orbit = Orbit.from_body_ephem(body, epoch) return self._plot(orbit, label=label or str(body), color=color, trail=trail)
def hill_radius(body, a=None, e=None): """Approximated radius of the Hill Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). e : float, optional Eccentricity of the body's orbit, default to 0 (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor and eccentricity axis at epoch J2000 for the body if it was not # introduced by the user if a is None or e is None: try: ss = Orbit.from_body_ephem(body, J2000_TDB) a = a if a is not None else ss.a e = e if e is not None else ss.ecc except KeyError: raise RuntimeError( """To compute the semimajor axis or eccentricity for Moon and Pluto use the JPL ephemeris: >>> from astropy.coordinates import solar_system_ephemeris >>> solar_system_ephemeris.set("jpl")""") mass_ratio = body.k / (3 * body.parent.k) r_SOI = a * (1 - e) * (mass_ratio**(1 / 3)) return r_SOI.decompose()
def laplace_radius(body, a=None): """Approximated radius of the Laplace Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor axis at epoch J2000 for the body if it was not # introduced by the user if a is None: a = Orbit.from_body_ephem(body, J2000_TDB).a r_SOI = a * (body.k / body.parent.k) ** (2 / 5) return r_SOI.decompose()
def laplace_radius(body, a=None): """Approximated radius of the Laplace Sphere of Influence (SOI) for a body. Parameters ---------- body : `~poliastro.bodies.Body` Astronomical body which the SOI's radius is computed for. a : float, optional Semimajor axis of the body's orbit, default to None (will be computed from ephemerides). Returns ------- astropy.units.quantity.Quantity Approximated radius of the Sphere of Influence (SOI) [m] """ # Compute semimajor axis at epoch J2000 for the body if it was not # introduced by the user if a is None: a = Orbit.from_body_ephem(body, J2000_TDB).a r_SOI = a * (body.k / body.parent.k)**(2 / 5) return r_SOI.decompose()
ss = Orbit.from_vectors(Earth, r, v) print(ss) from poliastro.plotting import plot #plot(ss) a = 1.523679 * u.AU ecc = 0.093315 * u.one inc = 1.85 * u.deg raan = 49.562 * u.deg argp = 286.537 * u.deg nu = 23.33 * u.deg ss = Orbit.from_classical(Sun, a, ecc, inc, raan, argp, nu) #plot(ss) from poliastro.examples import iss print(iss) from poliastro.maneuver import Maneuver dv = [5, 0, 0] * u.m / u.s man = Maneuver.impulse(dv) man = Maneuver((0 * u.s, dv)) from astropy import time epoch = time.Time("2018-01-25 20:00") from poliastro import ephem new = Orbit.from_body_ephem(Earth, epoch) print(new)
def test_orbit_from_ephem_is_in_icrs_frame(body): ss = Orbit.from_body_ephem(body) assert ss.frame.is_equivalent_frame(ICRS())
def test_orbit_from_ephem_with_no_epoch_is_today(): # This is not that obvious http://stackoverflow.com/q/6407362/554319 body = Earth ss = Orbit.from_body_ephem(body) assert (Time.now() - ss.epoch).sec < 1
date_liftoff = time.Time('1969-07-16 14:32', scale='tdb') date_launch = date_liftoff + (2 * u.h + 44 * u.min) #date_launch is the time at which Translunar Insertion Maneuver is performed date_arrival = date_launch + (75 * u.h + 54 * u.min) #date_arrival is the time at which Cislunar Insertion Maneuver is performed tof = date_arrival - date_launch #Apollo Parking Orbit Around Earth apollo = Orbit.circular(Earth, alt=185.21 * u.km, inc=32.521 * u.deg, epoch=date_launch) #Moon Orbit aqcuisition and conversion to GCRS EPOCH = date_arrival moon = Orbit.from_body_ephem(Moon, EPOCH) moon_icrs = ICRS(x=moon.r[0], y=moon.r[1], z=moon.r[2], v_x=moon.v[0], v_y=moon.v[1], v_z=moon.v[2], representation=CartesianRepresentation, differential_cls=CartesianDifferential) moon_gcrs = moon_icrs.transform_to(GCRS(obstime=EPOCH)) moon_gcrs.representation = CartesianRepresentation moon_gcrs moon = Orbit.from_vectors( Earth, [moon_gcrs.x, moon_gcrs.y, moon_gcrs.z] * u.km,
from poliastro.examples import iss iss #plot (iss) iss.epoch iss.nu.to(u.deg) iss.n.to(u.deg / u.min) iss_30m = iss.propagate(30 * u.min) iss_30m.epoch iss_30m.nu.to(u.deg) #plot (iss_30m) earth = Orbit.from_body_ephem(Earth) #plot(earth) earth_30d = earth.propagate(30 * u.day) #plot(earth_30d) from poliastro.maneuver import Maneuver dv = [5, 0, 0] * u.m / u.s man = Maneuver.impulse(dv) man = Maneuver((0 * u.s, dv)) ss_i = Orbit.circular(Earth, alt=700 * u.km) ss_i #plot(ss_i) hoh = Maneuver.hohmann(ss_i, 36000 * u.km) hoh.get_total_cost()
import numpy as np from astropy import units as u from poliastro.bodies import Earth, Jupiter, Sun from poliastro.twobody import Orbit from poliastro.util import norm # Orbits ss_Earth = Orbit.from_body_ephem(Earth) ss_Jupiter = Orbit.from_body_ephem(Jupiter) # Radius vector r_Earth = ss_Earth.r.to(u.m) r_Jupiter = ss_Jupiter.r.to(u.m) # Radius vector norm R_E = norm(r_Earth) R_J = norm(r_Jupiter) # Velocity vectors v_Earth = ss_Earth.v.to(u.m / u.s) v_Jupiter = ss_Jupiter.v.to(u.m / u.s) # Velocity vectors direction v_Earth_dir = v_Earth / norm(v_Earth)
import numpy as np from poliastro.twobody import Orbit from poliastro.util import norm from astropy.time import Time from poliastro import iod from poliastro.threebody.flybys import compute_flyby from brentq import brentq import matplotlib.pyplot as plt T_ref = 150 * u.day k = Sun.k a_ref = np.cbrt(k * T_ref**2 / (4 * np.pi**2)).to(u.km) energy_ref = (-k / (2 * a_ref)).to(u.J / u.kg) flyby_1_time = Time("2018-09-28", scale="tdb") r_mag_ref = norm(Orbit.from_body_ephem(Venus, epoch=flyby_1_time).r) v_mag_ref = np.sqrt(2 * k / r_mag_ref - k / a_ref) d_launch = Time("2018-08-11", scale="tdb") ss0 = Orbit.from_body_ephem(Earth, d_launch) ss1 = Orbit.from_body_ephem(Venus, epoch=flyby_1_time) tof = flyby_1_time - d_launch (v0, v1_pre), = iod.lambert(Sun.k, ss0.r, ss1.r, tof.to(u.s)) V = Orbit.from_body_ephem(Venus, epoch=flyby_1_time).v h = 2548 * u.km d_flyby_1 = Venus.R + h V_2_v_, delta_ = compute_flyby(v1_pre, V, Venus.k, d_flyby_1) theta_range = np.linspace(0, 2 * np.pi) def func(theta): V_2_v, _ = compute_flyby(v1_pre, V, Venus.k, d_flyby_1, theta * u.rad)
# print ("a: " + str(perDiff(a, aJPL)) + "%") # print ("e: " + str(perDiff(e, eJPL)) + "%") # print ("i: " + str(perDiff(i, iJPL)) + "%") # print ("Lon ascending node: " + str(perDiff(lOmega[0], lOmegaJPL)) + "%") # print ("Perihelion: " + str(perDiff(aPerihelion, omegaJPL)) + "%") # print ("M: " + str(perDiff(M, MJPL)) + "%") a = a * units.AU ecc = e * units.one inc = i * units.deg raan = lOmega[0] * units.deg argp = aPerihelion * units.deg nu = v * units.deg epoch = time.Time(t2, format='jd', scale='utc') earth_orbit = Orbit.from_body_ephem(Earth) earth_orbit = earth_orbit.propagate(time.Time(t2, format='jd', scale='tdb'), rtol=1e-10) magellan_orbit = neows.orbit_from_name('2018ez2') magellan_orbit = magellan_orbit.propagate(time.Time(t2, format='jd', scale='tdb'), rtol=1e-10) estimated_orbit = Orbit.from_classical(Sun, a, ecc, inc, raan, argp, nu, epoch) op = OrbitPlotter() op.plot(earth_orbit, label='Earth') op.plot(magellan_orbit, label='2018 EZ2') op.plot(estimated_orbit, label='Estimated') plt.show()
from poliastro.maneuver import Maneuver from poliastro.iod import izzo from poliastro.plotting import plot, OrbitPlotter from poliastro.util import norm solar_system_ephemeris.set("jpl") ## Initial data # Links and sources: https://github.com/poliastro/poliastro/wiki/EuroPython:-Per-Python-ad-Astra date_launch = Time("2022-08-05 16:25", scale='tdb') C_3 = 31.1 * u.km**2 / u.s**2 date_flyby = Time("2024-10-09 19:21", scale='tdb') date_arrival = Time("2026-07-05 03:18", scale='tdb') # Initial state of the Earth ss_e0 = Orbit.from_body_ephem(Earth, date_launch) r_e0, v_e0 = ss_e0.rv() print("Position of Earth: ",r_e0) print("Velocity of Earth: ",v_e0) # State of the Earth the day of the flyby ss_efly = Orbit.from_body_ephem(Earth, date_flyby) r_efly, v_efly = ss_efly.rv() # Assume that the insertion velocity is tangential to that of the Earth dv = C_3**.5 * v_e0 / norm(v_e0) man = Maneuver.impulse(dv) # Inner Cruise 1 ic1 = ss_e0.apply_maneuver(man)
a = (r_p + r_a) / 2 roadster = Orbit.from_classical(attractor=Sun, a=0.9860407221838553 * u.AU, ecc=0.2799145376150214 * u.one, inc=1.194199764898942 * u.deg, raan=49 * u.deg, argp=286 * u.deg, nu=23 * u.deg, epoch=date) for date in days_as: apophis_orbit = neows.orbit_from_name('99942') spacex = neows.orbit_from_name('-143205') op.orbits.clear() earth = Orbit.from_body_ephem(Earth, date) mars = Orbit.from_body_ephem(Mars, date) op.plot(earth, label=Earth) op.plot(mars, label=Mars) op.plot(roadster, label='Roadster') op.plot(apophis_orbit, label='Apophis') op._redraw() plt.pause(0.01) input('type to exit') op.plot(Orbit.from_body_ephem(Mars, time.Time("2018-07-28 12:00", scale='utc')), label=Mars)