Exemple #1
0
def get_earth_rotation(dset):
    """Get corrections for satellite position and velocity by Earth rotation

    In a Earth-fixed reference system the Earth's rotation has to be applied, which accounts for time effect of Earth
    rotation during the signal propagates from the satellite to the receiver. Eq. 5.11 in :cite:`subirana2013` is used
    for correcting the satellite position and velocity in the Dataset field 'sat_posvel' about the Earth's rotation
    effect.

    Args:
        dset(Dataset):    Model data

    Returns:
        tuple:    with following entries

    =============== =============== ==================================================================================
     Elements        Type            Description
    =============== =============== ==================================================================================
     sat_pos         numpy.ndarray   Satellite position vector corrections in ITRS and [m]
     vel_pos         numpy.ndarray   Satellite velocity corrections in ITRS and [m/s]
    =============== =============== ==================================================================================
    """
    sat_pos = np.zeros((dset.num_obs, 3))
    sat_vel = np.zeros((dset.num_obs, 3))

    flight_time = get_flight_time(dset)
    rotation_angle = flight_time * constant.omega

    sat_pos = (
        rotation.R3(rotation_angle) @ dset.sat_posvel.trs.pos.val[:, :, None] -
        dset.sat_posvel.trs.pos.val[:, :, None])
    sat_vel = (
        rotation.R3(rotation_angle) @ dset.sat_posvel.trs.vel.val[:, :, None] -
        dset.sat_posvel.trs.vel.val[:, :, None])

    return sat_pos[:, :, 0], sat_vel[:, :, 0]
Exemple #2
0
def Q(time):
    """Transformation matrix for the celestial motion of the CIP

    The transformation matrix is described in the IERS Conventions [2], section 5.4.4. The implementation is based on
    section 5.6 "IAU 2006/2000A, CIO based, using X, Y series" in the SOFA Tools for Earth Attitude [1].

    Args:
        time:  A lib.time Time-object

    Returns:
        numpy.array: An array of 3x3 transformation matrices
    """
    return rotation.R3(-E(time)) @ rotation.R2(-d(time)) @ rotation.R3(E(time)) @ rotation.R3(s(time))
Exemple #3
0
def findsun(time):
    """Obtains the position vector of the Sun in relation to Earth (in ECEF).

    This routine is a reimplementation of routine findSun() in model.c of gLAB 3.0.0 software.

    Args:
        time(Time):    Time object

    Returns:
        numpy.ndarray:  Sun position vector given in ECEF [m]
    """
    AU = 1.495_978_70e8
    gstr, slong, sra, sdec = gsdtime_sun(time)

    sun_pos_x = np.cos(np.deg2rad(sdec)) * np.cos(np.deg2rad(sra)) * AU
    sun_pos_y = np.cos(np.deg2rad(sdec)) * np.sin(np.deg2rad(sra)) * AU
    sun_pos_z = np.sin(np.deg2rad(sdec)) * AU
    sun_pos_eci = np.vstack((sun_pos_x, sun_pos_y, sun_pos_z)).T

    # Rotate from inertial to non inertial system (ECI to ECEF)
    sun_pos_ecef = (
        rotation.R3(np.deg2rad(gstr)) @ sun_pos_eci.T)[:, :,
                                                       0]  # remove 1 dimension

    return sun_pos_ecef
Exemple #4
0
def dW_dxp(time):
    """Derivative of transformation matrix for the polar motion with regards to the CIP (Celestial Intermediate Pole)
    in TRF along the Greenwich meridian x_p.

    This is done according to equations (2.31) in Teke :cite:`teke2011` which is the analytical partial derivative of
    equation (5.3) in :cite:'iers2010'.
    """
    return rotation.R3(-s_prime(time)) @ rotation.dR2(xp(time)) @ rotation.R1(yp(time))
Exemple #5
0
def dQ_dY(time):
    """Derivative of transformation matrix for nutation/presession with regards to the Y coordinate of CIP in GCRS
    """
    # Rotation matrices
    R3_E = rotation.R3(E(time))
    R3_s = rotation.R3(s(time))
    R2_md = rotation.R2(-d(time))
    R3_mE = rotation.R3(-E(time))
    dR3_s = rotation.dR3(s(time))
    dR3_E = rotation.dR3(E(time))
    dR3_mE = rotation.dR3(-E(time))
    dR2_md = rotation.dR2(-d(time))

    return (
        dR3_mE @ R2_md @ R3_E @ R3_s * (-dE_dY(time))
        + R3_mE @ dR2_md @ R3_E @ R3_s * (-dd_dY(time))
        + R3_mE @ R2_md @ dR3_E @ R3_s * (dE_dY(time))
        + R3_mE @ R2_md @ R3_E @ dR3_s * (ds_dY(time))
    )
Exemple #6
0
def W(time):
    """Transformation matrix for the polar motion

    The transformation matrix is described in the IERS Conventions [2], section 5.4.1. The implementation is based on
    section 5.6 "IAU 2006/2000A, CIO based, using X, Y series" in the SOFA Tools for Earth Attitude [1].

    Args:
        time:  A lib.time Time-object

    Returns:
        numpy.array: An array of 3x3 transformation matrices
    """
    return rotation.R3(-s_prime(time)) @ rotation.R2(xp(time)) @ rotation.R1(yp(time))
Exemple #7
0
    def _get_satellite_position_vector(self, bdict):
        """Determine satellite position vector in Earth centered Earth fixed (ECEF) coordinate system.

        Following equations are based on Table 20-IV. in :cite:`is-gps-200h`.

        Args:
            bdict (dict):       Selected and prepared broadcast ephemeris dictionary with following entries

        ===============  ======  =============================================================
         Keys             Unit    Description
        ===============  ======  =============================================================
         a                m       Semimajor axis
         e                        Eccentricity of the orbit
         E                rad     Eccentric anomaly
         i                rad     Inclination
         lambda_          rad     Instantaneous Greenwich longitude of the ascending node
         n                rad/s   Corrected mean motion
         r                m       Orbit radius
         tk               s       Eclapsed time referred to ephemeris reference epoch
         u                rad     Argument of latitude
         vega             rad     True anomaly
        ===============  ======  =============================================================

        Returns:
            dict:    Following entries are added to broadcast ephemeris dictionary

        ===============  ======  ==================================================================================
         Keys             Unit    Description
        ===============  ======  ==================================================================================
         r_ecef           m       3-dimensional numpy array with satellite position in Earth centered Earth fixed (ECEF)
                                  coordinate system
         r_orb            m       3-dimensional numpy array with satellite position in orbital coordinate system
        ===============  ======  ==================================================================================
        """
        # TODO: What should be done for GEO satellites (e.g. see in gLAB function getPositionBRDC() in model.c)?

        # Transformation from spherical to cartesian orbital coordinate system
        r_orb = np.array([
            bdict["r"] * np.cos(bdict["u"]), bdict["r"] * np.sin(bdict["u"]),
            0.0
        ])

        # Transformation from cartesian orbital to Earth centered Earth fixed (ECEF) geocentric equatorial coordinate
        # system
        r_ecef = rotation.R3(-bdict["lambda_"]).dot(
            rotation.R1(-bdict["i"])).dot(r_orb.T)

        bdict.update({"r_ecef": r_ecef, "r_orb": r_orb})
Exemple #8
0
def R(time):
    """Transformation matrix for the Earth rotation

    The transformation matrix is described in the IERS Conventions [2]_, section 5.4.2. The implementation is based on
    section 5.6 "IAU 2006/2000A, CIO based, using X, Y series" in the SOFA Tools for Earth Attitude [1]_.

    According to equation (5.5) in the IERS Conventions [2]_, `The CIO based transformation matrix arising from the
    rotation of the Earth around the axis of the CIP can be expressed as`

    .. math::

        R(t) = R_3(-ERA)

    Args:
        time:  A lib.time Time-object

    Returns:
        numpy.array: An array of 3x3 transformation matrices

    """

    return rotation.R3(-ERA(time))
Exemple #9
0
def dW_dyp(time):
    """Derivative of transformation matrix for the polar motion with regards to the CIP in ITRS.

    Analytical partial derivative of equation (5.3) in :cite:'iers2010'.
    """
    return rotation.R3(-s_prime(time)) @ rotation.R2(xp(time)) @ rotation.dR1(yp(time))
Exemple #10
0
    def _keplerian_to_geocentric(self,
                                 a,
                                 e,
                                 i,
                                 Omega,
                                 omega,
                                 x_anomaly,
                                 anomaly="E"):
        r"""Compute orbit position and velocity vector in geocentric equatorial coordinate system based on Keplerian
        elements for elliptic orbits.

        The transformation is done either for float type or numpy array/list type input arguments. The implementation
        is based on Section 2.2.3 in :cite:`montenbruck2012`.

        Args:
            a (numpy.ndarray):          Semimajor axis of orbit in [m]
            e (numpy.ndarray):          Eccentricity of the orbit
            i (numpy.ndarray):          Inclination of orbital plane in [rad]
            Omega (numpy.ndarray):      Right ascension of ascending node in [rad]
            omega (numpy.ndarray):      Argument of perigee in [rad]
            x_anomaly (numpy.ndarray):  Anomaly in [rad], which can be either mean, eccentric or true anomaly in
                                        dependency of 'anomaly' argument
            anomaly (str):              Anomaly, which can be 'M' (mean anomaly), 'E' (eccentric anomaly) or
                                        'v' (true anomaly)

        Returns:
            tuple with numpy.ndarray types:         with following elements

        ==========  =====  =======================================================================
         Element    Unit   Description
        ==========  =====  =======================================================================
         R           m     Orbit position vector in geocentric equatorial coordinate system
         V           m     Orbit velocity vector in geocentric equatorial coordinate system
        ==========  =====  =======================================================================

        """

        # Determine eccentric anomaly E
        if anomaly == "M":  # mean anomaly in [rad]
            E = get_eccentric_anomaly(
                x_anomaly, e)  # TODO: get_eccentric_anomaly is not defined ...
        elif anomaly == "E":  # eccentric anomaly in [rad]
            E = x_anomaly
        elif anomaly == "v":  # true anomaly in [rad]  (see Eq. 3.5 in [2])
            E = 2 * np.atan(
                np.tan(v / 2) * np.sqrt(1 - e /
                                        (1 + e)))  # TODO: v is not defined ...
        else:
            log.fatal(
                "Anomaly flag '{}' is wrong. It should be either 'M' (mean anomaly), 'E' (eccentric anomaly) "
                "or 'v' (true anomaly).",
                anomaly,
            )

        num_obs = len(E)
        r_orb = np.zeros((num_obs, 3))
        v_orb = np.zeros((num_obs, 3))
        R = np.zeros((num_obs, 3))
        V = np.zeros((num_obs, 3))

        cosE = np.cos(E)
        sinE = np.sin(E)
        fac = np.sqrt((1 - e) * (1 + e))
        r = a * (1 - e * cosE)  # Distance
        v = np.sqrt(constant.GM * a) / r  # Velocity

        for idx in range(0, num_obs):  # Todo: Vectorize

            # Transformation from spherical to cartesian orbital coordinate system
            r_orb = np.array([[
                a[idx] * (cosE[idx] - e[idx]), a[idx] * fac[idx] * sinE[idx],
                0.0
            ]])
            v_orb = np.array(
                [[-v[idx] * sinE[idx], v[idx] * fac[idx] * cosE[idx], 0.0]])

            # Transformation from cartesian orbital to geocentric equatorial coordinate system
            PQW = rotation.R3(-Omega[idx]).dot(rotation.R1(-i[idx])).dot(
                rotation.R3(-omega[idx]))

            R[idx] = (PQW.dot(r_orb.T)).T
            V[idx] = (PQW.dot(v_orb.T)).T

        return R, V