예제 #1
0
    def test_mean2true(self):
        M = n.linspace(0, 1.5 * n.pi, num=100, dtype=n.float)
        nu = dpt.mean2true(M, 0.0)
        nt.assert_array_almost_equal(nu, M, decimal=7)

        e = n.linspace(0, 0.9, num=100, dtype=n.float)
        nu = dpt.mean2true(n.pi, e)
        nu0 = n.ones(e.shape, dtype=n.float) * n.pi
        nt.assert_array_almost_equal(nu, nu0, decimal=7)
예제 #2
0
    def _gen_cart(self, p):
        orb = n.array([
            self.init_data['a'],
            self.init_data['e'],
            self.init_data['inc'],
            self.init_data['aop'],
            self.init_data['raan'],
            dpt.mean2true(self.init_data['mu0'],
                          self.init_data['e'],
                          radians=False),
        ])
        cart = dpt.kep2cart(orb,
                            m=self.init_data['m'],
                            M_cent=p.M_earth,
                            radians=False)

        self.init_data_cart = {
            'x': cart[0],
            'y': cart[1],
            'z': cart[2],
            'vx': cart[3],
            'vy': cart[4],
            'vz': cart[5],
            'mjd0': 57125.7729,
            'C_D': 2.3,
            'C_R': 1.0,
            'm': 8000,
            'A': 1.0,
        }
예제 #3
0
    def get_orbit(self,t,a,e,inc,raan,aop,mu0,mjd0, **kwargs):
        '''
        **Implementation:**
    
        Units are in meters and degrees.

        Keyword arguments are:

        **Uses:**
            * 
        
        See :func:`propagator_base.PropagatorBase.get_orbit`.
        '''

        m = kwargs.setdefault('m', 0.0)

        orb = np.array([a,e,inc,aop,raan,dpt.mean2true(mu0,e, radians = False)], dtype=np.float)
        
        if self._inframe_to_heliocentric:
            M_cent = self.planets_mass[self._earth_ind - 1]
        else:
            M_cent = self.m_sun

        x, y, z, vx, vy, vz = dpt.kep2cart(
            orb,
            m=m,
            M_cent=M_cent,
            radians=False,
        )

        return self.get_orbit_cart(t, x, y, z, vx, vy, vz, mjd0, **kwargs)
예제 #4
0
    def test_mean_true_inverse_array(self):
        M = n.linspace(0.0, 1.5 * n.pi, num=100, dtype=n.float)
        e = n.linspace(0, 0.99, num=100, dtype=n.float)

        Mv, ev = n.meshgrid(M, e)

        nu_test = dpt.mean2true(Mv, ev)
        M_test = dpt.true2mean(nu_test, ev)
        nt.assert_array_almost_equal(M_test, Mv, decimal=7)
예제 #5
0
    def test_mean_true_inverse_float(self):
        M = n.linspace(0.0, 1.5 * n.pi, num=100, dtype=n.float)
        e = n.linspace(0, 0.99, num=100, dtype=n.float)

        for eit in e:
            for Mit in M:
                nu_test = dpt.mean2true(Mit, eit)
                M_test = dpt.true2mean(nu_test, eit)
                nt.assert_almost_equal(M_test, Mit, decimal=7)
예제 #6
0
 def get_states(self, M_cent = propagator_sgp4.M_earth):
     '''Use the orbital parameters and get the state.'''
     orbs = self.get_all_orbits(order_angs = True).T
     orbs[:,5] = dpt.mean2true(orbs[:,5], orbs[:,1], radians=False)
     if 'm' in self.header:
         mv = self.objs['m']
     else:
         mv = np.zeros(len(self), dtype=self._default_dtype)
     states = dpt.kep2cart(orbs, m=mv, M_cent=M_cent, radians=False).T
     return states
예제 #7
0
    def get_orbit(self, t, a, e, inc, raan, aop, mu0, mjd0, **kwargs):
        '''
        **Implementation:**
    
        All state-vector units are in meters.

        Keyword arguments contain only mass :code:`m` in kg and is not required.

        They also contain a option to give angles in radians or degrees. By default input is assumed to be degrees.

        **Frame:**

        The input frame is always the same as the output frame.
    
        :param float m: Mass of the object in kg.
        :param bool radians: If true, all angles are assumed to be in radians.
        '''

        radians = kwargs.setdefault('radians', False)
        m = kwargs.setdefault('m', 0.0)

        if radians:
            one_lap = np.pi*2.0
        else:
            one_lap = 360.0

        gravitational_param = consts.G*(M_earth + m)

        mean_motion = np.sqrt(gravitational_param/(a**3.0))/(np.pi*2.0)

        t = self._make_numpy(t)

        mean_anomalies = mu0 + t*mean_motion*one_lap
        mean_anomalies = np.remainder(mean_anomalies, one_lap)

        true_anomalies = dpt.mean2true(mean_anomalies, e, radians=radians)

        orb0 = np.array([a, e, inc, aop, raan], dtype=np.float64)
        orb0.shape = (5,1)

        orbs = np.empty((6, len(t)), dtype=np.float64)
        orbs[:5, :] = np.repeat(orb0, len(t), axis=1)
        orbs[5, :] = true_anomalies

        states_raw = dpt.kep2cart(orbs, m=m, M_cent=M_earth, radians=radians)

        if self.in_frame != self.out_frame:
            states = frame_conversion(states_raw, t/(3600.0*24.0) + mjd0, self.orekit_in_frame, self.orekit_out_frame)
        else:
            states = states_raw
        
        return states
예제 #8
0
파일: TLE_tools.py 프로젝트: zzwei1/SORTSpp
def _sgp4_elems2cart(kep, radians=True):
    '''Orbital elements to cartesian coordinates. Wrap DPT-function to use mean anomaly, km and reversed order on aoe and raan.
    
    Neglecting mass is sufficient for this calculation (the standard gravitational parameter is 24 orders larger then the change).
    '''
    _kep = kep.copy()
    _kep[0] *= 1e3
    tmp = _kep[4]
    _kep[4] = _kep[3]
    _kep[3] = tmp
    _kep[5] = dpt.mean2true(_kep[5], _kep[1], radians=radians)
    cart = dpt.kep2cart(kep,
                        m=0.0,
                        M_cent=propagator_sgp4.M_earth,
                        radians=radians)
    return cart
예제 #9
0
    def get_orbit(self, t, a, e, inc, raan, aop, mu0, mjd0, **kwargs):
        '''
        **Implementation:**
    
        All state-vector units are in meters.

        Keyword arguments contain only information needed for ballistic coefficient :code:`B` used by SGP4. Either :code:`B` or :code:`C_D`, :code:`A` and :code:`m` must be supplied.
        They also contain a option to give angles in radians or degrees. By default input is assumed to be degrees.

        **Frame:**

        The input frame is ECI (TEME) for orbital elements and Cartesian. The output frame is as standard ECEF (ITRF). But can be set to TEME.

        :param float B: Ballistic coefficient
        :param float C_D: Drag coefficient
        :param float A: Cross-sectional Area
        :param float m: Mass
        :param bool radians: If true, all angles are assumed to be in radians.
        '''
        if 'm' in kwargs:
            m = kwargs['m']
        else:
            m = 0.0

        if 'radians' in kwargs:
            radians = kwargs['radians']
        else:
            radians = False
        
        if not radians:
            inc = np.radians(inc)
            mu0 = np.radians(mu0)
            raan = np.radians(raan)
            aop = np.radians(aop)

        orb = np.array([a, e, inc, aop, raan, dpt.mean2true(mu0, e, radians=True)],dtype=np.float)

        state_c = dpt.kep2cart(orb, m=m, M_cent=M_earth, radians=True)

        return self.get_orbit_cart(t, x=state_c[0], y=state_c[1], z=state_c[2], vx=state_c[3], vy=state_c[4], vz=state_c[5], mjd0=mjd0, **kwargs)
예제 #10
0
    def update(self, **kwargs):
        '''Updates the orbital elements and Cartesian state vector of the space object.

        Can update any of the related state parameters, all others will automatically update.

        Cannot update Keplerian and Cartesian elements simultaneously.

        :param float a: Semi-major axis in km
        :param float e: Eccentricity
        :param float i: Inclination in degrees
        :param float aop: Argument of perigee in degrees
        :param float raan: Right ascension of the ascending node in degrees
        :param float mu0: Mean anomaly in degrees
        :param float x: X position in km
        :param float y: Y position in km
        :param float z: Z position in km
        :param float vx: X-direction velocity in km/s
        :param float vy: Y-direction velocity in km/s
        :param float vz: Z-direction velocity in km/s
        '''

        kep = ['a', 'e', 'i', 'raan', 'aop', 'mu0']
        cart = ['x', 'y', 'z', 'vx', 'vy', 'vz']

        kep_orb = False
        cart_orb = False

        for key, val in kwargs.items():
            if key in kep:
                kep_orb = True
                setattr(self, key, val)

            elif key in cart:
                cart_orb = True
                setattr(self, key, val)

            else:
                raise TypeError('{} variable cannot be updated'.format(key))

        if kep_orb and cart_orb:
            raise TypeError(
                'Cannot update both Cartesian and Kepler elements at the same time'
            )

        if kep_orb:
            orb = n.array([
                self.a * 1e3, self.e, self.i, self.aop, self.raan,
                dpt.mean2true(self.mu0, self.e, radians=False)
            ],
                          dtype=n.float)
            state_c = dpt.kep2cart(
                orb, m=n.array([self.m
                                ]), M_cent=self.M_cent, radians=False) * 1e-3

        if cart_orb:
            state = n.array(
                [self.x, self.y, self.z, self.vx, self.vy, self.vz],
                dtype=n.float) * 1e3
            self.state_cart = state
            orb_c = dpt.cart2kep(state,
                                 m=self.m,
                                 M_cent=self.M_cent,
                                 radians=False)

        if kep_orb:
            self.x = state_c[0]
            self.y = state_c[1]
            self.z = state_c[2]
            self.vx = state_c[3]
            self.vy = state_c[4]
            self.vz = state_c[5]
            self.state_cart = state_c * 1e3

        if cart_orb:
            self.a = orb_c[0] * 1e-3
            self.e = orb_c[1]
            self.i = orb_c[2]
            self.raan = orb_c[4]
            self.aop = orb_c[3]
            self.mu0 = dpt.true2mean(orb_c[5], orb_c[1], radians=False)
예제 #11
0
    def __init__(self,
                 a,
                 e,
                 i,
                 raan,
                 aop,
                 mu0,
                 d=0.01,
                 C_D=2.3,
                 A=1.0,
                 m=1.0,
                 mjd0=57125.7729,
                 oid=42,
                 M_cent=M_e,
                 C_R=1.0,
                 propagator=default_propagator,
                 propagator_options={},
                 **kwargs):

        self.kwargs = kwargs

        self.M_cent = M_cent

        orb = n.array(
            [a * 1e3, e, i, aop, raan,
             dpt.mean2true(mu0, e, radians=False)],
            dtype=n.float)
        state_c = dpt.kep2cart(orb, m=m, M_cent=self.M_cent,
                               radians=False) * 1e-3

        x = state_c[0]
        y = state_c[1]
        z = state_c[2]
        vx = state_c[3]
        vy = state_c[4]
        vz = state_c[5]

        self.state_cart = state_c * 1e3

        self.a = a
        self.e = e
        self.i = i
        self.oid = oid
        self.raan = raan
        self.aop = aop
        self.mu0 = mu0

        self.x = x
        self.y = y
        self.z = z
        self.vx = vx
        self.vy = vy
        self.vz = vz

        self.C_D = C_D
        self.C_R = C_R
        self.A = A
        self.m = m
        self.mjd0 = mjd0
        self._propagator = propagator
        self.propagator_options = propagator_options
        self.prop = propagator(**propagator_options)
        self.d = d
예제 #12
0
orbs_fail = []
fail_inds = []
fail_err = []
fail_errv = []
for ind, kep in enumerate(orb_init_list):
    #print('{}/{} done'.format(ind, len(orb_init_list)))
    M_earth = propagator_sgp4.SGP4.GM * 1e9 / consts.G

    state_TEME = dpt.kep2cart(kep, m=0.0, M_cent=M_earth, radians=False) * 1e-3

    mean_elements = tle.TEME_to_TLE(state_TEME, mjd0=mjd0, kepler=False)
    mlst = mean_elements.tolist()
    mlst[0] *= 1e3
    mlst[4] = mean_elements[3]
    mlst[3] = mean_elements[4]
    mlst[5] = dpt.mean2true(mean_elements[5], mean_elements[1], radians=True)
    mean_orbs.append(mlst)
    state = propagator_sgp4.sgp4_propagation(mjd0, mean_elements, B=0, dt=0.0)

    state_diff = np.abs(state - state_TEME) * 1e3

    try:
        nt.assert_array_less(state_diff[:3],
                             np.full((3, ), 100, dtype=state_diff.dtype))
        nt.assert_array_less(state_diff[3:],
                             np.full((3, ), 10, dtype=state_diff.dtype))
        orbs_pass.append(kep.tolist())
        cols.append(0.0)
    except AssertionError as err:
        fail_inds.append(ind)
        orbs_fail.append(kep.tolist())
import numpy as n

from keplerian_sgp4 import sgp4_propagator as sgp_p
import dpt_tools as dpt

init_data = {
    'a': 7000,
    'e': 0.0,
    'inc': 90.0,
    'raan': 10,
    'aop': 10,
    'mu0': 40.0,
    'mjd0': 2457126.2729,
    'C_D': 2.3,
    'm': 8000,
    'A': 1.0,
}

self.t0 = n.array([0.0], dtype=n.float)

p = sgp_p()

ecefs = p.get_orbit(self.t, **self.init_data)
o = n.array(
    [7000e3, 0.0, 90.0, 10.0, 10.0,
     dpt.mean2true(40.0, 0.0, radians=False)])

x = dpt.kep2cart(o, m=init_data['m'], M_cent=5.98e24, radians=False)

print(x)
print(ecefs)
예제 #14
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