open-space-toolkit-astrodynamics 1.2.0__py310-none-any.whl → 4.2.0__py310-none-any.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 (65) hide show
  1. {open_space_toolkit_astrodynamics-1.2.0.dist-info → open_space_toolkit_astrodynamics-4.2.0.dist-info}/METADATA +2 -2
  2. open_space_toolkit_astrodynamics-4.2.0.dist-info/RECORD +25 -0
  3. ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-310-x86_64-linux-gnu.so +0 -0
  4. ostk/astrodynamics/__init__.py +6 -0
  5. ostk/astrodynamics/{libopen-space-toolkit-astrodynamics.so.1 → libopen-space-toolkit-astrodynamics.so.4} +0 -0
  6. ostk/astrodynamics/pytrajectory/pystate.py +36 -0
  7. ostk/astrodynamics/test/test_access.py +2 -6
  8. ostk/astrodynamics/test/test_converters.py +1 -3
  9. ostk/astrodynamics/test/test_event_condition.py +24 -41
  10. ostk/astrodynamics/test/test_import.py +3 -3
  11. ostk/astrodynamics/test/test_viewer.py +1 -2
  12. ostk/astrodynamics/viewer.py +1 -1
  13. open_space_toolkit_astrodynamics-1.2.0.dist-info/RECORD +0 -72
  14. ostk/astrodynamics/test/access/__init__.py +0 -1
  15. ostk/astrodynamics/test/access/test_generator.py +0 -248
  16. ostk/astrodynamics/test/conjunction/messages/ccsds/__init__.py +0 -1
  17. ostk/astrodynamics/test/conjunction/messages/ccsds/conftest.py +0 -325
  18. ostk/astrodynamics/test/conjunction/messages/ccsds/data/cdm.json +0 -303
  19. ostk/astrodynamics/test/conjunction/messages/ccsds/test_cdm.py +0 -418
  20. ostk/astrodynamics/test/event_condition/test_coe_condition.py +0 -95
  21. ostk/astrodynamics/test/event_condition/test_conjunctive.py +0 -64
  22. ostk/astrodynamics/test/event_condition/test_disjunctive.py +0 -63
  23. ostk/astrodynamics/test/event_condition/test_duration_condition.py +0 -36
  24. ostk/astrodynamics/test/event_condition/test_logical_connective.py +0 -37
  25. ostk/astrodynamics/test/flight/__init__.py +0 -1
  26. ostk/astrodynamics/test/flight/profile/__init__.py +0 -1
  27. ostk/astrodynamics/test/flight/profile/test_state.py +0 -144
  28. ostk/astrodynamics/test/flight/system/__init__.py +0 -1
  29. ostk/astrodynamics/test/flight/system/dynamics/__init__.py +0 -1
  30. ostk/astrodynamics/test/flight/system/dynamics/test_atmospheric_drag.py +0 -86
  31. ostk/astrodynamics/test/flight/system/dynamics/test_central_body_gravity.py +0 -57
  32. ostk/astrodynamics/test/flight/system/dynamics/test_position_derivative.py +0 -49
  33. ostk/astrodynamics/test/flight/system/dynamics/test_third_body_gravity.py +0 -65
  34. ostk/astrodynamics/test/flight/system/test_satellite_system.py +0 -77
  35. ostk/astrodynamics/test/flight/test_profile.py +0 -147
  36. ostk/astrodynamics/test/flight/test_system.py +0 -55
  37. ostk/astrodynamics/test/solvers/__init__.py +0 -1
  38. ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +0 -153
  39. ostk/astrodynamics/test/test_numerical_solver.py +0 -248
  40. ostk/astrodynamics/test/trajectory/__init__.py +0 -1
  41. ostk/astrodynamics/test/trajectory/orbit/__init__.py +0 -1
  42. ostk/astrodynamics/test/trajectory/orbit/messages/__init__.py +0 -1
  43. ostk/astrodynamics/test/trajectory/orbit/messages/spacex/__init__.py +0 -1
  44. ostk/astrodynamics/test/trajectory/orbit/messages/spacex/conftest.py +0 -18
  45. ostk/astrodynamics/test/trajectory/orbit/messages/spacex/data/opm_1.yaml +0 -44
  46. ostk/astrodynamics/test/trajectory/orbit/messages/spacex/test_opm.py +0 -108
  47. ostk/astrodynamics/test/trajectory/orbit/models/__init__.py +0 -1
  48. ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py +0 -1
  49. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py +0 -108
  50. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +0 -1
  51. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +0 -332
  52. ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +0 -130
  53. ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +0 -197
  54. ostk/astrodynamics/test/trajectory/orbit/models/test_sgp4.py +0 -1
  55. ostk/astrodynamics/test/trajectory/orbit/models/test_tabulated.py +0 -383
  56. ostk/astrodynamics/test/trajectory/orbit/test_model.py +0 -1
  57. ostk/astrodynamics/test/trajectory/orbit/test_pass.py +0 -55
  58. ostk/astrodynamics/test/trajectory/test_model.py +0 -1
  59. ostk/astrodynamics/test/trajectory/test_orbit.py +0 -92
  60. ostk/astrodynamics/test/trajectory/test_propagator.py +0 -233
  61. ostk/astrodynamics/test/trajectory/test_state.py +0 -70
  62. {open_space_toolkit_astrodynamics-1.2.0.dist-info → open_space_toolkit_astrodynamics-4.2.0.dist-info}/WHEEL +0 -0
  63. {open_space_toolkit_astrodynamics-1.2.0.dist-info → open_space_toolkit_astrodynamics-4.2.0.dist-info}/top_level.txt +0 -0
  64. {open_space_toolkit_astrodynamics-1.2.0.dist-info → open_space_toolkit_astrodynamics-4.2.0.dist-info}/zip-safe +0 -0
  65. /ostk/{__init__.py → astrodynamics/pytrajectory/__init__.py} +0 -0
@@ -1,55 +0,0 @@
1
- # Apache License 2.0
2
-
3
- import pytest
4
-
5
- import numpy as np
6
-
7
- import ostk.mathematics as mathematics
8
-
9
- import ostk.physics as physics
10
-
11
- import ostk.astrodynamics as astrodynamics
12
-
13
- Cuboid = mathematics.geometry.d3.objects.Cuboid
14
- Composite = mathematics.geometry.d3.objects.Composite
15
- Point = mathematics.geometry.d3.objects.Point
16
-
17
- Mass = physics.units.Mass
18
-
19
- System = astrodynamics.flight.System
20
-
21
-
22
- @pytest.fixture
23
- def system_default_inputs():
24
- mass = Mass(90.0, Mass.Unit.Kilogram)
25
- geometry = Composite(
26
- Cuboid(
27
- Point(0.0, 0.0, 0.0),
28
- [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
29
- [1.0, 0.0, 0.0],
30
- )
31
- )
32
-
33
- return (mass, geometry)
34
-
35
-
36
- @pytest.fixture
37
- def system(system_default_inputs) -> System:
38
- return System(*system_default_inputs)
39
-
40
-
41
- class TestSatelliteSystem:
42
- def test_constructors(self, system: System):
43
- assert system is not None
44
- assert isinstance(system, System)
45
- assert system.is_defined()
46
-
47
- def test_comparators(self, system: System):
48
- assert (system == system) is True
49
- assert (system != system) is False
50
-
51
- def test_getters(self, system_default_inputs, system: System):
52
- (mass, geometry) = system_default_inputs
53
-
54
- assert system.get_mass() == mass
55
- assert system.get_geometry() == geometry
@@ -1 +0,0 @@
1
- # Apache License 2.0
@@ -1,153 +0,0 @@
1
- # Apache License 2.0
2
-
3
- import pytest
4
-
5
- from ostk.physics.units import Length
6
- from ostk.physics.units import Angle
7
- from ostk.physics.time import Instant
8
- from ostk.physics.time import Duration
9
- from ostk.physics.time import Interval
10
- from ostk.physics.time import DateTime
11
- from ostk.physics.time import Scale
12
- from ostk.physics import Environment
13
-
14
- from ostk.astrodynamics.trajectory import Orbit
15
- from ostk.astrodynamics.trajectory.orbit.models import Kepler
16
- from ostk.astrodynamics.trajectory.orbit.models.kepler import COE
17
- from ostk.astrodynamics.access import Generator
18
- from ostk.astrodynamics.solvers import TemporalConditionSolver
19
-
20
-
21
- @pytest.fixture
22
- def temporal_condition_solver() -> TemporalConditionSolver:
23
- return TemporalConditionSolver(
24
- time_step=Duration.seconds(30.0),
25
- tolerance=Duration.milliseconds(1.0),
26
- maximum_iteration_count=1234,
27
- )
28
-
29
-
30
- @pytest.fixture
31
- def interval() -> Interval:
32
- return Interval.closed(
33
- Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC),
34
- Instant.date_time(DateTime(2018, 1, 1, 2, 0, 0), Scale.UTC),
35
- )
36
-
37
-
38
- class TestTemporalConditionSolver:
39
- def test_constructor_success(self):
40
- temporal_condition_solver = TemporalConditionSolver(
41
- time_step=Duration.seconds(30.0),
42
- tolerance=Duration.milliseconds(1.0),
43
- maximum_iteration_count=1234,
44
- )
45
-
46
- assert isinstance(temporal_condition_solver, TemporalConditionSolver)
47
-
48
- def test_getters_success(
49
- self,
50
- temporal_condition_solver: TemporalConditionSolver,
51
- ):
52
- assert temporal_condition_solver.get_time_step() == Duration.seconds(30.0)
53
- assert temporal_condition_solver.get_tolerance() == Duration.milliseconds(1.0)
54
- assert temporal_condition_solver.get_maximum_iteration_count() == 1234
55
-
56
- def test_solve_success_one_condition_always_true(
57
- self,
58
- temporal_condition_solver: TemporalConditionSolver,
59
- interval: Interval,
60
- ):
61
- solution: list[Interval] = temporal_condition_solver.solve(
62
- condition=lambda _: True,
63
- interval=interval,
64
- )
65
-
66
- assert isinstance(solution, list)
67
- assert solution == [interval]
68
-
69
- def test_solve_success_one_condition_always_false(
70
- self,
71
- temporal_condition_solver: TemporalConditionSolver,
72
- interval: Interval,
73
- ):
74
- solution: list[Interval] = temporal_condition_solver.solve(
75
- condition=lambda _: False,
76
- interval=interval,
77
- )
78
-
79
- assert isinstance(solution, list)
80
- assert solution == []
81
-
82
- def test_solve_success_multiple_conditions_always_true(
83
- self,
84
- temporal_condition_solver: TemporalConditionSolver,
85
- interval: Interval,
86
- ):
87
- solution: list[Interval] = temporal_condition_solver.solve(
88
- conditions=[
89
- lambda _: True,
90
- lambda _: True,
91
- ],
92
- interval=interval,
93
- )
94
-
95
- assert isinstance(solution, list)
96
- assert solution == [interval]
97
-
98
- def test_solve_success_multiple_conditions_one_always_false(
99
- self,
100
- temporal_condition_solver: TemporalConditionSolver,
101
- interval: Interval,
102
- ):
103
- solution: list[Interval] = temporal_condition_solver.solve(
104
- conditions=[
105
- lambda _: True,
106
- lambda _: False,
107
- ],
108
- interval=interval,
109
- )
110
-
111
- assert isinstance(solution, list)
112
- assert solution == []
113
-
114
- def test_solve_success_using_access_generator(
115
- self,
116
- temporal_condition_solver: TemporalConditionSolver,
117
- interval: Interval,
118
- ):
119
- environment = Environment.default()
120
-
121
- generator = Generator(
122
- environment=environment,
123
- )
124
-
125
- earth = environment.access_celestial_object_with_name("Earth")
126
-
127
- trajectory = Orbit(
128
- model=Kepler(
129
- coe=COE(
130
- semi_major_axis=Length.kilometers(7000.0),
131
- eccentricity=0.0,
132
- inclination=Angle.degrees(45.0),
133
- raan=Angle.degrees(0.0),
134
- aop=Angle.degrees(0.0),
135
- true_anomaly=Angle.degrees(0.0),
136
- ),
137
- epoch=Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC),
138
- celestial_object=earth,
139
- perturbation_type=Kepler.PerturbationType.No,
140
- ),
141
- celestial_object=earth,
142
- )
143
-
144
- solution: list[Interval] = temporal_condition_solver.solve(
145
- condition=generator.get_condition_function(
146
- from_trajectory=trajectory,
147
- to_trajectory=trajectory,
148
- ),
149
- interval=interval,
150
- )
151
-
152
- assert isinstance(solution, list)
153
- assert solution == [interval]
@@ -1,248 +0,0 @@
1
- # Apache License 2.0
2
-
3
- import pytest
4
-
5
- import numpy as np
6
- import math
7
-
8
- from ostk.astrodynamics import NumericalSolver, EventCondition
9
-
10
-
11
- def oscillator(x, dxdt, _):
12
- dxdt[0] = x[1]
13
- dxdt[1] = -x[0]
14
- return dxdt
15
-
16
-
17
- def get_state_vec(time: float) -> np.ndarray:
18
- return np.array([math.sin(time), math.cos(time)])
19
-
20
-
21
- @pytest.fixture
22
- def initial_state_vec() -> np.ndarray:
23
- return get_state_vec(0.0)
24
-
25
-
26
- @pytest.fixture
27
- def custom_condition() -> EventCondition:
28
- class CustomCondition(EventCondition):
29
- def __init__(self, target: float, criteria: EventCondition.Criteria):
30
- super().__init__("Custom", criteria)
31
- self._target = target
32
-
33
- def evaluate(self, state_vector, time: float) -> bool:
34
- return time - self._target
35
-
36
- return CustomCondition(5.0, EventCondition.Criteria.StrictlyPositive)
37
-
38
-
39
- @pytest.fixture
40
- def numerical_solver_default_inputs() -> (
41
- tuple[NumericalSolver.LogType, NumericalSolver.StepperType, float, float, float]
42
- ):
43
- log_type = NumericalSolver.LogType.NoLog
44
- stepper_type = NumericalSolver.StepperType.RungeKuttaCashKarp54
45
- initial_time_step = 5.0
46
- relative_tolerance = 1.0e-15
47
- absolute_tolerance = 1.0e-15
48
-
49
- return (
50
- log_type,
51
- stepper_type,
52
- initial_time_step,
53
- relative_tolerance,
54
- absolute_tolerance,
55
- )
56
-
57
-
58
- @pytest.fixture
59
- def numerical_solver(numerical_solver_default_inputs) -> NumericalSolver:
60
- return NumericalSolver(*numerical_solver_default_inputs)
61
-
62
-
63
- @pytest.fixture
64
- def numerical_solver_conditional() -> NumericalSolver:
65
- return NumericalSolver(
66
- NumericalSolver.LogType.NoLog,
67
- NumericalSolver.StepperType.RungeKuttaDopri5,
68
- 5.0,
69
- 1.0e-15,
70
- 1.0e-15,
71
- )
72
-
73
-
74
- class TestNumericalSolver:
75
- def test_constructors(self, numerical_solver: NumericalSolver):
76
- assert numerical_solver is not None
77
- assert isinstance(numerical_solver, NumericalSolver)
78
- assert numerical_solver.is_defined()
79
-
80
- numericalsolver_2: NumericalSolver = NumericalSolver(numerical_solver)
81
-
82
- assert numericalsolver_2 is not None
83
- assert isinstance(numericalsolver_2, NumericalSolver)
84
- assert numericalsolver_2.is_defined()
85
-
86
- def test_comparators(self, numerical_solver: NumericalSolver):
87
- assert numerical_solver == numerical_solver
88
- assert (numerical_solver != numerical_solver) is False
89
-
90
- def test_get_types(
91
- self,
92
- numerical_solver_default_inputs: tuple[
93
- NumericalSolver.LogType, NumericalSolver.StepperType, float, float, float
94
- ],
95
- numerical_solver: NumericalSolver,
96
- ):
97
- (
98
- log_type,
99
- stepper_type,
100
- initial_time_step,
101
- relative_tolerance,
102
- absolute_tolerance,
103
- ) = numerical_solver_default_inputs
104
-
105
- assert numerical_solver.get_log_type() == log_type
106
- assert numerical_solver.get_stepper_type() == stepper_type
107
- assert numerical_solver.get_time_step() == initial_time_step
108
- assert numerical_solver.get_relative_tolerance() == relative_tolerance
109
- assert numerical_solver.get_absolute_tolerance() == absolute_tolerance
110
- assert numerical_solver.get_root_solver() is not None
111
-
112
- def test_get_string_from_types(self):
113
- assert (
114
- NumericalSolver.string_from_stepper_type(
115
- NumericalSolver.StepperType.RungeKutta4
116
- )
117
- == "RungeKutta4"
118
- )
119
- assert (
120
- NumericalSolver.string_from_stepper_type(
121
- NumericalSolver.StepperType.RungeKuttaCashKarp54
122
- )
123
- == "RungeKuttaCashKarp54"
124
- )
125
- assert (
126
- NumericalSolver.string_from_stepper_type(
127
- NumericalSolver.StepperType.RungeKuttaFehlberg78
128
- )
129
- == "RungeKuttaFehlberg78"
130
- )
131
- assert (
132
- NumericalSolver.string_from_log_type(NumericalSolver.LogType.NoLog)
133
- == "NoLog"
134
- )
135
- assert (
136
- NumericalSolver.string_from_log_type(NumericalSolver.LogType.LogConstant)
137
- == "LogConstant"
138
- )
139
- assert (
140
- NumericalSolver.string_from_log_type(NumericalSolver.LogType.LogAdaptive)
141
- == "LogAdaptive"
142
- )
143
-
144
- def test_integrate_duration(
145
- self, numerical_solver: NumericalSolver, initial_state_vec: np.ndarray
146
- ):
147
- integration_duration: float = 100.0
148
-
149
- state_vector, _ = numerical_solver.integrate_duration(
150
- initial_state_vec, integration_duration, oscillator
151
- )
152
-
153
- assert 5e-9 >= abs(state_vector[0] - math.sin(integration_duration))
154
- assert 5e-9 >= abs(state_vector[1] - math.cos(integration_duration))
155
-
156
- integration_durations = np.arange(100.0, 1000.0, 50.0)
157
- solutions = numerical_solver.integrate_duration(
158
- initial_state_vec, integration_durations, oscillator
159
- )
160
-
161
- for solution, integration_duration in zip(solutions, integration_durations):
162
- state_vector, _ = solution
163
-
164
- assert 5e-9 >= abs(state_vector[0] - math.sin(integration_duration))
165
- assert 5e-9 >= abs(state_vector[1] - math.cos(integration_duration))
166
-
167
- def test_integrate_time(self, numerical_solver: NumericalSolver):
168
- start_time: float = 500.0
169
- end_time: float = start_time + 100.0
170
-
171
- initial_state_vec = get_state_vec(start_time)
172
-
173
- state_vector, _ = numerical_solver.integrate_time(
174
- initial_state_vec, start_time, end_time, oscillator
175
- )
176
-
177
- assert 5e-9 >= abs(state_vector[0] - math.sin(end_time))
178
- assert 5e-9 >= abs(state_vector[1] - math.cos(end_time))
179
-
180
- end_times = np.arange(600.0, 1000.0, 50.0)
181
- solutions = numerical_solver.integrate_time(
182
- initial_state_vec, start_time, end_times, oscillator
183
- )
184
-
185
- for solution, end_time in zip(solutions, end_times):
186
- state_vector, _ = solution
187
-
188
- assert 5e-9 >= abs(state_vector[0] - math.sin(end_time))
189
- assert 5e-9 >= abs(state_vector[1] - math.cos(end_time))
190
-
191
- def test_integrate_duration_with_condition(
192
- self,
193
- numerical_solver_conditional: NumericalSolver,
194
- initial_state_vec: np.ndarray,
195
- custom_condition: EventCondition,
196
- ):
197
- integration_duration: float = 100.0
198
-
199
- condition_solution = numerical_solver_conditional.integrate_duration(
200
- initial_state_vec, integration_duration, oscillator, custom_condition
201
- )
202
-
203
- assert condition_solution.condition_is_satisfied
204
- assert (
205
- condition_solution.iteration_count
206
- < numerical_solver_conditional.get_root_solver().get_maximum_iteration_count()
207
- )
208
-
209
- state_vector, time = condition_solution.solution
210
-
211
- assert abs(time - custom_condition._target) < 1e-6
212
-
213
- assert 5e-9 >= abs(state_vector[0] - math.sin(time))
214
- assert 5e-9 >= abs(state_vector[1] - math.cos(time))
215
-
216
- def test_integrate_time_with_condition(
217
- self,
218
- numerical_solver_conditional: NumericalSolver,
219
- custom_condition: EventCondition,
220
- ):
221
- start_time: float = 500.0
222
- end_time: float = start_time + 100.0
223
-
224
- initial_state_vec = get_state_vec(start_time)
225
-
226
- condition_solution = numerical_solver_conditional.integrate_time(
227
- initial_state_vec, start_time, end_time, oscillator, custom_condition
228
- )
229
-
230
- assert condition_solution.condition_is_satisfied
231
- assert (
232
- condition_solution.iteration_count
233
- < numerical_solver_conditional.get_root_solver().get_maximum_iteration_count()
234
- )
235
-
236
- state_vector, time = condition_solution.solution
237
-
238
- assert abs(time - start_time - custom_condition._target) < 1e-6
239
-
240
- assert 5e-9 >= abs(state_vector[0] - math.sin(time))
241
- assert 5e-9 >= abs(state_vector[1] - math.cos(time))
242
-
243
- def test_default(self):
244
- assert NumericalSolver.default() is not None
245
-
246
- def test_undefined(self):
247
- assert NumericalSolver.undefined() is not None
248
- assert NumericalSolver.undefined().is_defined() is False
@@ -1 +0,0 @@
1
- # Apache License 2.0
@@ -1 +0,0 @@
1
- # Apache License 2.0
@@ -1 +0,0 @@
1
- # Apache License 2.0
@@ -1 +0,0 @@
1
- # Apache License 2.0
@@ -1,18 +0,0 @@
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"))
@@ -1,44 +0,0 @@
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
@@ -1,108 +0,0 @@
1
- # Apache License 2.0
2
-
3
- import pytest
4
-
5
- from datetime import datetime
6
-
7
- from ostk.core.containers import Dictionary
8
- from ostk.core.filesystem import Path
9
- from ostk.core.filesystem import File
10
-
11
- from ostk.physics.units import Length
12
- from ostk.physics.units 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.messages.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
@@ -1 +0,0 @@
1
- # Apache License 2.0
@@ -1 +0,0 @@
1
- # Apache License 2.0