Example #1
0
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
Example #2
0
def test_sso_disposal_numerical(ecc_0, ecc_f):
    a_0 = Earth.R.to(u.km).value + 900  # km
    f = 2.4e-7  # km / s2, assumed constant

    k = Earth.k.decompose([u.km, u.s]).value

    _, t_f = extra_quantities(k, a_0, ecc_0, ecc_f, f)

    # Retrieve r and v from initial orbit
    s0 = Orbit.from_classical(Earth, a_0 * u.km, ecc_0 * u.one,
                              0 * u.deg, 0 * u.deg, 0 * u.deg, 0 * u.deg)
    r0, v0 = s0.rv()

    optimal_accel = guidance_law(s0, ecc_f, f)

    # Propagate orbit
    r, v = cowell(k,
                  r0.to(u.km).value,
                  v0.to(u.km / u.s).value,
                  t_f,
                  ad=optimal_accel,
                  nsteps=1000000)

    sf = Orbit.from_vectors(Earth,
                            r * u.km,
                            v * u.km / u.s,
                            s0.epoch + t_f * u.s)

    assert_allclose(sf.ecc.value, ecc_f, rtol=1e-4, atol=1e-4)
Example #3
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 = Orbit.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,
                  ad=constant_accel)

    ss_final = Orbit.from_vectors(Earth,
                       r * u.km,
                       v * u.km / u.s)

    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)
Example #4
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 = Orbit.circular(Earth, 500 * u.km)
    tof = 20 * ss.period

    r, v = cowell(ss,
                  tof.to(u.s).value,
                  ad=constant_accel)

    ss_final = Orbit.from_vectors(
        Earth, r * u.km, v * u.km / u.s)

    da_a0 = (ss_final.a - ss.a) / ss.a
    dv_v0 = abs(norm(ss_final.v) - norm(ss.v)) / norm(ss.v)
    assert_quantity_allclose(da_a0, 2 * dv_v0, rtol=1e-2)

    dv = abs(norm(ss_final.v) - norm(ss.v))
    accel_dt = accel * u.km / u.s**2 * tof
    assert_quantity_allclose(dv, accel_dt, rtol=1e-2)
Example #5
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:
        Orbit.from_vectors(Sun, _d, wrong_v)
    assert ("UnitsError: Argument 'v' to function 'from_vectors' must be in units convertible to 'm / s'."
            in excinfo.exconly())
Example #6
0
def test_leo_geo_numerical(inc_0):
    edelbaum_accel = guidance_law(k, a_0, a_f, inc_0, inc_f, f)

    _, t_f = extra_quantities(k, a_0, a_f, inc_0, inc_f, f)

    # Retrieve r and v from initial orbit
    s0 = Orbit.circular(Earth, a_0 * u.km - Earth.R, inc_0 * u.rad)
    r0, v0 = s0.rv()

    # Propagate orbit
    r, v = cowell(k,
                  r0.to(u.km).value,
                  v0.to(u.km / u.s).value,
                  t_f,
                  ad=edelbaum_accel,
                  nsteps=1000000)

    sf = Orbit.from_vectors(Earth,
                            r * u.km,
                            v * u.km / u.s,
                            s0.epoch + t_f * u.s)

    assert_allclose(sf.a.to(u.km).value, a_f, rtol=1e-5)
    assert_allclose(sf.ecc.value, 0.0, atol=1e-2)
    assert_allclose(sf.inc.to(u.rad).value, inc_f, atol=1e-3)
Example #7
0
def test_parabolic_elements_fail_early():
    attractor = Earth
    ecc = 1.0 * u.one
    _d = 1.0 * u.AU  # Unused distance
    _a = 1.0 * u.deg  # Unused angle
    with pytest.raises(ValueError) as excinfo:
        Orbit.from_classical(attractor, _d, ecc, _a, _a, _a, _a)
    assert ("ValueError: For parabolic orbits use Orbit.parabolic instead" in excinfo.exconly())
Example #8
0
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)
Example #9
0
def test_bad_hyperbolic_raises_exception():
    bad_a = 1.0 * u.AU
    ecc = 1.5 * u.one
    _a = 1.0 * u.deg  # Unused angle
    _inc = 100 * u.deg  # Unused inclination
    _body = Sun  # Unused body
    with pytest.raises(ValueError) as excinfo:
        Orbit.from_classical(_body, bad_a, ecc, _inc, _a, _a, _a)
    assert ("Hyperbolic orbits have negative semimajor axis" in excinfo.exconly())
Example #10
0
def test_bad_inclination_raises_exception():
    _d = 1.0 * u.AU  # Unused distance
    _ = 0.5 * u.one  # Unused dimensionless value
    _a = 1.0 * u.deg  # Unused angle
    bad_inc = 200 * u.deg
    _body = Sun  # Unused body
    with pytest.raises(ValueError) as excinfo:
        Orbit.from_classical(_body, _d, _, bad_inc, _a, _a, _a)
    assert ("ValueError: Inclination must be between 0 and 180 degrees" in excinfo.exconly())
Example #11
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:
        Orbit.from_classical(Sun, _d, _, _a, _a, _a, wrong_angle)
    assert ("UnitsError: Argument 'nu' to function 'from_classical' must be in units convertible to 'rad'."
            in excinfo.exconly())
Example #12
0
def test_mean_motion(ecc):
    _a = 0.0 * u.rad
    tof = 1.0 * u.min
    if ecc < 1.0:
        orbit = Orbit.from_classical(Earth, 10000 * u.km, ecc * u.one, _a, _a, _a, 1.0 * u.rad)
    else:
        orbit = Orbit.from_classical(Earth, -10000 * u.km, ecc * u.one, _a, _a, _a, 1.0 * u.rad)
    orbit_cowell = orbit.propagate(tof, method=cowell)
    orbit_mean_motion = orbit.propagate(tof, method=mean_motion)

    assert_quantity_allclose(orbit_cowell.r, orbit_mean_motion.r)
    assert_quantity_allclose(orbit_cowell.v, orbit_mean_motion.v)
Example #13
0
def test_propagation_mean_motion_parabolic():
    # example from Howard Curtis (3rd edition), section 3.5, problem 3.15
    p = 2.0 * 6600 * u.km
    _a = 0.0 * u.deg
    orbit = Orbit.parabolic(Earth, p, _a, _a, _a, _a)
    orbit = orbit.propagate(0.8897 / 2.0 * u.h, method=mean_motion)

    _, _, _, _, _, nu0 = rv2coe(Earth.k.to(u.km**3 / u.s**2).value,
                                orbit.r.to(u.km).value,
                                orbit.v.to(u.km / u.s).value)
    assert_quantity_allclose(nu0, np.deg2rad(90.0), rtol=1e-4)

    orbit = Orbit.parabolic(Earth, p, _a, _a, _a, _a)
    orbit = orbit.propagate(36.0 * u.h, method=mean_motion)
    assert_quantity_allclose(norm(orbit.r), 304700.0 * u.km, rtol=1e-4)
Example #14
0
def test_propagating_to_certain_nu_is_correct():
    # take an elliptic orbit
    a = 1.0 * u.AU
    ecc = 1.0 / 3.0 * u.one
    _a = 0.0 * u.rad
    nu = 10 * u.deg
    elliptic = Orbit.from_classical(Sun, a, ecc, _a, _a, _a, nu)

    elliptic_at_perihelion = elliptic.propagate_to_anomaly(0.0 * u.rad)
    r_per, _ = elliptic_at_perihelion.rv()

    elliptic_at_aphelion = elliptic.propagate_to_anomaly(np.pi * u.rad)
    r_ap, _ = elliptic_at_aphelion.rv()

    assert_quantity_allclose(norm(r_per), a * (1.0 - ecc))
    assert_quantity_allclose(norm(r_ap), a * (1.0 + ecc))

    # TODO: Test specific values
    assert elliptic_at_perihelion.epoch > elliptic.epoch
    assert elliptic_at_aphelion.epoch > elliptic.epoch

    # test 10 random true anomaly values
    for _ in range(10):
        nu = np.random.uniform(low=0.0, high=2 * np.pi)
        elliptic = elliptic.propagate_to_anomaly(nu * u.rad)
        r, _ = elliptic.rv()
        assert_quantity_allclose(norm(r), a * (1.0 - ecc ** 2) / (1 + ecc * np.cos(nu)))
Example #15
0
def test_soyuz_standard_gto_numerical():
    # Data from Soyuz Users Manual, issue 2 revision 0
    r_a = (Earth.R + 35950 * u.km).to(u.km).value
    r_p = (Earth.R + 250 * u.km).to(u.km).value

    a = (r_a + r_p) / 2  # km
    ecc = r_a / a - 1
    argp_0 = (178 * u.deg).to(u.rad).value  # rad
    argp_f = (178 * u.deg + 5 * u.deg).to(u.rad).value  # rad
    f = 2.4e-7  # km / s2

    k = Earth.k.to(u.km**3 / u.s**2).value

    a_d, _, t_f = change_argp(k, a, ecc, argp_0, argp_f, f)

    # Retrieve r and v from initial orbit
    s0 = Orbit.from_classical(
        Earth,
        a * u.km, (r_a / a - 1) * u.one, 6 * u.deg,
        188.5 * u.deg, 178 * u.deg, 0 * u.deg
    )

    # Propagate orbit
    sf = s0.propagate(t_f * u.s, method=cowell, ad=a_d, rtol=1e-8)

    assert_allclose(sf.argp.to(u.rad).value, argp_f, rtol=1e-4)
Example #16
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 = Orbit.parabolic(attractor, _d, _a, _a, _a, _a)
    assert_almost_equal(ss.energy.value, 0.0)
Example #17
0
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_results_array(a, ecc_0, ecc_f, inc_0, inc_f, argp, f):
    k = Earth.k.decompose([u.km, u.s]).value

    _, _, t_f = extra_quantities(k, a, ecc_0, ecc_f, inc_0, inc_f, argp, f)

    # Retrieve r and v from initial orbit
    s0 = Orbit.from_classical(
        Earth,
        a * u.km, ecc_0 * u.one, inc_0 * u.deg,
        0 * u.deg, argp * u.deg, 0 * u.deg
    )
    r0, v0 = s0.rv()

    combined_ei_accel = guidance_law(s0, ecc_f, inc_f, f)

    # Propagate orbit
    with ProgressResultsCallback(t_f) as res:
        cowell(
            k, r0.to(u.km).value, v0.to(u.km / u.s).value, t_f,
            ad=combined_ei_accel,
            callback=res,
            nsteps=1000000
        )

    return res.get_results()  # ~70 k rows, 7 columns, 3 MB in memory
Example #19
0
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()
Example #20
0
def test_J2_propagation_Earth():
    # from Curtis example 12.2:
    r0 = np.array([-2384.46, 5729.01, 3050.46])  # km
    v0 = np.array([-7.36138, -2.98997, 1.64354])  # km/s

    orbit = Orbit.from_vectors(Earth, r0 * u.km, v0 * u.km / u.s)

    tofs = [48.0] * u.h
    rr, vv = cowell(
        Earth.k,
        orbit.r,
        orbit.v,
        tofs,
        ad=J2_perturbation,
        J2=Earth.J2.value,
        R=Earth.R.to(u.km).value,
    )

    k = Earth.k.to(u.km ** 3 / u.s ** 2).value

    _, _, _, raan0, argp0, _ = rv2coe(k, r0, v0)
    _, _, _, raan, argp, _ = rv2coe(k, rr[0].to(u.km).value, vv[0].to(u.km / u.s).value)

    raan_variation_rate = (raan - raan0) / tofs[0].to(u.s).value
    argp_variation_rate = (argp - argp0) / tofs[0].to(u.s).value

    raan_variation_rate = (raan_variation_rate * u.rad / u.s).to(u.deg / u.h)
    argp_variation_rate = (argp_variation_rate * u.rad / u.s).to(u.deg / u.h)

    assert_quantity_allclose(raan_variation_rate, -0.172 * u.deg / u.h, rtol=1e-2)
    assert_quantity_allclose(argp_variation_rate, 0.282 * u.deg / u.h, rtol=1e-2)
Example #21
0
def test_cowell_works_with_small_perturbations():
    r0 = [-2384.46, 5729.01, 3050.46] * u.km
    v0 = [-7.36138, -2.98997, 1.64354] * u.km / u.s

    r_expected = [
        13179.39566663877121754922,
        -13026.25123408228319021873,
        -9852.66213692844394245185,
    ] * u.km
    v_expected = (
        [2.78170542314378943516, 3.21596786944631274352, 0.16327165546278937791]
        * u.km
        / u.s
    )

    initial = Orbit.from_vectors(Earth, r0, v0)

    def accel(t0, state, k):
        v_vec = state[3:]
        norm_v = (v_vec * v_vec).sum() ** 0.5
        return 1e-5 * v_vec / norm_v

    final = initial.propagate(3 * u.day, method=cowell, ad=accel)

    assert_quantity_allclose(final.r, r_expected)
    assert_quantity_allclose(final.v, v_expected)
Example #22
0
def test_3rd_body_Curtis(test_params):
    # based on example 12.11 from Howard Curtis
    body = test_params['body']
    with solar_system_ephemeris.set('builtin'):
        j_date = 2454283.0 * u.day
        tof = (test_params['tof']).to(u.s).value
        body_r = build_ephem_interpolant(body, test_params['period'], (j_date, j_date + test_params['tof']), rtol=1e-2)

        epoch = Time(j_date, format='jd', scale='tdb')
        initial = Orbit.from_classical(Earth, *test_params['orbit'], epoch=epoch)
        r, v = cowell(initial, np.linspace(0, tof, 400), rtol=1e-10, ad=third_body,
                      k_third=body.k.to(u.km**3 / u.s**2).value, third_body=body_r)

        incs, raans, argps = [], [], []
        for ri, vi in zip(r, v):
            angles = Angle(rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi)[2:5] * u.rad)  # inc, raan, argp
            angles = angles.wrap_at(180 * u.deg)
            incs.append(angles[0].value)
            raans.append(angles[1].value)
            argps.append(angles[2].value)

        # averaging over 5 last values in the way Curtis does
        inc_f, raan_f, argp_f = np.mean(incs[-5:]), np.mean(raans[-5:]), np.mean(argps[-5:])

        assert_quantity_allclose([(raan_f * u.rad).to(u.deg) - test_params['orbit'][3],
                                  (inc_f * u.rad).to(u.deg) - test_params['orbit'][2],
                                  (argp_f * u.rad).to(u.deg) - test_params['orbit'][4]],
                                 [test_params['raan'], test_params['inc'], test_params['argp']],
                                 rtol=1e-1)
Example #23
0
def test_orbit_accepts_ecliptic_plane():
    r = [1E+09, -4E+09, -1E+09] * u.km
    v = [5E+00, -1E+01, -4E+00] * u.km / u.s

    ss = Orbit.from_vectors(Sun, r, v, plane=Planes.EARTH_ECLIPTIC)

    assert ss.frame.is_equivalent_frame(HeliocentricEclipticJ2000(obstime=J2000))
Example #24
0
def test_atmospheric_drag():
    # http://farside.ph.utexas.edu/teaching/celestial/Celestialhtml/node94.html#sair (10.148)
    # given the expression for \dot{r} / r, aproximate \Delta r \approx F_r * \Delta t

    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value

    # parameters of a circular orbit with h = 250 km (any value would do, but not too small)
    orbit = Orbit.circular(Earth, 250 * u.km)
    r0, _ = orbit.rv()
    r0 = r0.to(u.km).value

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    # parameters of the atmosphere
    rho0 = Earth.rho0.to(u.kg / u.km**3).value  # kg/km^3
    H0 = Earth.H0.to(u.km).value
    tof = 100000  # s

    dr_expected = -B * rho0 * np.exp(-(norm(r0) - R) / H0) * np.sqrt(k * norm(r0)) * tof
    # assuming the atmospheric decay during tof is small,
    # dr_expected = F_r * tof (Newton's integration formula), where
    # F_r = -B rho(r) |r|^2 sqrt(k / |r|^3) = -B rho(r) sqrt(k |r|)

    r, v = cowell(orbit, tof, ad=atmospheric_drag, R=R, C_D=C_D, A=A, m=m, H0=H0, rho0=rho0)

    assert_quantity_allclose(norm(r) - norm(r0), dr_expected, rtol=1e-2)
Example #25
0
def test_parabolic_has_proper_eccentricity():
    attractor = Earth
    _d = 1.0 * u.AU  # Unused distance
    _a = 1.0 * u.deg  # Unused angle
    expected_ecc = 1.0 * u.one
    ss = Orbit.parabolic(attractor, _d, _a, _a, _a, _a)
    assert_allclose(ss.ecc, expected_ecc)
Example #26
0
def test_solar_pressure():
    # based on example 12.9 from Howard Curtis
    with solar_system_ephemeris.set('builtin'):
        j_date = 2438400.5 * u.day
        tof = 600 * u.day
        sun_r = build_ephem_interpolant(Sun, 365 * u.day, (j_date, j_date + tof), rtol=1e-2)
        epoch = Time(j_date, format='jd', scale='tdb')
        drag_force_orbit = [10085.44 * u.km, 0.025422 * u.one, 88.3924 * u.deg,
                            45.38124 * u.deg, 227.493 * u.deg, 343.4268 * u.deg]

        initial = Orbit.from_classical(Earth, *drag_force_orbit, epoch=epoch)
        # in Curtis, the mean distance to Sun is used. In order to validate against it, we have to do the same thing
        sun_normalized = functools.partial(normalize_to_Curtis, sun_r=sun_r)

        r, v = cowell(initial, np.linspace(0, (tof).to(u.s).value, 4000), rtol=1e-8, ad=radiation_pressure,
                      R=Earth.R.to(u.km).value, C_R=2.0, A=2e-4, m=100, Wdivc_s=Sun.Wdivc.value, star=sun_normalized)

        delta_eccs, delta_incs, delta_raans, delta_argps = [], [], [], []
        for ri, vi in zip(r, v):
            orbit_params = rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi)
            delta_eccs.append(orbit_params[1] - drag_force_orbit[1].value)
            delta_incs.append((orbit_params[2] * u.rad).to(u.deg).value - drag_force_orbit[2].value)
            delta_raans.append((orbit_params[3] * u.rad).to(u.deg).value - drag_force_orbit[3].value)
            delta_argps.append((orbit_params[4] * u.rad).to(u.deg).value - drag_force_orbit[4].value)

        # averaging over 5 last values in the way Curtis does
        for check in solar_pressure_checks:
            index = int(1.0 * check['t_days'] / tof.to(u.day).value * 4000)
            delta_ecc, delta_inc, delta_raan, delta_argp = np.mean(delta_eccs[index - 5:index]), \
                np.mean(delta_incs[index - 5:index]), np.mean(delta_raans[index - 5:index]), \
                np.mean(delta_argps[index - 5:index])
            assert_quantity_allclose([delta_ecc, delta_inc, delta_raan, delta_argp],
                                     check['deltas_expected'], rtol=1e-1, atol=1e-4)
Example #27
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 = J2000
    ss = Orbit.from_classical(_body, _d, _, _a, _a, _a, _a)
    assert ss.epoch == expected_epoch
Example #28
0
def test_sample_numpoints():
    _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
    ss = Orbit.from_classical(_body, _d, _, _a, _a, _a, _a)
    positions = ss.sample(values=50)
    assert len(positions) == 50
Example #29
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 = Orbit.parabolic(attractor, _d, _a, _a, _a, _a)
    assert_almost_equal(ss.ecc, expected_ecc)
Example #30
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 = Orbit.from_classical(Sun, _d, _, _a, _a, _a, _a)
    dt = 1 * u.h
    dv = [0, 0, 0] * u.km / u.s
    orbit_new = ss.apply_maneuver([(dt, dv)])
    assert orbit_new.epoch == ss.epoch + dt
Example #31
0
def j3_earth(initial, time, f_time):  # perturbation for oblateness
    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value
    #s0 = Orbit.from_classical(Earth, x[0] * u.km, x[1] * u.one, x[4] * u.deg, * u.deg, x[3] * u.deg, 0 * u.deg, epoch=Time(0, format='jd', scale='tdb'))

    #orbit = Orbit.circular(
    #    Earth, 250 * u.km, epoch=Time(0.0, format="jd", scale="tdb"))

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    J3 = Earth.J3.value
    print(
        "Use default constants or you want to customize?\n1.Default.\n2.Custom."
    )
    check = input()
    if (check == '1'):
        pass
    else:
        J3 = input("Enter J3 constant:")
        R = input("Enter radius of earth in km:")

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    rr = propagate(initial,
                   tofs,
                   method=cowell,
                   ad=J3_perturbation,
                   J3=J3,
                   R=R)

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    print("")
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
	# a: semieix major
	# ecc: excentricitat
	# inc: inclinacio respecte la horizontal(sera 0 en totes les orbites 
	# 	ja que es troben en el mateix pla per guio del treball)
	# raan: inclinacio respecte la vertical
	# argp: argument del periheli
	# nu: posicio punt 

a = 0.999855 * u.AU
ecc = 0  * u.one
inc = 0 * u.deg
raan = 0 * u.deg
argp = 0 * u.deg
nu = 0 * u.deg

Terra = Orbit.from_classical(Sun, a, ecc, inc, raan, argp, nu)

a = 5.20336301 * u.AU
ecc = 0  * u.one
inc = 0 * u.deg
raan = 0 * u.deg
argp = 0 * u.deg
nu = 163 * u.deg

Jupiter = Orbit.from_classical(Sun, a, ecc, inc, raan, argp, nu)

a = 9.53707032 * u.AU
ecc = 0 * u.one
inc = 0 * u.deg
raan = 0 * u.deg
argp = 0 * u.deg
Example #33
0
"""Example data.

"""
from astropy import time, units as u

from poliastro.bodies import Earth, Sun
from poliastro.twobody import Orbit

iss = Orbit.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"),
)
"""ISS orbit example

Taken from Plyades (c) 2012 Helge Eichhorn (MIT License)

"""

molniya = Orbit.from_classical(Earth, 26600 * u.km, 0.75 * u.one, 63.4 * u.deg,
                               0 * u.deg, 270 * u.deg, 80 * u.deg)
"""Molniya orbit example"""

_r_a = Earth.R + 35950 * u.km
_r_p = Earth.R + 250 * u.km
_a = (_r_a + _r_p) / 2
soyuz_gto = Orbit.from_classical(Earth, _a, _r_a / _a - 1, 6 * u.deg,
                                 188.5 * u.deg, 178 * u.deg, 0 * u.deg)
"""Soyuz geostationary transfer orbit (GTO) example
Example #34
0
def get_vectors_from_orbit(ss: Orbit, delta_seconds: float) -> np.array:
    ss = ss.propagate(delta_seconds * u.s)
    return np.concatenate([ss.r.to_value(), ss.v.to_value()])
Example #35
0
def test_orbit_representation():
    ss = Orbit.circular(Earth, 600 * u.km, 20 * u.deg)
    expected_str = "6978 x 6978 km x 20.0 deg orbit around Earth (\u2641)"

    assert str(ss) == repr(ss) == expected_str
Example #36
0
def test_circular_has_proper_semimajor_axis():
    alt = 500 * u.km
    attractor = Earth
    expected_a = Earth.R + alt
    ss = Orbit.circular(attractor, alt)
    assert ss.a == expected_a
Example #37
0
from poliastro.twobody import Orbit
from poliastro.maneuver import Maneuver


# In[2]:


ZOOM = True

R = np.linspace(2, 75, num=100)
Rstar = [15.58, 40, 60, 100, 200, np.inf]

hohmann_data = np.zeros_like(R)
bielliptic_data = np.zeros((len(R), len(Rstar)))

ss_i = Orbit.circular(Earth, 1.8 * u.km)
r_i = ss_i.a
v_i = np.sqrt(ss_i.v.dot(ss_i.v))
for ii, r in enumerate(R):
    r_f = r * r_i
    man = Maneuver.hohmann(ss_i, r_f)
    hohmann_data[ii] = (man.get_total_cost() / v_i).decompose().value
    for jj, rstar in enumerate(Rstar):
        r_b = rstar * r_i
        man = Maneuver.bielliptic(ss_i, r_b, r_f)
        bielliptic_data[ii, jj] = (
            man.get_total_cost() / v_i).decompose().value

idx_max = np.argmax(hohmann_data)

ylims = (0.35, 0.6)
Example #38
0
def propagate_to_desc_node(o: Orbit):
    """ Propagates the orbit to the descending node."""
    _, dn, _, _ = calculate_nodes_dist(o)

    o_f = o.propagate_to_anomaly(dn)
    return o_f
Example #39
0
def propagate_to_asc_node(o: Orbit):
    """ Propagates the orbit to the ascending node."""
    an, _, _, __ = calculate_nodes_dist(o)

    o_f = o.propagate_to_anomaly(an)
    return o_f
Example #40
0
def test_solar_pressure(t_days, deltas_expected, sun_r):
    # based on example 12.9 from Howard Curtis
    with solar_system_ephemeris.set("builtin"):
        j_date = 2_438_400.5 * u.day
        tof = 600 * u.day
        epoch = Time(j_date, format="jd", scale="tdb")

        initial = Orbit.from_classical(
            Earth,
            10085.44 * u.km,
            0.025422 * u.one,
            88.3924 * u.deg,
            45.38124 * u.deg,
            227.493 * u.deg,
            343.4268 * u.deg,
            epoch=epoch,
        )
        # in Curtis, the mean distance to Sun is used. In order to validate against it, we have to do the same thing
        sun_normalized = functools.partial(normalize_to_Curtis, sun_r=sun_r)

        rr, vv = cowell(
            Earth.k,
            initial.r,
            initial.v,
            np.linspace(0, (tof).to(u.s).value, 4000) * u.s,
            rtol=1e-8,
            ad=radiation_pressure,
            R=Earth.R.to(u.km).value,
            C_R=2.0,
            A=2e-4,
            m=100,
            Wdivc_s=Wdivc_sun.value,
            star=sun_normalized,
        )

        delta_eccs, delta_incs, delta_raans, delta_argps = [], [], [], []
        for ri, vi in zip(rr.to(u.km).value, vv.to(u.km / u.s).value):
            orbit_params = rv2coe(Earth.k.to(u.km**3 / u.s**2).value, ri, vi)
            delta_eccs.append(orbit_params[1] - initial.ecc.value)
            delta_incs.append((orbit_params[2] * u.rad).to(u.deg).value -
                              initial.inc.value)
            delta_raans.append((orbit_params[3] * u.rad).to(u.deg).value -
                               initial.raan.value)
            delta_argps.append((orbit_params[4] * u.rad).to(u.deg).value -
                               initial.argp.value)

        # averaging over 5 last values in the way Curtis does
        index = int(1.0 * t_days / tof.to(u.day).value * 4000  # type: ignore
                    )
        delta_ecc, delta_inc, delta_raan, delta_argp = (
            np.mean(delta_eccs[index - 5:index]),
            np.mean(delta_incs[index - 5:index]),
            np.mean(delta_raans[index - 5:index]),
            np.mean(delta_argps[index - 5:index]),
        )
        assert_quantity_allclose(
            [delta_ecc, delta_inc, delta_raan, delta_argp],
            deltas_expected,
            rtol=1e0,  # TODO: Excessively low, rewrite test?
            atol=1e-4,
        )
Example #41
0
def test_sample_big_orbits(method):
    # See https://github.com/poliastro/poliastro/issues/265
    ss = Orbit.from_vectors(Sun, [-9018878.6, -94116055, 22619059] * u.km,
                            [-49.950923, -12.948431, -4.2925158] * u.km / u.s)
    times, positions = ss.sample(15, method=method)
    assert len(times) == len(positions) == 15
Example #42
0
def atmd_earth(initial, time, f_time):  # perturbation for atmospheric drag
    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value
    #s0 = Orbit.from_classical(Earth, x[0] * u.km, x[1] * u.one, x[4] * u.deg, * u.deg, x[3] * u.deg, 0 * u.deg, epoch=Time(0, format='jd', scale='tdb'))

    #orbit = Orbit.circular(
    #    Earth, 250 * u.km, epoch=Time(0.0, format="jd", scale="tdb"))

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    # parameters of the atmosphere
    rho0 = Earth.rho0.to(u.kg / u.km**3).value  # kg/km^3
    H0 = Earth.H0.to(u.km).value

    print(
        "Use default constants or you want to customize?\n1.Default.\n2.Custom."
    )
    check = input()
    if (check == '1'):
        pass
    else:
        m = input("Enter mass of the body in kg:")
        R = input("Enter radius of earth in km:")
        C_D = input("Enter C_D(dimension):")
        H0 = input("Enter atmospheric parameter H0:")
        #rho0=input("Enter atmospheric parameter rho0:")
        R = R * u.km
        H0 = H0 * u.km
        #rho0=rho0*(u.kg / u.km ** 3)

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    #print("tofs:")
    #print(tofs)
    #print("ie:")
    #print(initial.epoch.iso)
    rr = propagate(
        initial,
        tofs,
        method=cowell,
        ad=atmospheric_drag,
        R=R,
        C_D=C_D,
        A=A,
        m=m,
        H0=H0,
        rho0=rho0,
    )

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    print("")
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
Example #43
0
def custom(initial, choice, state, time,
           f_time):  # requires modification and validation
    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value
    #s0 = Orbit.from_classical(Earth, x[0] * u.km, x[1] * u.one, x[4] * u.deg, * u.deg, x[3] * u.deg, 0 * u.deg, epoch=Time(0, format='jd', scale='tdb'))

    #orbit = Orbit.circular(
    #    Earth, 250 * u.km, epoch=Time(0.0, format="jd", scale="tdb"))

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    # parameters of the atmosphere
    rho0 = Earth.rho0.to(u.kg / u.km**3).value  # kg/km^3
    H0 = Earth.H0.to(u.km).value

    #J2,J3 parameters
    J3 = Earth.J3.value
    J2 = Earth.J2.value

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    if (choice == '7'):

        rr = propagate(
            initial,
            tofs,
            method=cowell,
            ad=accel,
            #k=k,
        )

    elif (choice == '5'):

        rr = propagate(
            initial,
            tofs,
            method=cowell,
            ad=a_d_1,
            #k=k,
            J2=J2,
            R=R,
            C_D=C_D,
            A=A,
            m=m,
            H0=H0,
            rho0=rho0)

    elif (choice == '6'):

        rr = propagate(
            initial,
            tofs,
            method=cowell,
            ad=a_d_2,
            #k=k,
            J3=J3,
            R=R,
            C_D=C_D,
            A=A,
            m=m,
            H0=H0,
            rho0=rho0)

    else:
        pass

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    print("")
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
Example #44
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)
Example #45
0
def test_geosync_has_proper_period():
    expected_period = 1436 * u.min

    ss = Orbit.circular(Earth, alt=42164 * u.km - Earth.R)

    assert_quantity_allclose(ss.period, expected_period, rtol=1e-4)
Example #46
0
def halley():
    return Orbit.from_vectors(
        Sun,
        [-9018878.63569932, -94116054.79839276, 22619058.69943215] * u.km,
        [-49.95092305, -12.94843055, -4.29251577] * u.km / u.s,
    )
Example #47
0
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.Time.now() - ss.epoch).sec < 1
Example #48
0
"""Example data.

"""
from astropy import time, units as u

from poliastro.bodies import Earth, Sun
from poliastro.twobody import Orbit

iss = Orbit.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"),
)
"""ISS orbit example

Taken from Plyades (c) 2012 Helge Eichhorn (MIT License)

"""

molniya = Orbit.from_classical(
    attractor=Earth,
    a=26600 * u.km,
    ecc=0.75 * u.one,
    inc=63.4 * u.deg,
    raan=0 * u.deg,
    argp=270 * u.deg,
    nu=80 * u.deg,
)
"""Molniya orbit example"""
Example #49
0
julianday = np.empty([0])
i = 0
for i in range(yd.shape[1]):
    mon, day, hr, minute, sec = daysToMonDayHrMinSec(yd[0, i], yd[1, i])
    julianday = np.hstack(
        [julianday, jday(yd[0, i], mon, day, hr, minute, sec)])

epoch_tles = Time(julianday, format='jd', scale='ut1')

#Estimate mean state and state covariance from TLEs
nu = D_to_nu(coe[5, yd.shape[1] - 1])
Xf_tle_n = Orbit.from_classical(Earth,
                                coe[0, yd.shape[1] - 1] * u.m,
                                coe[1, yd.shape[1] - 1] * u.one,
                                coe[2, yd.shape[1] - 1] * u.deg,
                                coe[3, yd.shape[1] - 1] * u.deg,
                                coe[4, yd.shape[1] - 1] * u.deg,
                                nu * u.deg,
                                epoch=epoch_tles[yd.shape[1] - 1])

Xf_n = mean_motion(Earth.k, Xf_tle_n.r, Xf_tle_n.v,
                   np.linspace(0, 0, num=1) * u.s)
# fill orbit
i = 0
X_res = np.empty((6, 1))
for i in range(yd.shape[1] - 1):
    nu = D_to_nu(coe[5, i])
    X0_tle_i = Orbit.from_classical(Earth,
                                    coe[0, i] * u.m,
                                    coe[1, i] * u.one,
                                    coe[2, i] * u.deg,
Example #50
0
def get_orbital_elements_from_vectors(x, y, z, Vx, Vy, Vz, total_seconds):
    r = [x, y, z] * u.km
    v = [Vx, Vy, Vz] * u.km / u.s
    dt = datetime(2014, 1, 1) + timedelta(seconds=total_seconds)
    ss = Orbit.from_vectors(Earth, r, v, epoch=Time(dt))
    return ss
Example #51
0
def test_propagation_custom_body_works():
    # See https://github.com/poliastro/poliastro/issues/649
    orbit = Orbit.circular(Moon, 100 * u.km)
    orbit.propagate(1 * u.h)
Example #52
0
def test_J3_propagation_Earth(test_params):
    # Nai-ming Qi, Qilong Sun, Yong Yang, (2018) "Effect of J3 perturbation on satellite position in LEO",
    # Aircraft Engineering and  Aerospace Technology, Vol. 90 Issue: 1,
    # pp.74-86, https://doi.org/10.1108/AEAT-03-2015-0092
    a_ini = 8970.667 * u.km
    ecc_ini = 0.25 * u.one
    raan_ini = 1.047 * u.rad
    nu_ini = 0.0 * u.rad
    argp_ini = 1.0 * u.rad
    inc_ini = test_params['inc']

    k = Earth.k.to(u.km**3 / u.s**2).value

    orbit = Orbit.from_classical(Earth, a_ini, ecc_ini, inc_ini, raan_ini,
                                 argp_ini, nu_ini)

    tof = (10.0 * u.day).to(u.s).value
    r_J2, v_J2 = cowell(orbit,
                        np.linspace(0, tof, int(1e+3)),
                        ad=J2_perturbation,
                        J2=Earth.J2.value,
                        R=Earth.R.to(u.km).value,
                        rtol=1e-8)
    a_J2J3 = lambda t0, u_, k_: J2_perturbation(t0, u_, k_, J2=Earth.J2.value, R=Earth.R.to(u.km).value) + \
        J3_perturbation(t0, u_, k_, J3=Earth.J3.value, R=Earth.R.to(u.km).value)

    r_J3, v_J3 = cowell(orbit,
                        np.linspace(0, tof, int(1e+3)),
                        ad=a_J2J3,
                        rtol=1e-8)

    a_values_J2 = np.array([
        rv2coe(k, ri, vi)[0] / (1.0 - rv2coe(k, ri, vi)[1]**2)
        for ri, vi in zip(r_J2, v_J2)
    ])
    a_values_J3 = np.array([
        rv2coe(k, ri, vi)[0] / (1.0 - rv2coe(k, ri, vi)[1]**2)
        for ri, vi in zip(r_J3, v_J3)
    ])
    da_max = np.max(np.abs(a_values_J2 - a_values_J3))

    ecc_values_J2 = np.array(
        [rv2coe(k, ri, vi)[1] for ri, vi in zip(r_J2, v_J2)])
    ecc_values_J3 = np.array(
        [rv2coe(k, ri, vi)[1] for ri, vi in zip(r_J3, v_J3)])
    decc_max = np.max(np.abs(ecc_values_J2 - ecc_values_J3))

    inc_values_J2 = np.array(
        [rv2coe(k, ri, vi)[2] for ri, vi in zip(r_J2, v_J2)])
    inc_values_J3 = np.array(
        [rv2coe(k, ri, vi)[2] for ri, vi in zip(r_J3, v_J3)])
    dinc_max = np.max(np.abs(inc_values_J2 - inc_values_J3))

    assert_quantity_allclose(dinc_max,
                             test_params['dinc_max'],
                             rtol=1e-1,
                             atol=1e-7)
    assert_quantity_allclose(decc_max,
                             test_params['decc_max'],
                             rtol=1e-1,
                             atol=1e-7)
    try:
        assert_quantity_allclose(da_max * u.km, test_params['da_max'])
    except AssertionError as exc:
        pytest.xfail('this assertion disagrees with the paper')
Example #53
0
def get_orbit_from_orbital_elements(orbital_elements: np.array,
                                    seconds_from_01_01: float) -> Orbit:
    return Orbit.from_classical(Earth, orbital_elements[0] * u.km, orbital_elements[1] * u.one, orbital_elements[2] * u.rad, \
                                orbital_elements[3] * u.rad, orbital_elements[4] * u.rad, orbital_elements[5] * u.rad,\
                                epoch=Time(datetime(2014, 1, 1) + timedelta(seconds=seconds_from_01_01)))
a = 6878.137 * u.km
ecc = 0 * u.one
#inc = 0.872699533 * u.rad
#raan = 6.280724393 * u.rad
#argp = 0 * u.rad
#nu = 6.280986192 * u.rad
# noinspection PyUnresolvedReferences
inc = 50.002 * u.deg
# noinspection PyUnresolvedReferences
raan = 359.859 * u.deg
# noinspection PyUnresolvedReferences
argp = 0 * u.deg
# noinspection PyUnresolvedReferences
nu = 359.874 * u.deg
date_epoch = Time("2019-09-01 00:00", scale='utc')
ss = Orbit.from_classical(Earth, a, ecc, inc, raan, argp, nu, date_epoch)
# 2448122.5

# Simulation Loop Starts
for delta_t in range(0, 60000, 100):
    print("Quaternion after ", delta_t, "milliseconds is: "),
    for i in range(0, 4):
        q[i] = q[i] + (rate_of_change[i] * delta_t * 0.001)
    mod_q = math.sqrt(q[0]**2 + q[1]**2 + q[2]**2 + q[3]**2)
    for i in range(0, 4):
        q[i] = q[i] / mod_q
        print(" ", q[i], " "),
    print("")
    print()
    # q conjugate
    q_star = [q[0], -q[1], -q[2], -q[3]]
Example #55
0
from bodies import Earth, Sun
from poliastro.twobody import Orbit

from matplotlib import pylab as plt
import mpl_scatter_density

# Data for Mars at J2000 from JPL HORIZONS
a = 1.523679 * u.AU
#a = 1.0779 * u.AU
ecc = 0.093315 * u.one
inc = 1.85 * u.deg
raan = 49.562 * u.deg  #this is Right ascension of the ascending node
argp = 286.537 * u.deg
nu = 23.33 * u.deg  #True anomaly

mars = Orbit.from_classical(Sun, a, ecc, inc, raan, argp, nu)

#then plot
from poliastro.plotting import StaticOrbitPlotter
#op = OrbitPlotter()
#op.plot(mars, label="Mars")

#-----------
#plot multiple

#redefining the elements here, sorry that's sloppy

a = 1.0779 * u.AU
ecc = 0.8268 * u.one
inc = 22.852 * u.deg
raan = 88.0822 * u.deg
Example #56
0
            time_obj = Time(time, format="iso", scale="utc")
            time_p_obj = Time(time_p, format="iso", scale="utc")
            #print("chk:")
            #print(time_obj.tdb.jd)
            nu = time2truean(x0[0], x0[1], mu, time_obj.tdb.jd, x0[2])
            eccentric_anomaly = truean2eccan(x0[1], nu)

            nu = np.rad2deg(nu)
            kep_i = (x0[0], x0[1], x0[4], x0[3], x0[5], nu)
            kep_i = np.asarray(kep_i)
            initial_state = kep_state(kep_i.reshape(-1, 1))
            initial = Orbit.from_classical(Earth,
                                           x0[0] * u.km,
                                           x0[1] * u.one,
                                           x0[4] * u.deg,
                                           x0[5] * u.deg,
                                           x0[3] * u.deg,
                                           nu * u.deg,
                                           epoch=Time(time,
                                                      format='iso',
                                                      scale='utc'))

        else:
            obs_arr = [int(item) for item in args.obs_array.split(',')]
            x0 = gauss_method_sat(args.file_path,
                                  obs_arr=obs_arr,
                                  bodyname=args.body_name,
                                  r2_root_ind_vec=args.root_index,
                                  refiters=args.iterations,
                                  plot=False)
            time = Time(x0[7], format='jd').iso
Example #57
0
def third_body_moon(
        initial, time,
        f_time):  # propogate under perturbation of a third body(moon)

    # database keeping positions of bodies in Solar system over time
    x_ephem = "de432s"
    questions = [
        inquirer.List(
            'Ephemerides',
            message=
            "Select ephemerides[de432s(default,small in size,faster)','de430(more precise)]:",
            choices=['de432s', 'de430'],
        ),
    ]
    answers = inquirer.prompt(questions)

    x_ephem = answers["Ephemerides"]

    solar_system_ephemeris.set(x_ephem)

    #epoch = Time(time, format='iso', scale='utc')  # setting the exact event date is important
    epoch = Time(time, format='iso').jd
    f_time_1 = Time(f_time, format='iso').jd

    # create interpolant of 3rd body coordinates (calling in on every iteration will be just too slow)     #check
    body_r = build_ephem_interpolant(
        Moon,
        28 * u.day,
        (epoch * u.day, f_time_1 * u.day),
        rtol=1e-2  #check
    )

    k_third = Moon.k.to(u.km**3 / u.s**2).value
    x = 400
    print(
        "Use default constants or you want to customize?\n1.Default.\n2.Custom."
    )
    check = input()
    if (check == '1'):
        pass
    else:
        k_third = input("Enter moon's gravity:")
        x = input(
            "Multiply Moon's gravity by X times so that effect is visible,input X:"
        )

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    # multiply Moon gravity by x so that effect is visible :)
    rr = propagate(
        initial,
        tofs,
        method=cowell,
        rtol=1e-6,
        ad=third_body,
        k_third=x * k_third,
        third_body=body_r,
    )

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
date_launch = time.Time("2011-11-26 15:02", scale="utc").tdb
date_arrival = time.Time("2012-08-06 05:17", scale="utc").tdb

# To compute the transfer orbit, we have the useful function `lambert` : according to a theorem with the same name, *the transfer orbit between two points in space only depends on those two points and the time it takes to go from one to the other*. We could make use of the raw algorithms available in `poliastro.iod` for solving this but working with the `poliastro.maneuvers` is even easier!
#
# We just need to create the orbits for each one of the planets at the specific departure and arrival dates.

# In[5]:

earth = Ephem.from_body(Earth, time_range(date_launch, end=date_arrival))
mars = Ephem.from_body(Mars, time_range(date_launch, end=date_arrival))

# In[6]:

# Solve for departure and target orbits
ss_earth = Orbit.from_ephem(Sun, earth, date_launch)
ss_mars = Orbit.from_ephem(Sun, mars, date_arrival)

# We can now solve for the maneuver that will take us from Earth to Mars. After solving it, we just need to apply it to the departure orbit to solve for the transfer one.

# In[7]:

# Solve for the transfer maneuver
man_lambert = Maneuver.lambert(ss_earth, ss_mars)

# Get the transfer and final orbits
ss_trans, ss_target = ss_earth.apply_maneuver(man_lambert, intermediate=True)

# Let's plot this transfer orbit in 3D!

# In[8]:
# 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()
Example #60
0
def propagate_to_periapsis(o: Orbit):
    """ Propagate given orbit to its periapsis. """
    if o.nu != 0 * u.deg:
        o_f = o.propagate_to_anomaly(0 * u.deg)
        return o_f
    return o