Beispiel #1
0
 def f(t0, u_, k):
     du_kep = func_twobody(t0, u_, k)
     ax, ay, az = J2_perturbation(
         t0, u_, k, J2=Earth.J2.value, R=Earth.R.to(u.km).value
     )
     du_ad = np.array([0, 0, 0, ax, ay, az])
     return du_kep + du_ad
    def setup(self):
        from poliastro.twobody import Orbit

        self.a_ini = 8970.667 * u.km
        self.ecc_ini = 0.25 * u.one
        self.raan_ini = 1.047 * u.rad
        self.nu_ini = 0.0 * u.rad
        self.argp_ini = 1.0 * u.rad
        self.inc_ini = 0.2618 * u.rad

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

        self.orbit = Orbit.from_classical(
            Earth,
            self.a_ini,
            self.ecc_ini,
            self.inc_ini,
            self.raan_ini,
            self.argp_ini,
            self.nu_ini,
        )
        self.tof = [1.0] * u.min
        self.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)
Beispiel #3
0
 def f_combined(t0, u_, k):
     du_kep = func_twobody(t0, u_, k)
     ax, ay, az = J2_perturbation(
         t0, u_, k, J2=Earth.J2.value, R=Earth.R.to_value(u.km)
     ) + J3_perturbation(t0, u_, k, J3=Earth.J3.value, R=Earth.R.to_value(u.km))
     du_ad = np.array([0, 0, 0, ax, ay, az])
     return du_kep + du_ad
Beispiel #4
0
 def a_J2J3(t0, u_, k_):
     j2 = J2_perturbation(t0,
                          u_,
                          k_,
                          J2=Earth.J2.value,
                          R=Earth.R.to(u.km).value)
     j3 = J3_perturbation(t0,
                          u_,
                          k_,
                          J3=Earth.J3.value,
                          R=Earth.R.to(u.km).value)
     return j2 + j3
Beispiel #5
0
def a_d(t0, state, k, perturbations: Dict):
    """
    Custom perturbation function that is passed directly to poliastro to be executed in their code, hence the need for
    summation() to be included within. Current structure allows user to pick and chose which perturbations they would
    like to include, requiring that the desired perturbation objects are created, filled, and passed.

    Note: To improve upon existing perturbation functions or to add more, everything must be self-contained within the
    function.

    :param t0: Required by poliastro
    :param state: Required by poliastro
    :param k: Required by poliastro (gravitational parameter-mu)
    :param perturbations: Dictionary of perturbations desired by the user. Keys correspond to the perturbations Enum
    class in Enum.py, while values correspond to objects in the dto.py class.
    :return: Returns a force that describes the impact of all desired perturbations
    """
    fun = []
    if Perturbations.J2 in perturbations:
        perturbation = perturbations.get(Perturbations.J2)
        fun.append(J2_perturbation(t0, state, k, perturbation.J2, perturbation.R))
    if Perturbations.Drag in perturbations:
        perturbation = perturbations.get(Perturbations.Drag)
        fun.append(atmospheric_drag(t0, state, k, perturbation.R, perturbation.C_D, perturbation.A, perturbation.m,
                                    perturbation.H0, perturbation.rho0))
    if Perturbations.J3 in perturbations:
        perturbation = perturbations.get(Perturbations.J3)
        fun.append(J3_perturbation(t0, state, k, perturbation.J3, perturbation.R))
    if Perturbations.SRP in perturbations:
        perturbation = perturbations.get(Perturbations.SRP)
        fun.append(radiation_pressure(t0, state, k, perturbation.R, perturbation.C_R, perturbation.A, perturbation.m,
                                      perturbation.Wdivc_s, perturbation.star))
    if Perturbations.Moon in perturbations:
        perturbation = perturbations.get(Perturbations.Moon)
        fun.append(third_body(t0, state, k, perturbation.k_third, perturbation.third_body))
    if Perturbations.Sun in perturbations:
        perturbation = perturbations.get(Perturbations.Sun)
        fun.append(third_body(t0, state, k, perturbation.k_third, perturbation.third_body))

    def summation(arr):
        if len(arr) == 0:
            return np.zeros(3)
        output = arr[0]
        for i in range(1, len(arr)):
            output += arr[i]
        return output

    return summation(fun)
Beispiel #6
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')
def a_d_1(t0, state, k, J2, R, C_D, A, m, H0, rho0):  # J2+atmospheric_drag
    return (J2_perturbation(t0, state, k, J2, R) +
            atmospheric_drag(t0, state, k, R, C_D, A, m, H0, rho0))
Beispiel #8
0
def J2_and_drag(t0, state, k, J2, R, C_D, A_over_m, H0, rho0):
    return J2_perturbation(t0, state, k, J2, R) + atmospheric_drag_exponential(
        t0, state, k, R, C_D, A_over_m, H0, rho0
    )
Beispiel #9
0
def J23_perturbation(t0, state, k, J2, J3, R):
    '''wrapper function that adds effects of J2 and J3 perturbations'''
    a2 = J2_perturbation(t0, state, k, J2, R)
    a3 = J3_perturbation(t0, state, k, J3, R)

    return a2 + a3
Beispiel #10
0
def a_d_j2j3(t0, state, k, J2, J3, R):
    return J2_perturbation(t0, state, k, J2, R) + J3_perturbation(
        t0, state, k, J3, R)