Пример #1
0
def test_cowell_propagation_circle_to_circle():
    # From [Edelbaum, 1961]
    accel = 1e-7

    def constant_accel(t0, u, k):
        v = u[3:]
        norm_v = (v[0]**2 + v[1]**2 + v[2]**2)**.5
        return accel * v / norm_v

    ss = State.circular(Earth, 500 * u.km)
    tof = 20 * ss.period

    r0, v0 = ss.rv()
    k = ss.attractor.k

    r, v = cowell(k.to(u.km**3 / u.s**2).value,
                  r0.to(u.km).value,
                  v0.to(u.km / u.s).value,
                  tof.to(u.s).value,
                  constant_accel)

    ss_final = State.from_vectors(Earth,
                                  r * u.km,
                                  v * u.km / u.s,
                                  ss.epoch + tof)

    da_a0 = (ss_final.a - ss.a) / ss.a
    dv_v0 = abs(norm(ss_final.v) - norm(ss.v)) / norm(ss.v)
    assert_almost_equal(da_a0.value, 2 * dv_v0.value, decimal=4)

    dv = abs(norm(ss_final.v) - norm(ss.v))
    accel_dt = accel * u.km / u.s**2 * tof
    assert_almost_equal(dv.value, accel_dt.value, decimal=4)
Пример #2
0
def test_perifocal_points_to_perigee():
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    ss = State.from_classical(Sun, _d, _, _a, _a, _a, _a)
    p, _, _ = ss.pqw()
    assert_almost_equal(p, ss.e_vec / ss.ecc)
Пример #3
0
def test_parabolic_has_zero_energy():
    attractor = Earth
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    ss = State.parabolic(attractor, _d, _a, _a, _a, _a)
    assert_almost_equal(ss.energy.value, 0.0)
Пример #4
0
def test_state_raises_unitserror_if_rv_units_are_wrong():
    _d = [1.0, 0.0, 0.0] * u.AU
    wrong_v = [0.0, 1.0e-6, 0.0] * u.AU
    with pytest.raises(u.UnitsError) as excinfo:
        ss = State.from_vectors(Sun, _d, wrong_v)
    assert ("UnitsError: Units must be consistent"
            in excinfo.exconly())
Пример #5
0
def test_parabolic_has_infinite_semimajor_axis():
    attractor = Earth
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    expected_a = np.inf * u.km
    ss = State.parabolic(attractor, _d, _a, _a, _a, _a)
    assert_equal(ss.a, expected_a)
Пример #6
0
def test_parabolic_has_proper_eccentricity():
    attractor = Earth
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    expected_ecc = 1.0 * u.one
    ss = State.parabolic(attractor, _d, _a, _a, _a, _a)
    assert_almost_equal(ss.ecc, expected_ecc)
Пример #7
0
def test_default_time_for_new_state():
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    _body = Sun  # Unused body
    expected_epoch = time.Time("J2000", scale='utc')
    ss = State.from_classical(_body, _d, _, _a, _a, _a, _a)
    assert ss.epoch == expected_epoch
Пример #8
0
def test_apply_maneuver_changes_epoch():
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    ss = State.from_classical(Sun, _d, _, _a, _a, _a, _a)
    dt = 1 * u.h
    dv = [0, 0, 0] * u.km / u.s
    ss_new = ss.apply_maneuver([(dt, dv)])
    assert ss_new.epoch == ss.epoch + dt
Пример #9
0
def test_pqw_for_circular_equatorial_orbit():
    ss = State.circular(Earth, 600 * u.km)
    expected_p = [1, 0, 0] * u.one
    expected_q = [0, 1, 0] * u.one
    expected_w = [0, 0, 1] * u.one
    p, q, w = ss.pqw()
    assert_almost_equal(p, expected_p)
    assert_almost_equal(q, expected_q)
    assert_almost_equal(w, expected_w)
Пример #10
0
def test_state_raises_unitserror_if_elements_units_are_wrong():
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    wrong_angle = 1.0 * u.AU
    with pytest.raises(u.UnitsError) as excinfo:
        ss = State.from_classical(Sun, _d, _, _a, _a, _a, wrong_angle)
    assert ("UnitsError: Units must be consistent"
            in excinfo.exconly())
Пример #11
0
def test_propagation_hyperbolic():
    # Data from Curtis, example 3.5
    r0 = [Earth.R.to(u.km).value + 300, 0, 0] * u.km
    v0 = [0, 15, 0] * u.km / u.s
    ss0 = State.from_vectors(Earth, r0, v0)
    tof = 14941 * u.s
    ss1 = ss0.propagate(tof)
    r, v = ss1.rv()
    assert_almost_equal(norm(r).to(u.km).value, 163180, decimal=-1)
    assert_almost_equal(norm(v).to(u.km/u.s).value, 10.51, decimal=2)
Пример #12
0
def test_state_has_elements_given_in_constructor():
    # Mars data from HORIZONS at J2000
    a = 1.523679 * u.AU
    ecc = 0.093315 * u.one
    p = a * (1 - ecc**2)
    inc = 1.85 * u.deg
    raan = 49.562 * u.deg
    argp = 286.537 * u.deg
    nu = 23.33 * u.deg
    ss = State.from_classical(Sun, p, ecc, inc, raan, argp, nu)
    assert ss.coe() == (p, ecc, inc, raan, argp, nu)
Пример #13
0
def test_perigee_and_apogee():
    expected_r_a = 500 * u.km
    expected_r_p = 300 * u.km
    a = (expected_r_a + expected_r_p) / 2
    ecc = expected_r_a / a - 1
    p = a * (1 - ecc**2)
    _a = 1.0 * u.deg  # Unused angle
    ss = State.from_classical(Earth, p, ecc, _a, _a, _a, _a)
    assert_almost_equal(ss.r_a.to(u.km).value,
                        expected_r_a.to(u.km).value)
    assert_almost_equal(ss.r_p.to(u.km).value,
                        expected_r_p.to(u.km).value)
Пример #14
0
def test_apply_zero_maneuver_returns_equal_state():
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    ss = State.from_classical(Sun, _d, _, _a, _a, _a, _a)
    dt = 0 * u.s
    dv = [0, 0, 0] * u.km / u.s
    ss_new = ss.apply_maneuver([(dt, dv)])
    assert_almost_equal(ss_new.r.to(u.km).value,
                        ss.r.to(u.km).value)
    assert_almost_equal(ss_new.v.to(u.km / u.s).value,
                        ss.v.to(u.km / u.s).value)
Пример #15
0
def test_propagation():
    # Data from Vallado, example 2.4
    r0 = [1131.340, -2282.343, 6672.423] * u.km
    v0 = [-5.64305, 4.30333, 2.42879] * u.km / u.s
    ss0 = State.from_vectors(Earth, r0, v0)
    tof = 40 * u.min
    ss1 = ss0.propagate(tof)
    r, v = ss1.rv()
    assert_array_almost_equal(r.value, [-4219.7527, 4363.0292, -3958.7666],
                              decimal=1)
    assert_array_almost_equal(v.value, [3.689866, -1.916735, -6.112511],
                              decimal=4)
Пример #16
0
def test_convert_from_coe_to_rv():
    # Data from Vallado, example 2.5
    attractor = Earth
    r = [6524.384, 6862.875, 6448.296] * u.km
    v = [4.901327, 5.533756, -1.976341] * u.km / u.s
    ss = State.from_vectors(Earth, r, v)
    p, ecc, inc, raan, argp, nu = ss.coe()
    assert_almost_equal(p.to(u.km).value, 11067.79, decimal=0)
    assert_almost_equal(ecc.value, 0.832853, decimal=4)
    assert_almost_equal(inc.to(u.deg).value, 87.870, decimal=2)
    assert_almost_equal(raan.to(u.deg).value, 227.89, decimal=1)
    assert_almost_equal(argp.to(u.deg).value, 53.38, decimal=2)
    assert_almost_equal(nu.to(u.deg).value, 92.335, decimal=2)
Пример #17
0
def test_propagation_zero_time_returns_same_state():
    # Bug #50
    r0 = [1131.340, -2282.343, 6672.423] * u.km
    v0 = [-5.64305, 4.30333, 2.42879] * u.km / u.s
    ss0 = State.from_vectors(Earth, r0, v0)
    tof = 0 * u.s

    ss1 = ss0.propagate(tof)

    r, v = ss1.rv()

    assert_array_almost_equal(r.value, r0.value)
    assert_array_almost_equal(v.value, v0.value)
Пример #18
0
def test_convert_from_rv_to_coe():
    # Data from Vallado, example 2.6
    attractor = Earth
    p = 11067.790 * u.km
    ecc = 0.83285 * u.one
    inc = 87.87 * u.deg
    raan = 227.89 * u.deg
    argp = 53.38 * u.deg
    nu = 92.335 * u.deg
    expected_r = [6525.344, 6861.535, 6449.125]  # km
    expected_v = [4.902276, 5.533124, -1.975709]  # km / s
    r, v = State.from_classical(Earth, p, ecc, inc, raan, argp, nu).rv()
    assert_array_almost_equal(r.value, expected_r, decimal=1)
    assert_array_almost_equal(v.value, expected_v, decimal=5)
Пример #19
0
def test_hohmann_maneuver():
    # Data from Vallado, example 6.1
    alt_i = 191.34411 * u.km
    alt_f = 35781.34857 * u.km
    ss_i = State.circular(Earth, alt_i)
    expected_dv = 3.935224 * u.km / u.s
    expected_t_trans = 5.256713 * u.h
    man = Maneuver.hohmann(ss_i, Earth.R + alt_f)
    assert_almost_equal(ss_i.apply_maneuver(man).ecc, 0)
    assert_almost_equal(man.get_total_cost().to(u.km / u.s).value,
                        expected_dv.value,
                        decimal=5)
    assert_almost_equal(man.get_total_time().to(u.h).value,
                        expected_t_trans.value,
                        decimal=5)
Пример #20
0
def test_state_has_individual_elements():
    a = 1.523679 * u.AU
    ecc = 0.093315 * u.one
    p = a * (1 - ecc**2)
    inc = 1.85 * u.deg
    raan = 49.562 * u.deg
    argp = 286.537 * u.deg
    nu = 23.33 * u.deg
    ss = State.from_classical(Sun, p, ecc, inc, raan, argp, nu)
    assert ss.a == a
    assert ss.ecc == ecc
    assert ss.inc == inc
    assert ss.raan == raan
    assert ss.argp == argp
    assert ss.nu == nu
Пример #21
0
def test_bielliptic_maneuver():
    # Data from Vallado, example 6.2
    alt_i = 191.34411 * u.km
    alt_b = 503873.0 * u.km
    alt_f = 376310.0 * u.km
    ss_i = State.circular(Earth, alt_i)
    expected_dv = 3.904057 * u.km / u.s
    expected_t_trans = 593.919803 * u.h
    man = Maneuver.bielliptic(ss_i, Earth.R + alt_b, Earth.R + alt_f)
    assert_almost_equal(ss_i.apply_maneuver(man).ecc, 0)
    assert_almost_equal(man.get_total_cost().to(u.km / u.s).value,
                        expected_dv.value,
                        decimal=5)
    assert_almost_equal(man.get_total_time().to(u.h).value,
                        expected_t_trans.value,
                        decimal=2)
Пример #22
0
# coding: utf-8
"""Example data.

"""

from astropy import time
from astropy import units as u

from poliastro.bodies import Earth
from poliastro.twobody import State

# Taken from Plyades (c) 2012 Helge Eichhorn (MIT License)
iss = State.from_vectors(Earth,
                         [8.59072560e2, -4.13720368e3, 5.29556871e3] * u.km,
                         [7.37289205, 2.08223573, 4.39999794e-1] * u.km / u.s,
                         time.Time("2013-03-18 12:00", scale='utc'))

molniya = State.from_classical(Earth,
                               26600 * u.km, 0.75 * u.one, 63.4 * u.deg,
                               0 * u.deg, 270 * u.deg, 80 * u.deg)
Пример #23
0
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)

times_rest = time.Time(jd_vec_rest, format='jd')
rr_earth_rest, _ = ephem.planet_ephem(ephem.EARTH, times_rest)
Пример #24
0
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)

times_rest = time.Time(jd_vec_rest, format='jd')
rr_earth_rest, _ = ephem.planet_ephem(ephem.EARTH, times_rest)
Пример #25
0
def test_geosync_has_proper_period():
    expected_period = 1436  # min
    ss = State.circular(Earth, alt=42164 * u.km - Earth.R)
    assert_almost_equal(ss.period.to(u.min).value, expected_period, decimal=0)
Пример #26
0
def test_circular_has_proper_semimajor_axis():
    alt = 500 * u.km
    attractor = Earth
    expected_a = Earth.R + alt
    ss = State.circular(attractor, alt)
    assert ss.a == expected_a
Пример #27
0
def test_state_has_rv_given_in_constructor():
    r = [1.0, 0.0, 0.0] * u.AU
    v = [0.0, 1.0e-6, 0.0] * u.AU / u.s
    ss = State.from_vectors(Sun, r, v)
    assert ss.rv() == (r, v)
Пример #28
0
def create_states(attractor, rad_init, rad_final, unit):
    ssi = State.circular(attractor, alt=rad_init.value * unit)
    hoh = Maneuver.hohmann(ssi, r_f=rad_final.value * unit)
    ssa, ssf = ssi.apply_maneuver(hoh, intermediate=True)
    return ssi, ssa, ssf, hoh
Пример #29
0
def test_state_has_attractor_given_in_constructor():
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    ss = State.from_classical(Sun, _d, _, _a, _a, _a, _a)
    assert ss.attractor == Sun