open-space-toolkit-astrodynamics 5.1.5__py38-none-any.whl → 5.2.0__py38-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.
- {open_space_toolkit_astrodynamics-5.1.5.dist-info → open_space_toolkit_astrodynamics-5.2.0.dist-info}/METADATA +1 -1
- open_space_toolkit_astrodynamics-5.2.0.dist-info/RECORD +96 -0
- ostk/__init__.py +1 -0
- ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-38-x86_64-linux-gnu.so +0 -0
- ostk/astrodynamics/converters.py +44 -6
- ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.5 +0 -0
- ostk/astrodynamics/pytrajectory/pystate.py +1 -3
- ostk/astrodynamics/test/access/__init__.py +1 -0
- ostk/astrodynamics/test/access/test_generator.py +248 -0
- ostk/astrodynamics/test/conjunction/messages/ccsds/__init__.py +1 -0
- ostk/astrodynamics/test/conjunction/messages/ccsds/conftest.py +325 -0
- ostk/astrodynamics/test/conjunction/messages/ccsds/data/cdm.json +303 -0
- ostk/astrodynamics/test/conjunction/messages/ccsds/test_cdm.py +416 -0
- ostk/astrodynamics/test/dynamics/__init__.py +1 -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_third_body_gravity.py +67 -0
- ostk/astrodynamics/test/dynamics/test_thruster.py +142 -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_coe_condition.py +87 -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/__init__.py +1 -0
- ostk/astrodynamics/test/flight/profile/test_state.py +144 -0
- ostk/astrodynamics/test/flight/system/__init__.py +1 -0
- ostk/astrodynamics/test/flight/system/test_propulsion_system.py +46 -0
- ostk/astrodynamics/test/flight/system/test_satellite_system.py +91 -0
- ostk/astrodynamics/test/flight/system/test_satellite_system_builder.py +71 -0
- ostk/astrodynamics/test/flight/test_profile.py +153 -0
- ostk/astrodynamics/test/flight/test_system.py +55 -0
- ostk/astrodynamics/test/guidance_law/test_constant_thrust.py +91 -0
- ostk/astrodynamics/test/guidance_law/test_qlaw.py +139 -0
- ostk/astrodynamics/test/solvers/__init__.py +1 -0
- ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +181 -0
- ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +153 -0
- ostk/astrodynamics/test/test_access.py +2 -6
- ostk/astrodynamics/test/test_converters.py +213 -6
- ostk/astrodynamics/test/test_viewer.py +1 -2
- ostk/astrodynamics/test/trajectory/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/messages/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/messages/spacex/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/messages/spacex/conftest.py +18 -0
- ostk/astrodynamics/test/trajectory/orbit/messages/spacex/data/opm_1.yaml +44 -0
- ostk/astrodynamics/test/trajectory/orbit/messages/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 +167 -0
- ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +331 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +130 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +195 -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 +55 -0
- ostk/astrodynamics/test/trajectory/state/coordinates_subset/test_angular_velocity.py +30 -0
- ostk/astrodynamics/test/trajectory/state/coordinates_subset/test_attitude_quaternion.py +18 -0
- ostk/astrodynamics/test/trajectory/state/coordinates_subset/test_cartesian_position.py +107 -0
- ostk/astrodynamics/test/trajectory/state/coordinates_subset/test_cartesian_velocity.py +115 -0
- ostk/astrodynamics/test/trajectory/state/test_coordinates_broker.py +84 -0
- ostk/astrodynamics/test/trajectory/state/test_coordinates_subset.py +43 -0
- ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +314 -0
- ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py +81 -0
- ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +64 -0
- ostk/astrodynamics/test/trajectory/test_model.py +1 -0
- ostk/astrodynamics/test/trajectory/test_orbit.py +92 -0
- ostk/astrodynamics/test/trajectory/test_propagator.py +402 -0
- ostk/astrodynamics/test/trajectory/test_segment.py +288 -0
- ostk/astrodynamics/test/trajectory/test_sequence.py +459 -0
- ostk/astrodynamics/test/trajectory/test_state.py +223 -0
- ostk/astrodynamics/test/trajectory/test_state_builder.py +171 -0
- ostk/astrodynamics/viewer.py +1 -3
- open_space_toolkit_astrodynamics-5.1.5.dist-info/RECORD +0 -25
- {open_space_toolkit_astrodynamics-5.1.5.dist-info → open_space_toolkit_astrodynamics-5.2.0.dist-info}/WHEEL +0 -0
- {open_space_toolkit_astrodynamics-5.1.5.dist-info → open_space_toolkit_astrodynamics-5.2.0.dist-info}/top_level.txt +0 -0
- {open_space_toolkit_astrodynamics-5.1.5.dist-info → open_space_toolkit_astrodynamics-5.2.0.dist-info}/zip-safe +0 -0
@@ -1,5 +1,7 @@
|
|
1
1
|
# Apache License 2.0
|
2
2
|
|
3
|
+
import pytest
|
4
|
+
|
3
5
|
from datetime import datetime, timedelta, timezone
|
4
6
|
|
5
7
|
import numpy as np
|
@@ -17,6 +19,7 @@ from ostk.physics.coordinate import Frame
|
|
17
19
|
|
18
20
|
from ostk.astrodynamics.converters import coerce_to_datetime
|
19
21
|
from ostk.astrodynamics.converters import coerce_to_instant
|
22
|
+
from ostk.astrodynamics.converters import coerce_to_iso
|
20
23
|
from ostk.astrodynamics.converters import coerce_to_interval
|
21
24
|
from ostk.astrodynamics.converters import coerce_to_duration
|
22
25
|
from ostk.astrodynamics.converters import coerce_to_position
|
@@ -25,27 +28,231 @@ from ostk.astrodynamics.converters import coerce_to_quaternion
|
|
25
28
|
|
26
29
|
|
27
30
|
def test_coerce_to_datetime_success_instant():
|
28
|
-
value = Instant.date_time(DateTime(2020, 1,
|
29
|
-
assert coerce_to_datetime(value) == datetime(
|
31
|
+
value = Instant.date_time(DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.UTC)
|
32
|
+
assert coerce_to_datetime(value) == datetime(
|
33
|
+
2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone.utc
|
34
|
+
)
|
35
|
+
|
36
|
+
value = Instant.date_time(DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.TAI)
|
37
|
+
assert coerce_to_datetime(value) == datetime(
|
38
|
+
2020, 1, 2, 3, 3, 28, 123456, tzinfo=timezone.utc
|
39
|
+
)
|
30
40
|
|
31
41
|
|
32
42
|
def test_coerce_to_datetime_success_datetime():
|
33
|
-
value = datetime(2020, 1,
|
43
|
+
value = datetime(2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone.utc)
|
34
44
|
assert coerce_to_datetime(value) == value
|
35
45
|
|
46
|
+
value = datetime(
|
47
|
+
2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone(timedelta(seconds=3600))
|
48
|
+
)
|
49
|
+
assert coerce_to_datetime(value) == value
|
50
|
+
|
51
|
+
|
52
|
+
def test_coerce_to_datetime_success_iso():
|
53
|
+
value = "2020-01-02T03:04:05.123456+00:00"
|
54
|
+
assert coerce_to_datetime(value) == datetime(
|
55
|
+
2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone.utc
|
56
|
+
)
|
57
|
+
|
58
|
+
value = "2020-01-02T03:04:05+00:00"
|
59
|
+
assert coerce_to_datetime(value) == datetime(2020, 1, 2, 3, 4, 5, tzinfo=timezone.utc)
|
60
|
+
|
61
|
+
value = "2020-01-02T03:04:05.123456+01:00"
|
62
|
+
assert coerce_to_datetime(value) == datetime(
|
63
|
+
2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone(timedelta(seconds=3600))
|
64
|
+
)
|
65
|
+
|
66
|
+
value = "2020-01-02T03:04:05.123456Z"
|
67
|
+
assert coerce_to_datetime(value) == datetime(
|
68
|
+
2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone.utc
|
69
|
+
)
|
70
|
+
|
71
|
+
value = "2020-01-02T03:04:05Z"
|
72
|
+
assert coerce_to_datetime(value) == datetime(2020, 1, 2, 3, 4, 5, tzinfo=timezone.utc)
|
73
|
+
|
74
|
+
|
75
|
+
def test_coerce_to_datetime_failure():
|
76
|
+
with pytest.raises(TypeError):
|
77
|
+
coerce_to_datetime(False)
|
78
|
+
|
79
|
+
with pytest.raises(Exception):
|
80
|
+
coerce_to_datetime("some_ill_formed_iso")
|
81
|
+
|
36
82
|
|
37
83
|
def test_coerce_to_instant_success_datetime():
|
38
|
-
value = datetime(2020, 1,
|
84
|
+
value = datetime(2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone.utc)
|
85
|
+
assert coerce_to_instant(value) == Instant.date_time(
|
86
|
+
DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.UTC
|
87
|
+
)
|
88
|
+
|
89
|
+
value = datetime(
|
90
|
+
2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone(timedelta(seconds=3600))
|
91
|
+
)
|
39
92
|
assert coerce_to_instant(value) == Instant.date_time(
|
40
|
-
DateTime(2020, 1,
|
93
|
+
DateTime(2020, 1, 2, 2, 4, 5, 123, 456), Scale.UTC
|
41
94
|
)
|
42
95
|
|
43
96
|
|
44
97
|
def test_coerce_to_instant_success_instant():
|
45
|
-
value = Instant.date_time(DateTime(2020, 1,
|
98
|
+
value = Instant.date_time(DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.UTC)
|
99
|
+
assert coerce_to_instant(value) == value
|
100
|
+
|
101
|
+
value = Instant.date_time(DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.TAI)
|
46
102
|
assert coerce_to_instant(value) == value
|
47
103
|
|
48
104
|
|
105
|
+
def test_coerce_to_instant_success_iso():
|
106
|
+
value = "2020-01-02T03:04:05.123456+00:00"
|
107
|
+
assert coerce_to_instant(value) == Instant.date_time(
|
108
|
+
DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.UTC
|
109
|
+
)
|
110
|
+
|
111
|
+
value = "2020-01-02T03:04:05+00:00"
|
112
|
+
assert coerce_to_instant(value) == Instant.date_time(
|
113
|
+
DateTime(2020, 1, 2, 3, 4, 5), Scale.UTC
|
114
|
+
)
|
115
|
+
|
116
|
+
value = "2020-01-02T03:04:05.123456+01:00"
|
117
|
+
assert coerce_to_instant(value) == Instant.date_time(
|
118
|
+
DateTime(2020, 1, 2, 2, 4, 5, 123, 456), Scale.UTC
|
119
|
+
)
|
120
|
+
|
121
|
+
value = "2020-01-02T03:04:05.123456Z"
|
122
|
+
assert coerce_to_instant(value) == Instant.date_time(
|
123
|
+
DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.UTC
|
124
|
+
)
|
125
|
+
|
126
|
+
value = "2020-01-02T03:04:05Z"
|
127
|
+
assert coerce_to_instant(value) == Instant.date_time(
|
128
|
+
DateTime(
|
129
|
+
2020,
|
130
|
+
1,
|
131
|
+
2,
|
132
|
+
3,
|
133
|
+
4,
|
134
|
+
5,
|
135
|
+
),
|
136
|
+
Scale.UTC,
|
137
|
+
)
|
138
|
+
|
139
|
+
|
140
|
+
def test_coerce_to_instant_failure():
|
141
|
+
with pytest.raises(TypeError):
|
142
|
+
coerce_to_instant(False)
|
143
|
+
|
144
|
+
with pytest.raises(Exception):
|
145
|
+
coerce_to_instant("some_ill_formed_iso")
|
146
|
+
|
147
|
+
|
148
|
+
def test_coerce_to_iso_success_datetime():
|
149
|
+
value = datetime(2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone.utc)
|
150
|
+
assert (
|
151
|
+
coerce_to_iso(value, timespec="microseconds")
|
152
|
+
== "2020-01-02T03:04:05.123456+00:00"
|
153
|
+
)
|
154
|
+
|
155
|
+
value = datetime(
|
156
|
+
2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone(timedelta(seconds=3600))
|
157
|
+
)
|
158
|
+
assert (
|
159
|
+
coerce_to_iso(value, timespec="microseconds")
|
160
|
+
== "2020-01-02T03:04:05.123456+01:00"
|
161
|
+
)
|
162
|
+
|
163
|
+
value = datetime(2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone.utc)
|
164
|
+
assert (
|
165
|
+
coerce_to_iso(value, timespec="milliseconds") == "2020-01-02T03:04:05.123+00:00"
|
166
|
+
)
|
167
|
+
|
168
|
+
value = datetime(2020, 1, 2, 3, 4, 5, 0, tzinfo=timezone.utc)
|
169
|
+
assert (
|
170
|
+
coerce_to_iso(value, timespec="microseconds")
|
171
|
+
== "2020-01-02T03:04:05.000000+00:00"
|
172
|
+
)
|
173
|
+
|
174
|
+
|
175
|
+
def test_coerce_to_iso_success_instant():
|
176
|
+
value = Instant.date_time(DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.UTC)
|
177
|
+
assert (
|
178
|
+
coerce_to_iso(value, timespec="microseconds")
|
179
|
+
== "2020-01-02T03:04:05.123456+00:00"
|
180
|
+
)
|
181
|
+
|
182
|
+
value = Instant.date_time(DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.TAI)
|
183
|
+
assert (
|
184
|
+
coerce_to_iso(value, timespec="microseconds")
|
185
|
+
== "2020-01-02T03:03:28.123456+00:00"
|
186
|
+
)
|
187
|
+
|
188
|
+
value = Instant.date_time(DateTime(2020, 1, 2, 3, 4, 5, 123, 456), Scale.UTC)
|
189
|
+
assert (
|
190
|
+
coerce_to_iso(value, timespec="milliseconds") == "2020-01-02T03:04:05.123+00:00"
|
191
|
+
)
|
192
|
+
|
193
|
+
value = Instant.date_time(DateTime(2020, 1, 2, 3, 4, 5, 123), Scale.UTC)
|
194
|
+
assert (
|
195
|
+
coerce_to_iso(value, timespec="microseconds")
|
196
|
+
== "2020-01-02T03:04:05.123000+00:00"
|
197
|
+
)
|
198
|
+
|
199
|
+
|
200
|
+
def test_coerce_to_iso_success_iso():
|
201
|
+
value = "2020-01-02T03:04:05.123456+00:00"
|
202
|
+
assert coerce_to_iso(value, timespec="microseconds") == value
|
203
|
+
|
204
|
+
value = "2020-01-02T03:04:05.123456+01:00"
|
205
|
+
assert coerce_to_iso(value, timespec="microseconds") == value
|
206
|
+
|
207
|
+
value = "2020-01-02T03:04:05.123456+00:00"
|
208
|
+
assert (
|
209
|
+
coerce_to_iso(value, timespec="milliseconds") == "2020-01-02T03:04:05.123+00:00"
|
210
|
+
)
|
211
|
+
|
212
|
+
value = "2020-01-02T03:04:05.123+00:00"
|
213
|
+
assert (
|
214
|
+
coerce_to_iso(value, timespec="microseconds")
|
215
|
+
== "2020-01-02T03:04:05.123000+00:00"
|
216
|
+
)
|
217
|
+
|
218
|
+
value = "2020-01-02T03:04:05+00:00"
|
219
|
+
assert (
|
220
|
+
coerce_to_iso(value, timespec="microseconds")
|
221
|
+
== "2020-01-02T03:04:05.000000+00:00"
|
222
|
+
)
|
223
|
+
|
224
|
+
value = "2020-01-02T03:04:05.123456Z"
|
225
|
+
assert (
|
226
|
+
coerce_to_iso(value, timespec="microseconds")
|
227
|
+
== "2020-01-02T03:04:05.123456+00:00"
|
228
|
+
)
|
229
|
+
|
230
|
+
value = "2020-01-02T03:04:05.123456Z"
|
231
|
+
assert (
|
232
|
+
coerce_to_iso(value, timespec="milliseconds") == "2020-01-02T03:04:05.123+00:00"
|
233
|
+
)
|
234
|
+
|
235
|
+
value = "2020-01-02T03:04:05.123Z"
|
236
|
+
assert (
|
237
|
+
coerce_to_iso(value, timespec="microseconds")
|
238
|
+
== "2020-01-02T03:04:05.123000+00:00"
|
239
|
+
)
|
240
|
+
|
241
|
+
value = "2020-01-02T03:04:05Z"
|
242
|
+
assert (
|
243
|
+
coerce_to_iso(value, timespec="microseconds")
|
244
|
+
== "2020-01-02T03:04:05.000000+00:00"
|
245
|
+
)
|
246
|
+
|
247
|
+
|
248
|
+
def test_coerce_to_iso_failure():
|
249
|
+
with pytest.raises(TypeError):
|
250
|
+
coerce_to_iso(False)
|
251
|
+
|
252
|
+
with pytest.raises(Exception):
|
253
|
+
coerce_to_iso("some_ill_formed_iso")
|
254
|
+
|
255
|
+
|
49
256
|
def test_coerce_to_interval_success_interval():
|
50
257
|
value = Interval.closed(
|
51
258
|
Instant.date_time(DateTime(2020, 1, 1), Scale.UTC),
|
@@ -103,8 +103,7 @@ class TestViewer:
|
|
103
103
|
assert "Cesium.IonResource.fromAssetId(123)" in rendered_html
|
104
104
|
assert "widget.entities.add({polyline:" in rendered_html
|
105
105
|
assert (
|
106
|
-
"widget.entities.add({position: widget.star_tracker_position"
|
107
|
-
in rendered_html
|
106
|
+
"widget.entities.add({position: widget.star_tracker_position" in rendered_html
|
108
107
|
)
|
109
108
|
assert rendered_html.endswith("</script>")
|
110
109
|
|
@@ -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 @@
|
|
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.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
|
@@ -0,0 +1 @@
|
|
1
|
+
# Apache License 2.0
|
@@ -0,0 +1 @@
|
|
1
|
+
# Apache License 2.0
|
@@ -0,0 +1,65 @@
|
|
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
|
+
|
8
|
+
from ostk.astrodynamics.trajectory.orbit.models import BrouwerLyddaneMean
|
9
|
+
|
10
|
+
|
11
|
+
@pytest.fixture
|
12
|
+
def semi_major_axis() -> Length:
|
13
|
+
return Length.kilometers(7000.0)
|
14
|
+
|
15
|
+
|
16
|
+
@pytest.fixture
|
17
|
+
def eccentricity() -> float:
|
18
|
+
return 1e-3
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.fixture
|
22
|
+
def inclination() -> Angle:
|
23
|
+
return Angle.degrees(35.0)
|
24
|
+
|
25
|
+
|
26
|
+
@pytest.fixture
|
27
|
+
def raan() -> Angle:
|
28
|
+
return Angle.degrees(40.0)
|
29
|
+
|
30
|
+
|
31
|
+
@pytest.fixture
|
32
|
+
def aop() -> Angle:
|
33
|
+
return Angle.degrees(50.0)
|
34
|
+
|
35
|
+
|
36
|
+
@pytest.fixture
|
37
|
+
def mean_anomaly() -> Angle:
|
38
|
+
return Angle.degrees(60.0)
|
39
|
+
|
40
|
+
|
41
|
+
@pytest.fixture
|
42
|
+
def brouwer_lyddane_mean(
|
43
|
+
semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
|
44
|
+
):
|
45
|
+
class BrouwerLyddaneMeanMock(BrouwerLyddaneMean):
|
46
|
+
def __init__(
|
47
|
+
self, semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
|
48
|
+
):
|
49
|
+
super().__init__(
|
50
|
+
semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
|
51
|
+
)
|
52
|
+
|
53
|
+
def to_coe():
|
54
|
+
return 0.0
|
55
|
+
|
56
|
+
return BrouwerLyddaneMeanMock(
|
57
|
+
semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
|
58
|
+
)
|
59
|
+
|
60
|
+
|
61
|
+
class TestBrouwerLyddaneMean:
|
62
|
+
def test_getters(self, brouwer_lyddane_mean: BrouwerLyddaneMean):
|
63
|
+
assert isinstance(brouwer_lyddane_mean.get_mean_anomaly(), Angle)
|
64
|
+
assert isinstance(brouwer_lyddane_mean.get_true_anomaly(), Angle)
|
65
|
+
assert isinstance(brouwer_lyddane_mean.get_eccentric_anomaly(), Angle)
|
@@ -0,0 +1,102 @@
|
|
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.environment.gravitational import Earth
|
8
|
+
|
9
|
+
from ostk.physics.coordinate import Frame
|
10
|
+
from ostk.physics.coordinate import Position
|
11
|
+
from ostk.physics.coordinate import Velocity
|
12
|
+
|
13
|
+
from ostk.astrodynamics.trajectory.orbit.models.kepler import COE
|
14
|
+
from ostk.astrodynamics.trajectory.orbit.models.brouwerLyddaneMean import (
|
15
|
+
BrouwerLyddaneMeanLong,
|
16
|
+
)
|
17
|
+
|
18
|
+
|
19
|
+
@pytest.fixture
|
20
|
+
def semi_major_axis() -> Length:
|
21
|
+
return Length.kilometers(7000.0)
|
22
|
+
|
23
|
+
|
24
|
+
@pytest.fixture
|
25
|
+
def eccentricity() -> float:
|
26
|
+
return 1e-3
|
27
|
+
|
28
|
+
|
29
|
+
@pytest.fixture
|
30
|
+
def inclination() -> Angle:
|
31
|
+
return Angle.degrees(35.0)
|
32
|
+
|
33
|
+
|
34
|
+
@pytest.fixture
|
35
|
+
def raan() -> Angle:
|
36
|
+
return Angle.degrees(40.0)
|
37
|
+
|
38
|
+
|
39
|
+
@pytest.fixture
|
40
|
+
def aop() -> Angle:
|
41
|
+
return Angle.degrees(50.0)
|
42
|
+
|
43
|
+
|
44
|
+
@pytest.fixture
|
45
|
+
def mean_anomaly() -> Angle:
|
46
|
+
return Angle.degrees(60.0)
|
47
|
+
|
48
|
+
|
49
|
+
@pytest.fixture
|
50
|
+
def coe(
|
51
|
+
semi_major_axis: Length,
|
52
|
+
eccentricity: float,
|
53
|
+
inclination: Angle,
|
54
|
+
raan: Angle,
|
55
|
+
aop: Angle,
|
56
|
+
mean_anomaly: Angle,
|
57
|
+
) -> COE:
|
58
|
+
return COE(semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly)
|
59
|
+
|
60
|
+
|
61
|
+
@pytest.fixture
|
62
|
+
def cartesian_state() -> tuple[Position, Velocity]:
|
63
|
+
return (
|
64
|
+
Position.meters(
|
65
|
+
[6596407.223662058, 2281266.582975321, -10540.61521486086], Frame.GCRF()
|
66
|
+
),
|
67
|
+
Velocity.meters_per_second(
|
68
|
+
[337.7269674273224, -969.7192552349448, 7488.702816619139], Frame.GCRF()
|
69
|
+
),
|
70
|
+
)
|
71
|
+
|
72
|
+
|
73
|
+
@pytest.fixture
|
74
|
+
def gravitational_parameter():
|
75
|
+
return Earth.EGM2008.gravitational_parameter
|
76
|
+
|
77
|
+
|
78
|
+
@pytest.fixture
|
79
|
+
def brouwer_lyddane_mean_long(
|
80
|
+
semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
|
81
|
+
):
|
82
|
+
return BrouwerLyddaneMeanLong(
|
83
|
+
semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
|
84
|
+
)
|
85
|
+
|
86
|
+
|
87
|
+
class TestBrouwerLyddaneMeanLong:
|
88
|
+
def test_to_coe(self, brouwer_lyddane_mean_long: BrouwerLyddaneMeanLong):
|
89
|
+
assert brouwer_lyddane_mean_long.to_coe().is_defined()
|
90
|
+
|
91
|
+
def test_coe(self, coe: COE):
|
92
|
+
assert BrouwerLyddaneMeanLong.COE(coe).is_defined()
|
93
|
+
|
94
|
+
def test_cartesian(
|
95
|
+
self, cartesian_state: tuple[Position, Velocity], gravitational_parameter
|
96
|
+
):
|
97
|
+
assert BrouwerLyddaneMeanLong.cartesian(
|
98
|
+
cartesian_state, gravitational_parameter
|
99
|
+
).is_defined()
|
100
|
+
|
101
|
+
def test_undefined(self):
|
102
|
+
assert BrouwerLyddaneMeanLong.undefined().is_defined() is False
|