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,316 @@
1
+ # Apache License 2.0
2
+
3
+ from typing import Callable
4
+
5
+ import pytest
6
+
7
+ import numpy as np
8
+ import math
9
+
10
+ from ostk.physics.time import Instant, Duration
11
+ from ostk.physics.coordinate import Frame
12
+
13
+ from ostk.astrodynamics.trajectory import State
14
+ from ostk.astrodynamics.trajectory.state import (
15
+ NumericalSolver,
16
+ CoordinateBroker,
17
+ CoordinateSubset,
18
+ )
19
+ from ostk.astrodynamics.event_condition import RealCondition
20
+
21
+
22
+ def oscillator(x, dxdt, _):
23
+ dxdt[0] = x[1]
24
+ dxdt[1] = -x[0]
25
+ return dxdt
26
+
27
+
28
+ def get_state_vec(time: float) -> np.ndarray:
29
+ return np.array([math.sin(time), math.cos(time)])
30
+
31
+
32
+ @pytest.fixture
33
+ def coordinate_subsets() -> list[CoordinateSubset]:
34
+ return [CoordinateSubset("Subset", 2)]
35
+
36
+
37
+ @pytest.fixture
38
+ def coordinate_broker(
39
+ coordinate_subsets: list[CoordinateSubset],
40
+ ) -> CoordinateBroker:
41
+ return CoordinateBroker(coordinate_subsets)
42
+
43
+
44
+ @pytest.fixture
45
+ def start_instant() -> Instant:
46
+ return Instant.J2000()
47
+
48
+
49
+ @pytest.fixture
50
+ def frame() -> Frame:
51
+ return Frame.GCRF()
52
+
53
+
54
+ @pytest.fixture
55
+ def initial_state(
56
+ start_instant: Instant,
57
+ frame: Frame,
58
+ coordinate_broker: CoordinateBroker,
59
+ ) -> State:
60
+ return State(start_instant, get_state_vec(0.0), frame, coordinate_broker)
61
+
62
+
63
+ @pytest.fixture
64
+ def custom_condition() -> RealCondition:
65
+ return RealCondition(
66
+ "Custom",
67
+ RealCondition.Criterion.StrictlyPositive,
68
+ lambda state: (state.get_instant() - Instant.J2000()).in_seconds(),
69
+ 5.0,
70
+ )
71
+
72
+
73
+ @pytest.fixture
74
+ def log_type() -> NumericalSolver.LogType:
75
+ return NumericalSolver.LogType.NoLog
76
+
77
+
78
+ @pytest.fixture
79
+ def variable_size_stepper_type() -> NumericalSolver.StepperType:
80
+ return NumericalSolver.StepperType.RungeKuttaCashKarp54
81
+
82
+
83
+ @pytest.fixture
84
+ def fixed_size_stepper_type() -> NumericalSolver.StepperType:
85
+ return NumericalSolver.StepperType.RungeKutta4
86
+
87
+
88
+ @pytest.fixture
89
+ def initial_time_step() -> float:
90
+ return 5.0
91
+
92
+
93
+ @pytest.fixture
94
+ def relative_tolerance() -> float:
95
+ return 1.0e-15
96
+
97
+
98
+ @pytest.fixture
99
+ def absolute_tolerance() -> float:
100
+ return 1.0e-15
101
+
102
+
103
+ @pytest.fixture
104
+ def state_logger() -> Callable:
105
+ def log_state(state: State) -> None:
106
+ print(state.get_coordinates())
107
+
108
+ return log_state
109
+
110
+
111
+ @pytest.fixture
112
+ def numerical_solver(
113
+ log_type: NumericalSolver.LogType,
114
+ variable_size_stepper_type: NumericalSolver.StepperType,
115
+ initial_time_step: float,
116
+ relative_tolerance: float,
117
+ absolute_tolerance: float,
118
+ ) -> NumericalSolver:
119
+ return NumericalSolver(
120
+ log_type=log_type,
121
+ stepper_type=variable_size_stepper_type,
122
+ time_step=initial_time_step,
123
+ relative_tolerance=relative_tolerance,
124
+ absolute_tolerance=absolute_tolerance,
125
+ )
126
+
127
+
128
+ @pytest.fixture
129
+ def numerical_solver_conditional() -> NumericalSolver:
130
+ return NumericalSolver.default_conditional()
131
+
132
+
133
+ class TestNumericalSolver:
134
+ def test_constructors(self, numerical_solver: NumericalSolver):
135
+ assert numerical_solver is not None
136
+ assert isinstance(numerical_solver, NumericalSolver)
137
+ assert numerical_solver.is_defined()
138
+
139
+ def test_comparators(self, numerical_solver: NumericalSolver):
140
+ assert numerical_solver == numerical_solver
141
+ assert (numerical_solver != numerical_solver) is False
142
+
143
+ def test_get_types(
144
+ self,
145
+ log_type: NumericalSolver.LogType,
146
+ variable_size_stepper_type: NumericalSolver.StepperType,
147
+ initial_time_step: float,
148
+ relative_tolerance: float,
149
+ absolute_tolerance: float,
150
+ numerical_solver: NumericalSolver,
151
+ ):
152
+ assert numerical_solver.get_log_type() == log_type
153
+ assert numerical_solver.get_stepper_type() == variable_size_stepper_type
154
+ assert numerical_solver.get_time_step() == initial_time_step
155
+ assert numerical_solver.get_relative_tolerance() == relative_tolerance
156
+ assert numerical_solver.get_absolute_tolerance() == absolute_tolerance
157
+ assert numerical_solver.get_root_solver() is not None
158
+ assert numerical_solver.get_observed_states() is not None
159
+
160
+ def test_get_string_from_types(self):
161
+ assert (
162
+ NumericalSolver.string_from_stepper_type(
163
+ NumericalSolver.StepperType.RungeKutta4
164
+ )
165
+ == "RungeKutta4"
166
+ )
167
+ assert (
168
+ NumericalSolver.string_from_stepper_type(
169
+ NumericalSolver.StepperType.RungeKuttaCashKarp54
170
+ )
171
+ == "RungeKuttaCashKarp54"
172
+ )
173
+ assert (
174
+ NumericalSolver.string_from_stepper_type(
175
+ NumericalSolver.StepperType.RungeKuttaFehlberg78
176
+ )
177
+ == "RungeKuttaFehlberg78"
178
+ )
179
+ assert (
180
+ NumericalSolver.string_from_log_type(NumericalSolver.LogType.NoLog) == "NoLog"
181
+ )
182
+ assert (
183
+ NumericalSolver.string_from_log_type(NumericalSolver.LogType.LogConstant)
184
+ == "LogConstant"
185
+ )
186
+ assert (
187
+ NumericalSolver.string_from_log_type(NumericalSolver.LogType.LogAdaptive)
188
+ == "LogAdaptive"
189
+ )
190
+
191
+ def test_integrate_time(
192
+ self,
193
+ initial_state: State,
194
+ numerical_solver: NumericalSolver,
195
+ ):
196
+ duration_seconds: float = 10.0
197
+ end_instant: Instant = initial_state.get_instant() + Duration.seconds(
198
+ duration_seconds
199
+ )
200
+
201
+ state_vector: np.ndarray = numerical_solver.integrate_time(
202
+ initial_state, end_instant, oscillator
203
+ ).get_coordinates()
204
+
205
+ assert 5e-9 >= abs(state_vector[0] - math.sin(duration_seconds))
206
+ assert 5e-9 >= abs(state_vector[1] - math.cos(duration_seconds))
207
+
208
+ end_instants: list[Instant] = [
209
+ initial_state.get_instant() + Duration.seconds(duration)
210
+ for duration in np.arange(60.0, 100.0, 20.0)
211
+ ]
212
+ states: list[State] = numerical_solver.integrate_time(
213
+ initial_state, end_instants, oscillator
214
+ )
215
+
216
+ for state, end_instant in zip(states, end_instants):
217
+ state_vector: np.ndarray = state.get_coordinates()
218
+
219
+ assert 5e-9 >= abs(
220
+ state_vector[0]
221
+ - math.sin((end_instant - initial_state.get_instant()).in_seconds())
222
+ )
223
+ assert 5e-9 >= abs(
224
+ state_vector[1]
225
+ - math.cos((end_instant - initial_state.get_instant()).in_seconds())
226
+ )
227
+
228
+ def test_integrate_time_with_condition(
229
+ self,
230
+ initial_state: State,
231
+ numerical_solver_conditional: NumericalSolver,
232
+ custom_condition: RealCondition,
233
+ ):
234
+ end_time: float = initial_state.get_instant() + Duration.seconds(100.0)
235
+
236
+ condition_solution = numerical_solver_conditional.integrate_time(
237
+ initial_state, end_time, oscillator, custom_condition
238
+ )
239
+
240
+ assert condition_solution.condition_is_satisfied
241
+ assert (
242
+ condition_solution.iteration_count
243
+ < numerical_solver_conditional.get_root_solver().get_maximum_iteration_count()
244
+ )
245
+ assert condition_solution.root_solver_has_converged
246
+
247
+ state_vector = condition_solution.state.get_coordinates()
248
+ time = (
249
+ condition_solution.state.get_instant() - initial_state.get_instant()
250
+ ).in_seconds()
251
+
252
+ assert abs(float(time - custom_condition.get_target().value)) < 1e-6
253
+
254
+ assert 5e-9 >= abs(state_vector[0] - math.sin(time))
255
+ assert 5e-9 >= abs(state_vector[1] - math.cos(time))
256
+
257
+ def test_integrate_conditional_with_logger(
258
+ self,
259
+ initial_state: State,
260
+ state_logger: Callable,
261
+ custom_condition: RealCondition,
262
+ capsys,
263
+ ):
264
+ numerical_solver: NumericalSolver = NumericalSolver.conditional(
265
+ 5.0,
266
+ 1.0e-15,
267
+ 1.0e-15,
268
+ state_logger,
269
+ )
270
+ end_time: float = initial_state.get_instant() + Duration.seconds(10.0)
271
+
272
+ numerical_solver.integrate_time(
273
+ initial_state, end_time, oscillator, custom_condition
274
+ )
275
+
276
+ captured = capsys.readouterr()
277
+
278
+ assert captured.out != ""
279
+
280
+ def test_default(self):
281
+ assert NumericalSolver.default() is not None
282
+
283
+ def test_undefined(self):
284
+ assert NumericalSolver.undefined() is not None
285
+ assert NumericalSolver.undefined().is_defined() is False
286
+
287
+ def test_fixed_step_size(
288
+ self,
289
+ fixed_size_stepper_type: NumericalSolver.StepperType,
290
+ variable_size_stepper_type: NumericalSolver.StepperType,
291
+ initial_time_step: float,
292
+ ):
293
+ assert (
294
+ NumericalSolver.fixed_step_size(fixed_size_stepper_type, initial_time_step)
295
+ is not None
296
+ )
297
+ with pytest.raises(Exception):
298
+ NumericalSolver.fixed_step_size(variable_size_stepper_type, initial_time_step)
299
+
300
+ def test_default_conditional(self, state_logger):
301
+ assert NumericalSolver.default_conditional() is not None
302
+ assert NumericalSolver.default_conditional(state_logger) is not None
303
+
304
+ def test_conditional(
305
+ self,
306
+ initial_time_step: float,
307
+ relative_tolerance: float,
308
+ absolute_tolerance: float,
309
+ state_logger,
310
+ ):
311
+ assert (
312
+ NumericalSolver.conditional(
313
+ initial_time_step, relative_tolerance, absolute_tolerance, state_logger
314
+ )
315
+ is not None
316
+ )
@@ -0,0 +1,81 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics.coordinate import Frame
6
+
7
+ from ostk.astrodynamics.trajectory import LocalOrbitalFrameFactory
8
+ from ostk.astrodynamics.trajectory import LocalOrbitalFrameDirection
9
+
10
+
11
+ @pytest.fixture
12
+ def local_orbital_frame_factory() -> LocalOrbitalFrameFactory:
13
+ return LocalOrbitalFrameFactory.VNC(Frame.GCRF())
14
+
15
+
16
+ @pytest.fixture
17
+ def direction_vector() -> list:
18
+ return [1.0, 0.0, 0.0]
19
+
20
+
21
+ @pytest.fixture
22
+ def local_orbital_frame_direction(
23
+ direction_vector: list,
24
+ local_orbital_frame_factory: LocalOrbitalFrameFactory,
25
+ ) -> LocalOrbitalFrameDirection:
26
+ return LocalOrbitalFrameDirection(
27
+ vector=direction_vector,
28
+ local_orbital_frame_factory=local_orbital_frame_factory,
29
+ )
30
+
31
+
32
+ class TestLocalOrbitalFrameDirection:
33
+ def test_constructor(
34
+ self,
35
+ direction_vector: list,
36
+ local_orbital_frame_factory: LocalOrbitalFrameFactory,
37
+ ):
38
+ local_orbital_frame_direction: LocalOrbitalFrameDirection = (
39
+ LocalOrbitalFrameDirection(
40
+ direction_vector,
41
+ local_orbital_frame_factory,
42
+ )
43
+ )
44
+
45
+ assert local_orbital_frame_direction is not None
46
+ assert isinstance(local_orbital_frame_direction, LocalOrbitalFrameDirection)
47
+
48
+ def test_equal_to_operator(
49
+ self, local_orbital_frame_direction: LocalOrbitalFrameDirection
50
+ ):
51
+ assert local_orbital_frame_direction == local_orbital_frame_direction
52
+ assert local_orbital_frame_direction != LocalOrbitalFrameDirection(
53
+ [0.0, 1.0, 0.0],
54
+ local_orbital_frame_direction.get_local_orbital_frame_factory(),
55
+ )
56
+
57
+ def test_is_defined(
58
+ self,
59
+ local_orbital_frame_direction: LocalOrbitalFrameDirection,
60
+ ):
61
+ assert local_orbital_frame_direction.is_defined()
62
+
63
+ def test_getters(
64
+ self,
65
+ local_orbital_frame_direction: LocalOrbitalFrameDirection,
66
+ direction_vector: list,
67
+ local_orbital_frame_factory: LocalOrbitalFrameFactory,
68
+ ):
69
+ assert list(local_orbital_frame_direction.get_value()) == direction_vector
70
+ assert (
71
+ local_orbital_frame_direction.get_local_orbital_frame_factory()
72
+ == local_orbital_frame_factory
73
+ )
74
+
75
+ def test_undefined(
76
+ self,
77
+ ):
78
+ local_orbital_frame_direction: LocalOrbitalFrameDirection = (
79
+ LocalOrbitalFrameDirection.undefined()
80
+ )
81
+ assert local_orbital_frame_direction.is_defined() is False
@@ -0,0 +1,119 @@
1
+ # Apache License 2.0
2
+
3
+ from typing import Callable
4
+
5
+ import pytest
6
+
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.coordinate import Frame
11
+ from ostk.physics.coordinate import Transform
12
+ from ostk.physics.coordinate import Position
13
+ from ostk.physics.coordinate import Velocity
14
+
15
+ from ostk.astrodynamics.trajectory import State
16
+ from ostk.astrodynamics.trajectory import LocalOrbitalFrameFactory
17
+ from ostk.astrodynamics.trajectory import LocalOrbitalFrameTransformProvider
18
+
19
+
20
+ @pytest.fixture
21
+ def parent_frame() -> Frame:
22
+ return Frame.GCRF()
23
+
24
+
25
+ @pytest.fixture
26
+ def local_orbital_transform_provider_type() -> LocalOrbitalFrameTransformProvider.Type:
27
+ return LocalOrbitalFrameTransformProvider.Type.VNC
28
+
29
+
30
+ @pytest.fixture
31
+ def transform_generator() -> Callable:
32
+ return lambda state: Transform.identity(Transform.Type.passive)
33
+
34
+
35
+ @pytest.fixture
36
+ def local_orbital_frame_factory(parent_frame: Frame) -> LocalOrbitalFrameFactory:
37
+ return LocalOrbitalFrameFactory.VNC(parent_frame)
38
+
39
+
40
+ @pytest.fixture
41
+ def instant() -> Instant:
42
+ return Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
43
+
44
+
45
+ @pytest.fixture
46
+ def position() -> Position:
47
+ return Position.meters([7500000.0, 0.0, 0.0], Frame.GCRF())
48
+
49
+
50
+ @pytest.fixture
51
+ def velocity() -> Velocity:
52
+ return Velocity.meters_per_second(
53
+ [0.0, 5335.865450622126, 5335.865450622126], Frame.GCRF()
54
+ )
55
+
56
+
57
+ @pytest.fixture
58
+ def state(
59
+ instant: Instant,
60
+ position: Position,
61
+ velocity: Velocity,
62
+ ) -> State:
63
+ return State(instant, position, velocity)
64
+
65
+
66
+ class TestLocalOrbitalFrameFactory:
67
+ def test_constructors(self):
68
+ assert LocalOrbitalFrameFactory.VNC(Frame.GCRF()) is not None
69
+ assert LocalOrbitalFrameFactory.NED(Frame.GCRF()) is not None
70
+ assert LocalOrbitalFrameFactory.LVLH(Frame.GCRF()) is not None
71
+ assert LocalOrbitalFrameFactory.QSW(Frame.GCRF()) is not None
72
+ assert LocalOrbitalFrameFactory.TNW(Frame.GCRF()) is not None
73
+ assert LocalOrbitalFrameFactory.VVLH(Frame.GCRF()) is not None
74
+
75
+ def test_accessors(
76
+ self,
77
+ parent_frame: Frame,
78
+ local_orbital_frame_factory: LocalOrbitalFrameFactory,
79
+ ):
80
+ assert parent_frame == local_orbital_frame_factory.access_parent_frame()
81
+ assert local_orbital_frame_factory.get_provider_type() is not None
82
+
83
+ def test_generate_frame(
84
+ self,
85
+ local_orbital_frame_factory: LocalOrbitalFrameFactory,
86
+ state: State,
87
+ ):
88
+ frame = local_orbital_frame_factory.generate_frame(state=state)
89
+
90
+ assert frame is not None
91
+ assert frame.is_defined()
92
+
93
+ def test_is_defined(
94
+ self,
95
+ local_orbital_frame_factory: LocalOrbitalFrameFactory,
96
+ ):
97
+ assert local_orbital_frame_factory.is_defined()
98
+
99
+ def test_constructor(
100
+ self,
101
+ local_orbital_transform_provider_type: LocalOrbitalFrameTransformProvider.Type,
102
+ parent_frame: Frame,
103
+ ):
104
+ assert (
105
+ LocalOrbitalFrameFactory.construct(
106
+ local_orbital_transform_provider_type, parent_frame
107
+ )
108
+ is not None
109
+ )
110
+
111
+ def test_custom_constructor(
112
+ self,
113
+ transform_generator: Callable,
114
+ parent_frame: Frame,
115
+ ):
116
+ assert (
117
+ LocalOrbitalFrameFactory.construct(transform_generator, parent_frame)
118
+ is not None
119
+ )
@@ -0,0 +1 @@
1
+ # Apache License 2.0