コード例 #1
0
def test_from_body_non_tdb_epochs_warning(epochs):
    unused_body = Earth
    epochs = Time.now()  # This uses UTC scale

    warning_pattern = "Input time was converted to scale='tdb'"
    with pytest.warns(TimeScaleWarning, match=warning_pattern):
        Ephem.from_body(unused_body, epochs)
コード例 #2
0
def test_from_body_non_tdb_epochs_warning(epochs):
    unused_body = Earth
    epochs = Time.now()  # This uses UTC scale

    with pytest.warns(TimeScaleWarning) as record:
        Ephem.from_body(unused_body, epochs)

    assert len(record) == 1
    assert "Input time was converted to scale='tdb'" in record[0].message.args[
        0]
    assert "Use Time(..., scale='tdb') instead" in record[0].message.args[0]
コード例 #3
0
 def _get_ephem(self):
     for x in self.body_dict["bodies"]:
         body = DummyBody(moon_dict[x]["index"])
         ephem = Ephem.from_body(body,
                                 self.current_time,
                                 attractor=self.body_dict["attractor"])
         self.ephems[x] = ephem
コード例 #4
0
def test_ephem_from_body_has_expected_properties(method, plane, FrameClass,
                                                 rtol):
    epochs = Time(
        [
            "2020-03-01 12:00:00", "2020-03-17 00:00:00.000",
            "2020-04-01 12:00:00.000"
        ],
        scale="tdb",
    )
    equatorial_coordinates = CartesianRepresentation(
        [
            (-1.40892271e08, 45067626.83900666, 19543510.68386639),
            (-1.4925067e08, 9130104.71634121, 3964948.59999307),
            (-1.46952333e08, -27413113.24215863, -11875983.21773582),
        ] * u.km,
        xyz_axis=1,
        differentials=CartesianDifferential(
            [
                (-10.14262131, -25.96929533, -11.25810932),
                (-2.28639444, -27.3906416, -11.87218591),
                (5.67814544, -26.84316701, -11.63720607),
            ] * (u.km / u.s),
            xyz_axis=1,
        ),
    )

    expected_coordinates = (
        ICRS(equatorial_coordinates).transform_to(FrameClass).represent_as(
            CartesianRepresentation, CartesianDifferential))

    earth = Ephem.from_body(Earth, epochs, plane=plane)
    coordinates = earth.sample(method=method)

    assert earth.epochs is epochs
    assert_coordinates_allclose(coordinates, expected_coordinates, rtol=rtol)
コード例 #5
0
ファイル: _base.py プロジェクト: bryanwweber/poliastro
    def _plot_body_orbit(
        self,
        body,
        epoch,
        *,
        label=None,
        color=None,
        trail=False,
    ):
        if color is None:
            color = BODY_COLORS.get(body.name)

        self.set_attractor(body.parent)

        # Get approximate, mean value for the period
        period = get_mean_elements(body, epoch).period

        label = generate_label(epoch, label or str(body))
        epochs = time_range(epoch,
                            periods=self._num_points,
                            end=epoch + period,
                            scale="tdb")
        ephem = Ephem.from_body(body,
                                epochs,
                                attractor=body.parent,
                                plane=self.plane)

        return self._plot_ephem(ephem,
                                epoch,
                                label=label,
                                color=color,
                                trail=trail)
コード例 #6
0
 def _get_ephem_from_list_of_bodies(
         bodies, epochs) -> Dict[str, Tuple[SolarSystemPlanet, Ephem]]:
     list_of_bodies = {}
     for i in bodies:
         ephem = Ephem.from_body(i, epochs)
         list_of_bodies[i.name] = (i, ephem)
     return list_of_bodies
コード例 #7
0
def distance_chart(body1, body2, date_start, interval, steps):
    """Generates a distance chart between body1 (e.g. Earth) and body2 (e.g. Mars)
       from date_start till interval (e.g. 10 days) and steps (36).
       Returns plotly's Figure."""

    eph1 = Ephem.from_body(
        body1, time_range(date_start, end=date_start + steps * interval))
    eph2 = Ephem.from_body(
        body2, time_range(date_start, end=date_start + steps * interval))

    # Solve for departure and target orbits
    orb1 = Orbit.from_ephem(Sun, eph1, date_start)
    orb2 = Orbit.from_ephem(Sun, eph2, date_start)

    t_tbl = []
    dist_tbl = []

    t = date_start

    for i in range(1, steps):
        day = str(orb1.epoch)[:10]  # take the first "2020-01-01" from the date
        t_tbl.append(day)
        dist = np.linalg.norm(orb1.r - orb2.r)
        dist_tbl.append(dist.value)

        orb1 = orb1.propagate(interval)
        orb2 = orb2.propagate(interval)

    fig = go.Figure()
    fig.add_trace(
        go.Scatter(x=t_tbl,
                   y=dist_tbl,
                   mode="lines+markers",
                   name="Earth - Mars distance"))

    name = body1.name + "-" + body2.name + " distance"

    fig.update_layout(legend=dict(orientation="h",
                                  yanchor="bottom",
                                  y=1.02,
                                  xanchor="right",
                                  x=1),
                      xaxis_title="date",
                      yaxis_title="Distance [km]",
                      title=name,
                      margin=dict(l=20, r=20, t=40, b=20))
    return fig
コード例 #8
0
def test_from_body_scalar_epoch_uses_reshaped_epochs():
    expected_epochs = Time(["2020-03-01 12:00:00"], scale="tdb")
    epochs = expected_epochs[0]

    unused_plane = Planes.EARTH_EQUATOR
    ephem = Ephem.from_body(Earth, epochs, plane=unused_plane)

    assert ephem.epochs == expected_epochs
コード例 #9
0
def get_earth_ephem(epoch=None):

    if epoch is None:
        today = date.today()
        epoch = time.Time(today.strftime("%Y-%m-%d") + " 12:00")  # UTC by default

    earth_eph = Ephem.from_body(Earth, epoch.tdb)

    return earth_eph
コード例 #10
0
def test_ephem_without_frame_raises_error():
    epochs = time.Time("2020-04-29 10:43", scale="tdb")
    earth = Ephem.from_body(Earth, epochs)
    plotter = OrbitPlotter2D()

    with pytest.raises(ValueError) as excinfo:
        plotter.set_attractor(Sun)
        plotter.plot_ephem(earth)
    assert ("A frame must be set up first, please use "
            "set_orbit_frame(orbit) or plot(orbit)" in excinfo.exconly())
コード例 #11
0
ファイル: test_orbit.py プロジェクト: zkl2/poliastro
def test_from_ephem_has_expected_properties():
    epoch = J2000_TDB
    ephem = Ephem.from_body(Earth, epoch, attractor=Sun)
    expected_r, expected_v = ephem.rv(epoch)

    ss = Orbit.from_ephem(Sun, ephem, epoch)

    assert ss.plane is ephem.plane
    assert ss.epoch == epoch
    assert_quantity_allclose(ss.r, expected_r)
    assert_quantity_allclose(ss.v, expected_v)
コード例 #12
0
ファイル: sunearth.py プロジェクト: ivanbelenky/Ctll
def bodies_vector(T, dt, body1, body2, epoch=J2000, timedelta = None):
    """Returns vector for every dt in [0,T] from bodie1 to bodie2
    
    Parameters
    ----------
    T : float
        time of propagation
    dt : float
        time interval
    body1 : ~poliastro.bodies.Body
        first body
    body2 : ~poliastro.bodies.Body
        second body
    epoch : ~astropy.time.Time, optional
        Epoch offset
    timedelta : ~astropy.time.Time, optional
        desired time of propagation
    
    Returns
    -------
    diff : ~astropy.units.quantity.Quantity
        vectors for timedelta propagation from body1 to body2
    """
    
    DT_TIME = 500
    if not timedelta:
        time_delta = Time([epoch + j*u.s for j in np.linspace(0,3600*24*1.01*T, int(3600*24*T/DT_TIME)) ] )
    else:
        time_delta = timedelta
    
    ephem_b1 = Ephem.from_body(body1, time_delta.tdb)
    ephem_b2 = Ephem.from_body(body2, time_delta.tdb)
    
    tofs = Time([epoch + j*dt*u.s for j in range(10,int(3600*24*T/dt)+10)])
    r_b1, _ = ephem_b1.rv(tofs)
    r_b2, _ = ephem_b2.rv(tofs)
    
    diff = (r_b2-r_b1).to(u.km)
    return diff
コード例 #13
0
    def reset(self):
        # get planet and spaceship positions at start_time, reset spaceship fuel,

        self.current_time = self.start_time

        self.current_ephem = self._get_ephem_from_list_of_bodies(
            self.body_list, self.start_time)

        # set up spacecraft
        self.spaceship = self._init_spaceship()

        start_body_ephem = Ephem.from_body(self.start_body, self.start_time)
        self.spaceship.rv = (self.spaceship.rv[0] + start_body_ephem.rv()[0],
                             self.spaceship.rv[1] + start_body_ephem.rv()[1])
        # convert spaceship rv to system-relative rather than earth

        observation = self._get_observation()

        return observation
コード例 #14
0
ファイル: horizons.py プロジェクト: tomaszmrugalski/perylune
def dist_chart(asteroid, date, timespan):
    solar_system_ephemeris.set('jpl')

    EPOCH = Time(date, scale="tdb")

    epochs = time_range(EPOCH - TimeDelta(timespan),
                        end=EPOCH + TimeDelta(timespan))

    epochs_moon = time_range(EPOCH - TimeDelta(15 * u.day),
                             end=EPOCH + TimeDelta(15 * u.day))

    moon = Ephem.from_body(Moon, epochs_moon, attractor=Earth)
    aster = Ephem.from_horizons(asteroid, epochs, attractor=Earth)

    plotter = StaticOrbitPlotter()
    plotter.set_attractor(Earth)
    plotter.set_body_frame(Moon)
    plotter.plot_ephem(moon, EPOCH, label=Moon)
    plotter.plot_ephem(aster, EPOCH, label=asteroid)

    return plotter
コード例 #15
0
ファイル: _base.py プロジェクト: bryanwweber/poliastro
    def set_body_frame(self, body, epoch=None):
        """Sets perifocal frame based on the orbit of a body at a particular epoch if given.

        Parameters
        ----------
        body : poliastro.bodies.SolarSystemPlanet
            Body.
        epoch : astropy.time.Time, optional
            Epoch of current position.

        """
        from warnings import warn

        from astropy import time

        from poliastro.bodies import Sun
        from poliastro.twobody import Orbit

        from ..warnings import TimeScaleWarning

        if not epoch:
            epoch = time.Time.now().tdb
        elif epoch.scale != "tdb":
            epoch = epoch.tdb
            warn(
                "Input time was converted to scale='tdb' with value "
                f"{epoch.tdb.value}. Use Time(..., scale='tdb') instead.",
                TimeScaleWarning,
                stacklevel=2,
            )

        with warnings.catch_warnings():
            ephem = Ephem.from_body(body,
                                    epoch,
                                    attractor=Sun,
                                    plane=self.plane)  # type: ignore
            orbit = Orbit.from_ephem(Sun, ephem, epoch).change_plane(
                self.plane)  # type: ignore

        self.set_orbit_frame(orbit)
コード例 #16
0
frame = OrbitPlotter3D()

frame.plot_body_orbit(Earth, J2000)
frame.plot(eros, label="eros")

# In[7]:

from poliastro.ephem import Ephem
from poliastro.util import time_range

# In[8]:

date_launch = time.Time("2011-11-26 15:02", scale="utc").tdb
date_arrival = time.Time("2012-08-06 05:17", scale="utc").tdb

earth = Ephem.from_body(Earth,
                        time_range(date_launch, end=date_arrival, periods=50))

# In[9]:

frame = OrbitPlotter3D()
frame.set_attractor(Sun)

frame.plot_body_orbit(Earth, J2000, label=Earth)
frame.plot_ephem(earth, label=Earth)

# In[10]:

frame = OrbitPlotter3D()

frame.plot(eros, label="eros")
frame.plot_trajectory(earth.sample(), label=Earth)
コード例 #17
0
ax.set_xlim(-8000, 8000)
ax.set_ylim(-20000, 20000);


# ### Option b): Compute $v_{\infty}$ using the Jupyter flyby
# 
# According to Wikipedia, the closest approach occurred at 05:43:40 UTC. We can use this data to compute the solution of the Lambert problem between the Earth and Jupiter.

# In[6]:


nh_date = time.Time("2006-01-19 19:00", scale="utc").tdb
nh_flyby_date = time.Time("2007-02-28 05:43:40", scale="utc").tdb
nh_tof = nh_flyby_date - nh_date

nh_r_0, v_earth = Ephem.from_body(Earth, nh_date).rv(nh_date)
nh_r_f, v_jup = Ephem.from_body(Jupiter, nh_flyby_date).rv(nh_flyby_date)

(nh_v_0, nh_v_f), = iod.lambert(Sun.k, nh_r_0, nh_r_f, nh_tof)


# The hyperbolic excess velocity is measured with respect to the Earth:

# In[7]:


C_3_lambert = (norm(nh_v_0 - v_earth)).to(u.km / u.s) ** 2
C_3_lambert


# In[8]:
# The initial data was gathered from Wikipedia: the date of the launch was on **November 26, 2011 at 15:02 UTC** and landing was on **August 6, 2012 at 05:17 UTC**. We compute then the time of flight, which is exactly what it sounds.

# In[4]:

# Initial data
date_launch = time.Time("2011-11-26 15:02", scale="utc").tdb
date_arrival = time.Time("2012-08-06 05:17", scale="utc").tdb

# To compute the transfer orbit, we have the useful function `lambert` : according to a theorem with the same name, *the transfer orbit between two points in space only depends on those two points and the time it takes to go from one to the other*. We could make use of the raw algorithms available in `poliastro.iod` for solving this but working with the `poliastro.maneuvers` is even easier!
#
# We just need to create the orbits for each one of the planets at the specific departure and arrival dates.

# In[5]:

earth = Ephem.from_body(Earth, time_range(date_launch, end=date_arrival))
mars = Ephem.from_body(Mars, time_range(date_launch, end=date_arrival))

# In[6]:

# Solve for departure and target orbits
ss_earth = Orbit.from_ephem(Sun, earth, date_launch)
ss_mars = Orbit.from_ephem(Sun, mars, date_arrival)

# We can now solve for the maneuver that will take us from Earth to Mars. After solving it, we just need to apply it to the departure orbit to solve for the transfer one.

# In[7]:

# Solve for the transfer maneuver
man_lambert = Maneuver.lambert(ss_earth, ss_mars)
from poliastro.ephem import Ephem
from poliastro.twobody import Orbit
from poliastro.maneuver import Maneuver
from poliastro.plotting.static import StaticOrbitPlotter
from poliastro.util import time_range

# In[2]:

# Departure and time of flight for the mission
EPOCH_DPT = Time("2018-12-01", scale="tdb")
EPOCH_ARR = EPOCH_DPT + 2 * u.year

epochs = time_range(EPOCH_DPT, end=EPOCH_ARR)

# Origin and target orbits
earth = Ephem.from_body(Earth, epochs=epochs)
mars = Ephem.from_body(Mars, epochs=epochs)

earth_departure = Orbit.from_ephem(Sun, earth, EPOCH_DPT)
mars_arrival = Orbit.from_ephem(Sun, mars, EPOCH_ARR)

# In[3]:


def lambert_transfer(ss_dpt, ss_arr, revs):
    """ Returns the short and long transfer orbits when solving Lambert's problem.
    
    Parameters
    ----------
    ss_dpt: poliastro.twobody.Orbit
        Deprature orbit.
コード例 #20
0
# In[8]:

from poliastro.ephem import Ephem
from poliastro.util import norm

from astropy.time import Time

# In[9]:

flyby_1_time = Time("2018-09-28", scale="tdb")
flyby_1_time

# In[10]:

r_mag_ref = norm(Ephem.from_body(Venus, flyby_1_time).rv()[0])
r_mag_ref.to(u.au)

# In[11]:

v_mag_ref = np.sqrt(2 * k / r_mag_ref - k / a_ref)
v_mag_ref.to(u.km / u.s)

# ## 2. Lambert arc between #0 and #1
#
# To compute the arrival velocity to Venus at flyby #1, we have the necessary data to solve the boundary value problem.

# In[12]:

d_launch = Time("2018-08-11", scale="tdb")
d_launch
コード例 #21
0
                    end=EPOCH + TimeDelta(3 * 30 * u.day))

# In[10]:

florence = Ephem.from_horizons("Florence", epochs, plane=Planes.EARTH_ECLIPTIC)
florence

# In[11]:

florence.plane

# And now, let's compute the distance between Florence and the Earth at that epoch:

# In[12]:

earth = Ephem.from_body(Earth, epochs, plane=Planes.EARTH_ECLIPTIC)
earth

# In[13]:

from poliastro.util import norm

# In[14]:

min_distance = norm(florence.rv(EPOCH)[0] - earth.rv(EPOCH)[0]) - Earth.R
min_distance.to(u.km)

# <div class="alert alert-success">This value is consistent with what ESA says! $7\,060\,160$ km</div>

# In[15]:
コード例 #22
0
 def _get_ephem_from_list_of_bodies(bodies, current_time):
     list_of_bodies = []
     for i in bodies:
         body = Ephem.from_body(i, current_time)
         list_of_bodies.append([i, body])
     return list_of_bodies
# Atlas V supplied a launch energy
C_3 = 31.1 * u.km**2 / u.s**2

# With previous dates we can create the different orbits that define the position of the Earth along the mission.

# In[3]:

# Plot initial Earth's position
Earth.plot(date_launch, label="Initial Earth's position")

# Since both Earth states have been obtained (initial and flyby) we can now solve for Juno's maneuvers. The first one sets Juno into an elliptical orbit around the Sun so it apply a gravity assist around the Earth.

# In[4]:

earth = Ephem.from_body(Earth,
                        time_range(date_launch, end=date_arrival, periods=500))

r_e0, v_e0 = earth.rv(date_launch)

# In[5]:

# Assume that the insertion velocity is tangential to that of the Earth
dv = C_3**0.5 * v_e0 / norm(v_e0)

# We create the maneuver from impulse constructor
man = Maneuver.impulse(dv)

# If we now apply previous maneuver to the Junos's initial orbit (assume it is the Earth's one for simplicity), we will obtain the orbit around the Sun for Juno. The first inner cruise maneuver is defined just till the ahelion orbit. While Juno is traveling around its new orbit, Earth is also moving. After Juno reaches the aphelion it will be necessary to apply a second maneuver so the flyby is performed around Earth. Once that is achieved a final maneuver will be made in order to benefit from the gravity assist. Let us first propagate Juno's orbit till the aphelion.

# In[6]: