Example #1
0
def test_solar_pressure():
    # based on example 12.9 from Howard Curtis
    solar_system_ephemeris.set('de432s')

    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_as, delta_eccs, delta_incs, delta_raans, delta_argps, delta_hs = [], [], [], [], [], []
    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 #2
0
def test_propagate_with_lunar_third_body():
    x = [66666, 0, 0, 0, 2.451, 0]
    dt = 8600
    r = x[0:3] * u.km
    v = x[3:6] * u.km / u.s
    epoch = Time(2454283.0, format="jd", scale="tdb")
    epoch_f = epoch + (dt * u.s)
    prop_params = PropParams(epoch)
    prop_params.add_perturbation(Perturbations.Moon,
                                 build_lunar_third_body(epoch))

    k_moon = Moon.k.to(u.km**3 / u.s**2).value
    body_moon = build_ephem_interpolant(
        Moon,
        lunar_period, (epoch.value * u.day, epoch.value * u.day + 60 * u.day),
        rtol=1e-2)
    sat_i = Orbit.from_vectors(Earth, r, v, epoch=epoch)
    sat_f = sat_i.cov_propagate(dt * u.s,
                                method=cowell,
                                ad=third_body,
                                k_third=k_moon,
                                third_body=body_moon)
    x_poli = np.concatenate([sat_f.r.value, sat_f.v.value])

    x_custom = state_propagate(np.array(x), epoch_f, prop_params)
    assert np.array_equal(x_custom, x_poli)
Example #3
0
def test_3rd_body_Curtis(test_params):
    # based on example 12.11 from Howard Curtis
    body = test_params['body']
    solar_system_ephemeris.set('de432s')

    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 #4
0
def test_propagate_with_srp():
    x = [66666, 0, 0, 0, 2.451, 0]
    dt = 1 * u.day
    r = x[0:3] * u.km
    v = x[3:6] * u.km / u.s
    epoch = Time(2454283.0, format="jd", scale="tdb")
    epoch_obs = epoch + dt
    C_R = 1
    A = 10
    m = 1000
    srp = build_srp(C_R, A, m, epoch)
    prop_params = PropParams(epoch)
    prop_params.add_perturbation(Perturbations.SRP, srp)

    body_sun = build_ephem_interpolant(
        Sun,
        solar_period, (epoch.value * u.day, epoch.value * u.day + 60 * u.day),
        rtol=1e-2)

    sat_i = Orbit.from_vectors(Earth, r, v, epoch=epoch)
    sat_f = sat_i.cov_propagate(dt,
                                method=cowell,
                                ad=radiation_pressure,
                                R=R,
                                C_R=C_R,
                                A=A,
                                m=m,
                                Wdivc_s=Wdivc_sun.value,
                                star=body_sun)
    x_poli = np.concatenate([sat_f.r.value, sat_f.v.value])

    x_custom = state_propagate(x, epoch_obs, prop_params)
    assert np.array_equal(x_custom, x_poli)
Example #5
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 #6
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 #7
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)
        rr, vv = cowell(
            Earth.k,
            initial.r,
            initial.v,
            np.linspace(0, tof, 400) * u.s,
            rtol=1e-10,
            ad=third_body,
            k_third=body.k.to(u.km**3 / u.s**2).value,
            perturbation_body=body_r,
        )

        incs, raans, argps = [], [], []
        for ri, vi in zip(rr.to(u.km).value, vv.to(u.km / u.s).value):
            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,
        )
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)
        rr, vv = cowell(
            Earth.k,
            initial.r,
            initial.v,
            np.linspace(0, tof, 400) * u.s,
            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(rr.to(u.km).value, vv.to(u.km / u.s).value):
            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 #9
0
def build_srp(c_r, a, m, epoch, rtol=1e-2) -> SRP:
    """
    Build Solar Radiation Object used in perturbation.
    :param c_r: Comparable to coefficient of Drag but for radiation pressure. Unitless
    :param a: Cross sectional area exposed to radiation pressure. Units [m^2]
    :param m: Mass of the satellite.  Units [kg]
    :param epoch: Time required to interpolate solar position
    :param rtol: determines number of points generated. Drives the time of execution significantly. Example online used
    rtol=1e-2. A smaller number is not accepted. Could be increased for more accuracy, that being said, the position of
    the Sun does not need to be that accurate.
    """
    body_sun = build_ephem_interpolant(Sun, 1 * u.year, (epoch.value * u.day, epoch.value * u.day + 60 * u.day),
                                       rtol=rtol)
    return SRP(R, c_r, a, m, Wdivc_sun.value, body_sun)
Example #10
0
def build_solar_third_body(epoch: Time, rtol=1e-2) -> ThirdBody:
    """
    This function creates a callable Sun object for third_body and SRP perturbation. Over long periods of integration,
    this may longer prove to be an accurate description. Needs to be investigated.
    :param epoch:   The time about which the interpolating function is created.
    :param rtol: determines number of points generated. Drives the time of execution significantly. Example online used
    rtol=1e-2. A smaller number is not accepted. Could be increased for more accuracy, that being said, the position of
    the Sun does not need to be that accurate.
    :return: Returns callable object that describes the Sun's position
    """
    k_sun = Sun.k.to(u.km ** 3 / u.s ** 2).value
    body_sun = build_ephem_interpolant(Sun, solar_period, (epoch.value * u.day, epoch.value * u.day + 60 * u.day),
                                       rtol=rtol)
    return ThirdBody(k_sun, body_sun)
Example #11
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))
Example #12
0
def sun_r():
    j_date = 2_438_400.5 * u.day
    tof = 600 * u.day
    return build_ephem_interpolant(Sun,
                                   365 * u.day, (j_date, j_date + tof),
                                   rtol=1e-2)
Example #13
0
# ### 3rd body
#
# Apart from time-independent perturbations such as atmospheric drag, J2/J3, we have time-dependend perturbations. Lets's see how Moon changes the orbit of GEO satellite over time!

# In[9]:

# database keeping positions of bodies in Solar system over time
solar_system_ephemeris.set("de432s")

epoch = Time(2454283.0, format="jd",
             scale="tdb")  # setting the exact event date is important

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

initial = Orbit.from_classical(
    Earth,
    42164.0 * u.km,
    0.0001 * u.one,
    1 * u.deg,
    0.0 * u.deg,
    0.0 * u.deg,
    0.0 * u.rad,
    epoch=epoch,
)

tofs = TimeDelta(np.linspace(0, 60 * u.day, num=1000))