Ejemplo n.º 1
0
def validate_coe2rv():

    # Initial COE of the orbit
    a, ecc, inc, raan, argp, nu = 8788e3, 0.1712, 2.6738, 4.4558, 0.3502, 0.4965

    # Build Orekit orbit
    k = C.IAU_2015_NOMINAL_EARTH_GM
    epoch_00 = AbsoluteDate.J2000_EPOCH
    gcrf_frame = FramesFactory.getGCRF()
    ss0_orekit = KeplerianOrbit(a, ecc, inc, argp, raan, nu,
                                PositionAngle.TRUE, gcrf_frame, epoch_00, k)

    # Build poliastro orbit
    ss0_poliastro = Orbit.from_classical(
        Earth,
        a * u.m,
        ecc * u.one,
        inc * u.rad,
        raan * u.rad,
        argp * u.rad,
        nu * u.rad,
    )

    # Retrieve Orekit final state vectors
    r_orekit = ss0_orekit.getPVCoordinates().position.toArray() * u.m
    v_orekit = ss0_orekit.getPVCoordinates().velocity.toArray() * u.m / u.s

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

    # Assert final state vector
    assert_quantity_allclose(r_poliastro, r_orekit)
    assert_quantity_allclose(v_poliastro, v_orekit)
Ejemplo n.º 2
0
def get_keplerian_parameters(spacecraft_state, anomaly_type="TRUE"):
    """
	Given a SpaceCraftState object this function computes the keplerian orbit parameters
    Note: parameter values may change but they'll define the same orbit
	Args:
		spacecraft_state (SpaceCraftState): SpaceCraftState orekit object that has an orbit attribute
        anomaly_type (string; "MEAN" or "TRUE"): tells to return true or mean anomaly, defaults to TRUE
	Returns:
		dict: dictionary of parameters containg eccentricity, semimajor_axis, inclination, perigee argument, right
		ascension of ascending node, anomaly, anomaly_type, and orbit_update_date
    """
    parameters = dict()
    new_orbit = KeplerianOrbit(spacecraft_state.getOrbit())

    parameters["semimajor_axis"] = new_orbit.getA()
    parameters["eccentricity"] = new_orbit.getE()
    parameters["inclination"] = new_orbit.getI()
    parameters["perigee_argument"] = new_orbit.getPerigeeArgument()
    parameters[
        "right_ascension_of_ascending_node"] = new_orbit.getRightAscensionOfAscendingNode(
        )
    parameters["orbit_update_date"] = new_orbit.getDate().toString()
    parameters["frame"] = frame_to_string(spacecraft_state.getFrame())
    if (anomaly_type == "MEAN"):
        parameters["anomaly"] = new_orbit.getMeanAnomaly()
        parameters["anomaly_type"] = "MEAN"
    else:
        parameters["anomaly"] = new_orbit.getTrueAnomaly()
        parameters["anomaly_type"] = "TRUE"
    return parameters
Ejemplo n.º 3
0
def keplerian_orbit(parameters):
    """
	Given a dictionary of parameters containg eccentricity, semimajor_axis, inclination, perigee_argument, right
	acension of ascending node, anomaly, anomaly_type and orbit_update_date this function returns a keplerian
	orbit orekit object
	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:
		KeplerianOrbit: Keplerian orbit orekit object
	"""
    eccentricity = float(parameters["eccentricity"])
    semimajor_axis = float(parameters["semimajor_axis"])
    inclination = float(parameters["inclination"])
    perigee_argument = float(parameters["perigee_argument"])
    right_ascension_of_ascending_node = float(
        parameters["right_ascension_of_ascending_node"])
    anomaly = float(parameters["anomaly"])
    orbit_update_date = absolute_time_converter_utc_string(
        parameters["orbit_update_date"])
    frame = string_to_frame(parameters["frame"])

    if (parameters["anomaly_type"] == "TRUE"):
        return KeplerianOrbit(semimajor_axis, eccentricity, inclination,
                              perigee_argument,
                              right_ascension_of_ascending_node, anomaly,
                              PositionAngle.TRUE, frame, orbit_update_date,
                              Constants.WGS84_EARTH_MU)
    elif (parameters["anomaly_type"] == "MEAN"):
        return KeplerianOrbit(semimajor_axis, eccentricity, inclination,
                              perigee_argument,
                              right_ascension_of_ascending_node, anomaly,
                              PositionAngle.MEAN, frame, orbit_update_date,
                              Constants.WGS84_EARTH_MU)
    else:
        return (
            "Error: Need to redefine anomoly_type, see function documentation")
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
    def test_keplerian_orbit(self):
        """
        keplerian_orbit 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)

        eccentricity = parameters["eccentricity"]
        semimajor_axis = parameters["semimajor_axis"]
        inclination = parameters["inclination"]
        perigee_argument = parameters["perigee_argument"]
        right_ascension_of_ascending_node = parameters["right_ascension_of_ascending_node"]
        true_anomaly = parameters["anomaly"]
        orbit_update_date = parameters["orbit_update_date"]
        epochDate = absolute_time_converter_utc_string(orbit_update_date)
        frame = orekit_utils.string_to_frame(parameters["frame"])

        self.assertTrue(KeplerianOrbit(semimajor_axis, eccentricity, inclination, perigee_argument,
                                    right_ascension_of_ascending_node,
                                    true_anomaly, PositionAngle.TRUE,
                                    frame, epochDate,
                                    Constants.WGS84_EARTH_MU).toString() == k_orbit.toString())
Ejemplo n.º 6
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
Ejemplo n.º 7
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")
Ejemplo n.º 8
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
Ejemplo n.º 9
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
Ejemplo n.º 10
0
Archivo: frame.py Proyecto: rev0nat/SMS
def kepler_gcrs_single(kep):

  date = kep.index[0]
  ok_date = AbsoluteDate(date.year, date.month, date.day, date.hour, date.minute,
                         date.second + float(date.microsecond) / 1000000., utc)
  kep = kep.astype(float)
  a, e, f, i, raan, w, date = kep['a[m]'][0], kep['e'][0], kep['ta[rad]'][0], kep['i[rad]'][0], kep['raan[rad]'][0], kep['omega[rad]'][0], \
                                kep.index[0]
  kep_orbit = KeplerianOrbit(a, e, i, w, raan, f, PositionAngle.TRUE, teme_f, ok_date, muearth)

  state = AbsolutePVCoordinates(gcrf_f, kep_orbit.getPVCoordinates(gcrf_f))
  pos = state.position
  vel = state.velocity
  X = pos.getX()
  Y = pos.getY()
  Z = pos.getZ()
  Vx = vel.getX()
  Vy = vel.getY()
  Vz = vel.getZ()
  dframe = pd.DataFrame({'x[m]': [X], 'y[m]': [Y], 'z[m]': [Z], 'vx[m/s]': [Vx], 'vy[m/s]': [Vy], 'vz[m/s]': [Vz]},index=kep.index)
  return dframe
Ejemplo n.º 11
0
def validate_rv2coe():
    # Orbit initial state vectors
    rx_0, ry_0, rz_0 = -6045.0e3, -3490.0e3, 2500.0e3
    vx_0, vy_0, vz_0 = -3.457e3, 6.618e3, 2.533e3

    # 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)

    # 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)

    # Orekit bounds COE angular magnitudes between [-pi, +pi]. Let us define a
    # converter function to map values between [0, +2pi]
    def unbound_angle(angle):
        """ Bound angle between [0, +2pi] """
        if -np.pi <= angle <= 0.0:
            angle += 2 * np.pi

        return angle

    # Map angles
    orekit_raan = unbound_angle(ss0_orekit.getRightAscensionOfAscendingNode())
    orekit_argp = unbound_angle(ss0_orekit.getPerigeeArgument())
    orekit_nu = unbound_angle(ss0_orekit.getTrueAnomaly())

    # Assert classical orbital elements
    assert_quantity_allclose(ss0_poliastro.a,
                             ss0_orekit.getA() * u.m,
                             rtol=1e-6)
    assert_quantity_allclose(ss0_poliastro.ecc,
                             ss0_orekit.getE() * u.one,
                             rtol=1e-6)
    assert_quantity_allclose(ss0_poliastro.inc,
                             ss0_orekit.getI() * u.rad,
                             rtol=1e-6)
    assert_quantity_allclose(ss0_poliastro.raan,
                             orekit_raan * u.rad,
                             rtol=1e-6)
    assert_quantity_allclose(ss0_poliastro.argp,
                             orekit_argp * u.rad,
                             rtol=1e-6)
    assert_quantity_allclose(ss0_poliastro.nu, orekit_nu * u.rad, rtol=1e-6)
Ejemplo n.º 12
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)
Ejemplo n.º 13
0
def propagate(tle_line1, tle_line2, duration, step, maneuvers=[]):
    tle = create_tle(tle_line1, tle_line2)
    tle_propagator = TLEPropagator.selectExtrapolator(tle)
    propagator_with_maneuvers = AdapterPropagator(tle_propagator)

    # TODO works only for chronological maneuvers, because of the "propagate" to get the state
    for maneuver in maneuvers:
        date, frame, deltaV, isp = maneuver
        propagator_with_maneuvers.addEffect(
            SmallManeuverAnalyticalModel(
                propagator_with_maneuvers.propagate(
                    datetime_to_absolutedate(date)), frame, deltaV, isp))

    ITRF = FramesFactory.getITRF(IERSConventions.IERS_2010, True)
    earth = OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
                             Constants.WGS84_EARTH_FLATTENING, ITRF)

    time = [tle.getDate().shiftedBy(float(dt)) \
            for dt in np.arange(0, duration, step)]
    orbits = [
        KeplerianOrbit(propagator_with_maneuvers.propagate(date).getOrbit())
        for date in time
    ]

    subpoints = [
        earth.transform(
            propagator_with_maneuvers.propagate(date).getPVCoordinates(),
            tle_propagator.getFrame(), date) for date in time
    ]
    return pd.DataFrame({
        'time':
        [absolutedate_to_datetime(orbit.getDate()) for orbit in orbits],
        'a': [orbit.getA() for orbit in orbits],
        'e': [orbit.getE() for orbit in orbits],
        'i': [orbit.getI() for orbit in orbits],
        'pom': [orbit.getPerigeeArgument() for orbit in orbits],
        'RAAN': [orbit.getRightAscensionOfAscendingNode() for orbit in orbits],
        'v': [orbit.getTrueAnomaly() for orbit in orbits],
        'ex': [orbit.getEquinoctialEx() for orbit in orbits],
        'ey': [orbit.getEquinoctialEy() for orbit in orbits],
        'hx': [orbit.getHx() for orbit in orbits],
        'hy': [orbit.getHy() for orbit in orbits],
        'latitude':
        [np.degrees(gp.getLatitude().getReal()) for gp in subpoints],
        'longitude':
        [np.degrees(gp.getLongitude().getReal()) for gp in subpoints]
    })
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
setup_orekit_curdir()

# To activate once if a problem of orekit.Exception appears. (.getUtc())
# orekit.pyhelpers.download_orekit_data_curdir()

utc = TimeScalesFactory.getUTC()

ra = 400 * 1000  #  Apogee
rp = 500 * 1000  #  Perigee
i = numpy.radians(87.0)  # inclination
# FIXME: Use Hipparchus Library instead of numpy
omega = numpy.radians(20.0)  # perigee argument
raan = numpy.radians(10.0)  # right ascension of ascending node
lv = numpy.radians(0.0)  # True anomaly

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

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(24464560.0, 0.7311, 0.122138, 3.10686, 1.00681,
                              0.048363, PositionAngle.MEAN,
                              FramesFactory.getEME2000(), epochDate,
                              Constants.GRS80_EARTH_MU)

print(initialOrbit)
Ejemplo n.º 16
0
 def init_keplerian_elements(self):
     return KeplerianOrbit(self.a, self.e, self.i, self.w, self.gom,
                           self.anomaly, self.position_angle, self.frame,
                           self.current_date, self.mu)
Ejemplo n.º 17
0
    def osc_elems_transformation_ore(self, other, dir):

        self._orekit_lock.acquire()

        self.load_orekit()

        KepOrbElem.vm.attachCurrentThread()

        utc = TimeScalesFactory.getUTC()

        orekit_date = AbsoluteDate(2017, 1, 1, 12, 1, 1.0, utc)
        inertialFrame = FramesFactory.getEME2000()
        a = float(other.a)
        e = float(other.e)
        i = float(other.i)
        w = float(other.w)
        O = float(other.O)
        v = float(other.v)

        initialOrbit = KeplerianOrbit(a * 1000.0, e, i, w, O, v,
                                      PositionAngle.TRUE, inertialFrame,
                                      orekit_date, Constants.mu_earth * 1e9)

        initialState = SpacecraftState(initialOrbit, 1.0)

        #zonal_forces= DSSTZonal(provider,2,1,5)
        zonal_forces = DSSTZonal(KepOrbElem.provider, 6, 4, 6)
        forces = ArrayList()
        forces.add(zonal_forces)
        try:
            equinoctial = None
            if dir:

                equinoctial = DSSTPropagator.computeMeanState(
                    initialState, None, forces)
            else:

                equinoctial = DSSTPropagator.computeOsculatingState(
                    initialState, None, forces)

            newOrbit = KeplerianOrbit(equinoctial.getOrbit())

            self.a = newOrbit.getA() / 1000.0
            self.e = newOrbit.getE()
            self.i = newOrbit.getI()
            self.w = newOrbit.getPerigeeArgument()
            self.O = newOrbit.getRightAscensionOfAscendingNode()
            self.v = newOrbit.getAnomaly(PositionAngle.TRUE)

            # correct ranges

            if self.i < 0:
                self.i += 2 * np.pi

            if self.w < 0:
                self.w += 2 * np.pi

            if self.O < 0:
                self.O += 2 * np.pi

            if self.v < 0:
                self.v += 2 * np.pi

        finally:
            self._orekit_lock.release()
Ejemplo n.º 18
0
    def get_orbit(self, t, a, e, inc, raan, aop, mu0, mjd0, **kwargs):
        '''
        **Implementation:**
    
        Units are in meters and degrees.

        Keyword arguments are:

            * float A: Area in m^2
            * float C_D: Drag coefficient
            * float C_R: Radiation pressure coefficient
            * float m: Mass of object in kg

        *NOTE:*
            * If the eccentricity is below 1e-10 the eccentricity will be set to 1e-10 to prevent Keplerian Jacobian becoming singular.
        

        The implementation first checks if the input frame is Pseudo inertial, if this is true this is used as the propagation frame. If not it is automatically converted to EME (ECI-J2000).

        Since there are forces that are dependent on the space-craft parameters, if these parameter has been changed since the last iteration the numerical integrator is re-initialized at every call of this method. The forces that can be initialized without spacecraft parameters (e.g. Earth gravitational field) are done at propagator construction.

        **Uses:**
            * :func:`propagator_base.PropagatorBase._make_numpy`
            * :func:`propagator_orekit.PropagatorOrekit._construct_propagator`
            * :func:`propagator_orekit.PropagatorOrekit._set_forces`
            * :func:`dpt_tools.kep2cart`
            * :func:`dpt_tools.cart2kep`
            * :func:`dpt_tools.true2mean`
            * :func:`dpt_tools.mean2true`
            
        
        See :func:`propagator_base.PropagatorBase.get_orbit`.
        '''

        if self.logger_func is not None:
            self._logger_start('get_orbit')

        if self.radiation_pressure:
            if 'C_R' not in kwargs:
                raise Exception(
                    'Radiation pressure force enabled but no coefficient "C_R" given'
                )
        else:
            kwargs['C_R'] = 1.0

        if self.drag_force:
            if 'C_D' not in kwargs:
                raise Exception(
                    'Drag force enabled but no drag coefficient "C_D" given')
        else:
            kwargs['C_D'] = 1.0

        t = self._make_numpy(t)

        initialDate = mjd2absdate(mjd0)

        if not self.inputFrame.isPseudoInertial():
            orb = np.array(
                [a, e, inc, aop, raan,
                 dpt.mean2true(mu0, e, radians=False)],
                dtype=np.float)
            cart = dpt.kep2cart(
                orb,
                m=kwargs['m'],
                M_cent=self.M_earth,
                radians=False,
            )

            pos = org.hipparchus.geometry.euclidean.threed.Vector3D(
                float(cart[0]), float(cart[1]), float(cart[2]))
            vel = org.hipparchus.geometry.euclidean.threed.Vector3D(
                float(cart[3]), float(cart[4]), float(cart[5]))
            PV_state = PVCoordinates(pos, vel)

            transform = self.inputFrame.getTransformTo(self.inertialFrame,
                                                       initialDate)
            new_PV = transform.transformPVCoordinates(PV_state)

            initialOrbit = CartesianOrbit(
                new_PV,
                self.inertialFrame,
                initialDate,
                self.mu + float(scipy.constants.G * kwargs['m']),
            )
        else:

            #this is to prevent Keplerian Jacobian to become singular
            use_equinoctial = False
            if e < dpt.e_lim:
                use_equinoctial = True
            if inc < dpt.i_lim:
                use_equinoctial = True

            if use_equinoctial:
                ex = e * np.cos(np.radians(aop) + np.radians(raan))
                ey = e * np.sin(np.radians(aop) + np.radians(raan))
                hx = np.tan(np.radians(inc) * 0.5) * np.cos(np.radians(raan))
                hy = np.tan(np.radians(inc) * 0.5) * np.sin(np.radians(raan))
                lv = np.radians(mu0) + np.radians(aop) + np.radians(raan)

                initialOrbit = EquinoctialOrbit(
                    float(a),
                    float(ex),
                    float(ey),
                    float(hx),
                    float(hy),
                    float(lv),
                    PositionAngle.MEAN,
                    self.inertialFrame,
                    initialDate,
                    self.mu + float(scipy.constants.G * kwargs['m']),
                )
            else:
                initialOrbit = KeplerianOrbit(
                    float(a),
                    float(e),
                    float(np.radians(inc)),
                    float(np.radians(aop)),
                    float(np.radians(raan)),
                    float(np.radians(mu0)),
                    PositionAngle.MEAN,
                    self.inertialFrame,
                    initialDate,
                    self.mu + float(scipy.constants.G * kwargs['m']),
                )

        self._construct_propagator(initialOrbit)
        self._set_forces(kwargs['A'], kwargs['C_D'], kwargs['C_R'])

        initialState = SpacecraftState(initialOrbit)

        self.propagator.setInitialState(initialState)

        tb_inds = t < 0.0
        t_back = t[tb_inds]

        tf_indst = t >= 0.0
        t_forward = t[tf_indst]

        if len(t_forward) == 1:
            if np.any(t_forward == 0.0):
                t_back = t
                t_forward = []
                tb_inds = t <= 0

        state = np.empty((6, len(t)), dtype=np.float)
        step_handler = PropagatorOrekit.OrekitVariableStep()

        if self.logger_func is not None:
            self._logger_start('propagation')

        if len(t_back) > 0:
            _t = t_back
            _t_order = np.argsort(np.abs(_t))
            _t_res = np.argsort(_t_order)
            _t = _t[_t_order]
            _state = np.empty((6, len(_t)), dtype=np.float)
            step_handler.set_params(_t, initialDate, _state, self.outputFrame)

            self.propagator.setMasterMode(step_handler)

            self.propagator.propagate(initialDate.shiftedBy(float(_t[-1])))

            #now _state is full and in the order of _t
            state[:, tb_inds] = _state[:, _t_res]

        if len(t_forward) > 0:
            _t = t_forward
            _t_order = np.argsort(np.abs(_t))
            _t_res = np.argsort(_t_order)
            _t = _t[_t_order]
            _state = np.empty((6, len(_t)), dtype=np.float)
            step_handler.set_params(_t, initialDate, _state, self.outputFrame)

            self.propagator.setMasterMode(step_handler)

            self.propagator.propagate(initialDate.shiftedBy(float(_t[-1])))

            #now _state is full and in the order of _t
            state[:, tf_indst] = _state[:, _t_res]

        if self.logger_func is not None:
            self._logger_record('propagation')

        if self.logger_func is not None:
            self._logger_record('get_orbit')

        return state
Ejemplo n.º 19
0
def main():

    a = 24396159.0  # semi major axis (m)
    e = 0.720  # eccentricity
    i = radians(10.0)  # inclination
    omega = radians(50.0)  # perigee argument
    raan = radians(150)  # right ascension of ascending node
    lM = 0.0  # mean anomaly

    # Set inertial frame
    inertialFrame = FramesFactory.getEME2000()

    # Initial date in UTC time scale
    utc = TimeScalesFactory.getUTC()
    initial_date = AbsoluteDate(2004, 1, 1, 23, 30, 00.000, utc)

    # Setup orbit propagator
    # gravitation coefficient
    mu = 3.986004415e+14

    # Orbit construction as Keplerian
    initialOrbit = KeplerianOrbit(a, e, i, omega, raan, lM, PositionAngle.MEAN,
                                  inertialFrame, initial_date, mu)

    initial_state = SpacecraftState(initialOrbit)

    # use a numerical propogator
    min_step = 0.001
    max_step = 1000.0
    position_tolerance = 10.0

    propagation_type = OrbitType.KEPLERIAN
    tolerances = NumericalPropagator.tolerances(position_tolerance,
                                                initialOrbit, propagation_type)

    integrator = DormandPrince853Integrator(min_step, max_step, 1e-5, 1e-10)

    propagator = NumericalPropagator(integrator)
    propagator.setOrbitType(propagation_type)

    # force model gravity field
    provider = GravityFieldFactory.getNormalizedProvider(10, 10)
    holmesFeatherstone = HolmesFeatherstoneAttractionModel(
        FramesFactory.getITRF(IERSConventions.IERS_2010, True), provider)

    # SRP
    # ssc = IsotropicRadiationSingleCoefficient(100.0, 0.8)  # Spacecraft surface area (m^2), C_r absorbtion
    # srp = SolarRadiationPressure(CelestialBodyFactory.getSun(), a, ssc)  # sun, semi-major Earth, spacecraft sensitivity

    propagator.addForceModel(holmesFeatherstone)
    # propagator.addForceModel(ThirdBodyAttraction(CelestialBodyFactory.getSun()))
    # propagator.addForceModel(ThirdBodyAttraction(CelestialBodyFactory.getMoon()))
    # propagator.addForceModel(srp)

    propagator.setMasterMode(60.0, TutorialStepHandler())

    propagator.setInitialState(initial_state)

    # propagator.setEphemerisMode()

    finalstate = propagator.propagate(initial_date.shiftedBy(
        10. * 24 * 60**2))  # TIme shift in seconds
Ejemplo n.º 20
0
    FramesFactory.getITRF(IERSConventions.IERS_2010, True),
)

# The COE for the orbit to be defined
a, ecc, inc, raan, argp, nu = (6828137.0, 0.0073, 87.0, 20.0, 10.0, 0)

# Define the orkeit and poliastro orbits to be used for all the event validation
# cases in this script
epoch0_orekit = AbsoluteDate(2020, 1, 1, 0, 0, 00.000,
                             TimeScalesFactory.getUTC())
ss0_orekit = KeplerianOrbit(
    float(a),
    float(ecc),
    float(inc * DEG_TO_RAD),
    float(argp * DEG_TO_RAD),
    float(raan * DEG_TO_RAD),
    float(nu * DEG_TO_RAD),
    PositionAngle.TRUE,
    FramesFactory.getEME2000(),
    epoch0_orekit,
    Constants.WGS84_EARTH_MU,
)
epoch0_poliastro = Time("2020-01-01", scale="utc")
ss0_poliastro = Orbit.from_classical(
    Earth,
    a * u.m,
    ecc * u.one,
    inc * u.deg,
    raan * u.deg,
    argp * u.deg,
    nu * u.deg,
    epoch0_poliastro,