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.
Files changed (151) hide show
  1. open_space_toolkit_astrodynamics-17.2.0.dist-info/METADATA +30 -0
  2. open_space_toolkit_astrodynamics-17.2.0.dist-info/RECORD +151 -0
  3. open_space_toolkit_astrodynamics-17.2.0.dist-info/WHEEL +5 -0
  4. open_space_toolkit_astrodynamics-17.2.0.dist-info/top_level.txt +1 -0
  5. open_space_toolkit_astrodynamics-17.2.0.dist-info/zip-safe +1 -0
  6. ostk/__init__.py +1 -0
  7. ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-312-x86_64-linux-gnu.so +0 -0
  8. ostk/astrodynamics/__init__.py +11 -0
  9. ostk/astrodynamics/__init__.pyi +720 -0
  10. ostk/astrodynamics/access.pyi +577 -0
  11. ostk/astrodynamics/conjunction/__init__.pyi +121 -0
  12. ostk/astrodynamics/conjunction/close_approach.pyi +89 -0
  13. ostk/astrodynamics/conjunction/message/__init__.pyi +3 -0
  14. ostk/astrodynamics/conjunction/message/ccsds.pyi +705 -0
  15. ostk/astrodynamics/converters.py +130 -0
  16. ostk/astrodynamics/converters.pyi +58 -0
  17. ostk/astrodynamics/data/__init__.pyi +3 -0
  18. ostk/astrodynamics/data/provider.pyi +22 -0
  19. ostk/astrodynamics/dataframe.py +597 -0
  20. ostk/astrodynamics/display.py +281 -0
  21. ostk/astrodynamics/dynamics.pyi +311 -0
  22. ostk/astrodynamics/eclipse.pyi +70 -0
  23. ostk/astrodynamics/estimator.pyi +268 -0
  24. ostk/astrodynamics/event_condition.pyi +910 -0
  25. ostk/astrodynamics/flight/__init__.pyi +626 -0
  26. ostk/astrodynamics/flight/profile/__init__.pyi +99 -0
  27. ostk/astrodynamics/flight/profile/model.pyi +179 -0
  28. ostk/astrodynamics/flight/system.pyi +268 -0
  29. ostk/astrodynamics/guidance_law.pyi +416 -0
  30. ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.17 +0 -0
  31. ostk/astrodynamics/pytrajectory/__init__.py +1 -0
  32. ostk/astrodynamics/pytrajectory/__init__.pyi +3 -0
  33. ostk/astrodynamics/pytrajectory/pystate.py +263 -0
  34. ostk/astrodynamics/pytrajectory/pystate.pyi +66 -0
  35. ostk/astrodynamics/solver.pyi +432 -0
  36. ostk/astrodynamics/test/__init__.py +1 -0
  37. ostk/astrodynamics/test/access/__init__.py +1 -0
  38. ostk/astrodynamics/test/access/test_generator.py +319 -0
  39. ostk/astrodynamics/test/access/test_visibility_criterion.py +201 -0
  40. ostk/astrodynamics/test/conftest.py +119 -0
  41. ostk/astrodynamics/test/conjunction/close_approach/__init__.py +0 -0
  42. ostk/astrodynamics/test/conjunction/close_approach/test_generator.py +228 -0
  43. ostk/astrodynamics/test/conjunction/message/ccsds/__init__.py +1 -0
  44. ostk/astrodynamics/test/conjunction/message/ccsds/conftest.py +325 -0
  45. ostk/astrodynamics/test/conjunction/message/ccsds/data/cdm.json +303 -0
  46. ostk/astrodynamics/test/conjunction/message/ccsds/test_cdm.py +416 -0
  47. ostk/astrodynamics/test/conjunction/test_close_approach.py +244 -0
  48. ostk/astrodynamics/test/data/provider/test_off_nadir.py +58 -0
  49. ostk/astrodynamics/test/dynamics/__init__.py +1 -0
  50. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity.csv +565 -0
  51. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity_Truth.csv +100 -0
  52. ostk/astrodynamics/test/dynamics/test_atmospheric_drag.py +128 -0
  53. ostk/astrodynamics/test/dynamics/test_central_body_gravity.py +58 -0
  54. ostk/astrodynamics/test/dynamics/test_dynamics.py +50 -0
  55. ostk/astrodynamics/test/dynamics/test_position_derivative.py +51 -0
  56. ostk/astrodynamics/test/dynamics/test_tabulated.py +138 -0
  57. ostk/astrodynamics/test/dynamics/test_third_body_gravity.py +67 -0
  58. ostk/astrodynamics/test/dynamics/test_thruster.py +157 -0
  59. ostk/astrodynamics/test/eclipse/__init__.py +1 -0
  60. ostk/astrodynamics/test/eclipse/test_generator.py +138 -0
  61. ostk/astrodynamics/test/estimator/test_orbit_determination_solver.py +261 -0
  62. ostk/astrodynamics/test/estimator/test_tle_solver.py +216 -0
  63. ostk/astrodynamics/test/event_condition/test_angular_condition.py +113 -0
  64. ostk/astrodynamics/test/event_condition/test_boolean_condition.py +55 -0
  65. ostk/astrodynamics/test/event_condition/test_brouwer_lyddane_mean_long_condition.py +135 -0
  66. ostk/astrodynamics/test/event_condition/test_coe_condition.py +135 -0
  67. ostk/astrodynamics/test/event_condition/test_instant_condition.py +48 -0
  68. ostk/astrodynamics/test/event_condition/test_logical_condition.py +120 -0
  69. ostk/astrodynamics/test/event_condition/test_real_condition.py +50 -0
  70. ostk/astrodynamics/test/flight/__init__.py +1 -0
  71. ostk/astrodynamics/test/flight/profile/model/test_tabulated_profile.py +115 -0
  72. ostk/astrodynamics/test/flight/system/__init__.py +1 -0
  73. ostk/astrodynamics/test/flight/system/test_propulsion_system.py +64 -0
  74. ostk/astrodynamics/test/flight/system/test_satellite_system.py +83 -0
  75. ostk/astrodynamics/test/flight/system/test_satellite_system_builder.py +71 -0
  76. ostk/astrodynamics/test/flight/test_maneuver.py +231 -0
  77. ostk/astrodynamics/test/flight/test_profile.py +293 -0
  78. ostk/astrodynamics/test/flight/test_system.py +45 -0
  79. ostk/astrodynamics/test/guidance_law/test_constant_thrust.py +177 -0
  80. ostk/astrodynamics/test/guidance_law/test_guidance_law.py +60 -0
  81. ostk/astrodynamics/test/guidance_law/test_heterogeneous_guidance_law.py +164 -0
  82. ostk/astrodynamics/test/guidance_law/test_qlaw.py +209 -0
  83. ostk/astrodynamics/test/solvers/__init__.py +1 -0
  84. ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +196 -0
  85. ostk/astrodynamics/test/solvers/test_least_squares_solver.py +334 -0
  86. ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +161 -0
  87. ostk/astrodynamics/test/test_access.py +128 -0
  88. ostk/astrodynamics/test/test_converters.py +290 -0
  89. ostk/astrodynamics/test/test_dataframe.py +1355 -0
  90. ostk/astrodynamics/test/test_display.py +184 -0
  91. ostk/astrodynamics/test/test_event_condition.py +80 -0
  92. ostk/astrodynamics/test/test_import.py +26 -0
  93. ostk/astrodynamics/test/test_root_solver.py +70 -0
  94. ostk/astrodynamics/test/test_trajectory.py +126 -0
  95. ostk/astrodynamics/test/test_utilities.py +338 -0
  96. ostk/astrodynamics/test/test_viewer.py +318 -0
  97. ostk/astrodynamics/test/trajectory/__init__.py +1 -0
  98. ostk/astrodynamics/test/trajectory/model/test_nadir_trajectory.py +87 -0
  99. ostk/astrodynamics/test/trajectory/model/test_tabulated_trajectory.py +303 -0
  100. ostk/astrodynamics/test/trajectory/model/test_target_scan_trajectory.py +126 -0
  101. ostk/astrodynamics/test/trajectory/orbit/__init__.py +1 -0
  102. ostk/astrodynamics/test/trajectory/orbit/message/__init__.py +1 -0
  103. ostk/astrodynamics/test/trajectory/orbit/message/spacex/__init__.py +1 -0
  104. ostk/astrodynamics/test/trajectory/orbit/message/spacex/conftest.py +18 -0
  105. ostk/astrodynamics/test/trajectory/orbit/message/spacex/data/opm_1.yaml +44 -0
  106. ostk/astrodynamics/test/trajectory/orbit/message/spacex/test_opm.py +108 -0
  107. ostk/astrodynamics/test/trajectory/orbit/models/__init__.py +1 -0
  108. ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py +1 -0
  109. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py +65 -0
  110. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py +102 -0
  111. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py +102 -0
  112. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py +305 -0
  113. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +1 -0
  114. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +337 -0
  115. ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +130 -0
  116. ostk/astrodynamics/test/trajectory/orbit/models/test_modified_equinoctial.py +142 -0
  117. ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +234 -0
  118. ostk/astrodynamics/test/trajectory/orbit/models/test_sgp4.py +1 -0
  119. ostk/astrodynamics/test/trajectory/orbit/models/test_tabulated.py +380 -0
  120. ostk/astrodynamics/test/trajectory/orbit/test_model.py +1 -0
  121. ostk/astrodynamics/test/trajectory/orbit/test_pass.py +75 -0
  122. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity.py +30 -0
  123. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py +18 -0
  124. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_acceleration.py +136 -0
  125. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py +107 -0
  126. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py +115 -0
  127. ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py +84 -0
  128. ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py +58 -0
  129. ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +316 -0
  130. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py +81 -0
  131. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +119 -0
  132. ostk/astrodynamics/test/trajectory/test_model.py +1 -0
  133. ostk/astrodynamics/test/trajectory/test_orbit.py +212 -0
  134. ostk/astrodynamics/test/trajectory/test_propagator.py +452 -0
  135. ostk/astrodynamics/test/trajectory/test_segment.py +694 -0
  136. ostk/astrodynamics/test/trajectory/test_sequence.py +550 -0
  137. ostk/astrodynamics/test/trajectory/test_state.py +629 -0
  138. ostk/astrodynamics/test/trajectory/test_state_builder.py +172 -0
  139. ostk/astrodynamics/trajectory/__init__.pyi +1982 -0
  140. ostk/astrodynamics/trajectory/model.pyi +259 -0
  141. ostk/astrodynamics/trajectory/orbit/__init__.pyi +349 -0
  142. ostk/astrodynamics/trajectory/orbit/message/__init__.pyi +3 -0
  143. ostk/astrodynamics/trajectory/orbit/message/spacex.pyi +264 -0
  144. ostk/astrodynamics/trajectory/orbit/model/__init__.pyi +648 -0
  145. ostk/astrodynamics/trajectory/orbit/model/brouwerLyddaneMean.pyi +121 -0
  146. ostk/astrodynamics/trajectory/orbit/model/kepler.pyi +709 -0
  147. ostk/astrodynamics/trajectory/orbit/model/sgp4.pyi +330 -0
  148. ostk/astrodynamics/trajectory/state/__init__.pyi +402 -0
  149. ostk/astrodynamics/trajectory/state/coordinate_subset.pyi +208 -0
  150. ostk/astrodynamics/utilities.py +396 -0
  151. 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