Exemplo n.º 1
0
def test_bielliptic_maneuver(nu):
    # Data from Vallado, example 6.2
    alt_i = 191.34411 * u.km
    alt_b = 503873.0 * u.km
    alt_f = 376310.0 * u.km
    _a = 0 * u.deg
    ss_i = Orbit.from_classical(Earth,
                                Earth.R + alt_i,
                                ecc=0 * u.one,
                                inc=_a,
                                raan=_a,
                                argp=_a,
                                nu=nu)

    # Expected output
    expected_dv = 3.904057 * u.km / u.s
    expected_t_pericenter = ss_i.time_to_anomaly(0 * u.deg)
    expected_t_trans = 593.919803 * u.h
    expected_total_time = expected_t_pericenter + expected_t_trans

    man = Maneuver.bielliptic(ss_i, Earth.R + alt_b, Earth.R + alt_f)

    assert_allclose(ss_i.apply_maneuver(man).ecc,
                    0 * u.one,
                    atol=1e-12 * u.one)
    assert_quantity_allclose(man.get_total_cost(), expected_dv, rtol=1e-5)
    assert_quantity_allclose(man.get_total_time(),
                             expected_total_time,
                             rtol=1e-6)
Exemplo n.º 2
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 = Orbit.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_allclose(ss_i.apply_maneuver(man).ecc, 0 * u.one, atol=1e-12 * u.one)
    assert_quantity_allclose(man.get_total_cost(), expected_dv, rtol=1e-5)
    assert_quantity_allclose(man.get_total_time(), expected_t_trans, rtol=1e-6)
Exemplo n.º 3
0
def test_repr_maneuver():
    alt_f = 35781.34857 * u.km
    r = [-6045, -3490, 2500] * u.km
    v = [-3.457, 6.618, 2.533] * u.km / u.s
    alt_b = 503873.0 * u.km
    alt_fi = 376310.0 * u.km
    ss_i = Orbit.from_vectors(Earth, r, v)

    expected_hohmann_manuever = "Number of impulses: 2, Total cost: 3.060548 km / s"
    expected_bielliptic_maneuver = "Number of impulses: 3, Total cost: 3.122556 km / s"

    assert repr(Maneuver.hohmann(ss_i,
                                 Earth.R + alt_f)) == expected_hohmann_manuever
    assert (repr(Maneuver.bielliptic(ss_i, Earth.R + alt_b, Earth.R +
                                     alt_fi)) == expected_bielliptic_maneuver)
Exemplo n.º 4
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 = Orbit.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)
Exemplo n.º 5
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 = Orbit.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)
Exemplo n.º 6
0
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)


# In[3]:


fig, ax = plt.subplots(figsize=(8, 6))

l, = ax.plot(R, hohmann_data, lw=2)
for jj in range(len(Rstar)):
Exemplo n.º 7
0
def validate_3D_bielliptic():

    # Initial orbit state vectors, final radius and time of flight
    # This orbit has an inclination of 22.30 [deg] so the maneuver will not be
    # applied on an equatorial orbit. See associated GMAT script:
    # gmat_validate_bielliptic3D.script
    rx_0, ry_0, rz_0 = 7200e3, -1000.0e3, 0.0
    vx_0, vy_0, vz_0 = 0.0, 8.0e3, 3.25e3
    rb_norm = 50000.00e3
    rf_norm = 35781.35e3
    tof_trans = 24500.00  # Impulse dVb is performed just a bit before this epoch
    tof = 72158.11

    # Build the initial Orekit orbit
    k = C.IAU_2015_NOMINAL_EARTH_GM
    r0_vec = Vector3D(rx_0, ry_0, rz_0)
    v0_vec = Vector3D(vx_0, vy_0, vz_0)
    rv_0 = PVCoordinates(r0_vec, v0_vec)
    epoch_00 = AbsoluteDate.J2000_EPOCH
    gcrf_frame = FramesFactory.getGCRF()
    ss_0 = KeplerianOrbit(rv_0, gcrf_frame, epoch_00, k)

    # Final desired orbit radius and auxiliary variables
    a_0, ecc_0 = ss_0.getA(), ss_0.getE()
    rp_norm = a_0 * (1 - ecc_0)
    vp_norm = np.sqrt(2 * k / rp_norm - k / a_0)
    a_trans1 = (rp_norm + rb_norm) / 2
    a_trans2 = (rb_norm + rf_norm) / 2

    # Compute the magnitude of Bielliptic's deltaV
    dv_a = np.sqrt(2 * k / rp_norm - k / a_trans1) - vp_norm
    dv_b = np.sqrt(2 * k / rb_norm - k / a_trans2) - np.sqrt(2 * k / rb_norm -
                                                             k / a_trans1)
    dv_c = np.sqrt(k / rf_norm) - np.sqrt(2 * k / rf_norm - k / a_trans2)

    # Convert previous magnitudes into vectors within the TNW frame, which
    # is aligned with local velocity vector
    dVa_vec, dVb_vec, dVc_vec = [
        Vector3D(float(dV), float(0), float(0)) for dV in (dv_a, dv_b, dv_c)
    ]

    # Local orbit frame: X-axis aligned with velocity, Z-axis towards momentum
    attitude_provider = LofOffset(gcrf_frame, LOFType.TNW)

    # Setup impulse triggers; default apside detector stops on increasing g
    # function (aka at perigee)
    at_apoapsis = ApsideDetector(ss_0).withHandler(StopOnDecreasing())
    at_periapsis = ApsideDetector(ss_0)

    # Build the impulsive maneuvers; ISP is only related to fuel mass cost
    ISP = float(300)
    imp_A = ImpulseManeuver(at_periapsis, attitude_provider, dVa_vec, ISP)
    imp_B = ImpulseManeuver(at_apoapsis, attitude_provider, dVb_vec, ISP)

    # Generate the propagator and add the first two impulses
    propagator = KeplerianPropagator(ss_0, attitude_provider)
    propagator.addEventDetector(imp_A)
    propagator.addEventDetector(imp_B)

    # Apply the maneuver by propagating the orbit
    epoch_trans = epoch_00.shiftedBy(tof_trans)
    ss_trans = propagator.propagate(epoch_trans).getOrbit()

    # Build a second propagator and add the last impulse so it is not confused
    # with the first one as both happen at perigee
    at_periapsis = ApsideDetector(ss_trans)
    imp_C = ImpulseManeuver(at_periapsis, attitude_provider, dVc_vec, ISP)
    propagator = KeplerianPropagator(ss_trans, attitude_provider)
    propagator.addEventDetector(imp_C)

    # Apply the last of the impulses
    tof_ff = float(tof - tof_trans)
    epoch_ff = epoch_trans.shiftedBy(tof_ff)
    rv_f = propagator.propagate(epoch_ff).getPVCoordinates(gcrf_frame)

    # Retrieve orekit final state vectors
    r_orekit, v_orekit = (
        rv_f.getPosition().toArray() * u.m,
        rv_f.getVelocity().toArray() * u.m / u.s,
    )

    # Build initial poliastro orbit and apply the maneuver
    r0_vec = [rx_0, ry_0, rz_0] * u.m
    v0_vec = [vx_0, vy_0, vz_0] * u.m / u.s
    ss0_poliastro = Orbit.from_vectors(Earth, r0_vec, v0_vec)
    man_poliastro = Maneuver.bielliptic(ss0_poliastro, rb_norm * u.m,
                                        rf_norm * u.m)

    # Retrieve propagation time after maneuver has been applied
    tof_prop = tof - man_poliastro.get_total_time().to(u.s).value
    ssf_poliastro = ss0_poliastro.apply_maneuver(man_poliastro).propagate(
        tof_prop * u.s, )

    # Retrieve poliastro final state vectors
    r_poliastro, v_poliastro = ssf_poliastro.rv()

    # Assert final state vectors
    assert_quantity_allclose(r_poliastro, r_orekit, rtol=1e-6)
    assert_quantity_allclose(v_poliastro, v_orekit, rtol=1e-6)