def test_man_tangential_boost(tangential): orb = tangential man_start = orb.date + timedelta(seconds=60) man_stop = man_start + timedelta(seconds=2 * np.pi / orb.propagator.n) forward = 70 # Advance 70 m closer to the target dv = forward * orb.propagator.n / (6 * np.pi) orb.maneuvers = [ ImpulsiveMan(man_start, orb.propagator._mat3 @ [0, -dv, 0]), ImpulsiveMan(man_stop, orb.propagator._mat3 @ [0, dv, 0]), ] # ephem = orb.ephem(stop=man_stop + timedelta(hours=1), step=timedelta(seconds=60)) # plot_ephem(ephem) orb2 = orb.propagate(man_stop + timedelta(seconds=120)) radial = 0 if orb.propagator.frame.orientation == "QSW" else 1 tan = 1 if orb.propagator.frame.orientation == "QSW" else 0 assert np.isclose(orb[radial], orb2[radial]) assert np.isclose(orb2[tan] - orb[tan], forward) assert np.isclose(orb2[tan], -30) assert orb[2] == orb2[2]
def ephem_cov(orbit_cov): ephem = orbit_cov.ephem(start=orbit_cov.date, stop=timedelta(hours=1), step=timedelta(minutes=2)) ephem.name = orbit_cov.name ephem.cospar_id = orbit_cov.cospar_id return ephem
def test_man_continuous(method, molniya_kepler): duration = timedelta(minutes=10) apo = find_event(molniya_kepler.iter(stop=timedelta(hours=26), listeners=ApsideListener()), 'Apoapsis', offset=1) if method == "dv": man1 = ContinuousMan(apo.date, duration, dv=[1427, 0, 0], frame="TNW", date_pos="median") else: man1 = ContinuousMan(apo.date, duration, accel=[2.37834, 0, 0], frame="TNW", date_pos="median") molniya_kepler.maneuvers = man1 altitude = [] eccentricity = [] dates = [] for p in molniya_kepler.iter(stop=timedelta(hours=26)): altitude.append(p.copy(form='spherical').r - p.frame.center.r) eccentricity.append(p.copy(form="keplerian").e) dates.append(p.date.datetime) # plot_delta_a(dates, altitude, eccentricity) man_idx_min = (np.array(dates) > man1.start.datetime).argmax() man_idx_max = (np.array(dates) > man1.stop.datetime).argmax() before = np.mean(altitude[:man_idx_min]) after = np.mean(altitude[man_idx_max:]) assert 8100000 < after - before < 8200000
def test_duty_cycle(orbit_kepler): with mock_step(orbit_kepler) as mock: date = Date(2018, 5, 4, 15) orbit_kepler.propagate(date) assert mock.call_count == count_steps(orbit_kepler.date - date, orbit_kepler.propagator.step) assert mock.call_count == 100 with mock_step(orbit_kepler) as mock: date = orbit_kepler.date - timedelta(seconds=652) orbit_kepler.propagate(date) assert mock.call_count == count_steps(orbit_kepler.date - date, orbit_kepler.propagator.step) assert mock.call_count == 11 with mock_step(orbit_kepler) as mock: start = Date(2018, 5, 4, 13) stop = start + timedelta(minutes=90) data = [] for p in orbit_kepler.iter(start=start, stop=stop): data.append(p) assert len(data) == 91 assert data[0].date == start assert data[-1].date == stop assert mock.call_count == ( count_steps(orbit_kepler.date - start, orbit_kepler.propagator.step) + count_steps(stop - start, orbit_kepler.propagator.step, False) )
def test_find_event_two_calls_bis(orbit): # This case, where we search for the 90 deg Argument of Latitude # does not crash unexpectedly. kwargs = { "start": Date(2018, 4, 5, 16, 50), "stop": timedelta(minutes=200), "step": timedelta(minutes=3), "listeners": AnomalyListener(np.pi / 2, "aol") } orb_iterator = orbit.iter(**kwargs) p1 = find_event(orb_iterator, "Argument of Latitude = 90.00") assert abs(p1.date - Date(2018, 4, 5, 17, 57, 7, 129464)).total_seconds() < 1.8e-5 assert p1.event.info == "Argument of Latitude = 90.00" orb_iterator2 = orbit.iter(**kwargs) p2 = find_event(orb_iterator2, "Argument of Latitude = 90.00", offset=1) assert abs(p2.date - Date(2018, 4, 5, 19, 29, 42, 991221)).total_seconds() < 1.8e-5 assert p2.event.info == "Argument of Latitude = 90.00" orb_iterator3 = orbit.iter(**kwargs) with raises(RuntimeError): find_event(orb_iterator3, "Argument of Latitude = 90.00", offset=2)
def ephem2(orbit): ephem = orbit.ephem(start=orbit.date, stop=timedelta(hours=5), step=timedelta(minutes=5)) ephem.name = orbit.name ephem.cospar_id = orbit.cospar_id return ephem
def test_man_delta_i(orb): i0 = orb.i # Search for the next ascending node for p in orb.iter(stop=timedelta(minutes=200), listeners=NodeListener()): if p.event and p.event.info.startswith("Asc"): man_date = p.date break man = DeltaCombined(man_date, delta_angle=np.radians(5)) orb.maneuvers = man inclination, dates = [], [] for p in orb.iter(stop=timedelta(minutes=100)): inclination.append(p.copy(form="keplerian").i) dates.append(p.date.datetime) # import matplotlib.pyplot as plt # plt.plot(dates, np.degrees(inclination)) # plt.show() before = np.degrees(np.mean(inclination[:30])) after = np.degrees(np.mean(inclination[-30:])) assert 4.99 < after - before <= 5.01
def test_propagate_rk4(orbit_kepler): orbit_kepler.propagator.method = KeplerNum.RK4 assert orbit_kepler.date == Date(2018, 5, 4, 13, 20, 47, 630976) # simple propagation with a Date object orb2 = orbit_kepler.propagate(orbit_kepler.date + timedelta(minutes=121, seconds=12)) assert orb2.date == Date(2018, 5, 4, 15, 21, 59, 630976) assert orb2.propagator.orbit is None # brand new propagator # simple propagation with a timedelta object orb3 = orb2.propagate(timedelta(minutes=12, seconds=5)) # Check if the propagator.orbit is initializd for orb2 # and not yet initialized for orb3 assert orb3.date == Date(2018, 5, 4, 15, 34, 4, 630976) assert orb2.propagator.orbit is not None assert orb3.propagator.orbit is None assert np.allclose( orb3, [-2267347.5906591383, 3865612.1569156954, -5093932.5567979375, -5238.634675262262, -5326.282920539333, -1708.6895889357945] ) # simple propagation with a negative step orb4 = orb3.propagate(timedelta(minutes=-15)) assert orb4.date == orb3.date - timedelta(minutes=15)
def test_station_no_mask(orbit, station): station.mask = np.array([[ 1.97222205, 2.11184839, 2.53072742, 2.74016693, 3.00196631, 3.42084533, 3.71755131, 4.15388362, 4.71238898, 6.28318531 ], [ 0.35255651, 0.34906585, 0.27401669, 0.18675023, 0.28099801, 0.16580628, 0.12915436, 0.03490659, 0.62831853, 1.3962634 ]]) listeners = stations_listeners(station) station.mask = None points = station.visibility( orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=30), step=timedelta(seconds=30), events=listeners, ) with raises(ValueError): points = list(points)
def test_man_delta_a(molniya_kepler): apo = find_event(molniya_kepler.iter(stop=timedelta(hours=26), listeners=ApsideListener()), 'Apoapsis', offset=1) man1 = KeplerianImpulsiveMan(apo.date, da=5900000) molniya_kepler.maneuvers = man1 altitude = [] dates = [] for p in molniya_kepler.iter(stop=timedelta(hours=26)): altitude.append(p.copy(form='spherical').r - p.frame.center.body.r) dates.append(p.date.datetime) # plot_delta_a(dates, altitude) man_idx = (np.array(dates) > man1.date.datetime).argmax() before = np.mean(altitude[:man_idx]) after = np.mean(altitude[man_idx:]) assert int(np.linalg.norm(man1._dv)) == 1477 assert 9100000 < after - before < 9200000
def test_man_tangetial_linear(tangential): orb = tangential forward = 60 dv = 0.1 duration = timedelta(seconds=abs(forward / dv)) dv1 = orb.propagator._mat3 @ [0, dv, 0] accel = (orb.propagator._mat3 @ [-1, 0, 0]) * 2 * orb.propagator.n * dv man_start = orb.date + timedelta(seconds=10) duration = timedelta(seconds=forward / dv) man_stop = man_start + duration orb.maneuvers = [ ImpulsiveMan(man_start, dv1), ContinuousMan(man_start, duration, accel=accel), ImpulsiveMan(man_stop, -dv1), ] # ephem = orb.ephem(stop=man_stop + timedelta(hours=1), step=timedelta(seconds=60)) # plot_ephem(ephem) orb2 = orb.propagate(man_stop + timedelta(seconds=120)) radial = 0 if orb.propagator.frame.orientation == "QSW" else 1 tan = 1 if orb.propagator.frame.orientation == "QSW" else 0 assert duration.total_seconds() == 600 assert np.isclose(orb2[radial], 0) assert np.isclose(orb2[tan] - orb[tan], forward) assert orb2[2] == orb[2]
def test_soi(jplfiles): opm = ccsds.loads("""CCSDS_OPM_VERS = 2.0 CREATION_DATE = 2019-02-22T23:22:31 ORIGINATOR = N/A META_START OBJECT_NAME = N/A OBJECT_ID = N/A CENTER_NAME = EARTH REF_FRAME = EME2000 TIME_SYSTEM = UTC META_STOP COMMENT State Vector EPOCH = 2018-05-02T00:00:00.000000 X = 6678.000000 [km] Y = 0.000000 [km] Z = 0.000000 [km] X_DOT = 0.000000 [km/s] Y_DOT = 7.088481 [km/s] Z_DOT = 3.072802 [km/s] COMMENT Keplerian elements SEMI_MAJOR_AXIS = 6678.000000 [km] ECCENTRICITY = 0.000000 INCLINATION = 23.436363 [deg] RA_OF_ASC_NODE = 0.000000 [deg] ARG_OF_PERICENTER = 0.000000 [deg] TRUE_ANOMALY = 0.000000 [deg] COMMENT Escaping Earth MAN_EPOCH_IGNITION = 2018-05-02T00:39:03.955092 MAN_DURATION = 0.000 [s] MAN_DELTA_MASS = 0.000 [kg] MAN_REF_FRAME = TNW MAN_DV_1 = 3.456791 [km/s] MAN_DV_2 = 0.000000 [km/s] MAN_DV_3 = 0.000000 [km/s] """) planetary_step = timedelta(seconds=180) solar_step = timedelta(hours=12) jpl.create_frames() central = jpl.get_body('Sun') planets = jpl.get_body('Earth') opm.propagator = SOIPropagator(solar_step, planetary_step, central, planets) frames = set() for orb in opm.iter(stop=timedelta(5)): frames.add(orb.frame.name) assert not frames.symmetric_difference(['Sun', 'EME2000']) # Check if the last point is out of Earth sphere of influence assert orb.copy(frame='EME2000', form="spherical").r > SOIPropagator.SOI['Earth'].radius
def test_soi(jplfiles): opm = ccsds.loads("""CCSDS_OPM_VERS = 2.0 CREATION_DATE = 2019-02-22T23:22:31 ORIGINATOR = N/A META_START OBJECT_NAME = N/A OBJECT_ID = N/A CENTER_NAME = EARTH REF_FRAME = EME2000 TIME_SYSTEM = UTC META_STOP COMMENT State Vector EPOCH = 2018-05-02T00:00:00.000000 X = 6678.000000 [km] Y = 0.000000 [km] Z = 0.000000 [km] X_DOT = 0.000000 [km/s] Y_DOT = 7.088481 [km/s] Z_DOT = 3.072802 [km/s] COMMENT Keplerian elements SEMI_MAJOR_AXIS = 6678.000000 [km] ECCENTRICITY = 0.000000 INCLINATION = 23.436363 [deg] RA_OF_ASC_NODE = 0.000000 [deg] ARG_OF_PERICENTER = 0.000000 [deg] TRUE_ANOMALY = 0.000000 [deg] COMMENT Escaping Earth MAN_EPOCH_IGNITION = 2018-05-02T00:39:03.955092 MAN_DURATION = 0.000 [s] MAN_DELTA_MASS = 0.000 [kg] MAN_REF_FRAME = TNW MAN_DV_1 = 3.456791 [km/s] MAN_DV_2 = 0.000000 [km/s] MAN_DV_3 = 0.000000 [km/s] """) planetary_step = timedelta(seconds=180) solar_step = timedelta(hours=12) jpl.create_frames() central = jpl.get_body('Sun') planets = jpl.get_body('Earth') opm.propagator = SOIPropagator(solar_step, planetary_step, central, planets) frames = set() for orb in opm.iter(stop=timedelta(5)): frames.add(orb.frame.name) assert not frames.symmetric_difference(['Sun', 'EME2000']) # Check if the last point is out of Earth sphere of influence assert orb.copy(frame='EME2000', form="spherical").r > SOIPropagator.SOI['Earth'].radius
def molniya(request, molniya_tle): orb = molniya_tle.orbit() if request.param == "tle": return orb elif request.param == "ephem": start = Date(2018, 4, 5, 16, 50) stop = timedelta(hours=15) step = timedelta(minutes=1) return orb.ephem(start=start, stop=stop, step=step)
def test_iter_on_dates(orbit_kepler): # Generate a free step ephemeris start = orbit_kepler.date stop = timedelta(hours=3) step = timedelta(seconds=10) drange = Date.range(start, stop, step, inclusive=True) ephem = orbit_kepler.ephem(dates=drange) assert ephem.start == start assert ephem.stop == start + stop assert ephem[1].date - ephem[0].date == step
def test_man_impulsive(molniya_kepler): # Test of a circularisation of a molniya orbit # At apogee, this is roughly 1400 m/s with raises(ValueError): ImpulsiveMan(Date(2018, 9, 20, 13, 48, 21, 763091), (28, 0, 0, 0)) apo = find_event(molniya_kepler.iter(stop=timedelta(hours=26), listeners=ApsideListener()), 'Apoapsis', offset=1) man = ImpulsiveMan(apo.date, (1427., 0, 0), frame="TNW") # Check on the sensitivity of the find_event function apo2 = find_event(molniya_kepler.iter(start=molniya_kepler.date + timedelta(seconds=243, minutes=5), stop=timedelta(hours=26), listeners=ApsideListener()), 'Apoapsis', offset=1) assert abs(apo.date - apo2.date) < timedelta(seconds=1) molniya_kepler.maneuvers = man altitude = [] eccentricity = [] dates = [] for p in molniya_kepler.iter(stop=timedelta(hours=36)): altitude.append(p.copy(form='spherical').r - p.frame.center.body.r) eccentricity.append(p.copy(form="keplerian").e) dates.append(p.date.datetime) # plot_delta_a(dates, altitude, eccentricity) # retrieve the index of the first point after the maneuver man_idx = (np.array(dates) > man.date.datetime).argmax() alt_before = np.mean(altitude[:man_idx]) alt_after = np.mean(altitude[man_idx:]) ecc_before = np.mean(eccentricity[:man_idx]) ecc_after = np.mean(eccentricity[man_idx:]) assert abs(ecc_before - 6.47e-1) < 2e-4 assert abs(ecc_after - 3e-3) < 2e-4 # assert abs(ecc_after - 6.57e-4) < 1e-6 assert str(man.date) == "2018-05-03T16:29:23.246451 UTC" # 8'000 km increment in altitude assert 8000000 < alt_after - alt_before < 8200000
def test_listener(orbit_kepler): with mock_step(orbit_kepler) as mock: start = Date(2018, 5, 4, 13) stop = start + timedelta(minutes=90) data = [] for p in orbit_kepler.iter(start=start, stop=stop, listeners=LightListener()): data.append(p) assert len(data) == 93 assert mock.call_count == ( count_steps(orbit_kepler.date - start, orbit_kepler.propagator.step) + count_steps(stop - start, orbit_kepler.propagator.step, False)) # assert mock.call_count == 111 events = [x for x in data if x.event] assert len(events) == 2 assert events[0].date == Date(2018, 5, 4, 13, 8, 38, 869126) assert events[0].event.info == "Umbra exit" assert events[1].date == Date(2018, 5, 4, 14, 5, 21, 256923) assert events[1].event.info == "Umbra entry" with mock_step(orbit_kepler) as mock: start = Date(2018, 5, 4, 13) stop = start + timedelta(minutes=90) data = [] for p in orbit_kepler.iter(start=start, stop=stop, listeners=ApsideListener()): data.append(p) assert len(data) == 93 assert mock.call_count == ( count_steps(orbit_kepler.date - start, orbit_kepler.propagator.step) + count_steps(stop - start, orbit_kepler.propagator.step, False)) # assert mock.call_count == 125 events = [x for x in data if x.event] assert len(events) == 2 assert str(events[0].date) == "2018-05-04T13:08:30.765145 UTC" assert events[0].event.info == "Periapsis" assert str(events[1].date) == "2018-05-04T13:54:50.178231 UTC" assert events[1].event.info == "Apoapsis"
def test_event_iterator(orbit): kwargs = { "start": Date(2018, 4, 5, 16, 50), "stop": timedelta(minutes=100), "step": timedelta(minutes=3), "listeners": [ AnomalyListener(3 * np.pi / 2, "aol"), AnomalyListener(np.pi / 2, "aol"), ApsideListener(), ] } # iterate over the orbit, but filter only the AoL events, leaving # apsides events out orb_iterator = orbit.iter(**kwargs) events = [ "Argument of Latitude = 270.00", "Argument of Latitude = 90.00", ] iterator = events_iterator(orb_iterator, *events) p = next(iterator) assert abs(p.date - Date(2018, 4, 5, 17, 10, 49, 816867)).total_seconds() < 1.8e-5 assert p.event.info == "Argument of Latitude = 270.00" p = next(iterator) assert abs(p.date - Date(2018, 4, 5, 17, 57, 7, 129464)).total_seconds() < 1.8e-5 assert p.event.info == "Argument of Latitude = 90.00" # No more events to filter in the iterator with raises(StopIteration): p = next(iterator) # Same iterator construction, but this time we filter only apsudes events iterator = events_iterator(orbit.iter(**kwargs), "Apoapsis") p = next(iterator) assert abs(p.date - Date(2018, 4, 5, 16, 58, 54, 546919)).total_seconds() < 4e-5 assert p.event.info == "Apoapsis" # No more events to filter in the iterator with raises(StopIteration): p = next(iterator)
def test_micro_step(orbit_kepler): with mock_step(orbit_kepler) as mock: # Propagation with micro-step (< to the Kepler propagator step size) orb2 = orbit_kepler.propagate(orbit_kepler.date + timedelta(seconds=20)) assert orb2.date == orbit_kepler.date + timedelta(seconds=20) assert mock.call_count == 7 with mock_step(orbit_kepler) as mock: # negative micro-step orb2 = orbit_kepler.propagate(orbit_kepler.date - timedelta(seconds=20)) assert orb2.date == orbit_kepler.date - timedelta(seconds=20) assert mock.call_count == 7
def test_station_visibility(orbit, station): station.mask = np.array([ [1.97222205, 2.11184839, 2.53072742, 2.74016693, 3.00196631, 3.42084533, 3.71755131, 4.15388362, 4.71238898, 6.28318531], [0.35255651, 0.34906585, 0.27401669, 0.18675023, 0.28099801, 0.16580628, 0.12915436, 0.03490659, 0.62831853, 1.3962634]]) points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=30), step=timedelta(seconds=30))) assert len(points) == 21 points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=Date(2018, 4, 5, 21, 30), step=timedelta(seconds=30))) assert len(points) == 21 # Events (AOS, MAX and LOS) points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=70), step=timedelta(seconds=30), events=True)) # Three more points than precedently, due to the events computation assert len(points) == 26 assert isinstance(points[0].event, SignalEvent) assert points[0].event.info == 'AOS' assert points[0].event.elev == 0 assert abs(points[0].phi) < 1e-5 assert points[0].event.station == station assert (points[0].date - Date(2018, 4, 5, 21, 4, 41, 789681)).total_seconds() <= 1e-5 assert isinstance(points[10].event, MaskEvent) assert points[10].event.info == "AOS" assert points[10].event.elev == "Mask" assert points[10].event.station == station assert (points[10].date - Date(2018, 4, 5, 21, 9, 4, 977230)).total_seconds() <= 1e-5 assert isinstance(points[13].event, MaxEvent) assert points[13].event.info == "MAX" assert points[13].event.station == station assert (points[13].date - Date(2018, 4, 5, 21, 10, 2, 884540)).total_seconds() <= 1e-5 assert isinstance(points[23].event, MaskEvent) assert points[23].event.info == "LOS" assert points[23].event.elev == "Mask" assert points[23].event.station == station assert (points[23].date - Date(2018, 4, 5, 21, 14, 33, 978945)).total_seconds() <= 5e-5 assert isinstance(points[-1].event, SignalEvent) assert points[-1].event.info == 'LOS' assert points[-1].event.elev == 0 assert abs(points[-1].phi) < 1e-5 assert points[-1].event.station == station assert (points[-1].date - Date(2018, 4, 5, 21, 15, 25, 169655)).total_seconds() <= 1e-5
def test_station_visibility(orbit, station): station.mask = np.array([ [1.97222205, 2.11184839, 2.53072742, 2.74016693, 3.00196631, 3.42084533, 3.71755131, 4.15388362, 4.71238898, 6.28318531], [0.35255651, 0.34906585, 0.27401669, 0.18675023, 0.28099801, 0.16580628, 0.12915436, 0.03490659, 0.62831853, 1.3962634]]) points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=30), step=timedelta(seconds=30))) assert len(points) == 21 points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=Date(2018, 4, 5, 21, 30), step=timedelta(seconds=30))) assert len(points) == 21 # Events (AOS, MAX and LOS) points = list(station.visibility(orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=70), step=timedelta(seconds=30), events=True)) # Three more points than precedently, due to the events computation assert len(points) == 26 assert isinstance(points[0].event, SignalEvent) assert points[0].event.info == 'AOS' assert points[0].event.elev == 0 assert abs(points[0].phi) < 1e-5 assert points[0].event.station == station assert (points[0].date - Date(2018, 4, 5, 21, 4, 41, 789681)).total_seconds() <= 1e-5 assert isinstance(points[10].event, MaskEvent) assert points[10].event.info == "AOS" assert points[10].event.elev == "Mask" assert points[10].event.station == station assert (points[10].date - Date(2018, 4, 5, 21, 9, 4, 977230)).total_seconds() <= 1e-5 assert isinstance(points[13].event, MaxEvent) assert points[13].event.info == "MAX" assert points[13].event.station == station assert (points[13].date - Date(2018, 4, 5, 21, 10, 2, 884540)).total_seconds() <= 1e-5 assert isinstance(points[23].event, MaskEvent) assert points[23].event.info == "LOS" assert points[23].event.elev == "Mask" assert points[23].event.station == station assert (points[23].date - Date(2018, 4, 5, 21, 14, 33, 978945)).total_seconds() <= 5e-5 assert isinstance(points[-1].event, SignalEvent) assert points[-1].event.info == 'LOS' assert points[-1].event.elev == 0 assert abs(points[-1].phi) < 1e-5 assert points[-1].event.station == station assert (points[-1].date - Date(2018, 4, 5, 21, 15, 25, 169655)).total_seconds() <= 1e-5
def next_3_passes(files, curr_day, curr_month, curr_year, curr_hour, curr_minute, curr_second, curr_microsecond, station_name, lat, lon, height): AOS_time_list = list() MAX_elev_list = list() LOS_time_list = list() with open(os.path.join(TLE_source_path, files), 'r') as f: data = f.readlines() tle = Tle(data) station = create_station(station_name, (lat, lon, height)) azims, elevs = [], [] #sadf from datetime import datetime starttime = Date( datetime(int(curr_year), int(curr_month), int(curr_day), int(curr_hour), int(curr_second))) q = 0 #print(" Time Azim Elev Distance Radial Velocity") #print("=========================================================") for orb in station.visibility(tle.orbit(), start=starttime, stop=timedelta(days=1), step=timedelta(minutes=2), events=True): #azim = -np.degrees(orb.theta) % 360 elev = np.degrees(orb.phi) #elevs.append(90 - elev) #asdf r = orb.r / 1000. #print("{event:7} {orb.date:%H:%M:%S} {azim:7.2f} {elev:7.2f} {r:10.2f} {orb.r_dot:10.2f}".format(orb=orb, r=r, azim=azim, elev=elev, event=orb.event.info if orb.event is not None else "")) if orb.event and orb.event.info == "AOS": AOS_time = str(orb.date)[:-4] + 'Z' AOS_time_list.append(AOS_time) q = q + 1 if orb.event and orb.event.info == "MAX": MAX_elev = str(round(elev, 4)) MAX_elev_list.append(MAX_elev) if orb.event and orb.event.info == "LOS": LOS_time = str(orb.date)[:-4] + 'Z' LOS_time_list.append(LOS_time) if q == 10: break more_AOS = True if len(AOS_time_list) > len(LOS_time_list): while more_AOS: AOS_time_list = AOS_time_list[:-1] q = q - 1 if not len(AOS_time_list) > len(LOS_time_list): more_AOS = False print(len(AOS_time_list), ' access events calculated') return AOS_time_list, MAX_elev_list, LOS_time_list, q
def test_find_event_offset(orbit): kwargs = { "start": Date(2018, 4, 5, 16, 50), "stop": timedelta(minutes=200), "step": timedelta(minutes=3), "listeners": AnomalyListener(3 * np.pi / 2, "aol") } orb_iterator = orbit.iter(**kwargs) p = find_event(orb_iterator, "Argument of Latitude = 270.00", offset=1) assert abs(p.date - Date(2018, 4, 5, 18, 43, 25, 683360)).total_seconds() < 1.8e-5 assert p.event.info == "Argument of Latitude = 270.00"
def orbit(request, iss_tle): orb = iss_tle.orbit() if request.param == "tle": return orb elif request.param == "ephem": start = Date(2018, 4, 5, 16, 50) stop = timedelta(hours=6) step = timedelta(seconds=15) return orb.ephem(start=start, stop=stop, step=step) elif request.param == "kepler": orb.propagator = KeplerNum(timedelta(seconds=60), get_body('Earth')) return orb
def test_iter_on_dates(orb): # Generate a free step ephemeris start = orb.date stop1 = start + timedelta(hours=3) step1 = timedelta(seconds=10) stop2 = stop1 + timedelta(hours=3) step2 = timedelta(seconds=120) dates = list(Date.range(start, stop1, step1)) + list(Date.range(stop1, stop2, step2, inclusive=True)) ephem = orb.ephem(dates=dates) assert ephem.start == start assert ephem.stop == stop2 assert ephem[1].date - ephem[0].date == step1 assert ephem[-1].date - ephem[-2].date == step2
def test_leo(iss_tle, direction): orbit = iss_tle.orbit().copy(form="keplerian_mean") target = orbit.copy() target.date = orbit.date + timedelta(minutes=45) # 600 km higher target[0] = orbit[0] + 600_000 # On the other side of the orbit target[-1] = (orbit[-1] + np.pi) % (np.pi * 2) target[2] = orbit[2] # print(repr(orbit)) # print(repr(target)) orb1, orb2 = lambert(orbit, target, direction == "prograde") # Check the position has not changed assert all(orb1[:3] == orbit.copy(form="cartesian")[:3]) assert all(orb2[:3] == target.copy(form="cartesian")[:3]) # Check the velocity has changed assert np.linalg.norm(orb1[3:]) > np.linalg.norm( orbit.copy(form="cartesian")[3:]) assert np.linalg.norm(orb2[3:]) < np.linalg.norm( target.copy(form="cartesian")[3:])
def loads(text): """Convert a string formatted along the CCSDS standard into an Orbit or Ephem instance. This function is a wrapper of :py:func:`beyond.io.ccsds.loads` and allows to integrate some space-command specific fields """ orb = ccsds.loads(text) if isinstance(orb, StateVector) and "ccsds_user_defined" in orb.complements: ud = orb.complements["ccsds_user_defined"] name = ud["PROPAGATOR"] if name == "KeplerNum": kwargs = { "step": timedelta(seconds=float(ud["PROPAGATOR_STEP_SECONDS"])), "bodies": [get_body(orb.frame.center.name)], "frame": orb.frame, "method": ud["PROPAGATOR_METHOD"], } else: kwargs = {} orb.as_orbit(get_propagator(name)(**kwargs)) return orb
def test_man(orb): print(repr(orb)) # At the altitude of the ISS, two maneuvers of 28 m/s should result in roughly # an increment of 100 km of altitude with raises(ValueError): Maneuver(Date(2008, 9, 20, 13, 48, 21, 763091), (28, 0, 0, 0)) man1 = Maneuver(Date(2008, 9, 20, 13, 48, 21, 763091), (28, 0, 0), frame="TNW") man2 = Maneuver(Date(2008, 9, 20, 14, 34, 39, 970298), (0, 28, 0), frame="QSW") orb.maneuvers = [man1, man2] altitude = [] dates = [] for p in orb.iter(stop=timedelta(minutes=300)): altitude.append(p.copy(form='spherical').r - p.frame.center.r) dates.append(p.date.datetime) # import matplotlib.pyplot as plt # plt.plot(dates, altitude) # plt.show() before = np.mean(altitude[:80]) after = np.mean(altitude[140:]) assert 98000 < after - before < 99000
def test_iter(orbit_kepler): data = [] for p in orbit_kepler.iter(stop=timedelta(minutes=120)): data.append(p) assert len(data) == 121 assert min(data, key=lambda x: x.date).date == orbit_kepler.date assert max(data, key=lambda x: x.date).date == orbit_kepler.date + timedelta(minutes=120) data2 = [] for p in orbit_kepler.iter(stop=timedelta(minutes=120)): data2.append(p) assert data[0].date == data2[0].date assert all(data[0] == data2[0]) assert data[0] is not data2[0]
def molniya_kepler(molniya_tle): molniya = molniya_tle.orbit() molniya.propagator = KeplerNum(timedelta(seconds=120), bodies=get_body('Earth')) return molniya
def test_iter(orb): data = [] for p in orb.iter(stop=timedelta(minutes=120)): data.append(p) assert len(data) == 121 assert min(data, key=lambda x: x.date).date == orb.date assert max(data, key=lambda x: x.date).date == orb.date + timedelta(minutes=120) data2 = [] for p in orb.iter(stop=timedelta(minutes=120)): data2.append(p) assert data[0].date == data2[0].date assert all(data[0] == data2[0]) assert data[0] is not data2[0]
def orbit_kepler(iss_tle): orbit = iss_tle.orbit() orbit.propagator = KeplerNum(timedelta(seconds=60), bodies=get_body('Earth')) return orbit
def test_listener(orb): with patch('beyond.propagators.kepler.Kepler._make_step', wraps=orb.propagator._make_step) as mock: data = [] for p in orb.iter(start=Date(2008, 9, 20, 13), stop=timedelta(minutes=90), listeners=LightListener()): data.append(p) assert len(data) == 93 assert mock.call_count == 228
def test_iter_on_dates(orbit): # Generate a free step ephemeris start = orbit.date if isinstance(orbit, Orbit) else orbit.start stop1 = start + timedelta(hours=3) step1 = timedelta(seconds=10) stop2 = stop1 + timedelta(hours=3) step2 = timedelta(seconds=120) dates = list(Date.range(start, stop1, step1)) + list( Date.range(stop1, stop2, step2, inclusive=True)) ephem = orbit.ephem(dates=dates) assert ephem.start == start assert ephem.stop == stop2 assert ephem[1].date - ephem[0].date == step1 assert ephem[-1].date - ephem[-2].date == step2
def test_true_anomaly(molniya, mode): if isinstance(molniya, Ephem): stop = molniya[0].infos.period else: stop = molniya.infos.period step = timedelta(minutes=10) events = iter_listeners(molniya, AnomalyListener(np.pi), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 18, 14, 7, 743079)).total_seconds() < 3.7e-5 assert p.event.info == "True Anomaly = 180.00" with raises(StopIteration): p = next(events) events = iter_listeners(molniya, AnomalyListener(3 * np.pi / 2), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 21, 33, 10, 712900)).total_seconds() < 3.7e-5 assert p.event.info == "True Anomaly = 270.00" with raises(StopIteration): p = next(events) events = iter_listeners(molniya, AnomalyListener(0), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 22, 0, 2, 409409)).total_seconds() < 8e-6 assert p.event.info == "True Anomaly = 0.00" with raises(StopIteration): next(events) events = iter_listeners(molniya, AnomalyListener(np.pi / 2), mode, stop=stop, step=step) p = next(events) assert abs(p.date - Date(2018, 4, 5, 22, 26, 54, 209357)).total_seconds() < 3.7e-5 assert p.event.info == "True Anomaly = 90.00" with raises(StopIteration): p = next(events)
def orbit_continuous_man(orbit): orbit = orbit.copy() orbit.propagator = KeplerNum(get_body("Earth"), timedelta(seconds=60)) orbit.maneuvers = [ ContinuousMan( Date(2008, 9, 20, 12, 41, 9, 984493), timedelta(minutes=3), dv=[280, 0, 0], frame="TNW", comment="Maneuver 1", ), ContinuousMan( Date(2008, 9, 20, 13, 33, 11, 374985), timedelta(minutes=3), dv=[270, 0, 0], frame="TNW", ), ] return orbit
def test_stable_tangential(tangential): orb = tangential.propagate(timedelta(minutes=5)) radial = 0 if tangential.propagator.frame.orientation == "QSW" else 1 tan = 1 if tangential.propagator.frame.orientation == "QSW" else 0 assert orb[radial] == tangential[radial] assert orb[tan] == tangential[tan] assert orb[2] == tangential[2]
def orbit(request, common_env): orb = Tle("""ISS (ZARYA) 1 25544U 98067A 18124.55610684 .00001524 00000-0 30197-4 0 9997 2 25544 51.6421 236.2139 0003381 47.8509 47.6767 15.54198229111731""").orbit() if request.param == "tle": return orb elif request.param == "ephem": start = Date(2018, 4, 5, 16, 50) stop = timedelta(hours=6) step = timedelta(seconds=15) return orb.ephem(start=start, stop=stop, step=step) elif request.param == "kepler": orb.propagator = Kepler( timedelta(seconds=60), get_body('Earth') ) return orb
def test_propagate_dopri(orb): orb.propagator.method = Kepler.DOPRI assert orb.date == Date(2008, 9, 20, 12, 25, 40, 104192) orb2 = orb.propagate(orb.date + timedelta(minutes=121, seconds=12)) assert orb2.date == Date(2008, 9, 20, 14, 26, 52, 104192) assert orb2.propagator.orbit is None # brand new propagator orb3 = orb2.propagate(timedelta(minutes=12, seconds=5)) assert orb3.date == Date(2008, 9, 20, 14, 38, 57, 104192) assert orb2.propagator.orbit is not None assert orb3.propagator.orbit is None assert np.allclose( np.array(orb3), [-3.32225199e+06, 2.71765285e+06, -5.18854771e+06, -3.72028909e+03, -6.64186005e+03, -1.10195602e+03] )
def test_propagate_euler(orb): orb.propagator.method = Kepler.EULER assert orb.date == Date(2008, 9, 20, 12, 25, 40, 104192) orb2 = orb.propagate(orb.date + timedelta(minutes=121, seconds=12)) assert orb2.date == Date(2008, 9, 20, 14, 26, 52, 104192) assert orb2.propagator.orbit is None # brand new propagator orb3 = orb2.propagate(timedelta(minutes=12, seconds=5)) assert orb3.date == Date(2008, 9, 20, 14, 38, 57, 104192) assert orb2.propagator.orbit is not None assert orb3.propagator.orbit is None assert np.allclose( np.array(orb3), [1.31798055e+06, -1.03274291e+07, 6.55473124e+06, 3.65036569e+03, 2.74331087e+03, 2.91576212e+03] )
def test_propagate_rk4(orb): orb.propagator.method = Kepler.RK4 assert orb.date == Date(2008, 9, 20, 12, 25, 40, 104192) orb2 = orb.propagate(orb.date + timedelta(minutes=121, seconds=12)) assert orb2.date == Date(2008, 9, 20, 14, 26, 52, 104192) assert orb2.propagator.orbit is None # brand new propagator orb3 = orb2.propagate(timedelta(minutes=12, seconds=5)) assert orb3.date == Date(2008, 9, 20, 14, 38, 57, 104192) assert orb2.propagator.orbit is not None assert orb3.propagator.orbit is None assert np.allclose( orb3, [-3.32227102e+06, 2.71760944e+06, -5.18854876e+06, -3.72026533e+03, -6.64188815e+03, -1.10191470e+03] )
def orb(): orb = Tle("""0 ISS (ZARYA) 1 25544U 98067A 08264.51782528 -.00002182 00000-0 -11606-4 0 2927 2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391563537""").orbit() orb.propagator = Kepler( timedelta(seconds=60), bodies=get_body('Earth') ) return orb
def test_station_no_mask(orbit, station): station.mask = np.array([ [1.97222205, 2.11184839, 2.53072742, 2.74016693, 3.00196631, 3.42084533, 3.71755131, 4.15388362, 4.71238898, 6.28318531], [0.35255651, 0.34906585, 0.27401669, 0.18675023, 0.28099801, 0.16580628, 0.12915436, 0.03490659, 0.62831853, 1.3962634]]) listeners = stations_listeners(station) station.mask = None points = station.visibility( orbit, start=Date(2018, 4, 5, 21), stop=timedelta(minutes=30), step=timedelta(seconds=30), events=listeners, ) with raises(ValueError): points = list(points)
def iter_listeners(orb, listeners, mode): start = Date(2018, 4, 5, 16, 50) stop = timedelta(minutes=100) step = timedelta(minutes=3) kwargs = {} if mode == 'range-nostep': kwargs['start'] = start kwargs['stop'] = stop if not isinstance(orb, Ephem): kwargs['step'] = step elif mode == 'range': kwargs['start'] = start kwargs['stop'] = stop kwargs['step'] = step else: kwargs['dates'] = Date.range(start, stop, step) for orb in orb.iter(listeners=listeners, **kwargs): if orb.event: yield orb
def test_man_delta_a(orb): # We try to dupplicate the change in altitude of the previous test man1 = DeltaCombined(Date(2008, 9, 20, 13, 48, 21, 763091), delta_a=50000) man2 = DeltaCombined(Date(2008, 9, 20, 14, 34, 39, 970298), delta_a=50000) orb.maneuvers = [man1, man2] altitude = [] dates = [] for p in orb.iter(stop=timedelta(minutes=300)): altitude.append(p.copy(form='spherical').r - p.frame.center.r) dates.append(p.date.datetime) # import matplotlib.pyplot as plt # plt.plot(dates, altitude) # plt.show() before = np.mean(altitude[:80]) after = np.mean(altitude[140:]) assert 99000 < after - before < 101000
from beyond.frames import create_station from beyond.config import config tle = Tle("""ISS (ZARYA) 1 25544U 98067A 16086.49419020 .00003976 00000-0 66962-4 0 9998 2 25544 51.6423 110.4590 0001967 0.7896 153.8407 15.54256299992114""").orbit() # Station definition station = create_station('TLS', (43.428889, 1.497778, 178.0)) azims, elevs = [], [] print(" Time Azim Elev Distance Radial Velocity") print("=========================================================") for orb in station.visibility(tle, start=Date.now(), stop=timedelta(hours=24), step=timedelta(seconds=30), events=True): elev = np.degrees(orb.phi) # Radians are counterclockwise and azimuth is clockwise azim = np.degrees(-orb.theta) % 360 # Archive for plotting azims.append(azim) # Matplotlib actually force 0 to be at the center of the polar plot, # so we trick it by inverting the values elevs.append(90 - elev) r = orb.r / 1000. print("{event:7} {orb.date:%H:%M:%S} {azim:7.2f} {elev:7.2f} {r:10.2f} {orb.r_dot:10.2f}".format( orb=orb, r=r, azim=azim, elev=elev, event=orb.event.info if orb.event is not None else "" ))
from mpl_toolkits.mplot3d import Axes3D from beyond.orbits import Tle from beyond.dates import timedelta from beyond.propagators.kepler import Kepler from beyond.env.solarsystem import get_body from beyond.orbits.man import Maneuver from beyond.orbits.listeners import ApsideListener orb = Tle("""ISS (ZARYA) 1 25544U 98067A 18124.55610684 .00001524 00000-0 30197-4 0 9997 2 25544 51.6421 236.2139 0003381 47.8509 47.6767 15.54198229111731""").orbit() start = orb.date stop = timedelta(minutes=300) step = timedelta(seconds=60) # Changing the propagator to Keplerian, as SGP4 is not able to perform maneuvers orb.propagator = Kepler(step, bodies=get_body("Earth")) # Research for the next perigee for p in orb.iter(start=start, stop=stop, step=step, listeners=ApsideListener()): if p.event and p.event.info == "Periapsis": perigee = p break man1 = Maneuver(perigee.date, (280, 0, 0), frame="TNW") orb.maneuvers = [man1] dates1, alt1 = [], []
#!/usr/bin/env python from beyond.dates import Date, timedelta from beyond.orbits import Tle from beyond.frames import create_station from beyond.orbits.listeners import stations_listeners, NodeListener, ApsideListener, LightListener tle = Tle("""ISS (ZARYA) 1 25544U 98067A 17153.89608442 .00001425 00000-0 28940-4 0 9997 2 25544 51.6419 109.5559 0004850 223.1783 180.8272 15.53969766 59532""").orbit() # Station definition station = create_station('TLS', (43.428889, 1.497778, 178.0)) # Listeners declaration listeners = stations_listeners(station) # AOS, LOS and MAX elevation listeners.append(NodeListener()) # Ascending and Descending Node listeners.append(ApsideListener()) # Apogee and Perigee listeners.append(LightListener()) # Illumination events start = Date.now() stop = timedelta(minutes=100) step = timedelta(seconds=180) for orb in tle.iter(start=start, stop=stop, step=step, listeners=listeners): event = orb.event if orb.event is not None else "" print("{orb.date:%Y-%m-%d %H:%M:%S} {event}".format(orb=orb, event=event))