open-space-toolkit-astrodynamics 9.4.1__py38-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 (98) hide show
  1. open_space_toolkit_astrodynamics-9.4.1.dist-info/METADATA +30 -0
  2. open_space_toolkit_astrodynamics-9.4.1.dist-info/RECORD +98 -0
  3. open_space_toolkit_astrodynamics-9.4.1.dist-info/WHEEL +5 -0
  4. open_space_toolkit_astrodynamics-9.4.1.dist-info/top_level.txt +1 -0
  5. open_space_toolkit_astrodynamics-9.4.1.dist-info/zip-safe +1 -0
  6. ostk/__init__.py +1 -0
  7. ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-38-x86_64-linux-gnu.so +0 -0
  8. ostk/astrodynamics/__init__.py +11 -0
  9. ostk/astrodynamics/converters.py +185 -0
  10. ostk/astrodynamics/display.py +220 -0
  11. ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.9 +0 -0
  12. ostk/astrodynamics/pytrajectory/__init__.py +1 -0
  13. ostk/astrodynamics/pytrajectory/pystate.py +36 -0
  14. ostk/astrodynamics/test/__init__.py +1 -0
  15. ostk/astrodynamics/test/access/__init__.py +1 -0
  16. ostk/astrodynamics/test/access/test_generator.py +248 -0
  17. ostk/astrodynamics/test/conftest.py +119 -0
  18. ostk/astrodynamics/test/conjunction/message/ccsds/__init__.py +1 -0
  19. ostk/astrodynamics/test/conjunction/message/ccsds/conftest.py +325 -0
  20. ostk/astrodynamics/test/conjunction/message/ccsds/data/cdm.json +303 -0
  21. ostk/astrodynamics/test/conjunction/message/ccsds/test_cdm.py +416 -0
  22. ostk/astrodynamics/test/dynamics/__init__.py +1 -0
  23. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity.csv +565 -0
  24. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity_Truth.csv +100 -0
  25. ostk/astrodynamics/test/dynamics/test_atmospheric_drag.py +128 -0
  26. ostk/astrodynamics/test/dynamics/test_central_body_gravity.py +58 -0
  27. ostk/astrodynamics/test/dynamics/test_dynamics.py +50 -0
  28. ostk/astrodynamics/test/dynamics/test_position_derivative.py +51 -0
  29. ostk/astrodynamics/test/dynamics/test_tabulated.py +138 -0
  30. ostk/astrodynamics/test/dynamics/test_third_body_gravity.py +67 -0
  31. ostk/astrodynamics/test/dynamics/test_thruster.py +142 -0
  32. ostk/astrodynamics/test/event_condition/test_angular_condition.py +113 -0
  33. ostk/astrodynamics/test/event_condition/test_boolean_condition.py +55 -0
  34. ostk/astrodynamics/test/event_condition/test_coe_condition.py +87 -0
  35. ostk/astrodynamics/test/event_condition/test_instant_condition.py +48 -0
  36. ostk/astrodynamics/test/event_condition/test_logical_condition.py +120 -0
  37. ostk/astrodynamics/test/event_condition/test_real_condition.py +50 -0
  38. ostk/astrodynamics/test/flight/__init__.py +1 -0
  39. ostk/astrodynamics/test/flight/system/__init__.py +1 -0
  40. ostk/astrodynamics/test/flight/system/test_propulsion_system.py +73 -0
  41. ostk/astrodynamics/test/flight/system/test_satellite_system.py +91 -0
  42. ostk/astrodynamics/test/flight/system/test_satellite_system_builder.py +71 -0
  43. ostk/astrodynamics/test/flight/test_maneuver.py +212 -0
  44. ostk/astrodynamics/test/flight/test_profile.py +153 -0
  45. ostk/astrodynamics/test/flight/test_system.py +55 -0
  46. ostk/astrodynamics/test/guidance_law/test_constant_thrust.py +91 -0
  47. ostk/astrodynamics/test/guidance_law/test_qlaw.py +138 -0
  48. ostk/astrodynamics/test/solvers/__init__.py +1 -0
  49. ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +181 -0
  50. ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +153 -0
  51. ostk/astrodynamics/test/test_access.py +128 -0
  52. ostk/astrodynamics/test/test_converters.py +387 -0
  53. ostk/astrodynamics/test/test_display.py +115 -0
  54. ostk/astrodynamics/test/test_event_condition.py +58 -0
  55. ostk/astrodynamics/test/test_import.py +26 -0
  56. ostk/astrodynamics/test/test_root_solver.py +70 -0
  57. ostk/astrodynamics/test/test_trajectory.py +40 -0
  58. ostk/astrodynamics/test/test_utilities.py +121 -0
  59. ostk/astrodynamics/test/test_viewer.py +129 -0
  60. ostk/astrodynamics/test/trajectory/__init__.py +1 -0
  61. ostk/astrodynamics/test/trajectory/orbit/__init__.py +1 -0
  62. ostk/astrodynamics/test/trajectory/orbit/message/__init__.py +1 -0
  63. ostk/astrodynamics/test/trajectory/orbit/message/spacex/__init__.py +1 -0
  64. ostk/astrodynamics/test/trajectory/orbit/message/spacex/conftest.py +18 -0
  65. ostk/astrodynamics/test/trajectory/orbit/message/spacex/data/opm_1.yaml +44 -0
  66. ostk/astrodynamics/test/trajectory/orbit/message/spacex/test_opm.py +108 -0
  67. ostk/astrodynamics/test/trajectory/orbit/models/__init__.py +1 -0
  68. ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py +1 -0
  69. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py +65 -0
  70. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py +102 -0
  71. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py +102 -0
  72. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py +167 -0
  73. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +1 -0
  74. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +331 -0
  75. ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +130 -0
  76. ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +234 -0
  77. ostk/astrodynamics/test/trajectory/orbit/models/test_sgp4.py +1 -0
  78. ostk/astrodynamics/test/trajectory/orbit/models/test_tabulated.py +380 -0
  79. ostk/astrodynamics/test/trajectory/orbit/test_model.py +1 -0
  80. ostk/astrodynamics/test/trajectory/orbit/test_pass.py +72 -0
  81. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity.py +30 -0
  82. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py +18 -0
  83. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py +107 -0
  84. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py +115 -0
  85. ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py +84 -0
  86. ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py +46 -0
  87. ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +314 -0
  88. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py +81 -0
  89. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +76 -0
  90. ostk/astrodynamics/test/trajectory/test_model.py +1 -0
  91. ostk/astrodynamics/test/trajectory/test_orbit.py +174 -0
  92. ostk/astrodynamics/test/trajectory/test_propagator.py +458 -0
  93. ostk/astrodynamics/test/trajectory/test_segment.py +305 -0
  94. ostk/astrodynamics/test/trajectory/test_sequence.py +477 -0
  95. ostk/astrodynamics/test/trajectory/test_state.py +237 -0
  96. ostk/astrodynamics/test/trajectory/test_state_builder.py +171 -0
  97. ostk/astrodynamics/utilities.py +158 -0
  98. ostk/astrodynamics/viewer.py +392 -0
@@ -0,0 +1,387 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from datetime import datetime, timedelta, timezone
6
+
7
+ import numpy as np
8
+
9
+ from ostk.mathematics.geometry.d3.transformation.rotation import Quaternion
10
+
11
+ from ostk.physics.time import Instant
12
+ from ostk.physics.time import Interval
13
+ from ostk.physics.time import Duration
14
+ from ostk.physics.time import DateTime
15
+ from ostk.physics.time import Scale
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.converters import coerce_to_datetime
21
+ from ostk.astrodynamics.converters import coerce_to_instant
22
+ from ostk.astrodynamics.converters import coerce_to_iso
23
+ from ostk.astrodynamics.converters import coerce_to_interval
24
+ from ostk.astrodynamics.converters import coerce_to_duration
25
+ from ostk.astrodynamics.converters import coerce_to_position
26
+ from ostk.astrodynamics.converters import coerce_to_velocity
27
+ from ostk.astrodynamics.converters import coerce_to_quaternion
28
+
29
+
30
+ def test_coerce_to_datetime_success_instant():
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
+ )
40
+
41
+
42
+ def test_coerce_to_datetime_success_datetime():
43
+ value = datetime(2020, 1, 2, 3, 4, 5, 123456, tzinfo=timezone.utc)
44
+ assert coerce_to_datetime(value) == value
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
+
82
+
83
+ def test_coerce_to_instant_success_datetime():
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
+ )
92
+ assert coerce_to_instant(value) == Instant.date_time(
93
+ DateTime(2020, 1, 2, 2, 4, 5, 123, 456), Scale.UTC
94
+ )
95
+
96
+
97
+ def test_coerce_to_instant_success_instant():
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)
102
+ assert coerce_to_instant(value) == value
103
+
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
+
256
+ def test_coerce_to_interval_success_interval():
257
+ value = Interval.closed(
258
+ Instant.date_time(DateTime(2020, 1, 1), Scale.UTC),
259
+ Instant.date_time(DateTime(2020, 1, 2), Scale.UTC),
260
+ )
261
+ assert coerce_to_interval(value) == value
262
+
263
+
264
+ def test_coerce_to_interval_success_tuple_instant():
265
+ value = (
266
+ Instant.date_time(DateTime(2020, 1, 1), Scale.UTC),
267
+ Instant.date_time(DateTime(2020, 1, 2), Scale.UTC),
268
+ )
269
+ assert coerce_to_interval(value) == Interval.closed(
270
+ Instant.date_time(DateTime(2020, 1, 1), Scale.UTC),
271
+ Instant.date_time(DateTime(2020, 1, 2), Scale.UTC),
272
+ )
273
+
274
+
275
+ def test_coerce_to_interval_success_list_instant():
276
+ value = [
277
+ Instant.date_time(DateTime(2020, 1, 1), Scale.UTC),
278
+ Instant.date_time(DateTime(2020, 1, 2), Scale.UTC),
279
+ ]
280
+ assert coerce_to_interval(value) == Interval.closed(
281
+ Instant.date_time(DateTime(2020, 1, 1), Scale.UTC),
282
+ Instant.date_time(DateTime(2020, 1, 2), Scale.UTC),
283
+ )
284
+
285
+
286
+ def test_coerce_to_interval_success_tuple_datetime():
287
+ value = (
288
+ datetime(2020, 1, 1, tzinfo=timezone.utc),
289
+ datetime(2020, 1, 2, tzinfo=timezone.utc),
290
+ )
291
+ assert coerce_to_interval(value) == Interval.closed(
292
+ Instant.date_time(DateTime(2020, 1, 1), Scale.UTC),
293
+ Instant.date_time(DateTime(2020, 1, 2), Scale.UTC),
294
+ )
295
+
296
+
297
+ def test_coerce_to_interval_success_list_datetime():
298
+ value = [
299
+ datetime(2020, 1, 1, tzinfo=timezone.utc),
300
+ datetime(2020, 1, 2, tzinfo=timezone.utc),
301
+ ]
302
+ assert coerce_to_interval(value) == Interval.closed(
303
+ Instant.date_time(DateTime(2020, 1, 1), Scale.UTC),
304
+ Instant.date_time(DateTime(2020, 1, 2), Scale.UTC),
305
+ )
306
+
307
+
308
+ def test_coerce_to_duration_success_duration():
309
+ value = Duration.seconds(1.0)
310
+ assert coerce_to_duration(value) == value
311
+
312
+
313
+ def test_coerce_to_duration_success_timedelta():
314
+ value = timedelta(seconds=1.0)
315
+ assert coerce_to_duration(value) == Duration.seconds(1.0)
316
+
317
+
318
+ def test_coerce_to_position_success_position():
319
+ value = Position.meters((1.0, 2.0, 3.0), Frame.GCRF())
320
+ assert coerce_to_position(value, Frame.GCRF()) == value
321
+
322
+
323
+ def test_coerce_to_position_success_tuple_float():
324
+ value = (1.0, 2.0, 3.0)
325
+ assert coerce_to_position(value, Frame.GCRF()) == Position.meters(
326
+ (1.0, 2.0, 3.0), Frame.GCRF()
327
+ )
328
+
329
+
330
+ def test_coerce_to_position_success_list_float():
331
+ value = [1.0, 2.0, 3.0]
332
+ assert coerce_to_position(value, Frame.GCRF()) == Position.meters(
333
+ (1.0, 2.0, 3.0), Frame.GCRF()
334
+ )
335
+
336
+
337
+ def test_coerce_to_position_success_np_array():
338
+ value = np.array((1.0, 2.0, 3.0))
339
+ assert coerce_to_position(value, Frame.GCRF()) == Position.meters(
340
+ (1.0, 2.0, 3.0), Frame.GCRF()
341
+ )
342
+
343
+
344
+ def test_coerce_to_velocity_success_velocity():
345
+ value = Velocity.meters_per_second((1.0, 2.0, 3.0), Frame.GCRF())
346
+ assert coerce_to_velocity(value, Frame.GCRF()) == value
347
+
348
+
349
+ def test_coerce_to_velocity_success_tuple_float():
350
+ value = (1.0, 2.0, 3.0)
351
+ assert coerce_to_velocity(value, Frame.GCRF()) == Velocity.meters_per_second(
352
+ (1.0, 2.0, 3.0), Frame.GCRF()
353
+ )
354
+
355
+
356
+ def test_coerce_to_velocity_success_list_float():
357
+ value = [1.0, 2.0, 3.0]
358
+ assert coerce_to_velocity(value, Frame.GCRF()) == Velocity.meters_per_second(
359
+ (1.0, 2.0, 3.0), Frame.GCRF()
360
+ )
361
+
362
+
363
+ def test_coerce_to_velocity_success_np_array():
364
+ value = np.array((1.0, 2.0, 3.0))
365
+ assert coerce_to_velocity(value, Frame.GCRF()) == Velocity.meters_per_second(
366
+ (1.0, 2.0, 3.0), Frame.GCRF()
367
+ )
368
+
369
+
370
+ def test_coerce_to_quaternion_success_quaternion():
371
+ value = Quaternion.xyzs(1.0, 2.0, 3.0, 4.0)
372
+ assert coerce_to_quaternion(value) == value
373
+
374
+
375
+ def test_coerce_to_quaternion_success_list_float():
376
+ value = [1.0, 2.0, 3.0, 4.0]
377
+ assert coerce_to_quaternion(value) == Quaternion.xyzs(1.0, 2.0, 3.0, 4.0)
378
+
379
+
380
+ def test_coerce_to_quaternion_success_np_array():
381
+ value = np.array((1.0, 2.0, 3.0, 4.0))
382
+ assert coerce_to_quaternion(value) == Quaternion.xyzs(1.0, 2.0, 3.0, 4.0)
383
+
384
+
385
+ def test_coerce_to_quaternion_success_tuple_float():
386
+ value = (1.0, 2.0, 3.0, 4.0)
387
+ assert coerce_to_quaternion(value) == Quaternion.xyzs(1.0, 2.0, 3.0, 4.0)
@@ -0,0 +1,115 @@
1
+ # Apache License 2.0
2
+
3
+ from ostk.mathematics.object import RealInterval
4
+
5
+ from ostk.physics import Environment
6
+ from ostk.physics.coordinate import Position
7
+ from ostk.physics.coordinate import Frame
8
+ from ostk.physics.coordinate.spherical import LLA
9
+ from ostk.physics.environment.object import Celestial
10
+ from ostk.physics.time import DateTime
11
+ from ostk.physics.time import Duration
12
+ from ostk.physics.time import Instant
13
+ from ostk.physics.time import Interval
14
+ from ostk.physics.time import Scale
15
+ from ostk.physics.unit import Length
16
+ from ostk.physics.unit import Angle
17
+
18
+ from ostk.astrodynamics import Trajectory
19
+ from ostk.astrodynamics import display
20
+ from ostk.astrodynamics.access import Generator as AccessGenerator
21
+ from ostk.astrodynamics.trajectory import Orbit
22
+ from ostk.astrodynamics.trajectory import State
23
+ from ostk.astrodynamics.trajectory.orbit.model import SGP4
24
+ from ostk.astrodynamics.trajectory.orbit.model.sgp4 import TLE
25
+
26
+
27
+ class TestDisplay:
28
+ def test_accesses_plot(self, state: State):
29
+ start_instant: Instant = Instant.date_time(
30
+ DateTime(2023, 1, 3, 0, 0, 0),
31
+ Scale.UTC,
32
+ )
33
+ duration: Duration = Duration.days(7.0)
34
+ step: Duration = Duration.seconds(10.0)
35
+ tolerance: Duration = Duration.seconds(1.0)
36
+
37
+ ground_station_lla: LLA = LLA(
38
+ Angle.degrees(70.0),
39
+ Angle.degrees(160.0),
40
+ Length.meters(0.0),
41
+ )
42
+
43
+ tle_1 = TLE(
44
+ "1 55076U 23001BV 23146.17959645 .00004328 00000-0 23719-3 0 9993",
45
+ "2 55076 97.4793 205.9529 0016244 89.9523 270.3571 15.14609100 21723",
46
+ )
47
+
48
+ tle_2 = TLE(
49
+ "1 48915U 21059AN 23146.32782040 .00004955 00000-0 24678-3 0 9999",
50
+ "2 48915 97.5954 279.7041 0010303 354.9434 5.1694 15.18004448105867",
51
+ )
52
+
53
+ environment: Environment = Environment.default()
54
+ earth: Celestial = environment.access_celestial_object_with_name("Earth")
55
+
56
+ ground_station_trajectory: Trajectory = Trajectory.position(
57
+ Position.meters(
58
+ ground_station_lla.to_cartesian(
59
+ earth.get_equatorial_radius(),
60
+ earth.get_flattening(),
61
+ ),
62
+ Frame.ITRF(),
63
+ ),
64
+ )
65
+
66
+ stop_instant: Instant = start_instant + duration
67
+ search_interval: RealInterval = Interval.closed(start_instant, stop_instant)
68
+
69
+ orbit_1: Orbit = Orbit(SGP4(tle_1), earth)
70
+ orbit_2: Orbit = Orbit(SGP4(tle_2), earth)
71
+
72
+ generator = AccessGenerator(
73
+ environment=environment,
74
+ step=step,
75
+ tolerance=tolerance,
76
+ )
77
+
78
+ accesses_1 = generator.compute_accesses(
79
+ interval=search_interval,
80
+ from_trajectory=ground_station_trajectory,
81
+ to_trajectory=orbit_1,
82
+ )
83
+
84
+ assert len(accesses_1) > 0
85
+
86
+ accesses_2 = generator.compute_accesses(
87
+ interval=search_interval,
88
+ from_trajectory=ground_station_trajectory,
89
+ to_trajectory=orbit_2,
90
+ )
91
+
92
+ assert len(accesses_2) > 0
93
+
94
+ accesses_plot = display.AccessesPlot(
95
+ earth=earth,
96
+ interval=search_interval,
97
+ trajectory_step=Duration.minutes(5.0),
98
+ access_step=Duration.seconds(10.0),
99
+ ground_station_lla=ground_station_lla,
100
+ color="green",
101
+ )
102
+
103
+ accesses_plot.add_satellite(
104
+ trajectory=orbit_1,
105
+ accesses=accesses_1,
106
+ rgb=[180, 0, 0],
107
+ )
108
+
109
+ accesses_plot.add_satellite(
110
+ trajectory=orbit_2,
111
+ accesses=accesses_2,
112
+ rgb=[0, 0, 180],
113
+ )
114
+
115
+ accesses_plot.show()
@@ -0,0 +1,58 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.astrodynamics import EventCondition
6
+
7
+
8
+ @pytest.fixture
9
+ def name() -> str:
10
+ return "MyEvent"
11
+
12
+
13
+ @pytest.fixture
14
+ def evaluator() -> callable:
15
+ return lambda state: 0.0
16
+
17
+
18
+ @pytest.fixture
19
+ def target_value() -> float:
20
+ return 0.0
21
+
22
+
23
+ @pytest.fixture
24
+ def target(target_value: float) -> EventCondition.Target:
25
+ return EventCondition.Target(target_value, EventCondition.Target.Type.Absolute)
26
+
27
+
28
+ @pytest.fixture
29
+ def event_condition(
30
+ name: str, evaluator: callable, target: EventCondition.Target
31
+ ) -> EventCondition:
32
+ class MyEventCondition(EventCondition):
33
+ def is_satisfied(
34
+ self,
35
+ current_state_vector,
36
+ current_time,
37
+ previous_state_vector,
38
+ previous_time,
39
+ ):
40
+ return current_state_vector[0] > 0.0 and previous_state_vector[0] < 0.0
41
+
42
+ return MyEventCondition(name, evaluator, target)
43
+
44
+
45
+ class TestEventCondition:
46
+ def test_subclass(self, event_condition: EventCondition):
47
+ assert event_condition is not None
48
+
49
+ def test_get_name(self, event_condition: EventCondition, name: str):
50
+ assert event_condition.get_name() == name
51
+
52
+ def test_get_evaluator(self, event_condition: EventCondition):
53
+ assert event_condition.get_evaluator() is not None
54
+
55
+ def test_get_target(
56
+ self, event_condition: EventCondition, target: EventCondition.Target
57
+ ):
58
+ assert event_condition.get_target() == target
@@ -0,0 +1,26 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+
6
+ class TestImport:
7
+ def test_import(self):
8
+ from ostk.astrodynamics import Trajectory
9
+ from ostk.astrodynamics.trajectory import State
10
+ from ostk.astrodynamics.trajectory import Orbit
11
+ from ostk.astrodynamics.trajectory import Model
12
+ from ostk.astrodynamics.trajectory.orbit import Pass
13
+ from ostk.astrodynamics.trajectory.orbit.model import Kepler
14
+ from ostk.astrodynamics.trajectory.orbit.model.kepler import COE
15
+ from ostk.astrodynamics.trajectory.orbit.model import SGP4
16
+ from ostk.astrodynamics.trajectory.orbit.model.sgp4 import TLE
17
+ from ostk.astrodynamics.trajectory.orbit.model import Propagated
18
+ from ostk.astrodynamics.flight import Profile
19
+ from ostk.astrodynamics.flight import System
20
+ from ostk.astrodynamics.flight import Maneuver
21
+ from ostk.astrodynamics.flight.system import SatelliteSystem
22
+ from ostk.astrodynamics.dynamics import CentralBodyGravity
23
+ from ostk.astrodynamics.dynamics import AtmosphericDrag
24
+ from ostk.astrodynamics import Access
25
+ from ostk.astrodynamics.access import Generator
26
+ from ostk.astrodynamics.trajectory.state import NumericalSolver
@@ -0,0 +1,70 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.astrodynamics import RootSolver
6
+
7
+
8
+ def quadratic_function(x):
9
+ return x**2 - 4
10
+
11
+
12
+ @pytest.fixture
13
+ def maximum_iteration_count() -> int:
14
+ return 100
15
+
16
+
17
+ @pytest.fixture
18
+ def tolerance() -> float:
19
+ return 1e-15
20
+
21
+
22
+ @pytest.fixture
23
+ def root_solver(maximum_iteration_count: int, tolerance: float) -> RootSolver:
24
+ return RootSolver(maximum_iteration_count, tolerance)
25
+
26
+
27
+ class TestRootSolver:
28
+ def test_constructor(self, maximum_iteration_count: int, tolerance: float):
29
+ assert (
30
+ RootSolver(
31
+ maximum_iteration_count=maximum_iteration_count, tolerance=tolerance
32
+ )
33
+ is not None
34
+ )
35
+
36
+ def test_getters(
37
+ self,
38
+ root_solver: RootSolver,
39
+ maximum_iteration_count: int,
40
+ tolerance: float,
41
+ ):
42
+ assert root_solver.get_tolerance() == tolerance
43
+ assert root_solver.get_maximum_iteration_count() == maximum_iteration_count
44
+
45
+ def test_bracket_and_solve(self, root_solver):
46
+ solution = root_solver.bracket_and_solve(
47
+ function=quadratic_function,
48
+ initial_guess=1.0,
49
+ is_rising=True,
50
+ )
51
+ assert pytest.approx(solution.root, abs=1e-15) == 2.0
52
+
53
+ def test_solve(self, root_solver):
54
+ solution = root_solver.solve(
55
+ function=quadratic_function,
56
+ lower_bound=1.0,
57
+ upper_bound=3.0,
58
+ )
59
+ assert pytest.approx(solution.root, abs=1e-15) == 2.0
60
+
61
+ def test_bisection(self, root_solver):
62
+ solution = root_solver.bisection(
63
+ function=quadratic_function,
64
+ lower_bound=1.0,
65
+ upper_bound=3.0,
66
+ )
67
+ assert pytest.approx(solution.root, abs=1e-15) == 2.0
68
+
69
+ def test_default(self):
70
+ assert RootSolver.default() is not None
@@ -0,0 +1,40 @@
1
+ # Apache License 2.0
2
+
3
+ import ostk.mathematics as mathematics
4
+
5
+ import ostk.physics as physics
6
+
7
+ import ostk.astrodynamics as astrodynamics
8
+
9
+ RealInterval = mathematics.object.RealInterval
10
+ Quaternion = mathematics.geometry.d3.transformation.rotation.Quaternion
11
+ Length = physics.unit.Length
12
+ Angle = physics.unit.Angle
13
+ DateTime = physics.time.DateTime
14
+ Scale = physics.time.Scale
15
+ Duration = physics.time.Duration
16
+ Instant = physics.time.Instant
17
+ Transform = physics.coordinate.Transform
18
+ Frame = physics.coordinate.Frame
19
+ Axes = physics.coordinate.Axes
20
+ DynamicProvider = physics.coordinate.frame.provider.Dynamic
21
+ Environment = physics.Environment
22
+ Earth = physics.environment.object.celestial.Earth
23
+ Trajectory = astrodynamics.Trajectory
24
+ Profile = astrodynamics.flight.Profile
25
+ SatelliteSystem = astrodynamics.flight.system.SatelliteSystem
26
+ Orbit = astrodynamics.trajectory.Orbit
27
+ State = astrodynamics.trajectory.State
28
+ Pass = astrodynamics.trajectory.orbit.Pass
29
+ Kepler = astrodynamics.trajectory.orbit.model.Kepler
30
+ COE = astrodynamics.trajectory.orbit.model.kepler.COE
31
+ SGP4 = astrodynamics.trajectory.orbit.model.sgp4
32
+ Access = astrodynamics.Access
33
+
34
+
35
+ def test_trajectory_undefined():
36
+ trajectory: Trajectory = Trajectory.undefined()
37
+
38
+ assert trajectory is not None
39
+ assert isinstance(trajectory, Trajectory)
40
+ assert trajectory.is_defined() is False