Esempio n. 1
0
    def propagate(self, value, method=mean_motion, rtol=1e-10, **kwargs):
        """Propagates an orbit a specified time.

        If value is true anomaly, propagate orbit to this anomaly and return the result.
        Otherwise, if time is provided, propagate this `Orbit` some `time` and return the result.

        Parameters
        ----------
        value : ~astropy.units.Quantity, ~astropy.time.Time, ~astropy.time.TimeDelta
            Scalar time to propagate.
        rtol : float, optional
            Relative tolerance for the propagation algorithm, default to 1e-10.
        method : function, optional
            Method used for propagation
        **kwargs
            parameters used in perturbation models

        Returns
        -------
        Orbit
            New orbit after propagation.

        """
        if isinstance(value, time.Time) and not isinstance(value, time.TimeDelta):
            time_of_flight = value - self.epoch
        else:
            # Works for both Quantity and TimeDelta objects
            time_of_flight = time.TimeDelta(value)

        cartesian = propagate(self, time_of_flight, method=method, rtol=rtol, **kwargs)
        new_epoch = self.epoch + time_of_flight

        # TODO: Unify with sample
        # If the frame supports obstime, set the time values
        try:
            kwargs = {}
            if "obstime" in self.frame.frame_attributes:
                kwargs["obstime"] = new_epoch

            # Use of a protected method instead of frame.realize_frame
            # because the latter does not let the user choose the representation type
            # in one line despite its parameter names, see
            # https://github.com/astropy/astropy/issues/7784
            coords = self.frame._replicate(
                cartesian, representation_type="cartesian", **kwargs
            )

            return self.from_coords(self.attractor, coords, plane=self.plane)

        except NotImplementedError:
            return self.from_vectors(
                self.attractor,
                cartesian[0].xyz,
                cartesian[0].differentials["s"].d_xyz,
                new_epoch,
            )
Esempio n. 2
0
    def _init_groundtrack_packet_cords_(self, i, rtol):
        """

        Parameters
        ----------
        i: int
            Index of referenced orbit
        rtol: float
            Maximum relative error permitted

        Returns
        -------
        coordinate list
        """
        cart_cords = []  # type: List[float]

        h = (self.end_epoch - self.orbits[i][2]).to(
            u.second) / self.orbits[i][1]

        # Get rounding factor given the relative tolerance
        rf = 0
        while rtol < 1:
            rtol *= 10
            rf += 1

        ellipsoid = self.cust_prop[0]

        for k in range(self.orbits[i][1] + 2):
            position = propagate(self.orbits[i][0],
                                 TimeDelta(k * h),
                                 rtol=rtol)

            cords = position.represent_as(CartesianRepresentation).xyz.to(
                u.meter).value
            cords = np.insert(cords, 0, h.value * k, axis=0)

            # flatten list
            cords = list(map(lambda x: round(x[0], rf), cords.tolist()))
            t, p = cords[0], cords[1:]
            pr_p = project_point_on_ellipsoid(p[0], p[1], p[2], ellipsoid[0],
                                              ellipsoid[1], ellipsoid[2])
            # Add a small number to ensure that our point lies above the surface of the
            # ellipsoid. We do this because small losses in precision may cause the point
            # to lie slightly bellow the surface. An iterative method could be used instead
            # but the error margin is too small to be worth it.

            _cords = t, pr_p[0] + 0.1, pr_p[1] + 0.1, pr_p[2] + 0.1
            cart_cords += _cords

        return cart_cords
Esempio n. 3
0
    def propagate(self, value, method=mean_motion, rtol=1e-10, **kwargs):
        """Propagates an orbit.

        If value is true anomaly, propagate orbit to this anomaly and return the result.
        Otherwise, if time is provided, propagate this `Orbit` some `time` and return the result.

        Parameters
        ----------
        value : Multiple options
            True anomaly values or time values. If given an angle, it will always propagate forward.
        rtol : float, optional
            Relative tolerance for the propagation algorithm, default to 1e-10.
        method : function, optional
            Method used for propagation
        **kwargs
            parameters used in perturbation models

        """
        if hasattr(value, "unit") and value.unit in ("rad", "deg"):
            p, ecc, inc, raan, argp, _ = rv2coe(
                self.attractor.k.to(u.km ** 3 / u.s ** 2).value,
                self.r.to(u.km).value,
                self.v.to(u.km / u.s).value,
            )

            # Compute time of flight for correct epoch
            M = nu_to_M(self.nu, self.ecc)
            new_M = nu_to_M(value, self.ecc)
            time_of_flight = Angle(new_M - M).wrap_at(360 * u.deg) / self.n

            return self.from_classical(
                self.attractor,
                p / (1.0 - ecc ** 2) * u.km,
                ecc * u.one,
                inc * u.rad,
                raan * u.rad,
                argp * u.rad,
                value,
                epoch=self.epoch + time_of_flight,
                plane=self._plane,
            )
        else:
            if isinstance(value, time.Time) and not isinstance(value, time.TimeDelta):
                time_of_flight = value - self.epoch
            else:
                time_of_flight = time.TimeDelta(value)

            return propagate(self, time_of_flight, method=method, rtol=rtol, **kwargs)
Esempio n. 4
0
	def _setcoords(self):
		"""Update tofs and coords. 
	
		Note
		----
		After updating T or kwargs this method is going to 
		be called in order to update the times of flight of the
		propagator as well as the resulting coordinate for the new
		timeframe or perturbative force.
		"""

		self.tofs = TimeDelta(np.linspace(0,self.T*24*3600*u.s,
		 num=int(self.T*24*3600/self._DT)))

		self.coords = propagation.propagate(self.orbit,
			self.tofs,method=self.method,**self.kwargs)
Esempio n. 5
0
    def sample(self, values=100, *, min_anomaly=None, max_anomaly=None):
        r"""Samples an orbit to some specified time values.

        .. versionadded:: 0.8.0

        Parameters
        ----------
        values : int
            Number of interval points (default to 100).
        min_anomaly, max_anomaly : ~astropy.units.Quantity, optional
            Anomaly limits to sample the orbit.
            For elliptic orbits the default will be :math:`E \in \left[0, 2 \pi \right]`,
            and for hyperbolic orbits it will be :math:`\nu \in \left[-\nu_c, \nu_c \right]`,
            where :math:`\nu_c` is either the current true anomaly
            or a value that corresponds to :math:`r = 3p`.

        Returns
        -------
        positions: ~astropy.coordinates.BaseCoordinateFrame
            Array of x, y, z positions, with proper times as the frame attributes if supported.

        Notes
        -----
        When specifying a number of points, the initial and final
        position is present twice inside the result (first and
        last row). This is more useful for plotting.

        Examples
        --------
        >>> from astropy import units as u
        >>> from poliastro.examples import iss
        >>> iss.sample()  # doctest: +ELLIPSIS
        <CartesianRepresentation (x, y, z) in km ...
        >>> iss.sample(10)  # doctest: +ELLIPSIS
        <CartesianRepresentation (x, y, z) in km ...

        """
        if self.ecc < 1:
            nu_values = self._sample_closed(values, min_anomaly, max_anomaly)
        else:
            nu_values = self._sample_open(values, min_anomaly, max_anomaly)

        time_values = time.TimeDelta(self._generate_time_values(nu_values))
        cartesian = propagate(self, time_values)

        return cartesian
Esempio n. 6
0
    def propagate(self, value, method=mean_motion, rtol=1e-10, **kwargs):
        """Propagates an orbit a specified time.

        If value is true anomaly, propagate orbit to this anomaly and return the result.
        Otherwise, if time is provided, propagate this `Orbit` some `time` and return the result.

        Parameters
        ----------
        value : ~astropy.units.Quantity, ~astropy.time.Time, ~astropy.time.TimeDelta
            Scalar time to propagate.
        rtol : float, optional
            Relative tolerance for the propagation algorithm, default to 1e-10.
        method : function, optional
            Method used for propagation
        **kwargs
            parameters used in perturbation models

        Returns
        -------
        Orbit
            New orbit after propagation.

        """
        if isinstance(value,
                      time.Time) and not isinstance(value, time.TimeDelta):
            time_of_flight = value - self.epoch
        else:
            # Works for both Quantity and TimeDelta objects
            time_of_flight = time.TimeDelta(value)

        # TODO: Create a from_coordinates method
        coords = propagate(self,
                           time_of_flight,
                           method=method,
                           rtol=rtol,
                           **kwargs)[0]

        # Even after indexing the result of propagate,
        # the frame obstime might have an array of times
        # See the propagate function for reasoning about the usage of a
        # protected method
        coords = coords._replicate(coords.data,
                                   representation_type="cartesian",
                                   obstime=coords.obstime[0])
        return self.from_coords(self.attractor, coords, plane=self.plane)
Esempio n. 7
0
    def propagate(self, epoch_or_duration, rtol=1e-10):
        """Propagate this `Orbit` some `time` and return the result.

        Parameters
        ----------
        epoch_or_duration : Time, TimeDelta or equivalent
            Final epoch or time of flight.
        rtol : float, optional
            Relative tolerance for the propagation algorithm, default to 1e-10.

        """
        if isinstance(epoch_or_duration, time.Time) and not isinstance(
                epoch_or_duration, time.TimeDelta):
            time_of_flight = epoch_or_duration - self.epoch
        else:
            time_of_flight = time.TimeDelta(epoch_or_duration)

        return propagate(self, time_of_flight, rtol=rtol)
Esempio n. 8
0
    def propagate(self, value, method=mean_motion, rtol=1e-10, **kwargs):
        """Propagates an orbit a specified time.

        If value is true anomaly, propagate orbit to this anomaly and return the result.
        Otherwise, if time is provided, propagate this `Orbit` some `time` and return the result.

        Parameters
        ----------
        value : ~astropy.units.Quantity, ~astropy.time.Time, ~astropy.time.TimeDelta
            Scalar time to propagate.
        rtol : float, optional
            Relative tolerance for the propagation algorithm, default to 1e-10.
        method : function, optional
            Method used for propagation
        **kwargs
            parameters used in perturbation models

        Returns
        -------
        Orbit
            New orbit after propagation.

        """
        if isinstance(value,
                      time.Time) and not isinstance(value, time.TimeDelta):
            time_of_flight = value - self.epoch
        else:
            # Works for both Quantity and TimeDelta objects
            time_of_flight = time.TimeDelta(value)

        cartesian = propagate(self,
                              time_of_flight,
                              method=method,
                              rtol=rtol,
                              **kwargs)
        new_epoch = self.epoch + time_of_flight

        return self.from_vectors(
            self.attractor,
            cartesian[0].xyz,
            cartesian[0].differentials["s"].d_xyz,
            new_epoch,
            plane=self.plane,
        )
Esempio n. 9
0
    def _init_orbit_packet_cords_(self, i):
        """

        Parameters
        ----------
        i: int
            Index of referenced orbit
        """
        h = (self.end_epoch - self.orbits[i][2]).to(
            u.second) / self.orbits[i][1]

        for k in range(self.orbits[i][1] + 2):
            position = propagate(self.orbits[i][0], TimeDelta(k * h))

            cords = position.represent_as(CartesianRepresentation).xyz.to(
                u.meter).value
            cords = np.insert(cords, 0, h.value * k, axis=0)

            self.czml[i]["position"]["cartesian"] += list(
                map(lambda x: x[0], cords.tolist()))
Esempio n. 10
0
def no_pert_earth(initial, time, f_time):  # No perturbation

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    rr = propagate(initial, tofs, method=cowell, ad=None)

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    print("")
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
Esempio n. 11
0
    def propagate(self, value, method=mean_motion, rtol=1e-10, **kwargs):
        """Propagates an orbit.

        If value is true anomaly, propagate orbit to this anomaly and return the result.
        Otherwise, if time is provided, propagate this `Orbit` some `time` and return the result.

        Parameters
        ----------
        value : Multiple options
            True anomaly values,
            Time values.
        rtol : float, optional
            Relative tolerance for the propagation algorithm, default to 1e-10.
        method : function, optional
            Method used for propagation
        **kwargs
            parameters used in perturbation models

        """
        if hasattr(value, "unit") and value.unit in ('rad', 'deg'):
            p, ecc, inc, raan, argp, _ = rv.rv2coe(
                self.attractor.k.to(u.km**3 / u.s**2).value,
                self.r.to(u.km).value,
                self.v.to(u.km / u.s).value)

            return self.from_classical(self.attractor,
                                       p / (1.0 - ecc**2) * u.km, ecc * u.one,
                                       inc * u.rad, raan * u.rad, argp * u.rad,
                                       value)
        else:
            if isinstance(value,
                          time.Time) and not isinstance(value, time.TimeDelta):
                time_of_flight = value - self.epoch
            else:
                time_of_flight = time.TimeDelta(value)

            return propagate(self,
                             time_of_flight,
                             method=method,
                             rtol=rtol,
                             **kwargs)
Esempio n. 12
0
    def propagate(self, value, method=mean_motion, rtol=1e-10, **kwargs):
        """Propagates an orbit.

        If value is true anomaly, propagate orbit to this anomaly and return the result.
        Otherwise, if time is provided, propagate this `Orbit` some `time` and return the result.

        Parameters
        ----------
        value : Multiple options
            True anomaly values or time values. If given an angle, it will always propagate forward.
        rtol : float, optional
            Relative tolerance for the propagation algorithm, default to 1e-10.
        method : function, optional
            Method used for propagation
        **kwargs
            parameters used in perturbation models

        """
        if hasattr(value, "unit") and value.unit in ('rad', 'deg'):
            p, ecc, inc, raan, argp, _ = rv2coe(self.attractor.k.to(u.km ** 3 / u.s ** 2).value,
                                                self.r.to(u.km).value,
                                                self.v.to(u.km / u.s).value)

            # Compute time of flight for correct epoch
            M = nu_to_M(self.nu, self.ecc)
            new_M = nu_to_M(value, self.ecc)
            time_of_flight = Angle(new_M - M).wrap_at(360 * u.deg) / self.n

            return self.from_classical(self.attractor, p / (1.0 - ecc ** 2) * u.km,
                                       ecc * u.one, inc * u.rad, raan * u.rad,
                                       argp * u.rad, value,
                                       epoch=self.epoch + time_of_flight, plane=self._plane)
        else:
            if isinstance(value, time.Time) and not isinstance(value, time.TimeDelta):
                time_of_flight = value - self.epoch
            else:
                time_of_flight = time.TimeDelta(value)

            return propagate(self, time_of_flight, method=method, rtol=rtol, **kwargs)
Esempio n. 13
0
    def _get_raw_coords(self, ss, t_deltas):
        """Generates raw orbit coordinates for given epochs

        Parameters
        ----------
        ss: ~poliastro.twobody.orbit
            Orbit to be propagated
        t_deltas: ~astropy.time.DeltaTime
            Desired observation time

        Returns
        -------
        raw_xyz: array
            A collection of raw cartessian position vectors
        raw_epochs: array
            Associated epoch with previously raw coordinates
        """

        # Solve for raw coordinates and epochs
        raw_xyz = propagate(ss, t_deltas)
        raw_epochs = ss.epoch + t_deltas

        return raw_xyz, raw_epochs
Esempio n. 14
0
    def from_orbit(
        cls,
        orbit,
        epochs,
        plane=Planes.EARTH_EQUATOR,
    ):
        """Return 'Ephem` from an `Orbit` at certain epochs.
        Parameters
        ----------
        orbit: ~poliastro.twobody.orbit.Orbit
            Orbit.
        epochs: ~astropy.time.Time
            Epochs to sample the orbit positions.
        plane: ~poliastro.frames.Planes, optional
            Fundamental plane of the frame, default to Earth Equator.
        """
        if epochs.isscalar:
            epochs = epochs.reshape(1)

        time_of_flights = epochs - orbit.epoch
        coordinates = propagate(orbit, time_of_flights)

        return cls(coordinates, epochs, plane)
Esempio n. 15
0
    def _init_orbit_packet_cords_(self, i, rtol):
        """

        Parameters
        ----------
        i: int
            Index of referenced orbit
        rtol: float
            Maximum relative error permitted
        Returns
        -------
        coordinate list
        """
        cart_cords = []  # type: List[float]

        h = (self.end_epoch - self.orbits[i][2]).to(
            u.second) / self.orbits[i][1]

        # Get rounding factor given the relative tolerance
        rf = 0
        while rtol < 1:
            rtol *= 10
            rf += 1

        for k in range(self.orbits[i][1] + 2):
            position = propagate(self.orbits[i][0],
                                 TimeDelta(k * h),
                                 rtol=rtol)

            cords = position.represent_as(CartesianRepresentation).xyz.to(
                u.meter).value
            cords = np.insert(cords, 0, h.value * k, axis=0)

            # flatten list
            cart_cords += list(map(lambda x: round(x[0], rf), cords.tolist()))

        return cart_cords
Esempio n. 16
0
def fx_obj(state, dt):
    return propagate(state, time.TimeDelta(dt * u.s), method=markley)
Esempio n. 17
0
A_over_m = ((np.pi / 4.0) * (u.m**2) / (100 * u.kg)).to_value(u.km**2 /
                                                              u.kg)  # km^2/kg
B = C_D * A_over_m

# parameters of the atmosphere
rho0 = rho0_earth.to(u.kg / u.km**3).value  # kg/km^3
H0 = H0_earth.to(u.km).value

tofs = TimeDelta(np.linspace(0 * u.h, 100000 * u.s, num=2000))

rr = propagate(
    orbit,
    tofs,
    method=cowell,
    ad=atmospheric_drag_exponential,
    R=R,
    C_D=C_D,
    A_over_m=A_over_m,
    H0=H0,
    rho0=rho0,
)

# In[4]:

plt.ylabel("h(t)")
plt.xlabel("t, days")
plt.plot(tofs.value, rr.norm() - Earth.R)

# ### Orbital Decay
#
# If atmospheric drag causes the orbit to fully decay, additional code
Esempio n. 18
0
def custom(initial, choice, state, time,
           f_time):  # requires modification and validation
    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value
    #s0 = Orbit.from_classical(Earth, x[0] * u.km, x[1] * u.one, x[4] * u.deg, * u.deg, x[3] * u.deg, 0 * u.deg, epoch=Time(0, format='jd', scale='tdb'))

    #orbit = Orbit.circular(
    #    Earth, 250 * u.km, epoch=Time(0.0, format="jd", scale="tdb"))

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    # parameters of the atmosphere
    rho0 = Earth.rho0.to(u.kg / u.km**3).value  # kg/km^3
    H0 = Earth.H0.to(u.km).value

    #J2,J3 parameters
    J3 = Earth.J3.value
    J2 = Earth.J2.value

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    if (choice == '7'):

        rr = propagate(
            initial,
            tofs,
            method=cowell,
            ad=accel,
            #k=k,
        )

    elif (choice == '5'):

        rr = propagate(
            initial,
            tofs,
            method=cowell,
            ad=a_d_1,
            #k=k,
            J2=J2,
            R=R,
            C_D=C_D,
            A=A,
            m=m,
            H0=H0,
            rho0=rho0)

    elif (choice == '6'):

        rr = propagate(
            initial,
            tofs,
            method=cowell,
            ad=a_d_2,
            #k=k,
            J3=J3,
            R=R,
            C_D=C_D,
            A=A,
            m=m,
            H0=H0,
            rho0=rho0)

    else:
        pass

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    print("")
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
Esempio n. 19
0
def atmd_earth(initial, time, f_time):  # perturbation for atmospheric drag
    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value
    #s0 = Orbit.from_classical(Earth, x[0] * u.km, x[1] * u.one, x[4] * u.deg, * u.deg, x[3] * u.deg, 0 * u.deg, epoch=Time(0, format='jd', scale='tdb'))

    #orbit = Orbit.circular(
    #    Earth, 250 * u.km, epoch=Time(0.0, format="jd", scale="tdb"))

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    # parameters of the atmosphere
    rho0 = Earth.rho0.to(u.kg / u.km**3).value  # kg/km^3
    H0 = Earth.H0.to(u.km).value

    print(
        "Use default constants or you want to customize?\n1.Default.\n2.Custom."
    )
    check = input()
    if (check == '1'):
        pass
    else:
        m = input("Enter mass of the body in kg:")
        R = input("Enter radius of earth in km:")
        C_D = input("Enter C_D(dimension):")
        H0 = input("Enter atmospheric parameter H0:")
        #rho0=input("Enter atmospheric parameter rho0:")
        R = R * u.km
        H0 = H0 * u.km
        #rho0=rho0*(u.kg / u.km ** 3)

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    #print("tofs:")
    #print(tofs)
    #print("ie:")
    #print(initial.epoch.iso)
    rr = propagate(
        initial,
        tofs,
        method=cowell,
        ad=atmospheric_drag,
        R=R,
        C_D=C_D,
        A=A,
        m=m,
        H0=H0,
        rho0=rho0,
    )

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    print("")
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
Esempio n. 20
0
def j3_earth(initial, time, f_time):  # perturbation for oblateness
    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value
    #s0 = Orbit.from_classical(Earth, x[0] * u.km, x[1] * u.one, x[4] * u.deg, * u.deg, x[3] * u.deg, 0 * u.deg, epoch=Time(0, format='jd', scale='tdb'))

    #orbit = Orbit.circular(
    #    Earth, 250 * u.km, epoch=Time(0.0, format="jd", scale="tdb"))

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    J3 = Earth.J3.value
    print(
        "Use default constants or you want to customize?\n1.Default.\n2.Custom."
    )
    check = input()
    if (check == '1'):
        pass
    else:
        J3 = input("Enter J3 constant:")
        R = input("Enter radius of earth in km:")

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    rr = propagate(initial,
                   tofs,
                   method=cowell,
                   ad=J3_perturbation,
                   J3=J3,
                   R=R)

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    print("")
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
Esempio n. 21
0
#create time and time step
start_date = time.Time('2018-01-01 00:00', scale='utc')
step = time.TimeDelta(1.0, format='jd')
end_date = time.Time('2018-12-31 00:00', scale='utc')

#create orbit with start_date
#for asteroid
a = (1.11 + 0.90) / 2 * u.AU
ecc = 0.104 * u.one
inc = 7.77 * u.deg
raan = 66.51 * u.deg
argp = 307.23 * u.deg
nu = np.rad2deg(ang.M_to_nu(np.deg2rad(297.53 * u.deg), ecc))
asteroid = Orbit.from_classical(Sun, a, ecc, inc, raan, argp, nu, start_date)
asteroid = propagate(asteroid, 150 * 3600 * 24 * u.second)

#for earth
a = 1 * u.AU
ecc = 0.0167086 * u.one
nu = np.rad2deg(ang.M_to_nu(np.deg2rad(358.617 * u.deg), ecc))
inc = 7.155 * u.deg
raan = -11.26064 * u.deg
argp = 114.207 * u.deg
earth = Orbit.from_classical(Sun, a, ecc, inc, raan, argp, nu, start_date)
op = OrbitPlotter()
op.plot(asteroid, label='asteroid')
op.plot(earth, label='earth')
plt.show()

day = 3600 * 24 * u.second
Esempio n. 22
0
def third_body_moon(
        initial, time,
        f_time):  # propogate under perturbation of a third body(moon)

    # database keeping positions of bodies in Solar system over time
    x_ephem = "de432s"
    questions = [
        inquirer.List(
            'Ephemerides',
            message=
            "Select ephemerides[de432s(default,small in size,faster)','de430(more precise)]:",
            choices=['de432s', 'de430'],
        ),
    ]
    answers = inquirer.prompt(questions)

    x_ephem = answers["Ephemerides"]

    solar_system_ephemeris.set(x_ephem)

    #epoch = Time(time, format='iso', scale='utc')  # setting the exact event date is important
    epoch = Time(time, format='iso').jd
    f_time_1 = Time(f_time, format='iso').jd

    # create interpolant of 3rd body coordinates (calling in on every iteration will be just too slow)     #check
    body_r = build_ephem_interpolant(
        Moon,
        28 * u.day,
        (epoch * u.day, f_time_1 * u.day),
        rtol=1e-2  #check
    )

    k_third = Moon.k.to(u.km**3 / u.s**2).value
    x = 400
    print(
        "Use default constants or you want to customize?\n1.Default.\n2.Custom."
    )
    check = input()
    if (check == '1'):
        pass
    else:
        k_third = input("Enter moon's gravity:")
        x = input(
            "Multiply Moon's gravity by X times so that effect is visible,input X:"
        )

    datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
    diff =datetime.strptime(str(f_time), datetimeFormat)\
        - datetime.strptime(str(time), datetimeFormat)
    print("Time difference:")
    print(diff)
    tofs = TimeDelta(f_time - time)
    tofs = TimeDelta(np.linspace(0, 31 * u.day, num=1))

    # multiply Moon gravity by x so that effect is visible :)
    rr = propagate(
        initial,
        tofs,
        method=cowell,
        rtol=1e-6,
        ad=third_body,
        k_third=x * k_third,
        third_body=body_r,
    )

    print("")
    print("Positions and velocity vectors are:")
    #print(str(rr.x))
    #print([float(s) for s in re.findall(r'-?\d+\.?\d*',str(rr.x))])
    r = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.y))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.z))][0]] * u.km
    v = [[float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_x))][0],
         [float(s) for s in re.findall(r'-?\d+\.?\d*', str(rr.v_y))][0],
         [float(s)
          for s in re.findall(r'-?\d+\.?\d*', str(rr.v_z))][0]] * u.km / u.s
    f_orbit = Orbit.from_vectors(Earth, r, v)
    print(r)
    print(v)
    #f_orbit.plot()
    print("")
    print("Orbital elements:")
    print(f_orbit.classical())
    #print("")
    #print(f_orbit.ecc)
    plotOrbit((f_orbit.a.value), (f_orbit.ecc.value), (f_orbit.inc.value),
              (f_orbit.raan.value), (f_orbit.argp.value), (f_orbit.nu.value))
Esempio n. 23
0
    def sample(
        self, values=100, *, min_anomaly=None, max_anomaly=None, method=mean_motion
    ):
        r"""Samples an orbit to some specified time values.

        .. versionadded:: 0.8.0

        Parameters
        ----------
        values : int
            Number of interval points (default to 100).
        min_anomaly, max_anomaly : ~astropy.units.Quantity, optional
            Anomaly limits to sample the orbit.
            For elliptic orbits the default will be :math:`E \in \left[0, 2 \pi \right]`,
            and for hyperbolic orbits it will be :math:`\nu \in \left[-\nu_c, \nu_c \right]`,
            where :math:`\nu_c` is either the current true anomaly
            or a value that corresponds to :math:`r = 3p`.
        method : function, optional
            Method used for propagation

        Returns
        -------
        positions: ~astropy.coordinates.BaseCoordinateFrame
            Array of x, y, z positions, with proper times as the frame attributes if supported.

        Notes
        -----
        When specifying a number of points, the initial and final
        position is present twice inside the result (first and
        last row). This is more useful for plotting.

        Examples
        --------
        >>> from astropy import units as u
        >>> from poliastro.examples import iss
        >>> iss.sample()  # doctest: +ELLIPSIS
        <GCRS Coordinate ...>
        >>> iss.sample(10)  # doctest: +ELLIPSIS
        <GCRS Coordinate ...>

        """
        if self.ecc < 1:
            nu_values = self._sample_closed(values, min_anomaly, max_anomaly)
        else:
            nu_values = self._sample_open(values, min_anomaly, max_anomaly)

        time_values = time.TimeDelta(self._generate_time_values(nu_values))
        cartesian = propagate(self, time_values, method=method)

        # TODO: Unify with propagate
        # If the frame supports obstime, set the time values
        try:
            kwargs = {}
            if "obstime" in self.frame.frame_attributes:
                kwargs["obstime"] = self.epoch + time_values
            else:
                warn(
                    "Frame {} does not support 'obstime', time values were not returned".format(
                        self.frame.__class__
                    )
                )

            # Use of a protected method instead of frame.realize_frame
            # because the latter does not let the user choose the representation type
            # in one line despite its parameter names, see
            # https://github.com/astropy/astropy/issues/7784
            coords = self.frame._replicate(
                cartesian, representation_type="cartesian", **kwargs
            )
            return coords

        except NotImplementedError:
            warn(
                "No frame found for attractor {}, returning only cartesian coordinates instead".format(
                    self.attractor
                )
            )
            return cartesian
Esempio n. 24
0
    def sample(self, values=100, *, min_anomaly=None, max_anomaly=None):
        r"""Samples an orbit to some specified time values.

        .. versionadded:: 0.8.0

        Parameters
        ----------
        values : int
            Number of interval points (default to 100).
        min_anomaly, max_anomaly : ~astropy.units.Quantity, optional
            Anomaly limits to sample the orbit.
            For elliptic orbits the default will be :math:`E \in \left[0, 2 \pi \right]`,
            and for hyperbolic orbits it will be :math:`\nu \in \left[-\nu_c, \nu_c \right]`,
            where :math:`\nu_c` is either the current true anomaly
            or a value that corresponds to :math:`r = 3p`.

        Returns
        -------
        positions: ~astropy.coordinates.BaseCoordinateFrame
            Array of x, y, z positions, with proper times as the frame attributes if supported.

        Notes
        -----
        When specifying a number of points, the initial and final
        position is present twice inside the result (first and
        last row). This is more useful for plotting.

        Examples
        --------
        >>> from astropy import units as u
        >>> from poliastro.examples import iss
        >>> iss.sample()  # doctest: +ELLIPSIS
        <GCRS Coordinate ...>
        >>> iss.sample(10)  # doctest: +ELLIPSIS
        <GCRS Coordinate ...>

        """
        if self.ecc < 1:
            nu_values = self._sample_closed(values, min_anomaly, max_anomaly)
        else:
            nu_values = self._sample_open(values, min_anomaly, max_anomaly)

        time_values = time.TimeDelta(self._generate_time_values(nu_values))
        cartesian = propagate(self, time_values)

        # TODO: Unify with propagate
        # If the frame supports obstime, set the time values
        try:
            kwargs = {}
            if "obstime" in self.frame.frame_attributes:
                kwargs["obstime"] = self.epoch + time_values
            else:
                warn(
                    "Frame {} does not support 'obstime', time values were not returned"
                    .format(self.frame.__class__))

            # Use of a protected method instead of frame.realize_frame
            # because the latter does not let the user choose the representation type
            # in one line despite its parameter names, see
            # https://github.com/astropy/astropy/issues/7784
            coords = self.frame._replicate(cartesian,
                                           representation_type="cartesian",
                                           **kwargs)
            return coords

        except NotImplementedError:
            warn(
                "No frame found for attractor {}, returning only cartesian coordinates instead"
                .format(self.attractor))
            return cartesian
Esempio n. 25
0
    def propagate(self, value, method=mean_motion, rtol=1e-10, **kwargs):
        """Propagates an orbit a specified time.

        If value is true anomaly, propagate orbit to this anomaly and return the result.
        Otherwise, if time is provided, propagate this `Orbit` some `time` and return the result.

        Parameters
        ----------
        value : ~astropy.units.Quantity, ~astropy.time.Time, ~astropy.time.TimeDelta
            Scalar time to propagate.
        rtol : float, optional
            Relative tolerance for the propagation algorithm, default to 1e-10.
        method : function, optional
            Method used for propagation
        **kwargs
            parameters used in perturbation models

        Returns
        -------
        Orbit
            New orbit after propagation.

        """
        if isinstance(value,
                      time.Time) and not isinstance(value, time.TimeDelta):
            time_of_flight = value - self.epoch
        else:
            # Works for both Quantity and TimeDelta objects
            time_of_flight = time.TimeDelta(value)

        cartesian = propagate(self,
                              time_of_flight,
                              method=method,
                              rtol=rtol,
                              **kwargs)
        new_epoch = self.epoch + time_of_flight

        # TODO: Unify with sample
        # If the frame supports obstime, set the time values
        try:
            kwargs = {}
            if "obstime" in self.frame.frame_attributes:
                kwargs["obstime"] = new_epoch

            # Use of a protected method instead of frame.realize_frame
            # because the latter does not let the user choose the representation type
            # in one line despite its parameter names, see
            # https://github.com/astropy/astropy/issues/7784
            coords = self.frame._replicate(cartesian,
                                           representation_type="cartesian",
                                           **kwargs)

            return self.from_coords(self.attractor, coords, plane=self.plane)

        except NotImplementedError:
            return self.from_vectors(
                self.attractor,
                cartesian[0].xyz,
                cartesian[0].differentials["s"].d_xyz,
                new_epoch,
            )
Esempio n. 26
0
    )  #Min kommentar: Här tror jag att jag kan ändra på värdet hos radien på omloppsbanan
    tofs = TimeDelta(
        np.linspace(0 * u.h, 100 * u.d, num=200)
    )  #Min kommentar: Här tror jag deltatiden beskrivs, att den mäter mellan noll timmar till ett max antal dagar, samt att den mäter 2000 gånger.

    from poliastro.twobody.events import LithobrakeEvent
    lithobrake_event = LithobrakeEvent(R)
    events = [lithobrake_event]

    rr = propagate(
        orbit,
        tofs,
        method=cowell,
        ad=atmospheric_drag_exponential,
        R=R,
        C_D=
        x,  #Min kommentar: Här ändrade jag från C_D till x på högra sidan likhetstecknet
        A_over_m=A_over_m,
        H0=H0,
        rho0=rho0,
        events=events,
    )

    print('{0} {1:.2f} {2}'.format('orbital decay seen after',
                                   lithobrake_event.last_t.to(u.d).value,
                                   'days'))

    plt.ylabel("h(t)")
    plt.xlabel("t, days")
    plt.plot(tofs.value, rr.norm() - Earth.R)
Esempio n. 27
0
    def propagate(self, time_of_flight, rtol=1e-10):
        """Propagate this `Orbit` some `time` and return the result.

        """
        return propagate(self, time_of_flight, rtol=rtol)
Esempio n. 28
0
        return accel * v / norm_v

    return constant_accel


# In[5]:

times = np.linspace(0, 10 * iss.period, 500)
times

# In[6]:

positions = propagate(
    iss,
    time.TimeDelta(times),
    method=cowell,
    rtol=1e-11,
    ad=constant_accel_factory(accel),
)

# And we plot the results:

# In[7]:

frame = OrbitPlotter3D()

frame.set_attractor(Earth)
frame.plot_trajectory(positions, label="ISS")

# ## Error checking
Esempio n. 29
0
orbit = Orbit.circular(Earth,
                       200 * u.km,
                       epoch=Time(0.0, format="jd", scale="tdb"))
tofs = TimeDelta(np.linspace(0 * u.h, 100000000 * u.d, num=200))

from poliastro.twobody.events import LithobrakeEvent

lithobrake_event = LithobrakeEvent(R)
events = [lithobrake_event]

rr = propagate(
    orbit,
    tofs,
    method=cowell,
    ad=atmospheric_drag_exponential,
    R=R,
    C_D=C_D,
    A_over_m=A_over_m,
    H0=H0,
    rho0=rho0,
    events=events,
)

print('{0} {1:.2f} {2}'.format('orbital decay seen after',
                               lithobrake_event.last_t.to(u.d).value, 'days'))

plt.ylabel("h(t)")
plt.xlabel("t, days")
plt.plot(tofs.value, rr.norm() - Earth.R)