예제 #1
0
    def __init__(self,
            propagator,
            propagator_options = {},
            propagator_args = {},
            parameters = {},
            epoch=Time(57125.7729, format='mjd'),
            oid=1,
            **kwargs
        ):

        self.oid = oid
        self.parameters = copy.copy(SpaceObject.default_parameters)
        self.parameters.update(parameters)
        
        #assume MJD if not "Time" object
        if not isinstance(epoch, Time):
            epoch = Time(epoch, format='mjd', scale='utc')

        self.epoch = epoch

        if 'state' in kwargs:
            self.state = kwargs['state']
        else:
            if 'aop' in kwargs:
                kwargs['omega'] = kwargs.pop('aop')
            if 'raan' in kwargs:
                kwargs['Omega'] = kwargs.pop('raan')
            if 'mu0' in kwargs:
                kwargs['anom'] = kwargs.pop('mu0')

            self.state = pyorb.Orbit(
                M0 = kwargs.get('M_cent', pyorb.M_earth), 
                degrees = True,
                type='mean',
                auto_update = True, 
                direct_update = True,
                num = 1,
                m = self.parameters.get('m', 0.0),
                **kwargs
            )

        self.__propagator = propagator
        self.propagator_options = propagator_options
        self.propagator_args = propagator_args

        self.propagator = propagator(**propagator_options)
예제 #2
0
    def get_orbit(self,
                  n,
                  fields=None,
                  M_cent=pyorb.M_earth,
                  degrees=True,
                  anomaly='mean'):
        '''Get the one row from the population as a :class:`pyorb.Orbit` instance.
        '''

        if fields is None:
            fields = self.state_fields

        kwargs = {}

        for key in fields:
            kwargs[key] = self.data[n][key]

        #TODO: generalize this better
        if 'aop' in kwargs:
            kwargs['omega'] = kwargs.pop('aop')
        if 'raan' in kwargs:
            kwargs['Omega'] = kwargs.pop('raan')
        if 'mu0' in kwargs:
            kwargs['anom'] = kwargs.pop('mu0')

        for key in ['X', 'Y', 'Z', 'VX', 'VY', 'VZ']:
            if key in kwargs:
                kwargs[key.lower()] = kwargs.pop(key)

        obj = pyorb.Orbit(M0=M_cent,
                          degrees=degrees,
                          type=anomaly,
                          auto_update=True,
                          direct_update=True,
                          num=1,
                          **kwargs)
        return obj
예제 #3
0
    def propagate(self, t, state0, epoch, **kwargs):
        '''Propagate a state

        :param float/list/numpy.ndarray/astropy.time.TimeDelta t: Time to propagate relative the initial state epoch.
        :param float/astropy.time.Time epoch: The epoch of the initial state.
        :param numpy.ndarray state0: 6-D Cartesian state vector in SI-units.
        :param bool radians: If true, all angles are assumed to be in radians.
        :return: 6-D Cartesian state vectors in SI-units.

        '''
        if self.profiler is not None:
            self.profiler.start('Kepler:propagate')
        if self.logger is not None:
            self.logger.debug(f'Kepler:propagate:len(t) = {len(t)}')

        t, epoch = self.convert_time(t, epoch)
        times = epoch + t
        tv = t.sec

        if self.profiler is not None:
            self.profiler.start('Kepler:propagate:in_frame')
        if isinstance(state0, pyorb.Orbit):
            orb = state0.copy()
        elif isinstance(state0, dict):
            kw = copy.copy(state0)
            kw.update(kwargs)
            orb = pyorb.Orbit(**kw)
            cart0 = frames.convert(
                epoch,
                orb.cartesian,
                in_frame=self.settings['in_frame'],
                out_frame='GCRS',
                profiler=self.profiler,
                logger=self.logger,
            )
            orb.cartesian = cart0
        else:
            cart0 = frames.convert(
                epoch,
                state0,
                in_frame=self.settings['in_frame'],
                out_frame='GCRS',
                profiler=self.profiler,
                logger=self.logger,
            )
            kw = {
                key: val
                for key, val in zip(pyorb.Orbit.CARTESIAN, cart0.flatten())
            }
            kw.update(kwargs)
            orb = pyorb.Orbit(**kw)
        if self.profiler is not None:
            self.profiler.stop('Kepler:propagate:in_frame')

        orb.direct_update = False
        orb.auto_update = False

        if self.profiler is not None:
            self.profiler.start('Kepler:propagate:mean_motion')

        orb.add(
            num=len(tv),
            **{
                key: val
                for key, val in zip(pyorb.Orbit.KEPLER, orb.kepler.flatten())
            })
        orb.delete(0)
        orb.propagate(tv)
        orb.calculate_cartesian()

        if self.profiler is not None:
            self.profiler.stop('Kepler:propagate:mean_motion')
        if self.profiler is not None:
            self.profiler.start('Kepler:propagate:out_frame')

        states = frames.convert(
            times,
            orb._cart,
            in_frame='GCRS',
            out_frame=self.settings['out_frame'],
            profiler=self.profiler,
            logger=self.logger,
        )

        if self.profiler is not None:
            self.profiler.stop('Kepler:propagate:out_frame')

        if self.profiler is not None:
            self.profiler.stop('Kepler:propagate')
        if self.logger is not None:
            self.logger.debug(f'Kepler:propagate:completed')

        return states
예제 #4
0
'''
Distribution transformation
============================
'''

import pyorb

import numpy as np
import matplotlib.pyplot as plt

#for reproducibility
np.random.seed(12398748)

#We first create a standard orbit around the sun in SI units
orb = pyorb.Orbit(M0=pyorb.M_sol)

#Create 1000 equal orbits
orb.add(num=1000, a=pyorb.AU, e=0, i=0, omega=0, Omega=0, anom=0)
#calculate cartesian elements
orb.calculate_cartesian()

#Add a symmetric Gaussian distribution in the plane on the velocity
std = 3e3
orb.vx += np.random.randn(orb.num) * std
orb.vy += np.random.randn(orb.num) * std

#now when we call any Keplerian element, the distribution in kepler space will be calculated automatically

fig, axes = plt.subplots(1, 2, figsize=(10, 6))
axes[0].plot(orb.vx * 1e-3, orb.vy * 1e-3, '.')
axes[0].set_title('Cartesian velocity', fontsize=22)
예제 #5
0
import matplotlib.pyplot as plt
import pyorb

import sorts
eiscat3d = sorts.radars.eiscat3d

from sorts.propagator import SGP4
Prop_cls = SGP4
Prop_opts = dict(
    settings = dict(
        out_frame='ITRS',
    ),
)
prop = Prop_cls(**Prop_opts)

orb = pyorb.Orbit(M0 = pyorb.M_earth, direct_update=True, auto_update=True, degrees=True, a=7200e3, e=0.05, i=75, omega=0, Omega=79, anom=72, epoch=53005.0)
print(orb)

t = sorts.equidistant_sampling(
    orbit = orb, 
    start_t = 0, 
    end_t = 3600*24*1, 
    max_dpos=1e3,
)

print(f'Temporal points: {len(t)}')
states = prop.propagate(t, orb.cartesian[:,0], orb.epoch, A=1.0, C_R = 1.0, C_D = 1.0)

passes = eiscat3d.find_passes(t, states)

fig = plt.figure(figsize=(15,15))
예제 #6
0
import pyorb

from astropy.utils import iers
from astropy.time import Time
iers.conf.auto_download = False

from sorts.propagator import SGP4
from sorts import frames

prop = SGP4()
orb = pyorb.Orbit(
    M0=pyorb.M_earth,
    direct_update=True,
    auto_update=True,
    degrees=True,
    a=7000e3,
    e=0,
    i=69,
    omega=0,
    Omega=0,
    anom=0,
)

t = np.linspace(0, 3600 * 24.0, num=5000)
mjd0 = Time(53005.0, format='mjd', scale='utc')
times = Time(mjd0 + t / (3600 * 24.0), format='mjd', scale='utc')

states_teme = prop.propagate(t,
                             orb.cartesian[:, 0],
                             epoch=mjd0,
                             A=1.0,
                             C_R=1.0,
예제 #7
0
    location='500@10',
    epochs=epoch.jd,
)
jpl_el = jpl_obj.elements()
print(jpl_obj)
print(jpl_el)
for key in jpl_el.keys():
    print(f'{key}:{jpl_el[key].data[0]}')

orb = pyorb.Orbit(
    M0=pyorb.M_sol,
    direct_update=True,
    auto_update=True,
    degrees=True,
    a=jpl_el['a'].data[0] * pyorb.AU,
    e=jpl_el['e'].data[0],
    i=jpl_el['incl'].data[0],
    omega=jpl_el['w'].data[0],
    Omega=jpl_el['Omega'].data[0],
    anom=jpl_el['M'].data[0],
    type='mean',
)
print('Initial orbit:')
print(orb)


def H_to_D(H, pV):
    return 10**(3.1236 - 0.5 * np.log10(pV) - 0.2 * H)


obj = sorts.SpaceObject(
예제 #8
0
import matplotlib.pyplot as plt
import numpy as np

import pyorb

num = 500
[ecc, anom] = np.meshgrid(
    np.linspace(0, 0.99, num=num),
    np.linspace(0, 360, num=num),
)

orb = pyorb.Orbit(M0=pyorb.M_sol,
                  num=num**2,
                  a=1 * pyorb.AU,
                  e=ecc.reshape(num**2),
                  i=0,
                  omega=90,
                  Omega=0,
                  anom=anom.reshape(num**2),
                  degrees=True,
                  type='true')

true = orb.true_anomaly.reshape(num, num)
mean = orb.mean_anomaly.reshape(num, num)

print(orb)
print(f'Orbit anomaly type: {orb.type}')

fig, ax = plt.subplots(1, 1)

c = ax.pcolormesh(ecc, true, mean - true)
ax.set_xlabel('Eccentricity [1]')
예제 #9
0
'''
Equinoctial orbits
====================
'''

import pyorb

import numpy as np

orb = pyorb.Orbit(M0=pyorb.M_sol, degrees=True)

#equinoctial orbit
orb.update(a=1 * pyorb.AU, e=0.01, i=0.9, omega=24, Omega=0, anom=22)
print(orb)

equi = orb.equinoctial
for ind, var in enumerate(orb.EQUINOCTIAL):
    print(f'{var:<2}: {equi[ind]}')

#change p variable

equi[3] += 0.1

#set values, kepler and cart automatically updated
orb.equinoctial = equi
print(orb)

equi = orb.equinoctial
for ind, var in enumerate(orb.EQUINOCTIAL):
    print(f'{var:<2}: {equi[ind]}')
예제 #10
0
#reproducibility
np.random.seed(324245)

prop = SGP4(settings=dict(
    in_frame='TEME',
    out_frame='TEME',
), )
std_pos = 1e3  #1km std noise on positions

orb = pyorb.Orbit(M0=pyorb.M_earth,
                  direct_update=True,
                  auto_update=True,
                  degrees=True,
                  a=7200e3,
                  e=0.05,
                  i=75,
                  omega=0,
                  Omega=79,
                  anom=72,
                  type='mean')
print(orb)

state0 = orb.cartesian[:, 0]
t = np.linspace(0, 600.0, num=100)
mjd0 = 53005

params = dict(A=1.0, C_R=1.0, C_D=2.3)

states = prop.propagate(t, state0, mjd0, **params)
noisy_pos = states[:3, :] + np.random.randn(3, len(t)) * std_pos
예제 #11
0
'''
Orbit transfer
===============
'''

import pyorb
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

init = pyorb.Orbit(M0=pyorb.M_sol,
                   degrees=True,
                   a=1 * pyorb.AU,
                   e=0,
                   i=0,
                   omega=0,
                   Omega=0,
                   anom=0)
target = pyorb.Orbit(M0=pyorb.M_sol,
                     degrees=True,
                     a=2 * pyorb.AU,
                     e=0,
                     i=23,
                     omega=0,
                     Omega=90,
                     anom=0)

sliders = []


def plot_transfer(init, target):
예제 #12
0
import sorts
eiscat3d = sorts.radars.eiscat3d
from sorts.controller import Tracker
from sorts.propagator import SGP4
from sorts.profiling import Profiler

p = Profiler()
p.start('total')

prop = SGP4(settings=dict(out_frame='ITRF', ), )

orb = pyorb.Orbit(M0=pyorb.M_earth,
                  direct_update=True,
                  auto_update=True,
                  degrees=True,
                  a=6700e3,
                  e=0,
                  i=75,
                  omega=0,
                  Omega=80,
                  anom=72)
t = np.linspace(0, 120, num=10)
mjd0 = 53005

p.start('propagate')
states = prop.propagate(t, orb.cartesian[:, 0], mjd0, A=1.0, C_R=1.0, C_D=1.0)
p.stop('propagate')

e3d = Tracker(radar=eiscat3d, t=t, ecefs=states[:3, :], profiler=p)

fig = plt.figure(figsize=(15, 15))
ax = fig.add_subplot(111, projection='3d')
예제 #13
0
'''
Propagation
============
'''

import pyorb

import numpy as np
import matplotlib.pyplot as plt

#for reproducibility
np.random.seed(12398748)

#We first create a standard orbit around the sun in SI units
#We want it to be completely empty to start with so we set num=0
orb = pyorb.Orbit(M0=pyorb.M_sol, num=0)

#Create 10 equal orbits
orb.add(num=25, a=pyorb.AU, e=0, i=0, omega=0, Omega=0, anom=0)

#calculate cartesian elements
orb.calculate_cartesian()

#Add a symmetric Gaussian distribution on the velocity
std = 3e3
orb.vx += np.random.randn(orb.num) * std
orb.vy += np.random.randn(orb.num) * std
orb.vz += np.random.randn(orb.num) * std

#Go back to kepler based on the cartesian
orb.calculate_kepler()
예제 #14
0
            names.append(meta['controller_type'].__name__)
            targets.append(meta['target'])
            for ri, rx in enumerate(radar.rx):
                data[ind, 1 + ri * 2] = rx.beam.azimuth
                data[ind, 2 + ri * 2] = rx.beam.elevation
        data = data.T.tolist() + [names, targets]
        data = list(map(list, zip(*data)))
        return data


orb = pyorb.Orbit(M0=pyorb.M_earth,
                  direct_update=True,
                  auto_update=True,
                  degrees=True,
                  num=3,
                  a=6700e3,
                  e=0,
                  i=75,
                  omega=0,
                  Omega=np.linspace(79, 82, num=3),
                  anom=72,
                  epoch=53005)
print(orb)

e3d = MyScheduler(radar=eiscat3d, propagator=prop)

e3d.update(orb)
data = e3d.schedule()

rx_head = [
    f'rx{i} {co}' for i in range(len(eiscat3d.rx)) for co in ['az', 'el']
]
예제 #15
0
'''
Perturbation by modifying elements
===================================
'''

import pyorb

import numpy as np
import matplotlib.pyplot as plt

#We first create a standard orbit around the sun in SI units
orb = pyorb.Orbit(
    M0=pyorb.M_sol,
    a=1 * pyorb.AU,
    e=0.2,
    i=0,
    omega=0,
    Omega=0,
    anom=0,
    degrees=True,
)
print(orb)

#prepare a propagation
dt = 3600 * 24.0
num = 1000
r = np.empty((3, num))

for ti in range(num):
    orb.propagate(dt)

    # We need to calculate all the perturbations before perturbing it
예제 #16
0
'''
Get started tutorial
=========================
'''

import pyorb

#We first create a standard orbit around the sun in SI units
orb = pyorb.Orbit(M0=pyorb.M_sol)

#Lets switch to degrees for more human readable units, this can also be given
# at orbit creation as a keyword parameter
orb.degrees = True

#Currently the orbit has no values
print(orb)
print('\n')

#give it a circular orbit in the plane
orb.update(a=1 * pyorb.AU, e=0, i=0, omega=0, Omega=0, anom=0)
print(orb)
print(f'Orbital period: {orb.period/(3600.0*24)} days')
print('\n')

#Now as soon as we try to look at any cartesian elements
# the orbit will be transformed to cartesian space and the
# Cartesian elements are stored
print(f'Orbit X-position is {orb.x*1e-3} km')
print(f'Orbit velocity vector is {orb.v*1e-3} km/s')
print(orb)
print('\n')