示例#1
0
    def sun_synchronous(cls,
                        *,
                        alt_km=None,
                        ecc=None,
                        inc_deg=None,
                        ltan_h=12,
                        date=None,
                        ta_deg=0):
        """Creates Sun synchronous predictor instance.

        Parameters
        ----------
        alt_km : float, optional
            Altitude, in km.
        ecc : float, optional
            Eccentricity.
        inc_deg : float, optional
            Inclination, in degrees.
        ltan_h : int, optional
            Local Time of the Ascending Node, in hours (default to noon).
        date : datetime.date, optional
            Reference date for the orbit, (default to today).
        ta_deg : float
            Increment or decrement of true anomaly, will adjust the epoch
            accordingly.

        Notes
        -----
        See Vallado "Fundamentals of Astrodynamics and Applications", 4th ed (2013)
        section 11.4.1.

        """
        if date is None:
            date = dt.datetime.today().date()

        try:
            with np.errstate(invalid="raise"):
                if alt_km is not None and ecc is not None:
                    # Normal case, solve for inclination
                    sma = R_E_KM + alt_km
                    inc_deg = degrees(
                        np.arccos(
                            (-2 * sma**(7 / 2) * OMEGA * (1 - ecc**2)**2) /
                            (3 * R_E_KM**2 * J2 * np.sqrt(MU_E))))

                elif alt_km is not None and inc_deg is not None:
                    # Not so normal case, solve for eccentricity
                    sma = R_E_KM + alt_km
                    ecc = np.sqrt(
                        1 - np.sqrt((-3 * R_E_KM**2 * J2 * np.sqrt(MU_E) *
                                     np.cos(radians(inc_deg))) /
                                    (2 * OMEGA * sma**(7 / 2))))

                elif ecc is not None and inc_deg is not None:
                    # Rare case, solve for altitude
                    sma = (-np.cos(radians(inc_deg)) *
                           (3 * R_E_KM**2 * J2 * np.sqrt(MU_E)) /
                           (2 * OMEGA * (1 - ecc**2)**2))**(2 / 7)

                else:
                    raise ValueError(
                        "Exactly two of altitude, eccentricity and inclination must be given"
                    )

        except FloatingPointError as e:
            raise InvalidOrbitError(
                "Cannot find Sun-synchronous orbit with given parameters"
            ) from e

        # TODO: Allow change in time or location
        # Right the epoch is fixed given the LTAN, as well as the sub-satellite point
        epoch = dt.datetime(date.year, date.month, date.day,
                            *float_to_hms(ltan_h))
        raan = raan_from_ltan(epoch, ltan_h)

        return cls(sma, ecc, inc_deg, raan, 0, ta_deg, epoch)
示例#2
0
def test_raan_from_ltan(when_utc, raan, ltan):
    assert pytest.approx(raan_from_ltan(when_utc, ltan), abs=1 / 3600) == raan
示例#3
0
    def sun_synchronous(cls,
                        *,
                        alt_km=None,
                        ecc=None,
                        inc_deg=None,
                        ltan_h=12,
                        date=None):
        """Creates Sun synchronous predictor instance.

        Parameters
        ----------
        alt_km : float, optional
            Altitude, in km.
        ecc : float, optional
            Eccentricity.
        inc_deg : float, optional
            Inclination, in degrees.
        ltan_h : int, optional
            Local Time of the Ascending Node, in hours (default to noon).
        date : datetime.date, optional
            Reference date for the orbit, (default to today).

        """
        if date is None:
            date = dt.datetime.today().date()

        # TODO: Allow change in time or location
        epoch = dt.datetime(date.year,
                            date.month,
                            date.day,
                            *float_to_hms(ltan_h),
                            tzinfo=dt.timezone.utc)
        raan = raan_from_ltan(epoch, ltan_h)

        try:
            with np.errstate(invalid="raise"):
                if alt_km is not None and ecc is not None:
                    # Normal case, solve for inclination
                    sma = R_E_KM + alt_km
                    inc_deg = degrees(
                        np.arccos(
                            (-2 * sma**(7 / 2) * OMEGA * (1 - ecc**2)**2) /
                            (3 * R_E_KM**2 * J2 * np.sqrt(MU_E))))

                elif alt_km is not None and inc_deg is not None:
                    # Not so normal case, solve for eccentricity
                    sma = R_E_KM + alt_km
                    ecc = np.sqrt(
                        1 - np.sqrt((-3 * R_E_KM**2 * J2 * np.sqrt(MU_E) *
                                     np.cos(radians(inc_deg))) /
                                    (2 * OMEGA * sma**(7 / 2))))

                elif ecc is not None and inc_deg is not None:
                    # Rare case, solve for altitude
                    sma = (-np.cos(radians(inc_deg)) *
                           (3 * R_E_KM**2 * J2 * np.sqrt(MU_E)) /
                           (2 * OMEGA * (1 - ecc**2)**2))**(2 / 7)

                else:
                    raise ValueError(
                        "Exactly two of altitude, eccentricity and inclination must be given"
                    )

        except FloatingPointError:
            raise InvalidOrbitError(
                "Cannot find Sun-synchronous orbit with given parameters")

        return cls(sma, ecc, inc_deg, raan, 0, 0, epoch)