Пример #1
0
    def __init__(self, orekit_data, settings=None, **kwargs):

        super(Orekit, self).__init__(settings=settings, **kwargs)

        if self.logger is not None:
            self.logger.debug(f'sorts.propagator.Orekit:init')
        if self.profiler is not None:
            self.profiler.start('Orekit:init')

        setup_orekit_curdir(filename=orekit_data)

        if self.logger is not None:
            self.logger.debug(f'Orekit:init:orekit-data = {orekit_data}')

        self.utc = TimeScalesFactory.getUTC()

        self.__settings = dict()
        self.__settings['SolarStrengthLevel'] = getattr(
            org.orekit.forces.drag.atmosphere.data.
            MarshallSolarActivityFutureEstimation.StrengthLevel,
            self.settings['solar_activity_strength'])
        self._tolerances = None

        if self.settings['constants_source'] == 'JPL-IAU':
            self.mu = Constants.JPL_SSD_EARTH_GM
            self.R_earth = Constants.IAU_2015_NOMINAL_EARTH_EQUATORIAL_RADIUS
            self.f_earth = (Constants.IAU_2015_NOMINAL_EARTH_EQUATORIAL_RADIUS
                            - Constants.IAU_2015_NOMINAL_EARTH_POLAR_RADIUS
                            ) / Constants.IAU_2015_NOMINAL_EARTH_POLAR_RADIUS
        else:
            self.mu = Constants.WGS84_EARTH_MU
            self.R_earth = Constants.WGS84_EARTH_EQUATORIAL_RADIUS
            self.f_earth = Constants.WGS84_EARTH_FLATTENING

        self.M_earth = self.mu / scipy.constants.G

        self.__params = None

        self._forces = {}

        if self.settings['radiation_pressure']:
            self._forces['radiation_pressure'] = None
        if self.settings['drag_force']:
            self._forces['drag_force'] = None

        if self.settings['earth_gravity'] == 'HolmesFeatherstone':
            provider = org.orekit.forces.gravity.potential.GravityFieldFactory.getNormalizedProvider(
                self.settings['gravity_order'][0],
                self.settings['gravity_order'][1])
            holmesFeatherstone = org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel(
                FramesFactory.getITRF(IERSConventions.IERS_2010, True),
                provider,
            )
            self._forces['earth_gravity'] = holmesFeatherstone

        elif self.settings['earth_gravity'] == 'Newtonian':
            Newtonian = org.orekit.forces.gravity.NewtonianAttraction(self.mu)
            self._forces['earth_gravity'] = Newtonian

        else:
            raise Exception(
                'Supplied Earth gravity model "{}" not recognized'.format(
                    self.settings['earth_gravity']))

        if self.settings['solarsystem_perturbers'] is not None:
            for body in self.settings['solarsystem_perturbers']:
                body_template = getattr(CelestialBodyFactory,
                                        'get{}'.format(body))
                body_instance = body_template()
                perturbation = org.orekit.forces.gravity.ThirdBodyAttraction(
                    body_instance)

                self._forces['perturbation_{}'.format(body)] = perturbation

        if self.logger is not None:
            for key in self._forces:
                if self._forces[key] is not None:
                    self.logger.debug(
                        f'Orekit:init:_forces:{key} = {type(self._forces[key])}'
                    )
                else:
                    self.logger.debug(f'Orekit:init:_forces:{key} = None')

        if self.profiler is not None:
            self.profiler.stop('Orekit:init')
Пример #2
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()
Пример #3
0
    def __init__(
        self,
        in_frame='EME',
        out_frame='ITRF',
        frame_tidal_effects=False,
        integrator='DormandPrince853',
        min_step=0.001,
        max_step=120.0,
        position_tolerance=10.0,
        earth_gravity='HolmesFeatherstone',
        gravity_order=(10, 10),
        solarsystem_perturbers=['Moon', 'Sun'],
        drag_force=True,
        atmosphere='DTM2000',
        radiation_pressure=True,
        solar_activity='Marshall',
        constants_source='WGS84',
        solar_activity_strength='WEAK',
        logger_func=None,
    ):
        super(PropagatorOrekit, self).__init__()

        self.logger_func = logger_func
        self.__log = {}
        self.__log_tmp = {}
        if self.logger_func is not None:
            self._logger_start('__init__')

        self.solarsystem_perturbers = solarsystem_perturbers
        self.in_frame = in_frame
        self.frame_tidal_effects = frame_tidal_effects
        self.out_frame = out_frame
        self.drag_force = drag_force
        self.gravity_order = gravity_order
        self.atmosphere = atmosphere
        self.radiation_pressure = radiation_pressure
        self.solar_activity = solar_activity
        self.SolarStrengthLevel = getattr(
            org.orekit.forces.drag.atmosphere.data.
            MarshallSolarActivityFutureEstimation.StrengthLevel,
            solar_activity_strength)
        self.integrator = integrator
        self.minStep = min_step
        self.maxStep = max_step
        self.position_tolerance = position_tolerance
        self._tolerances = None

        self.constants_source = constants_source
        if constants_source == 'JPL-IAU':
            self.mu = Constants.JPL_SSD_EARTH_GM
            self.R_earth = Constants.IAU_2015_NOMINAL_EARTH_EQUATORIAL_RADIUS
            self.f_earth = (Constants.IAU_2015_NOMINAL_EARTH_EQUATORIAL_RADIUS
                            - Constants.IAU_2015_NOMINAL_EARTH_POLAR_RADIUS
                            ) / Constants.IAU_2015_NOMINAL_EARTH_POLAR_RADIUS
        else:
            self.mu = Constants.WGS84_EARTH_MU
            self.R_earth = Constants.WGS84_EARTH_EQUATORIAL_RADIUS
            self.f_earth = Constants.WGS84_EARTH_FLATTENING

        self.M_earth = self.mu / scipy.constants.G

        self.earth_gravity = earth_gravity

        self.__params = None

        self.inputFrame = self._get_frame(self.in_frame)
        self.outputFrame = self._get_frame(self.out_frame)

        if self.inputFrame.isPseudoInertial():
            self.inertialFrame = self.inputFrame
        else:
            self.inertialFrame = FramesFactory.getEME2000()

        self.body = OneAxisEllipsoid(self.R_earth, self.f_earth,
                                     self.outputFrame)

        self._forces = {}

        if self.radiation_pressure:
            self._forces['radiation_pressure'] = None
        if self.drag_force:
            self._forces['drag_force'] = None

        if self.earth_gravity == 'HolmesFeatherstone':
            provider = org.orekit.forces.gravity.potential.GravityFieldFactory.getNormalizedProvider(
                self.gravity_order[0], self.gravity_order[1])
            holmesFeatherstone = org.orekit.forces.gravity.HolmesFeatherstoneAttractionModel(
                FramesFactory.getITRF(IERSConventions.IERS_2010, True),
                provider,
            )
            self._forces['earth_gravity'] = holmesFeatherstone

        elif self.earth_gravity == 'Newtonian':
            Newtonian = org.orekit.forces.gravity.NewtonianAttraction(self.mu)
            self._forces['earth_gravity'] = Newtonian

        else:
            raise Exception(
                'Supplied Earth gravity model "{}" not recognized'.format(
                    self.earth_gravity))

        if self.solarsystem_perturbers is not None:
            for body in self.solarsystem_perturbers:
                body_template = getattr(CelestialBodyFactory,
                                        'get{}'.format(body))
                body_instance = body_template()
                perturbation = org.orekit.forces.gravity.ThirdBodyAttraction(
                    body_instance)

                self._forces['perturbation_{}'.format(body)] = perturbation
        if self.logger_func is not None:
            self._logger_record('__init__')
Пример #4
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)