open-space-toolkit-astrodynamics 17.2.0__py312-none-manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- open_space_toolkit_astrodynamics-17.2.0.dist-info/METADATA +30 -0
- open_space_toolkit_astrodynamics-17.2.0.dist-info/RECORD +151 -0
- open_space_toolkit_astrodynamics-17.2.0.dist-info/WHEEL +5 -0
- open_space_toolkit_astrodynamics-17.2.0.dist-info/top_level.txt +1 -0
- open_space_toolkit_astrodynamics-17.2.0.dist-info/zip-safe +1 -0
- ostk/__init__.py +1 -0
- ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-312-x86_64-linux-gnu.so +0 -0
- ostk/astrodynamics/__init__.py +11 -0
- ostk/astrodynamics/__init__.pyi +720 -0
- ostk/astrodynamics/access.pyi +577 -0
- ostk/astrodynamics/conjunction/__init__.pyi +121 -0
- ostk/astrodynamics/conjunction/close_approach.pyi +89 -0
- ostk/astrodynamics/conjunction/message/__init__.pyi +3 -0
- ostk/astrodynamics/conjunction/message/ccsds.pyi +705 -0
- ostk/astrodynamics/converters.py +130 -0
- ostk/astrodynamics/converters.pyi +58 -0
- ostk/astrodynamics/data/__init__.pyi +3 -0
- ostk/astrodynamics/data/provider.pyi +22 -0
- ostk/astrodynamics/dataframe.py +597 -0
- ostk/astrodynamics/display.py +281 -0
- ostk/astrodynamics/dynamics.pyi +311 -0
- ostk/astrodynamics/eclipse.pyi +70 -0
- ostk/astrodynamics/estimator.pyi +268 -0
- ostk/astrodynamics/event_condition.pyi +910 -0
- ostk/astrodynamics/flight/__init__.pyi +626 -0
- ostk/astrodynamics/flight/profile/__init__.pyi +99 -0
- ostk/astrodynamics/flight/profile/model.pyi +179 -0
- ostk/astrodynamics/flight/system.pyi +268 -0
- ostk/astrodynamics/guidance_law.pyi +416 -0
- ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.17 +0 -0
- ostk/astrodynamics/pytrajectory/__init__.py +1 -0
- ostk/astrodynamics/pytrajectory/__init__.pyi +3 -0
- ostk/astrodynamics/pytrajectory/pystate.py +263 -0
- ostk/astrodynamics/pytrajectory/pystate.pyi +66 -0
- ostk/astrodynamics/solver.pyi +432 -0
- ostk/astrodynamics/test/__init__.py +1 -0
- ostk/astrodynamics/test/access/__init__.py +1 -0
- ostk/astrodynamics/test/access/test_generator.py +319 -0
- ostk/astrodynamics/test/access/test_visibility_criterion.py +201 -0
- ostk/astrodynamics/test/conftest.py +119 -0
- ostk/astrodynamics/test/conjunction/close_approach/__init__.py +0 -0
- ostk/astrodynamics/test/conjunction/close_approach/test_generator.py +228 -0
- ostk/astrodynamics/test/conjunction/message/ccsds/__init__.py +1 -0
- ostk/astrodynamics/test/conjunction/message/ccsds/conftest.py +325 -0
- ostk/astrodynamics/test/conjunction/message/ccsds/data/cdm.json +303 -0
- ostk/astrodynamics/test/conjunction/message/ccsds/test_cdm.py +416 -0
- ostk/astrodynamics/test/conjunction/test_close_approach.py +244 -0
- ostk/astrodynamics/test/data/provider/test_off_nadir.py +58 -0
- ostk/astrodynamics/test/dynamics/__init__.py +1 -0
- ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity.csv +565 -0
- ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity_Truth.csv +100 -0
- ostk/astrodynamics/test/dynamics/test_atmospheric_drag.py +128 -0
- ostk/astrodynamics/test/dynamics/test_central_body_gravity.py +58 -0
- ostk/astrodynamics/test/dynamics/test_dynamics.py +50 -0
- ostk/astrodynamics/test/dynamics/test_position_derivative.py +51 -0
- ostk/astrodynamics/test/dynamics/test_tabulated.py +138 -0
- ostk/astrodynamics/test/dynamics/test_third_body_gravity.py +67 -0
- ostk/astrodynamics/test/dynamics/test_thruster.py +157 -0
- ostk/astrodynamics/test/eclipse/__init__.py +1 -0
- ostk/astrodynamics/test/eclipse/test_generator.py +138 -0
- ostk/astrodynamics/test/estimator/test_orbit_determination_solver.py +261 -0
- ostk/astrodynamics/test/estimator/test_tle_solver.py +216 -0
- ostk/astrodynamics/test/event_condition/test_angular_condition.py +113 -0
- ostk/astrodynamics/test/event_condition/test_boolean_condition.py +55 -0
- ostk/astrodynamics/test/event_condition/test_brouwer_lyddane_mean_long_condition.py +135 -0
- ostk/astrodynamics/test/event_condition/test_coe_condition.py +135 -0
- ostk/astrodynamics/test/event_condition/test_instant_condition.py +48 -0
- ostk/astrodynamics/test/event_condition/test_logical_condition.py +120 -0
- ostk/astrodynamics/test/event_condition/test_real_condition.py +50 -0
- ostk/astrodynamics/test/flight/__init__.py +1 -0
- ostk/astrodynamics/test/flight/profile/model/test_tabulated_profile.py +115 -0
- ostk/astrodynamics/test/flight/system/__init__.py +1 -0
- ostk/astrodynamics/test/flight/system/test_propulsion_system.py +64 -0
- ostk/astrodynamics/test/flight/system/test_satellite_system.py +83 -0
- ostk/astrodynamics/test/flight/system/test_satellite_system_builder.py +71 -0
- ostk/astrodynamics/test/flight/test_maneuver.py +231 -0
- ostk/astrodynamics/test/flight/test_profile.py +293 -0
- ostk/astrodynamics/test/flight/test_system.py +45 -0
- ostk/astrodynamics/test/guidance_law/test_constant_thrust.py +177 -0
- ostk/astrodynamics/test/guidance_law/test_guidance_law.py +60 -0
- ostk/astrodynamics/test/guidance_law/test_heterogeneous_guidance_law.py +164 -0
- ostk/astrodynamics/test/guidance_law/test_qlaw.py +209 -0
- ostk/astrodynamics/test/solvers/__init__.py +1 -0
- ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +196 -0
- ostk/astrodynamics/test/solvers/test_least_squares_solver.py +334 -0
- ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +161 -0
- ostk/astrodynamics/test/test_access.py +128 -0
- ostk/astrodynamics/test/test_converters.py +290 -0
- ostk/astrodynamics/test/test_dataframe.py +1355 -0
- ostk/astrodynamics/test/test_display.py +184 -0
- ostk/astrodynamics/test/test_event_condition.py +80 -0
- ostk/astrodynamics/test/test_import.py +26 -0
- ostk/astrodynamics/test/test_root_solver.py +70 -0
- ostk/astrodynamics/test/test_trajectory.py +126 -0
- ostk/astrodynamics/test/test_utilities.py +338 -0
- ostk/astrodynamics/test/test_viewer.py +318 -0
- ostk/astrodynamics/test/trajectory/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/model/test_nadir_trajectory.py +87 -0
- ostk/astrodynamics/test/trajectory/model/test_tabulated_trajectory.py +303 -0
- ostk/astrodynamics/test/trajectory/model/test_target_scan_trajectory.py +126 -0
- ostk/astrodynamics/test/trajectory/orbit/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/message/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/message/spacex/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/message/spacex/conftest.py +18 -0
- ostk/astrodynamics/test/trajectory/orbit/message/spacex/data/opm_1.yaml +44 -0
- ostk/astrodynamics/test/trajectory/orbit/message/spacex/test_opm.py +108 -0
- ostk/astrodynamics/test/trajectory/orbit/models/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py +65 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py +102 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py +102 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py +305 -0
- ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +337 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +130 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_modified_equinoctial.py +142 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +234 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_sgp4.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_tabulated.py +380 -0
- ostk/astrodynamics/test/trajectory/orbit/test_model.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/test_pass.py +75 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity.py +30 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py +18 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_acceleration.py +136 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py +107 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py +115 -0
- ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py +84 -0
- ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py +58 -0
- ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +316 -0
- ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py +81 -0
- ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +119 -0
- ostk/astrodynamics/test/trajectory/test_model.py +1 -0
- ostk/astrodynamics/test/trajectory/test_orbit.py +212 -0
- ostk/astrodynamics/test/trajectory/test_propagator.py +452 -0
- ostk/astrodynamics/test/trajectory/test_segment.py +694 -0
- ostk/astrodynamics/test/trajectory/test_sequence.py +550 -0
- ostk/astrodynamics/test/trajectory/test_state.py +629 -0
- ostk/astrodynamics/test/trajectory/test_state_builder.py +172 -0
- ostk/astrodynamics/trajectory/__init__.pyi +1982 -0
- ostk/astrodynamics/trajectory/model.pyi +259 -0
- ostk/astrodynamics/trajectory/orbit/__init__.pyi +349 -0
- ostk/astrodynamics/trajectory/orbit/message/__init__.pyi +3 -0
- ostk/astrodynamics/trajectory/orbit/message/spacex.pyi +264 -0
- ostk/astrodynamics/trajectory/orbit/model/__init__.pyi +648 -0
- ostk/astrodynamics/trajectory/orbit/model/brouwerLyddaneMean.pyi +121 -0
- ostk/astrodynamics/trajectory/orbit/model/kepler.pyi +709 -0
- ostk/astrodynamics/trajectory/orbit/model/sgp4.pyi +330 -0
- ostk/astrodynamics/trajectory/state/__init__.pyi +402 -0
- ostk/astrodynamics/trajectory/state/coordinate_subset.pyi +208 -0
- ostk/astrodynamics/utilities.py +396 -0
- ostk/astrodynamics/viewer.py +851 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from ostk.physics.environment.object.celestial import Earth
|
|
6
|
+
from ostk.physics.time import Instant
|
|
7
|
+
from ostk.physics.time import DateTime
|
|
8
|
+
from ostk.physics.time import Scale
|
|
9
|
+
from ostk.physics.unit import Length
|
|
10
|
+
from ostk.physics.unit import Angle
|
|
11
|
+
|
|
12
|
+
from ostk.astrodynamics.trajectory import Orbit
|
|
13
|
+
from ostk.astrodynamics.trajectory import State
|
|
14
|
+
from ostk.astrodynamics.trajectory.model import Nadir
|
|
15
|
+
from ostk.astrodynamics.trajectory.orbit.model import Kepler
|
|
16
|
+
from ostk.astrodynamics.trajectory.orbit.model.kepler import COE
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def orbit() -> Orbit:
|
|
21
|
+
earth = Earth.WGS84()
|
|
22
|
+
coe = COE(
|
|
23
|
+
semi_major_axis=Length.kilometers(7000.0),
|
|
24
|
+
eccentricity=0.0,
|
|
25
|
+
inclination=Angle.degrees(98.0),
|
|
26
|
+
raan=Angle.degrees(0.0),
|
|
27
|
+
aop=Angle.degrees(0.0),
|
|
28
|
+
true_anomaly=Angle.degrees(0.0),
|
|
29
|
+
)
|
|
30
|
+
keplerian_model = Kepler(
|
|
31
|
+
coe=coe,
|
|
32
|
+
epoch=Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC),
|
|
33
|
+
gravitational_parameter=earth.get_gravitational_parameter(),
|
|
34
|
+
equatorial_radius=earth.get_equatorial_radius(),
|
|
35
|
+
j2=earth.get_j2(),
|
|
36
|
+
j4=earth.get_j4(),
|
|
37
|
+
perturbation_type=Kepler.PerturbationType.No,
|
|
38
|
+
)
|
|
39
|
+
return Orbit(keplerian_model, earth)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.fixture
|
|
43
|
+
def nadir(orbit: Orbit) -> Nadir:
|
|
44
|
+
return Nadir(orbit)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class TestNadir:
|
|
48
|
+
def test_constructor(
|
|
49
|
+
self,
|
|
50
|
+
nadir: Nadir,
|
|
51
|
+
):
|
|
52
|
+
assert nadir.is_defined()
|
|
53
|
+
|
|
54
|
+
def test_calculate_state_at(
|
|
55
|
+
self,
|
|
56
|
+
nadir: Nadir,
|
|
57
|
+
):
|
|
58
|
+
instant: Instant = Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
|
59
|
+
|
|
60
|
+
state: State = nadir.calculate_state_at(instant)
|
|
61
|
+
|
|
62
|
+
assert state is not None
|
|
63
|
+
|
|
64
|
+
def test_equality_operator(
|
|
65
|
+
self,
|
|
66
|
+
nadir: Nadir,
|
|
67
|
+
):
|
|
68
|
+
assert nadir == nadir
|
|
69
|
+
|
|
70
|
+
def test_inequality_operator(
|
|
71
|
+
self,
|
|
72
|
+
nadir: Nadir,
|
|
73
|
+
):
|
|
74
|
+
nadir2 = Nadir(Orbit.undefined())
|
|
75
|
+
assert nadir != nadir2
|
|
76
|
+
|
|
77
|
+
def test_get_orbit(
|
|
78
|
+
self,
|
|
79
|
+
nadir: Nadir,
|
|
80
|
+
):
|
|
81
|
+
assert nadir.get_orbit() is not None
|
|
82
|
+
|
|
83
|
+
def test_get_step_size(
|
|
84
|
+
self,
|
|
85
|
+
nadir: Nadir,
|
|
86
|
+
):
|
|
87
|
+
assert nadir.get_step_size() is not None
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
from ostk.mathematics.curve_fitting import Interpolator
|
|
8
|
+
|
|
9
|
+
from ostk.physics.time import Instant
|
|
10
|
+
from ostk.physics.time import DateTime
|
|
11
|
+
from ostk.physics.time import Scale
|
|
12
|
+
from ostk.physics.coordinate import Position
|
|
13
|
+
from ostk.physics.coordinate import Velocity
|
|
14
|
+
from ostk.physics.coordinate import Frame
|
|
15
|
+
|
|
16
|
+
from ostk.astrodynamics.trajectory import State
|
|
17
|
+
from ostk.astrodynamics.trajectory.model import Tabulated
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.fixture
|
|
21
|
+
def reference_states() -> list[State]:
|
|
22
|
+
data = [
|
|
23
|
+
[
|
|
24
|
+
"2023-04-18T08:28:32.744064",
|
|
25
|
+
-3310024.847608758,
|
|
26
|
+
-6052528.239971979,
|
|
27
|
+
7626.534641683145,
|
|
28
|
+
-855.2088930507367,
|
|
29
|
+
495.9541573743367,
|
|
30
|
+
7536.520188134902,
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
"2023-04-18T08:28:33.744064",
|
|
34
|
+
-3310878.047628086,
|
|
35
|
+
-6052028.610429457,
|
|
36
|
+
15163.0493833017,
|
|
37
|
+
-851.1838953959017,
|
|
38
|
+
503.31279367207185,
|
|
39
|
+
7536.506322816037,
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"2023-04-18T08:28:34.744064",
|
|
43
|
+
-3311727.222133691,
|
|
44
|
+
-6051521.622540367,
|
|
45
|
+
22699.545682944226,
|
|
46
|
+
-847.1578341126227,
|
|
47
|
+
510.67087060642456,
|
|
48
|
+
7536.483268627912,
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
"2023-04-18T08:28:35.744064",
|
|
52
|
+
-3312572.370064364,
|
|
53
|
+
-6051007.276868478,
|
|
54
|
+
30236.014351773065,
|
|
55
|
+
-843.1307141262514,
|
|
56
|
+
518.0283791399937,
|
|
57
|
+
7536.451025467619,
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
"2023-04-18T08:28:36.744064",
|
|
61
|
+
-3313413.490363804,
|
|
62
|
+
-6050485.573986613,
|
|
63
|
+
37772.44620082258,
|
|
64
|
+
-839.1025403636198,
|
|
65
|
+
525.3853102358,
|
|
66
|
+
7536.40959324377,
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
"2023-04-18T08:28:37.744064",
|
|
70
|
+
-3314250.5819806806,
|
|
71
|
+
-6049956.514476612,
|
|
72
|
+
45308.83204108345,
|
|
73
|
+
-835.0733177529921,
|
|
74
|
+
532.7416548573802,
|
|
75
|
+
7536.358971876497,
|
|
76
|
+
],
|
|
77
|
+
[
|
|
78
|
+
"2023-04-18T08:28:38.744064",
|
|
79
|
+
-3315083.6438685474,
|
|
80
|
+
-6049420.098929363,
|
|
81
|
+
52845.16268340493,
|
|
82
|
+
-831.0430512241197,
|
|
83
|
+
540.0974039686765,
|
|
84
|
+
7536.299161297429,
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
"2023-04-18T08:28:39.744064",
|
|
88
|
+
-3315912.6749859042,
|
|
89
|
+
-6048876.327944793,
|
|
90
|
+
60381.42893867038,
|
|
91
|
+
-827.0117457081434,
|
|
92
|
+
547.4525485342174,
|
|
93
|
+
7536.23016144972,
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"2023-04-18T08:28:40.744064",
|
|
97
|
+
-3316737.6742961914,
|
|
98
|
+
-6048325.2021318525,
|
|
99
|
+
67917.62161760827,
|
|
100
|
+
-822.9794061376964,
|
|
101
|
+
554.8070795189376,
|
|
102
|
+
7536.1519722880375,
|
|
103
|
+
],
|
|
104
|
+
[
|
|
105
|
+
"2023-04-18T08:28:41.744064",
|
|
106
|
+
-3317558.640767768,
|
|
107
|
+
-6047766.722108539,
|
|
108
|
+
75453.73153099201,
|
|
109
|
+
-818.9460374467976,
|
|
110
|
+
562.1609878883643,
|
|
111
|
+
7536.064593778564,
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
"2023-04-18T08:28:42.744064",
|
|
115
|
+
-3318375.5733739412,
|
|
116
|
+
-6047200.888501875,
|
|
117
|
+
82989.7494894997,
|
|
118
|
+
-814.9116445709234,
|
|
119
|
+
569.5142646084902,
|
|
120
|
+
7535.968025898996,
|
|
121
|
+
],
|
|
122
|
+
[
|
|
123
|
+
"2023-04-18T08:28:43.744064",
|
|
124
|
+
-3319188.471092942,
|
|
125
|
+
-6046627.7019479135,
|
|
126
|
+
90525.66630384693,
|
|
127
|
+
-810.8762324469382,
|
|
128
|
+
576.866900645898,
|
|
129
|
+
7535.862268638544,
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
"2023-04-18T08:28:44.744064",
|
|
133
|
+
-3319997.332907958,
|
|
134
|
+
-6046047.163091751,
|
|
135
|
+
98061.47278470133,
|
|
136
|
+
-806.8398060131411,
|
|
137
|
+
584.2188869676824,
|
|
138
|
+
7535.747321997941,
|
|
139
|
+
],
|
|
140
|
+
[
|
|
141
|
+
"2023-04-18T08:28:45.744064",
|
|
142
|
+
-3320802.157807084,
|
|
143
|
+
-6045459.272587514,
|
|
144
|
+
105597.15974279115,
|
|
145
|
+
-802.8023702092072,
|
|
146
|
+
591.5702145415504,
|
|
147
|
+
7535.62318598943,
|
|
148
|
+
],
|
|
149
|
+
[
|
|
150
|
+
"2023-04-18T08:28:46.744064",
|
|
151
|
+
-3321602.9447833803,
|
|
152
|
+
-6044864.0310983565,
|
|
153
|
+
113132.71798877101,
|
|
154
|
+
-798.7639299762548,
|
|
155
|
+
598.9208743356983,
|
|
156
|
+
7535.48986063679,
|
|
157
|
+
],
|
|
158
|
+
[
|
|
159
|
+
"2023-04-18T08:28:47.744064",
|
|
160
|
+
-3322399.692834845,
|
|
161
|
+
-6044261.439296465,
|
|
162
|
+
120668.13833342775,
|
|
163
|
+
-794.7244902567405,
|
|
164
|
+
606.2708573190106,
|
|
165
|
+
7535.347345975296,
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
"2023-04-18T08:28:48.744064",
|
|
169
|
+
-3323192.400964402,
|
|
170
|
+
-6043651.497863061,
|
|
171
|
+
128203.41158748553,
|
|
172
|
+
-790.6840559945587,
|
|
173
|
+
613.6201544608678,
|
|
174
|
+
7535.195642051765,
|
|
175
|
+
],
|
|
176
|
+
[
|
|
177
|
+
"2023-04-18T08:28:49.744064",
|
|
178
|
+
-3323981.068179951,
|
|
179
|
+
-6043034.207488383,
|
|
180
|
+
135738.52856182377,
|
|
181
|
+
-786.6426321349277,
|
|
182
|
+
620.9687567313651,
|
|
183
|
+
7535.034748924513,
|
|
184
|
+
],
|
|
185
|
+
[
|
|
186
|
+
"2023-04-18T08:28:50.744064",
|
|
187
|
+
-3324765.6934943097,
|
|
188
|
+
-6042409.568871722,
|
|
189
|
+
143273.48006733102,
|
|
190
|
+
-782.6002236244674,
|
|
191
|
+
628.3166551011666,
|
|
192
|
+
7534.864666663388,
|
|
193
|
+
],
|
|
194
|
+
[
|
|
195
|
+
"2023-04-18T08:28:51.744064",
|
|
196
|
+
-3325546.2759252544,
|
|
197
|
+
-6041777.582721372,
|
|
198
|
+
150808.25691495842,
|
|
199
|
+
-778.5568354111685,
|
|
200
|
+
635.6638405415614,
|
|
201
|
+
7534.68539534976,
|
|
202
|
+
],
|
|
203
|
+
]
|
|
204
|
+
return [
|
|
205
|
+
State(
|
|
206
|
+
instant=Instant.date_time(DateTime.parse(row[0]), Scale.UTC),
|
|
207
|
+
position=Position.meters(
|
|
208
|
+
[float(row[1]), float(row[2]), float(row[3])], Frame.GCRF()
|
|
209
|
+
),
|
|
210
|
+
velocity=Velocity.meters_per_second(
|
|
211
|
+
[float(row[4]), float(row[5]), float(row[6])], Frame.GCRF()
|
|
212
|
+
),
|
|
213
|
+
)
|
|
214
|
+
for row in data
|
|
215
|
+
]
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
@pytest.fixture
|
|
219
|
+
def test_states(reference_states: list[State]) -> list[State]:
|
|
220
|
+
return reference_states[::4]
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@pytest.fixture
|
|
224
|
+
def interpolation_type() -> Interpolator.Type:
|
|
225
|
+
return Interpolator.Type.CubicSpline
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@pytest.fixture
|
|
229
|
+
def tabulated(
|
|
230
|
+
test_states: list[State],
|
|
231
|
+
interpolation_type: Interpolator.Type,
|
|
232
|
+
) -> Tabulated:
|
|
233
|
+
return Tabulated(
|
|
234
|
+
states=test_states,
|
|
235
|
+
interpolation_type=interpolation_type,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class TestTabulatedTrajectory:
|
|
240
|
+
@pytest.mark.parametrize(
|
|
241
|
+
"interpolation_type",
|
|
242
|
+
(
|
|
243
|
+
(Interpolator.Type.Linear),
|
|
244
|
+
(Interpolator.Type.CubicSpline),
|
|
245
|
+
(Interpolator.Type.BarycentricRational),
|
|
246
|
+
),
|
|
247
|
+
)
|
|
248
|
+
def test_constructor(
|
|
249
|
+
self,
|
|
250
|
+
test_states: list[State],
|
|
251
|
+
interpolation_type: Interpolator.Type,
|
|
252
|
+
):
|
|
253
|
+
assert (
|
|
254
|
+
Tabulated(
|
|
255
|
+
states=test_states,
|
|
256
|
+
interpolation_type=interpolation_type,
|
|
257
|
+
)
|
|
258
|
+
is not None
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
def test_get_interpolation_type(
|
|
262
|
+
self,
|
|
263
|
+
test_states: list[State],
|
|
264
|
+
tabulated: Tabulated,
|
|
265
|
+
interpolation_type: Interpolator.Type,
|
|
266
|
+
):
|
|
267
|
+
assert tabulated.get_interpolation_type() == Interpolator.Type.CubicSpline
|
|
268
|
+
|
|
269
|
+
@pytest.mark.parametrize(
|
|
270
|
+
"interpolation_type,error_tolerance",
|
|
271
|
+
(
|
|
272
|
+
(Interpolator.Type.Linear, 420.0),
|
|
273
|
+
(Interpolator.Type.CubicSpline, 5e-3),
|
|
274
|
+
(Interpolator.Type.BarycentricRational, 5e-2),
|
|
275
|
+
),
|
|
276
|
+
)
|
|
277
|
+
def test_calculate_state_at(
|
|
278
|
+
self,
|
|
279
|
+
test_states: list[State],
|
|
280
|
+
reference_states: list[State],
|
|
281
|
+
interpolation_type: Interpolator.Type,
|
|
282
|
+
error_tolerance: float,
|
|
283
|
+
):
|
|
284
|
+
tabulated: Tabulated = Tabulated(
|
|
285
|
+
states=test_states,
|
|
286
|
+
interpolation_type=interpolation_type,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
for reference_state in reference_states:
|
|
290
|
+
if not tabulated.get_interval().contains_instant(
|
|
291
|
+
reference_state.get_instant()
|
|
292
|
+
):
|
|
293
|
+
continue
|
|
294
|
+
|
|
295
|
+
calculated_state: State = tabulated.calculate_state_at(
|
|
296
|
+
reference_state.get_instant()
|
|
297
|
+
)
|
|
298
|
+
assert np.all(
|
|
299
|
+
np.abs(
|
|
300
|
+
calculated_state.get_coordinates() - reference_state.get_coordinates()
|
|
301
|
+
)
|
|
302
|
+
< error_tolerance
|
|
303
|
+
)
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from ostk.physics.coordinate.spherical import LLA
|
|
6
|
+
from ostk.physics.environment.object.celestial import Earth
|
|
7
|
+
from ostk.physics.time import Instant
|
|
8
|
+
from ostk.physics.time import DateTime
|
|
9
|
+
from ostk.physics.time import Scale
|
|
10
|
+
from ostk.physics.time import Duration
|
|
11
|
+
from ostk.physics.unit import Derived
|
|
12
|
+
from ostk.astrodynamics.trajectory.model import TargetScan
|
|
13
|
+
from ostk.astrodynamics.trajectory import State
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.fixture
|
|
17
|
+
def earth() -> Earth:
|
|
18
|
+
return Earth.WGS84()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@pytest.fixture
|
|
22
|
+
def start_lla() -> LLA:
|
|
23
|
+
return LLA.vector([0.0, 0.0, 0.0])
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.fixture
|
|
27
|
+
def end_lla() -> LLA:
|
|
28
|
+
return LLA.vector([0.0, 1.0, 0.0])
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.fixture
|
|
32
|
+
def start_instant() -> Instant:
|
|
33
|
+
return Instant.date_time(DateTime(2023, 1, 1, 0, 0, 0), Scale.UTC)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@pytest.fixture
|
|
37
|
+
def end_instant() -> Instant:
|
|
38
|
+
return Instant.date_time(DateTime(2023, 1, 1, 0, 10, 0), Scale.UTC)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.fixture
|
|
42
|
+
def target_scan(
|
|
43
|
+
earth: Earth,
|
|
44
|
+
start_lla: LLA,
|
|
45
|
+
end_lla: LLA,
|
|
46
|
+
start_instant: Instant,
|
|
47
|
+
end_instant: Instant,
|
|
48
|
+
) -> TargetScan:
|
|
49
|
+
return TargetScan(
|
|
50
|
+
start_lla=start_lla,
|
|
51
|
+
end_lla=end_lla,
|
|
52
|
+
start_instant=start_instant,
|
|
53
|
+
end_instant=end_instant,
|
|
54
|
+
celestial=earth,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class TestTargetScan:
|
|
59
|
+
def test_constructor(
|
|
60
|
+
self,
|
|
61
|
+
target_scan: TargetScan,
|
|
62
|
+
):
|
|
63
|
+
assert target_scan.is_defined()
|
|
64
|
+
|
|
65
|
+
def test_calculate_state_at(
|
|
66
|
+
self,
|
|
67
|
+
target_scan: TargetScan,
|
|
68
|
+
):
|
|
69
|
+
instant: Instant = Instant.date_time(DateTime(2023, 1, 1, 0, 5, 0), Scale.UTC)
|
|
70
|
+
state: State = target_scan.calculate_state_at(instant)
|
|
71
|
+
assert state is not None
|
|
72
|
+
|
|
73
|
+
def test_equality_operator(
|
|
74
|
+
self,
|
|
75
|
+
target_scan: TargetScan,
|
|
76
|
+
):
|
|
77
|
+
assert target_scan == target_scan
|
|
78
|
+
|
|
79
|
+
def test_inequality_operator(
|
|
80
|
+
self,
|
|
81
|
+
target_scan: TargetScan,
|
|
82
|
+
start_lla: LLA,
|
|
83
|
+
end_lla: LLA,
|
|
84
|
+
start_instant: Instant,
|
|
85
|
+
earth: Earth,
|
|
86
|
+
):
|
|
87
|
+
target_scan2 = TargetScan(
|
|
88
|
+
start_lla=start_lla,
|
|
89
|
+
end_lla=end_lla,
|
|
90
|
+
start_instant=start_instant,
|
|
91
|
+
end_instant=Instant.undefined(),
|
|
92
|
+
celestial=earth,
|
|
93
|
+
)
|
|
94
|
+
assert target_scan != target_scan2
|
|
95
|
+
|
|
96
|
+
def test_getters(
|
|
97
|
+
self,
|
|
98
|
+
target_scan: TargetScan,
|
|
99
|
+
):
|
|
100
|
+
assert target_scan.get_start_lla() is not None
|
|
101
|
+
assert target_scan.get_end_lla() is not None
|
|
102
|
+
assert target_scan.get_start_instant() is not None
|
|
103
|
+
assert target_scan.get_end_instant() is not None
|
|
104
|
+
assert target_scan.get_celestial() is not None
|
|
105
|
+
assert target_scan.get_step_size() is not None
|
|
106
|
+
|
|
107
|
+
def test_from_ground_speed(
|
|
108
|
+
self,
|
|
109
|
+
start_lla: LLA,
|
|
110
|
+
end_lla: LLA,
|
|
111
|
+
start_instant: Instant,
|
|
112
|
+
earth: Earth,
|
|
113
|
+
):
|
|
114
|
+
ground_speed: Derived = Derived(100.0, Derived.Unit.meter_per_second())
|
|
115
|
+
step_size: Duration = Duration.seconds(1.0)
|
|
116
|
+
|
|
117
|
+
target_scan = TargetScan.from_ground_speed(
|
|
118
|
+
start_lla=start_lla,
|
|
119
|
+
end_lla=end_lla,
|
|
120
|
+
ground_speed=ground_speed,
|
|
121
|
+
start_instant=start_instant,
|
|
122
|
+
celestial=earth,
|
|
123
|
+
step_size=step_size,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
assert target_scan.is_defined()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
import pathlib
|
|
6
|
+
|
|
7
|
+
from ostk.core.filesystem import Path
|
|
8
|
+
from ostk.core.filesystem import File
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@pytest.fixture
|
|
12
|
+
def data_directory_path() -> str:
|
|
13
|
+
return f"{pathlib.Path(__file__).parent.absolute()}/data"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.fixture
|
|
17
|
+
def opm_file(data_directory_path: str) -> File:
|
|
18
|
+
return File.path(Path.parse(f"{data_directory_path}/opm_1.yaml"))
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Dummy SpaceX OPM output
|
|
2
|
+
|
|
3
|
+
# Notes:
|
|
4
|
+
# - ECEF velocity is Earth relative
|
|
5
|
+
# - Apogee/Perigee altitude assumes a spherical Earth, 6378.137 km radius
|
|
6
|
+
# - Orbital elements are computed in an inertial frame realized by inertially
|
|
7
|
+
# freezing the WGS84 ECEF frame at time of current state
|
|
8
|
+
# - State is post-deployment, so includes separation delta-velocity
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
header:
|
|
12
|
+
generation_date: 2020-01-01T12:34:56.789Z
|
|
13
|
+
launch_date: 2020-01-02T12:34:56.789Z
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
deployments:
|
|
17
|
+
|
|
18
|
+
- name: satellite_a
|
|
19
|
+
sequence_number: 1
|
|
20
|
+
mission_time_s: 3600.0
|
|
21
|
+
date: 2020-01-02T13:34:56.789Z
|
|
22
|
+
r_ecef_m: [693289.644, 6876578.628, -133035.288]
|
|
23
|
+
v_ecef_m_per_s: [1305.783, 39.783, 7525.920]
|
|
24
|
+
mean_perigee_altitude_km: 526.768
|
|
25
|
+
mean_apogee_altitude_km: 568.430
|
|
26
|
+
mean_inclination_deg: 97.123
|
|
27
|
+
mean_argument_of_perigee_deg: -179.513
|
|
28
|
+
mean_longitude_ascending_node_deg: 85.057
|
|
29
|
+
mean_mean_anomaly_deg: 179.263
|
|
30
|
+
ballistic_coef_kg_per_m2: 47.55
|
|
31
|
+
|
|
32
|
+
- name: satellite_b
|
|
33
|
+
sequence_number: 2
|
|
34
|
+
mission_time_s: 7200.0
|
|
35
|
+
date: 2020-01-02T14:34:56.789Z
|
|
36
|
+
r_ecef_m: [699863.059, 6875647.517, -123777.595]
|
|
37
|
+
v_ecef_m_per_s: [1504.658, 6.705, 7538.669]
|
|
38
|
+
mean_perigee_altitude_km: 536.779
|
|
39
|
+
mean_apogee_altitude_km: 529.851
|
|
40
|
+
mean_inclination_deg: 97.124
|
|
41
|
+
mean_argument_of_perigee_deg: 136.875
|
|
42
|
+
mean_longitude_ascending_node_deg: 85.032
|
|
43
|
+
mean_mean_anomaly_deg: -127.164
|
|
44
|
+
ballistic_coef_kg_per_m2: 44.26
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
from ostk.core.container import Dictionary
|
|
8
|
+
from ostk.core.filesystem import Path
|
|
9
|
+
from ostk.core.filesystem import File
|
|
10
|
+
|
|
11
|
+
from ostk.physics.unit import Length
|
|
12
|
+
from ostk.physics.unit import Angle
|
|
13
|
+
from ostk.physics.time import Instant
|
|
14
|
+
from ostk.physics.time import Scale
|
|
15
|
+
from ostk.physics.time import Duration
|
|
16
|
+
from ostk.physics.coordinate import Position
|
|
17
|
+
from ostk.physics.coordinate import Velocity
|
|
18
|
+
from ostk.physics.coordinate import Frame
|
|
19
|
+
|
|
20
|
+
from ostk.astrodynamics.trajectory.orbit.message.spacex import OPM
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.fixture
|
|
24
|
+
def opm() -> OPM:
|
|
25
|
+
return OPM(
|
|
26
|
+
header=OPM.Header(
|
|
27
|
+
generation_date=Instant.date_time(datetime(2020, 1, 2, 3, 4, 5), Scale.UTC),
|
|
28
|
+
launch_date=Instant.date_time(datetime(2020, 1, 3, 3, 4, 5), Scale.UTC),
|
|
29
|
+
),
|
|
30
|
+
deployments=[
|
|
31
|
+
OPM.Deployment(
|
|
32
|
+
name="A",
|
|
33
|
+
sequence_number=1,
|
|
34
|
+
mission_time=Duration.hours(3600.0),
|
|
35
|
+
date=Instant.date_time(datetime(2020, 1, 4, 3, 4, 5), Scale.UTC),
|
|
36
|
+
position=Position.meters((1.0, 2.0, 3.0), Frame.ITRF()),
|
|
37
|
+
velocity=Velocity.meters_per_second((4.0, 5.0, 6.0), Frame.ITRF()),
|
|
38
|
+
mean_perigee_altitude=Length.kilometers(500.0),
|
|
39
|
+
mean_apogee_altitude=Length.kilometers(500.0),
|
|
40
|
+
mean_inclination=Angle.degrees(1.0),
|
|
41
|
+
mean_argument_of_perigee=Angle.degrees(2.0),
|
|
42
|
+
mean_longitude_ascending_node=Angle.degrees(3.0),
|
|
43
|
+
mean_mean_anomaly=Angle.degrees(4.0),
|
|
44
|
+
ballistic_coefficient=123.456,
|
|
45
|
+
),
|
|
46
|
+
],
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class TestOPM:
|
|
51
|
+
def test_constructor(self, opm: OPM):
|
|
52
|
+
assert opm is not None
|
|
53
|
+
|
|
54
|
+
def test_get_header(self, opm: OPM):
|
|
55
|
+
assert opm.get_header() is not None
|
|
56
|
+
|
|
57
|
+
def test_get_deployments(self, opm: OPM):
|
|
58
|
+
assert len(opm.get_deployments()) == 1
|
|
59
|
+
|
|
60
|
+
def test_get_deployment_at(self, opm: OPM):
|
|
61
|
+
assert opm.get_deployment_at(index=0).name == "A"
|
|
62
|
+
|
|
63
|
+
def test_get_deployment_with_name(self, opm: OPM):
|
|
64
|
+
assert opm.get_deployment_with_name(name="A").name == "A"
|
|
65
|
+
|
|
66
|
+
def test_undefined(self):
|
|
67
|
+
assert OPM.undefined().is_defined() is False
|
|
68
|
+
|
|
69
|
+
def test_dictionary(self):
|
|
70
|
+
dictionary = Dictionary(
|
|
71
|
+
{
|
|
72
|
+
"header": {
|
|
73
|
+
"generation_date": "2020-01-01T12:34:56.789Z",
|
|
74
|
+
"launch_date": "2020-01-02T12:34:56.789Z",
|
|
75
|
+
},
|
|
76
|
+
"deployments": [
|
|
77
|
+
{
|
|
78
|
+
"name": "satellite_a",
|
|
79
|
+
"sequence_number": 1,
|
|
80
|
+
"mission_time_s": 3600.0,
|
|
81
|
+
"date": "2020-01-02T13:34:56.789Z",
|
|
82
|
+
"r_ecef_m": [693289.644, 6876578.628, -133035.288],
|
|
83
|
+
"v_ecef_m_per_s": [1305.783, 39.783, 7525.920],
|
|
84
|
+
"mean_perigee_altitude_km": 526.768,
|
|
85
|
+
"mean_apogee_altitude_km": 568.430,
|
|
86
|
+
"mean_inclination_deg": 97.123,
|
|
87
|
+
"mean_argument_of_perigee_deg": -179.513,
|
|
88
|
+
"mean_longitude_ascending_node_deg": 85.057,
|
|
89
|
+
"mean_mean_anomaly_deg": 179.263,
|
|
90
|
+
"ballistic_coef_kg_per_m2": 47.55,
|
|
91
|
+
}
|
|
92
|
+
],
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
assert OPM.dictionary(dictionary) is not None
|
|
97
|
+
|
|
98
|
+
def test_parse(self, opm_file: File):
|
|
99
|
+
with open(str(opm_file.get_path().to_string()), "r") as stream:
|
|
100
|
+
assert OPM.parse(string=stream.read()) is not None
|
|
101
|
+
|
|
102
|
+
def test_load(self, opm_file: File):
|
|
103
|
+
assert OPM.load(file=opm_file) is not None
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class TestOPMDeployment:
|
|
107
|
+
def test_to_state(self, opm: OPM):
|
|
108
|
+
assert opm.get_deployment_with_name(name="A").to_state() is not None
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Apache License 2.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Apache License 2.0
|