Exemple #1
0
def validate_elliptic_propagation():
    # Orbit initial state vectors and time of flight
    rx_0, ry_0, rz_0 = 1131.340e3, -2282.343e3, 6672.423e3
    vx_0, vy_0, vz_0 = -5.64305e3, 4.30333e3, 2.42879e3
    tof = 1.5 * 3600

    # 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()
    ss0_orekit = KeplerianOrbit(rv_0, gcrf_frame, epoch_00, k)
    orekit_propagator = KeplerianPropagator(ss0_orekit)
    ssf_orekit = orekit_propagator.propagate(
        epoch_00.shiftedBy(tof)).getOrbit()

    # Build poliastro orbit
    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)
    ssf_poliastro = ss0_poliastro.propagate(tof * u.s)

    # Retrieve Orekit final state vectors
    r_orekit = ssf_orekit.getPVCoordinates().position.toArray() * u.m
    v_orekit = ssf_orekit.getPVCoordinates().velocity.toArray() * u.m / 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, atol=10 * u.m)
    assert_quantity_allclose(v_poliastro, v_orekit, rtol=1e-5)
    def test_analytical_propagator(self):
        """
        analytical_propagator test
        """
        parameters = {
            "eccentricity": 0.0008641,
            "semimajor_axis": 6801395.04,
            "inclination": radians(87.0),
            "perigee_argument": radians(20.0),
            "right_ascension_of_ascending_node": radians(10.0),
            "anomaly": radians(0.0),
            "anomaly_type": "TRUE",
            "orbit_update_date": '2021-12-02T00:00:00.000',
            "frame": "EME"
        }
        k_orbit = keplerian_orbit(parameters)
        test1 = analytical_propagator(parameters)
        test2 = KeplerianPropagator(keplerian_orbit(parameters),
                                    Constants.WGS84_EARTH_MU)
        time1 = orekit_utils.absolute_time_converter_utc_string(
            '2022-01-02T00:00:00.000')

        self.assertTrue(
            test1.getPVCoordinates(time1, FramesFactory.getEME2000()).toString(
            ) == test2.getPVCoordinates(time1,
                                        FramesFactory.getEME2000()).toString())
Exemple #3
0
    def test_get_ground_passes(self):
        """
        Testing whether OreKit finds ground passess
        """
        # test will fail if setup_orekit fails

        utc = TimeScalesFactory.getUTC()
        ra = 500 * 1000         #  Apogee
        rp = 400 * 1000         #  Perigee
        i = radians(55.0)      # inclination
        omega = radians(20.0)   # perigee argument
        raan = radians(10.0)  # right ascension of ascending node
        lv = radians(0.0)    # True anomaly

        epochDate = AbsoluteDate(2020, 1, 1, 0, 0, 00.000, utc)
        initial_date = epochDate

        a = (rp + ra + 2 * Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / 2.0
        e = 1.0 - (rp + Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / a

        ## Inertial frame where the satellite is defined
        inertialFrame = FramesFactory.getEME2000()

        ## Orbit construction as Keplerian
        initialOrbit = KeplerianOrbit(a, e, i, omega, raan, lv,
                                    PositionAngle.TRUE,
                                    inertialFrame, epochDate, Constants.WGS84_EARTH_MU)

        propagator = KeplerianPropagator(initialOrbit)
        durand_lat = 37.4269
        durand_lat = -122.1733
        durand_alt = 10.0

        output = get_ground_passes(propagator, durand_lat, durand_lat, durand_alt, initial_date, initial_date.shiftedBy(3600.0 * 24), ploting_param=False)
        assert len(output) == 5
Exemple #4
0
    def __init__(self,
                 name,
                 mu,
                 state,
                 trj_date,
                 rot_state=None,
                 oneshot=False):
        """Currently hard implemented for SC."""

        super().__init__(name)

        self.trj_date = trj_date
        self.auto_targeting = rot_state is None

        att_provider = []
        if rot_state is not None:
            attitude = Attitude(trj_date, self.ref_frame, rot_state)
            att_provider = [FixedRate(attitude)]

        if oneshot:
            self.date_history = [trj_date]
            self.pos_history = [state.getPosition()]
            self.vel_history = [state.getVelocity()]
            self.rot_history = [
                None if rot_state is None else rot_state.getRotation()
            ]
        else:
            self.trajectory = KeplerianOrbit(state, self.ref_frame,
                                             self.trj_date, mu)
            self.propagator = KeplerianPropagator(self.trajectory,
                                                  *att_provider)

        self.payload = None

        logger.debug("Init finished")
Exemple #5
0
def analytical_propagator(parameters):
    """
	Takes in a dictionary of keplarian parameters and returns an Keplarian analytical propogator
	Args:
		Args:
    		parameters (dict): dictionary of parameters containg eccentricity, semimajor_axis (meters),
            inclination, perigee argument, right ascension of ascending node, orbit_update_date, and
            anomoly with another defining key
            ["anomaly_type"] = "MEAN" or "TRUE"
            ["frame"] = "EME2000", "J2000", or "TEME" only
        Ex.
                parameters = {
                            "eccentricity": 0.0008641,
                            "semimajor_axis": 6801395.04,
                            "inclination": radians(87.0),
                            "perigee_argument": radians(20.0),
                            "right_ascension_of_ascending_node":radians(10.0),
                            "anomaly": radians(0.0),
                            "anomaly_type": "TRUE",
                            "orbit_update_date":'2021-12-02T00:00:00.000',
                            "frame": "EME"}
	Returns:
		AbstractAnalyticalPropagator: propagator that can be used to propagate an orbit
                                      and acts as a PVCoordinatesProvider
                                      (PV = position, velocity)
	"""
    return KeplerianPropagator(keplerian_orbit(parameters),
                               Constants.WGS84_EARTH_MU)
Exemple #6
0
    def __init__(self, name, mu, trj, att, model_file=None):
        """Currently hard implemented for Didymos."""
        super().__init__(name, model_file=model_file)

        date = trj["date"]
        trj_date = AbsoluteDate(int(date["year"]), int(date["month"]),
                                int(date["day"]), int(date["hour"]),
                                int(date["minutes"]), float(date["seconds"]),
                                self.timescale)

        # rotation axis
        self.axis_ra = math.radians(att["RA"]) if "RA" in att else 0.
        self.axis_dec = math.radians(
            att["Dec"]) if "Dec" in att else math.pi / 2

        # rotation offset, zero longitude right ascension at epoch
        self.rotation_zlra = math.radians(att["ZLRA"]) if "ZLRA" in att else 0.

        # rotation angular velocity [rad/s]
        if "rotation_rate" in att:
            self.rotation_rate = att["rotation_rate"] * 2.0 * math.pi / 180.0
        else:
            self.rotation_rate = 2. * math.pi / (2.2593 * 3600
                                                 )  # didymain by default

        # Define initial rotation, set rotation convention
        #  - For me, FRAME_TRANSFORM order makes more sense, the rotations are applied from left to right
        #    so that the following rotations apply on previously rotated axes  +Olli
        self.rot_conv = RotationConvention.FRAME_TRANSFORM
        init_rot = Rotation(RotationOrder.ZYZ, self.rot_conv, self.axis_ra,
                            math.pi / 2 - self.axis_dec, self.rotation_zlra)

        if "r" in trj:
            self.date_history = [trj_date]
            self.pos_history = [Vector3D(*trj["r"])]
            self.vel_history = [
                Vector3D(*(trj["v"] if "v" in trj else [0., 0., 0.]))
            ]
            self.rot_history = [init_rot]
            return

        # Define trajectory/orbit
        self.trajectory = KeplerianOrbit(
            trj["a"] * ok_utils.Constants.IAU_2012_ASTRONOMICAL_UNIT, trj["e"],
            math.radians(trj["i"]), math.radians(trj["omega"]),
            math.radians(trj["Omega"]), math.radians(trj["M"]),
            PositionAngle.MEAN, self.ref_frame, trj_date, mu)

        rotation = ok_utils.AngularCoordinates(
            init_rot, Vector3D(0., 0., self.rotation_rate))
        attitude = Attitude(trj_date, self.ref_frame, rotation)
        att_provider = FixedRate(attitude)

        # Create propagator
        self.propagator = KeplerianPropagator(self.trajectory, att_provider)

        # Loaded coma object, currently only used with OpenGL based rendering
        self.coma = None
Exemple #7
0
    def __init__(self, name, mu, state, trj_date):
        """Currently hard implemented for SC."""

        super().__init__(name)

        self.trj_date = trj_date

        self.trajectory = KeplerianOrbit(state, self.ref_frame, self.trj_date,
                                         mu)
        self.propagator = KeplerianPropagator(self.trajectory)

        self.payload = None
Exemple #8
0
def validate_event_detector(event_name):

    # Unpack orekit and poliastro events
    orekit_event, poliastro_event = DICT_OF_EVENTS[event_name]

    # Time of fliht for propagating the orbit
    tof = float(2 * 24 * 3600)

    # Build the orekit propagator and add the event to it.
    propagator = KeplerianPropagator(ss0_orekit)
    propagator.addEventDetector(orekit_event)

    # Propagate orekit's orbit
    state = propagator.propagate(epoch0_orekit, epoch0_orekit.shiftedBy(tof))
    orekit_event_epoch_raw = state.orbit.getPVCoordinates().getDate()
    # Convert orekit epoch to astropy Time instance
    orekit_event_epoch_str = orekit_event_epoch_raw.toString(
        TimeScalesFactory.getUTC())
    orekit_event_epoch = Time(orekit_event_epoch_str,
                              scale="utc",
                              format="isot")
    orekit_event_epoch.format = "iso"
    print(f"{orekit_event_epoch}")

    # Propagate poliastro's orbit
    _, _ = cowell(
        Earth.k,
        ss0_poliastro.r,
        ss0_poliastro.v,
        # Generate a set of tofs, each one for each propagation second
        np.linspace(0, tof, 100) * u.s,
        events=[poliastro_event],
    )
    poliastro_event_epoch = ss0_poliastro.epoch + poliastro_event.last_t
    print(f"{poliastro_event_epoch}")

    # Test both event epochs by checking the distance in seconds between them
    dt = np.abs((orekit_event_epoch - poliastro_event_epoch).to(u.s))
    assert_quantity_allclose(dt, 0 * u.s, atol=5 * u.s, rtol=1e-7)
Exemple #9
0
    def __init__(self, name, mu, trj, att, model_file=None):
        """Currently hard implemented for Didymos."""
        super().__init__(name, model_file=model_file)

        date = trj["date"]
        trj_date = AbsoluteDate(int(date["year"]), int(date["month"]),
                                int(date["day"]), int(date["hour"]),
                                int(date["minutes"]), float(date["seconds"]),
                                self.timescale)

        if "a" and "e" and "i" and "omega" and "Omega" and "M" not in trj:
            a = 1.644641475071416E+00 * utils.Constants.IAU_2012_ASTRONOMICAL_UNIT
            P = 7.703805051391988E+02 * utils.Constants.JULIAN_DAY
            e = 3.838774437558215E-01
            i = math.radians(3.408231185574551E+00)
            omega = math.radians(3.192958853076784E+02)
            Omega = math.radians(7.320940216397703E+01)
            M = math.radians(1.967164895190036E+02)

        if "rotation_rate" not in att:
            rotation_rate = 2. * math.pi / (2.2593 * 3600)
        else:
            rotation_rate = att["rotation_rate"] * 2.0 * math.pi / 180.0

        if "RA" not in att:
            self.RA = 0.
        else:
            self.RA = math.radians(att["RA"])

        if "Dec" not in att:
            self.Dec = 0.
        else:
            self.Dec = math.radians(att["Dec"])

        # Define trajectory/orbit
        self.trajectory = KeplerianOrbit(
            trj["a"] * utils.Constants.IAU_2012_ASTRONOMICAL_UNIT, trj["e"],
            math.radians(trj["i"]), math.radians(trj["omega"]),
            math.radians(trj["Omega"]), math.radians(trj["M"]),
            PositionAngle.MEAN, self.ref_frame, trj_date, mu)

        # Define attitude
        self.rot_conv = RotationConvention.valueOf("VECTOR_OPERATOR")

        rotation = utils.AngularCoordinates(Rotation.IDENTITY,
                                            Vector3D(0., 0., rotation_rate))
        attitude = Attitude(trj_date, self.ref_frame, rotation)
        att_provider = FixedRate(attitude)

        # Create propagator
        self.propagator = KeplerianPropagator(self.trajectory, att_provider)
Exemple #10
0
def simple_keplarian(initialOrbit, initialDate):
    """
    :param initialOrbit: initial Keplarian orbit and central body
    :param initialDate: intial start date
    :return: plot xy orbit
    """

    # Simple extrapolation with Keplerian motion
    kepler = KeplerianPropagator(initialOrbit)
    # Set the propagator to slave mode (could be omitted as it is the default mode)
    kepler.setSlaveMode()
    # Setup propagation time
    # Overall duration in seconds for extrapolation
    duration = 24 * 60.0**2
    # Stop date
    finalDate = AbsoluteDate(initial_date, duration, utc)
    # Step duration in seconds
    stepT = 30.0
    # Perform propagation
    # Extrapolation loop
    cpt = 1.0
    extrapDate = initial_date
    px, py = [], []
    while extrapDate.compareTo(finalDate) <= 0:
        currentState = kepler.propagate(extrapDate)
        print('step {}: time {} {}\n'.format(cpt, currentState.getDate(),
                                             currentState.getOrbit()))
        coord = currentState.getPVCoordinates().getPosition()
        px.append(coord.getX())
        py.append(coord.getY())
        # P[:,cpt]=[coord.getX coord.getY coord.getZ]
        extrapDate = AbsoluteDate(extrapDate, stepT, utc)
        cpt += 1
    plt.plot(px, py)
    plt.show()
    pass
Exemple #11
0
 def propagate_keplerian_elements(self):
     propagator = KeplerianPropagator(self.initial_orbit)
     return propagator.propagate(self.initial_date, self.shifted_date)
Exemple #12
0
def validate_3D_hohmann():

    # 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_hohmann3D.script
    rx_0, ry_0, rz_0 = 7200e3, -1000.0e3, 0.0
    vx_0, vy_0, vz_0 = 0.0, 8.0e3, 3.25e3
    rf_norm = 35781.35e3
    tof = 19800.00

    # 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_trans = (rp_norm + rf_norm) / 2

    # Compute the magnitude of Hohmann's deltaV
    dv_a = np.sqrt(2 * k / rp_norm - k / a_trans) - vp_norm
    dv_b = np.sqrt(k / rf_norm) - np.sqrt(2 * k / rf_norm - k / a_trans)

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

    # 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 maneuvers
    propagator = KeplerianPropagator(ss_0, attitude_provider)
    propagator.addEventDetector(imp_A)
    propagator.addEventDetector(imp_B)

    # Apply the maneuver by propagating the orbit
    epoch_ff = epoch_00.shiftedBy(tof)
    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.hohmann(ss0_poliastro, 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)