Example #1
0
def _targetting(departure_body, target_body, t_launch, t_arrival):
    """This function returns the increment in departure and arrival velocities.

    """

    rr_dpt_body, vv_dpt_body = _get_state(departure_body, t_launch)
    rr_arr_body, vv_arr_body = _get_state(target_body, t_arrival)

    # Compute time of flight
    tof = t_arrival - t_launch

    if tof <= 0:
        return None, None, None, None, None

    try:
        (v_dpt, v_arr), = lambert(Sun.k, rr_dpt_body.xyz, rr_arr_body.xyz, tof)

        # Compute all the output variables
        dv_dpt = norm(v_dpt - vv_dpt_body.xyz)
        dv_arr = norm(v_arr - vv_arr_body.xyz)
        c3_launch = dv_dpt**2
        c3_arrival = dv_arr**2

        return (
            dv_dpt.to(u.km / u.s).value,
            dv_arr.to(u.km / u.s).value,
            c3_launch.to(u.km**2 / u.s**2).value,
            c3_arrival.to(u.km**2 / u.s**2).value,
            tof.jd,
        )

    except AssertionError:
        return None, None, None, None, None
Example #2
0
def _targetting(departure_body, target_body, t_launch, t_arrival):
    """This function returns the increment in departure and arrival velocities.

    """

    rr_dpt_body, vv_dpt_body = _get_state(departure_body, t_launch)
    rr_arr_body, vv_arr_body = _get_state(target_body, t_arrival)

    # Compute time of flight
    tof = t_arrival - t_launch

    if tof <= 0:
        return None, None, None, None, None

    try:
        (v_dpt, v_arr), = lambert(Sun.k, rr_dpt_body.xyz, rr_arr_body.xyz, tof)

        # Compute all the output variables
        dv_dpt = norm(v_dpt - vv_dpt_body.xyz)
        dv_arr = norm(v_arr - vv_arr_body.xyz)
        c3_launch = dv_dpt ** 2
        c3_arrival = dv_arr ** 2

        return (
            dv_dpt.to(u.km / u.s).value,
            dv_arr.to(u.km / u.s).value,
            c3_launch.to(u.km ** 2 / u.s ** 2).value,
            c3_arrival.to(u.km ** 2 / u.s ** 2).value,
            tof.jd,
        )

    except AssertionError:
        return None, None, None, None, None
Example #3
0
 def lambert(self, r0, rf, tof, m=0):
     k = self.star.mu * u.m**3 / u.s**2
     r0 = r0 * u.m
     rf = rf * u.m
     tof = tof * u.s
     (v0, v), = iod.lambert(k, r0, rf, tof, M=m)
     v0 = [1000 * v0.value[0], 1000 * v0.value[1], 1000 * v0.value[2]]
     v = [1000 * v.value[0], 1000 * v.value[1], 1000 * v.value[2]]
     return v0, v
Example #4
0
 def test_curtis53(self):
     k = k_earth.to(units.km ** 3 / units.s ** 2).value
     r0 = np.array([273378.0, 0.0, 0.0])
     r = np.array([145820.0, 12758.0, 0.0])
     tof = 13.5 * 3600.0
     va, vb = lambert(k, r0, r, tof)
     # ERRATA: j component is positive
     assert_array_almost_equal(va, np.array([-2.4356, 0.26741, 0.0]),
                               decimal=3)
Example #5
0
 def test_curtis52(self):
     k = k_earth.to(units.km ** 3 / units.s ** 2).value
     r0 = np.array([5000.0, 10000.0, 2100.0])
     r = np.array([-14600.0, 2500.0, 7000.0])
     tof = 3600.0
     va, vb = lambert(k, r0, r, tof)
     assert_array_almost_equal(va, np.array([-5.9925, 1.9254, 3.2456]),
                               decimal=3)
     assert_array_almost_equal(vb, np.array([-3.3125, -4.1966, -0.38529]),
                               decimal=3)
Example #6
0
 def test_vallado75(self):
     k = k_earth.to(units.km ** 3 / units.s ** 2).value
     r0 = np.array([15945.34, 0.0, 0.0])
     r = np.array([12214.83399, 10249.46731, 0.0])
     tof = 76.0 * 60.0
     va, vb = lambert(k, r0, r, tof)
     assert_array_almost_equal(va, np.array([2.058925, 2.915956, 0.0]),
                               decimal=3)
     assert_array_almost_equal(vb, np.array([-3.451569, 0.910301, 0.0]),
                               decimal=3)
Example #7
0
def test_curtis53():
    k = Earth.k
    r0 = [273378.0, 0.0, 0.0] * u.km
    r = [145820.0, 12758.0, 0.0] * u.km
    tof = 13.5 * u.h

    # ERRATA: j component is positive
    expected_va = [-2.4356, 0.26741, 0.0] * u.km / u.s

    va, vb = lambert(k, r0, r, tof)
    assert_array_almost_equal(va.to(u.km / u.s).value,
                              expected_va.value,
                              decimal=3)
Example #8
0
def test_curtis52():
    k = Earth.k
    r0 = [5000.0, 10000.0, 2100.0] * u.km
    r = [-14600.0, 2500.0, 7000.0] * u.km
    tof = 1.0 * u.h

    expected_va = [-5.9925, 1.9254, 3.2456] * u.km / u.s
    expected_vb = [-3.3125, -4.1966, -0.38529] * u.km / u.s

    va, vb = lambert(k, r0, r, tof)
    assert_array_almost_equal(va.to(u.km / u.s).value,
                              expected_va.value,
                              decimal=4)
    assert_array_almost_equal(vb.to(u.km / u.s).value,
                              expected_vb.value,
                              decimal=4)
Example #9
0
def test_vallado75():
    k = Earth.k
    r0 = [15945.34, 0.0, 0.0] * u.km
    r = [12214.83399, 10249.46731, 0.0] * u.km
    tof = 76.0 * u.min

    expected_va = [2.058925, 2.915956, 0.0] * u.km / u.s
    expected_vb = [-3.451569, 0.910301, 0.0] * u.km / u.s

    va, vb = lambert(k, r0, r, tof)
    assert_array_almost_equal(va.to(u.km / u.s).value,
                              expected_va.value,
                              decimal=4)
    assert_array_almost_equal(vb.to(u.km / u.s).value,
                              expected_vb.value,
                              decimal=5)
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
Example #11
0
def transit(date, date_arrival, planet1, planet2):
    #czas trwania misji
    tof = date_arrival - date
    N = 50
    tof.to(u.h)
    times_vector = time_range(date, end=date_arrival, periods=N)

    # okreslenie pozycji planet w przedziale czasu: od startu do końca misji
    rr_planet1, vv_planet1 = get_body_barycentric_posvel(planet1, times_vector)
    rr_planet2, vv_planet2 = get_body_barycentric_posvel(planet2, times_vector)

    r0 = rr_planet1[0].xyz  #wektor pozycji Ziemi w momencie startu
    v0 = vv_planet1[0].xyz  #wektor predkosci Ziemi w momencie startu
    rf = rr_planet2[
        -1].xyz  #wektor pozycji planety docelowej w momencie końca misji
    vf = vv_planet2[
        -1].xyz  #wektor predkosci planety docelowej w momencie końca misji

    # rozwiazanie problemu Lamberta
    (va, vb), = iod.lambert(Sun.k, r0, rf, tof, numiter=1000)

    return (r0, v0, rf, vf, va, vb, rr_planet1, rr_planet2, times_vector)
Example #12
0
times_vector = time.Time(jd_vec, format='jd')

rr_earth, vv_earth = ephem.planet_ephem(ephem.EARTH, times_vector)
rr_earth[:, 0]
vv_earth[:, 0]

rr_mars, vv_mars = ephem.planet_ephem(ephem.MARS, times_vector)
rr_mars[:, 0]
vv_mars[:, 0]

# Compute the transfer orbit!
r0 = rr_earth[:, 0]
rf = rr_mars[:, -1]

(va, vb), = iod.lambert(Sun.k, r0, rf, tof)

ss0_trans = State.from_vectors(Sun, r0, va, date_launch)
ssf_trans = State.from_vectors(Sun, rf, vb, date_arrival)

# Extract whole orbit of Earth, Mars and transfer (for plotting)
rr_trans = np.zeros_like(rr_earth)
rr_trans[:, 0] = r0
for ii in range(1, len(jd_vec)):
    tof = (jd_vec[ii] - jd_vec[0]) * u.day
    rr_trans[:, ii] = ss0_trans.propagate(tof).r

# Better compute backwards
jd_init = (date_arrival - 1 * u.year).jd
jd_vec_rest = np.linspace(jd_init, jd_launch, num=N)
Example #13
0
times_vector = time.Time(jd_vec, format='jd')

rr_earth, vv_earth = ephem.planet_ephem(ephem.EARTH, times_vector)
rr_earth[:, 0]
vv_earth[:, 0]

rr_mars, vv_mars = ephem.planet_ephem(ephem.MARS, times_vector)
rr_mars[:, 0]
vv_mars[:, 0]

# Compute the transfer orbit!
r0 = rr_earth[:, 0]
rf = rr_mars[:, -1]

(va, vb), = iod.lambert(Sun.k, r0, rf, tof)

ss0_trans = State.from_vectors(Sun, r0, va, date_launch)
ssf_trans = State.from_vectors(Sun, rf, vb, date_arrival)

# Extract whole orbit of Earth, Mars and transfer (for plotting)
rr_trans = np.zeros_like(rr_earth)
rr_trans[:, 0] = r0
for ii in range(1, len(jd_vec)):
    tof = (jd_vec[ii] - jd_vec[0]) * u.day
    rr_trans[:, ii] = ss0_trans.propagate(tof).r

# Better compute backwards
jd_init = (date_arrival - 1 * u.year).jd
jd_vec_rest = np.linspace(jd_init, jd_launch, num=N)
Example #14
0
                 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,
    [moon_gcrs.v_x, moon_gcrs.v_y, moon_gcrs.v_z] * (u.km / u.s),
    epoch=EPOCH)

ss0 = apollo
ssf = moon

#Solve for Lambert's Problem (Determining Translunar Trajectory)
(v0, v), = iod.lambert(Earth.k, ss0.r, ssf.r, tof)
ss0_trans = Orbit.from_vectors(Earth, ss0.r, v0, date_launch)

dv = (ss0_trans.v - ss0.v)
dv = dv.to(u.m / u.s)
man = Maneuver.impulse(dv)
ss_f = ss0.apply_maneuver(man)
print(
    "The required Delta-V to perform the Translunar Injection maneuver is: " +
    str(dv))

#Plotting Solution in 2D - Earth close-up
plt.ion()
op = OrbitPlotter()
op.plot(ss0, label="Apollo")
op.plot(ssf, label="Moon")
Example #15
0
# ### Option b): Compute $v_{\infty}$ using the Jupyter flyby
# 
# According to Wikipedia, the closest approach occurred at 05:43:40 UTC. We can use this data to compute the solution of the Lambert problem between the Earth and Jupiter.

# In[6]:


nh_date = time.Time("2006-01-19 19:00", scale="utc").tdb
nh_flyby_date = time.Time("2007-02-28 05:43:40", scale="utc").tdb
nh_tof = nh_flyby_date - nh_date

nh_r_0, v_earth = Ephem.from_body(Earth, nh_date).rv(nh_date)
nh_r_f, v_jup = Ephem.from_body(Jupiter, nh_flyby_date).rv(nh_flyby_date)

(nh_v_0, nh_v_f), = iod.lambert(Sun.k, nh_r_0, nh_r_f, nh_tof)


# The hyperbolic excess velocity is measured with respect to the Earth:

# In[7]:


C_3_lambert = (norm(nh_v_0 - v_earth)).to(u.km / u.s) ** 2
C_3_lambert


# In[8]:


print("Relative error of {:.2f} %".format((C_3_lambert - C_3_A) / C_3_A * 100))
Example #16
0
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)
    ss_1 = Orbit.from_vectors(Sun, ss1.r, V_2_v, epoch=flyby_1_time)
    return (ss_1.period - T_ref).to(u.day).value


plt.plot(theta_range, [func(theta) for theta in theta_range])
plt.axhline(0, color="k", linestyle="dashed")
Example #17
0
def go_to_mars(offset=0., tof_=6000.):
    # Initial data
    N = 50

    date_launch = time.Time('2011-11-26 15:02', scale='utc') + offset * u.day
    #date_arrival = time.Time('2012-08-06 05:17', scale='utc')
    tof = tof_ * u.h

    # Calculate vector of times from launch and arrival
    date_arrival = date_launch + tof
    dt = (date_arrival - date_launch) / N

    # Idea from http://docs.astropy.org/en/stable/time/#getting-started
    times_vector = date_launch + dt * np.arange(N + 1)

    rr_earth, vv_earth = get_body_ephem("earth", times_vector)
    rr_mars, vv_mars = get_body_ephem("mars", times_vector)

    # Compute the transfer orbit!
    r0 = rr_earth[:, 0]
    rf = rr_mars[:, -1]

    (va, vb), = iod.lambert(Sun.k, r0, rf, tof)

    ss0_trans = Orbit.from_vectors(Sun, r0, va, date_launch)
    ssf_trans = Orbit.from_vectors(Sun, rf, vb, date_arrival)

    # Extract whole orbit of Earth, Mars and transfer (for plotting)
    rr_trans = np.zeros_like(rr_earth)
    rr_trans[:, 0] = r0
    for ii in range(1, len(times_vector)):
        tof = (times_vector[ii] - times_vector[0]).to(u.day)
        rr_trans[:, ii] = ss0_trans.propagate(tof).r

    # Better compute backwards
    date_final = date_arrival - 1 * u.year
    dt2 = (date_final - date_launch) / N

    times_rest_vector = date_launch + dt2 * np.arange(N + 1)
    rr_earth_rest, _ = get_body_ephem("earth", times_rest_vector)
    rr_mars_rest, _ = get_body_ephem("mars", times_rest_vector)

    # Plot figure
    fig = plt.gcf()
    ax = plt.gca()
    ax.cla()

    def plot_body(ax, r, color, size, border=False, **kwargs):
        """Plots body in axes object.

        """
        return ax.plot(*r[:, None],
                       marker='o',
                       color=color,
                       ms=size,
                       mew=int(border),
                       **kwargs)

    # I like color
    color_earth0 = '#3d4cd5'
    color_earthf = '#525fd5'
    color_mars0 = '#ec3941'
    color_marsf = '#ec1f28'
    color_sun = '#ffcc00'
    color_orbit = '#888888'
    color_trans = '#444444'

    # Plotting orbits is easy!
    ax.plot(*rr_earth.to(u.km).value, color=color_earth0)
    ax.plot(*rr_mars.to(u.km).value, color=color_mars0)

    ax.plot(*rr_trans.to(u.km).value, color=color_trans)
    ax.plot(*rr_earth_rest.to(u.km).value, ls='--', color=color_orbit)
    ax.plot(*rr_mars_rest.to(u.km).value, ls='--', color=color_orbit)

    # But plotting planets feels even magical!
    plot_body(ax, np.zeros(3), color_sun, 16)

    plot_body(ax, r0.to(u.km).value, color_earth0, 8)
    plot_body(ax, rr_earth[:, -1].to(u.km).value, color_earthf, 8)

    plot_body(ax, rr_mars[:, 0].to(u.km).value, color_mars0, 8)
    plot_body(ax, rf.to(u.km).value, color_marsf, 8)

    # Add some text
    #ax.text(-0.75e8, -3.5e8, -1.5e8, "MSL mission:\nfrom Earth to Mars", size=20, ha='center', va='center', bbox={"pad": 30, "lw": 0, "fc": "w"})
    ax.text(r0[0].to(u.km).value * 1.4,
            r0[1].to(u.km).value * 0.4,
            r0[2].to(u.km).value * 1.25,
            f"Earth at launch\n({date_launch.datetime:%b %d})",
            ha="left",
            va="bottom",
            backgroundcolor='#ffffff')
    ax.text(rf[0].to(u.km).value * 0.7,
            rf[1].to(u.km).value * 1.1,
            rf[2].to(u.km).value,
            f"Mars at arrival\n({date_arrival.datetime:%b %d})",
            ha="left",
            va="top",
            backgroundcolor='#ffffff')
    ax.text(-1.9e8,
            8e7,
            0,
            "Transfer\norbit",
            ha="right",
            va="center",
            backgroundcolor='#ffffff')

    # Tune axes
    ax.set_xlim(-3e8, 3e8)
    ax.set_ylim(-3e8, 3e8)
    ax.set_zlim(-3e8, 3e8)
    ax.view_init(30, 260)
r0 = r0[0]
r1 = r1[0]
V = V[0]

# In[15]:

tof = flyby_1_time - d_launch

# In[16]:

from poliastro import iod

# In[17]:

((v0, v1_pre), ) = iod.lambert(Sun.k, r0, r1, tof.to(u.s))

# In[18]:

v0

# In[19]:

v1_pre

# In[20]:

norm(v1_pre)

# ## 3. Flyby #1 around Venus
#
Example #19
0
tuple(val.decompose([u.km, u.s]) for val in hoh[1])

ss_f = ss_i.apply_maneuver(hoh)
#plot(ss_f)

from poliastro.plotting import OrbitPlotter

op = OrbitPlotter()
ss_a, ss_f = ss_i.apply_maneuver(hoh, intermediate=True)
#op.plot(ss_i, label="Initial orbit")
#op.plot(ss_a, label="Transfer orbit")
#op.plot(ss_f, label="Final orbit")

from astropy import time
epoch = time.Time("2015-05-09 10:43")

Orbit.from_body_ephem(Earth, epoch)

from astropy.coordinates import solar_system_ephemeris
solar_system_ephemeris.set("jpl")

date_launch = time.Time('2011-11-26 15:02', scale='utc')
date_arrival = time.Time('2012-08-06 05:17', scale='utc')
tof = date_arrival - date_launch
ss0 = Orbit.from_body_ephem(Earth, date_launch)
ssf = Orbit.from_body_ephem(Mars, date_arrival)
from poliastro import iod
(v0, v), = iod.lambert(Sun.k, ss0.r, ssf.r, tof)

#op.plot(ss0)
#op.plot(ssf)
Example #20
0
def test():
    """Not consolodted test function, just a place to copy/paste interactive test case
    """
    ## From http://nbviewer.jupyter.org/github/poliastro/poliastro/blob/master/examples/Going%20to%20Mars%20with%20Python%20using%20poliastro.ipynb
    r_earth = [64601872, 1.2142001e8, 52638008] * u.km
    r_mars = [-1.2314831e8, 1.9075313e8, 90809903] * u.km

    ## Not a valid funciton, just writing down some useful starting point tests
    import astropy.units as u
    from astropy import time

    from poliastro import iod  # This is the big one!
    from poliastro.bodies import Sun
    from poliastro.twobody import Orbit
    from poliastro import ephem
    ephem.download_kernel("de421")
    ## MSL Stats from: http://mars.jpl.nasa.gov/msl/mission/overview/
    launch_date = time.Time("2011-11-26 15:02:00", scale="utc")
    arrival_date = time.Time("2012-08-06 05:17:00", scale="utc")
    tof = arrival_date - launch_date
    print("Time of flight: {} hours".format(tof.to(u.h)))
    ## Get vector of times from launch and arrival Julian days
    N = 50
    launch_jd = launch_date.jd
    arrival_jd = arrival_date.jd
    jd_vec = np.linspace(launch_jd, arrival_jd, num=N)

    times_vec = time.Time(jd_vec, format="jd")
    ## Use `ephem` module to get Earth and Mars positions
    r_earth, v_earth = ephem.planet_ephem(ephem.EARTH, times_vec)
    r_mars, v_mars = ephem.planet_ephem(ephem.MARS, times_vec)
    r0 = r_earth[:, 0]
    r1 = r_mars[:, -1]

    ## Compute departure/arrival velocities, using Sun as main attractor
    (v_depart_iod, v_arrive_iod), = iod.lambert(Sun.k, r0, r1, tof)
    vd, va = lambert._gauss_universal_variable(Sun.k.value,
                                               r0.value,
                                               r1.value,
                                               tof.to(u.s).value,
                                               rtol=1e-8,
                                               finder=1,
                                               maxiter=1000000)

    departures = [
        time.Time(d, format="jd") for d in np.linspace(
            time.Time("2020-01-01").jd,
            time.Time("2020-04-01").jd)
    ]
    arrivals = [
        time.Time(d, format="jd") for d in np.linspace(
            time.Time("2020-08-01").jd,
            time.Time("2021-04-01").jd)
    ]
    xx = np.zeros((50, 5))

    idx = 0
    for d in departures:
        x, y = lambert.interplanetary_trajectory("Earth", "mars", d, arrivals)
        xx[idx] = x
        idx += 1
    c = contour([D.value for D in departures], [A.value for A in arrivals], xx)
    clabel(c, inline=1, fontsize=10)