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
@@ -0,0 +1,416 @@
|
|
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 File
|
9
|
+
|
10
|
+
from ostk.physics.units import Length
|
11
|
+
from ostk.physics.units import Mass
|
12
|
+
from ostk.physics.time import Instant
|
13
|
+
from ostk.physics.time import Scale
|
14
|
+
from ostk.physics.time import Duration
|
15
|
+
from ostk.physics.coordinate import Frame
|
16
|
+
from ostk.physics.coordinate import Position
|
17
|
+
from ostk.physics.coordinate import Velocity
|
18
|
+
|
19
|
+
from ostk.astrodynamics.trajectory import State
|
20
|
+
from ostk.astrodynamics.conjunction.messages.ccsds import CDM
|
21
|
+
|
22
|
+
|
23
|
+
@pytest.fixture
|
24
|
+
def cdm() -> CDM:
|
25
|
+
return CDM(
|
26
|
+
header=CDM.Header(
|
27
|
+
ccsds_cdm_version="1.0",
|
28
|
+
creation_date=Instant.date_time(datetime(2010, 3, 12, 22, 31, 12), Scale.UTC),
|
29
|
+
originator="JSPOC",
|
30
|
+
message_for="SATELLITE A",
|
31
|
+
message_id="201113719185",
|
32
|
+
),
|
33
|
+
relative_metadata=CDM.RelativeMetadata(
|
34
|
+
comment="",
|
35
|
+
time_of_closest_approach=Instant.date_time(
|
36
|
+
datetime(2010, 3, 13, 22, 37, 52, 618), Scale.UTC
|
37
|
+
),
|
38
|
+
miss_distance=Length.meters(715.0),
|
39
|
+
start_screen_period=Instant.date_time(
|
40
|
+
datetime(2010, 3, 12, 18, 29, 32, 212), Scale.UTC
|
41
|
+
),
|
42
|
+
end_screen_period=Instant.date_time(
|
43
|
+
datetime(2010, 3, 15, 18, 29, 32, 212), Scale.UTC
|
44
|
+
),
|
45
|
+
screen_volume_frame="RTN",
|
46
|
+
screen_volume_shape="ELLIPSOID",
|
47
|
+
screen_volume_x=200.0,
|
48
|
+
screen_volume_y=1000.0,
|
49
|
+
screen_volume_z=1000.0,
|
50
|
+
screen_entry_time=Instant.date_time(
|
51
|
+
datetime(2010, 3, 13, 22, 37, 52, 222), Scale.UTC
|
52
|
+
),
|
53
|
+
screen_exit_time=Instant.date_time(
|
54
|
+
datetime(2010, 3, 13, 22, 37, 52, 824), Scale.UTC
|
55
|
+
),
|
56
|
+
collision_probability=0.0000435,
|
57
|
+
collision_probability_method="FOSTER-1992",
|
58
|
+
),
|
59
|
+
objects_metadata_array=[
|
60
|
+
CDM.Metadata(
|
61
|
+
comment="",
|
62
|
+
object="OBJECT1",
|
63
|
+
object_designator=12345,
|
64
|
+
catalog_name="SATCAT",
|
65
|
+
object_name="SATELLITE A",
|
66
|
+
international_designator="1997−030E",
|
67
|
+
object_type=CDM.ObjectType.Payload,
|
68
|
+
operator_contact_position="OSA",
|
69
|
+
operator_organization="EUTMETSAT",
|
70
|
+
operator_phone="+49615130312",
|
71
|
+
operator_email="JOHN.DOE@SOMEWHERE.NET",
|
72
|
+
ephemeris_name="EPHEMERIS SATELLITE A",
|
73
|
+
covariance_method="CALCULATED",
|
74
|
+
maneuverable="YES",
|
75
|
+
orbit_center="",
|
76
|
+
reference_frame="EME2000",
|
77
|
+
gravity_model="EGM-96: 36D 36O",
|
78
|
+
atmospheric_model="JACCHIA 70 DCA",
|
79
|
+
n_body_perturbations="MOON, SUN",
|
80
|
+
solar_radiation_pressure=False,
|
81
|
+
earth_tides=False,
|
82
|
+
in_track_thrust=False,
|
83
|
+
),
|
84
|
+
CDM.Metadata(
|
85
|
+
object="OBJECT2",
|
86
|
+
object_designator=12346,
|
87
|
+
catalog_name="SATCAT",
|
88
|
+
object_name="SATELLITE B",
|
89
|
+
international_designator="1997−030F",
|
90
|
+
object_type=CDM.ObjectType.Payload,
|
91
|
+
ephemeris_name="EPHEMERIS SATELLITE B",
|
92
|
+
covariance_method="CALCULATED",
|
93
|
+
maneuverable="YES",
|
94
|
+
reference_frame="EME2000",
|
95
|
+
),
|
96
|
+
],
|
97
|
+
objects_data_array=[
|
98
|
+
CDM.Data(
|
99
|
+
time_last_observation_start=Instant.date_time(
|
100
|
+
datetime(2010, 3, 12, 2, 14, 12, 746), Scale.UTC
|
101
|
+
),
|
102
|
+
time_last_observation_end=Instant.date_time(
|
103
|
+
datetime(2010, 3, 12, 2, 14, 12, 746), Scale.UTC
|
104
|
+
),
|
105
|
+
recommended_od_span=Duration.days(7.88),
|
106
|
+
actual_od_span=Duration.days(5.50),
|
107
|
+
observations_available=592,
|
108
|
+
observations_used=579,
|
109
|
+
tracks_available=123,
|
110
|
+
tracks_used=119,
|
111
|
+
residuals_accepted=97.8,
|
112
|
+
weighted_rms=0.864,
|
113
|
+
area_pc=5.2,
|
114
|
+
area_drag=0.0,
|
115
|
+
area_srp=0.0,
|
116
|
+
mass=Mass.kilograms(251.6),
|
117
|
+
cd_area_over_mass=0.0,
|
118
|
+
cr_area_over_mass=0.0,
|
119
|
+
thrust_acceleration=0.0,
|
120
|
+
sedr=0.0,
|
121
|
+
),
|
122
|
+
CDM.Data(
|
123
|
+
time_last_observation_start=Instant.date_time(
|
124
|
+
datetime(2010, 3, 12, 2, 14, 12, 746), Scale.UTC
|
125
|
+
),
|
126
|
+
time_last_observation_end=Instant.date_time(
|
127
|
+
datetime(2010, 3, 12, 2, 14, 12, 746), Scale.UTC
|
128
|
+
),
|
129
|
+
recommended_od_span=Duration.days(7.88),
|
130
|
+
actual_od_span=Duration.days(5.50),
|
131
|
+
observations_available=592,
|
132
|
+
observations_used=579,
|
133
|
+
tracks_available=123,
|
134
|
+
tracks_used=119,
|
135
|
+
residuals_accepted=97.8,
|
136
|
+
weighted_rms=0.864,
|
137
|
+
area_pc=5.2,
|
138
|
+
area_drag=0.0,
|
139
|
+
area_srp=0.0,
|
140
|
+
mass=Mass.kilograms(251.6),
|
141
|
+
cd_area_over_mass=0.0,
|
142
|
+
cr_area_over_mass=0.0,
|
143
|
+
thrust_acceleration=0.0,
|
144
|
+
sedr=0.0,
|
145
|
+
),
|
146
|
+
],
|
147
|
+
)
|
148
|
+
|
149
|
+
|
150
|
+
class TestCDM:
|
151
|
+
def test_constructor(self, cdm: CDM):
|
152
|
+
assert cdm is not None
|
153
|
+
|
154
|
+
def test_get_header(self, cdm: CDM):
|
155
|
+
cdm_header: CDM.Header = cdm.get_header()
|
156
|
+
|
157
|
+
assert cdm_header is not None
|
158
|
+
assert cdm_header.ccsds_cdm_version == "1.0"
|
159
|
+
assert cdm_header.creation_date == Instant.date_time(
|
160
|
+
datetime(2010, 3, 12, 22, 31, 12), Scale.UTC
|
161
|
+
)
|
162
|
+
assert cdm_header.originator == "JSPOC"
|
163
|
+
assert cdm_header.message_for == "SATELLITE A"
|
164
|
+
assert cdm_header.message_id == "201113719185"
|
165
|
+
|
166
|
+
def test_get_relative_metadata(self, cdm: CDM):
|
167
|
+
cdm_relative_metadata: CDM.RelativeMetadata = cdm.get_relative_metadata()
|
168
|
+
|
169
|
+
assert cdm_relative_metadata is not None
|
170
|
+
assert cdm_relative_metadata.comment == ""
|
171
|
+
assert cdm_relative_metadata.time_of_closest_approach == Instant.date_time(
|
172
|
+
datetime(2010, 3, 13, 22, 37, 52, 618), Scale.UTC
|
173
|
+
)
|
174
|
+
assert cdm_relative_metadata.miss_distance == Length.meters(715.0)
|
175
|
+
assert cdm_relative_metadata.start_screen_period == Instant.date_time(
|
176
|
+
datetime(2010, 3, 12, 18, 29, 32, 212), Scale.UTC
|
177
|
+
)
|
178
|
+
assert cdm_relative_metadata.end_screen_period == Instant.date_time(
|
179
|
+
datetime(2010, 3, 15, 18, 29, 32, 212), Scale.UTC
|
180
|
+
)
|
181
|
+
assert cdm_relative_metadata.screen_volume_frame == "RTN"
|
182
|
+
assert cdm_relative_metadata.screen_volume_shape == "ELLIPSOID"
|
183
|
+
assert cdm_relative_metadata.screen_volume_x == 200.0
|
184
|
+
assert cdm_relative_metadata.screen_volume_y == 1000.0
|
185
|
+
assert cdm_relative_metadata.screen_volume_z == 1000.0
|
186
|
+
assert cdm_relative_metadata.screen_entry_time == Instant.date_time(
|
187
|
+
datetime(2010, 3, 13, 22, 37, 52, 222), Scale.UTC
|
188
|
+
)
|
189
|
+
assert cdm_relative_metadata.screen_exit_time == Instant.date_time(
|
190
|
+
datetime(2010, 3, 13, 22, 37, 52, 824), Scale.UTC
|
191
|
+
)
|
192
|
+
assert cdm_relative_metadata.collision_probability == 0.0000435
|
193
|
+
assert cdm_relative_metadata.collision_probability_method == "FOSTER-1992"
|
194
|
+
|
195
|
+
def test_get_metadata_array(self, cdm: CDM):
|
196
|
+
assert cdm.get_metadata_array() is not None
|
197
|
+
assert len(cdm.get_metadata_array()) == 2
|
198
|
+
|
199
|
+
def test_get_data_array(self, cdm: CDM):
|
200
|
+
assert cdm.get_data_array() is not None
|
201
|
+
assert len(cdm.get_data_array()) == 2
|
202
|
+
|
203
|
+
def test_get_object_metadata_at(self, cdm: CDM):
|
204
|
+
assert cdm.get_object_metadata_at(0) is not None
|
205
|
+
assert cdm.get_object_metadata_at(1) is not None
|
206
|
+
|
207
|
+
cdm_object_1_metadata: CDM.Metadata = cdm.get_object_metadata_at(0)
|
208
|
+
|
209
|
+
assert cdm_object_1_metadata.comment == ""
|
210
|
+
assert cdm_object_1_metadata.object == "OBJECT1"
|
211
|
+
assert cdm_object_1_metadata.object_designator == 12345
|
212
|
+
assert cdm_object_1_metadata.catalog_name == "SATCAT"
|
213
|
+
assert cdm_object_1_metadata.object_name == "SATELLITE A"
|
214
|
+
assert cdm_object_1_metadata.international_designator == "1997−030E"
|
215
|
+
assert cdm_object_1_metadata.object_type == CDM.ObjectType.Payload
|
216
|
+
assert cdm_object_1_metadata.operator_contact_position == "OSA"
|
217
|
+
assert cdm_object_1_metadata.operator_organization == "EUTMETSAT"
|
218
|
+
assert cdm_object_1_metadata.operator_phone == "+49615130312"
|
219
|
+
assert cdm_object_1_metadata.operator_email == "JOHN.DOE@SOMEWHERE.NET"
|
220
|
+
assert cdm_object_1_metadata.ephemeris_name == "EPHEMERIS SATELLITE A"
|
221
|
+
assert cdm_object_1_metadata.covariance_method == "CALCULATED"
|
222
|
+
assert cdm_object_1_metadata.maneuverable == "YES"
|
223
|
+
assert cdm_object_1_metadata.orbit_center == ""
|
224
|
+
assert cdm_object_1_metadata.reference_frame == "EME2000"
|
225
|
+
assert cdm_object_1_metadata.gravity_model == "EGM-96: 36D 36O"
|
226
|
+
assert cdm_object_1_metadata.atmospheric_model == "JACCHIA 70 DCA"
|
227
|
+
assert cdm_object_1_metadata.n_body_perturbations == "MOON, SUN"
|
228
|
+
assert cdm_object_1_metadata.solar_radiation_pressure == False
|
229
|
+
assert cdm_object_1_metadata.earth_tides == False
|
230
|
+
assert cdm_object_1_metadata.in_track_thrust == False
|
231
|
+
|
232
|
+
cdm_object_2_metadata: CDM.Metadata = cdm.get_object_metadata_at(1)
|
233
|
+
|
234
|
+
assert cdm_object_2_metadata.comment == ""
|
235
|
+
assert cdm_object_2_metadata.object == "OBJECT2"
|
236
|
+
assert cdm_object_2_metadata.object_designator == 12346
|
237
|
+
assert cdm_object_2_metadata.catalog_name == "SATCAT"
|
238
|
+
assert cdm_object_2_metadata.object_name == "SATELLITE B"
|
239
|
+
assert cdm_object_2_metadata.international_designator == "1997−030F"
|
240
|
+
assert cdm_object_2_metadata.object_type == CDM.ObjectType.Payload
|
241
|
+
assert cdm_object_2_metadata.operator_contact_position == ""
|
242
|
+
assert cdm_object_2_metadata.operator_organization == ""
|
243
|
+
assert cdm_object_2_metadata.operator_phone == ""
|
244
|
+
assert cdm_object_2_metadata.operator_email == ""
|
245
|
+
assert cdm_object_2_metadata.ephemeris_name == "EPHEMERIS SATELLITE B"
|
246
|
+
assert cdm_object_2_metadata.covariance_method == "CALCULATED"
|
247
|
+
assert cdm_object_2_metadata.maneuverable == "YES"
|
248
|
+
assert cdm_object_2_metadata.orbit_center == ""
|
249
|
+
assert cdm_object_2_metadata.reference_frame == "EME2000"
|
250
|
+
assert cdm_object_2_metadata.gravity_model == ""
|
251
|
+
assert cdm_object_2_metadata.atmospheric_model == ""
|
252
|
+
assert cdm_object_2_metadata.n_body_perturbations == ""
|
253
|
+
assert cdm_object_2_metadata.solar_radiation_pressure == False
|
254
|
+
assert cdm_object_2_metadata.earth_tides == False
|
255
|
+
assert cdm_object_2_metadata.in_track_thrust == False
|
256
|
+
|
257
|
+
with pytest.raises(Exception) as e:
|
258
|
+
cdm.get_object_metadata_at(2)
|
259
|
+
|
260
|
+
def test_get_object_data_at(self, cdm: CDM):
|
261
|
+
assert cdm.get_object_data_at(0) is not None
|
262
|
+
assert cdm.get_object_data_at(1) is not None
|
263
|
+
|
264
|
+
cdm_object_1_data: CDM.Data = cdm.get_object_data_at(0)
|
265
|
+
|
266
|
+
assert cdm_object_1_data.time_last_observation_start == Instant.date_time(
|
267
|
+
datetime(2010, 3, 12, 2, 14, 12, 746), Scale.UTC
|
268
|
+
)
|
269
|
+
assert cdm_object_1_data.time_last_observation_end == Instant.date_time(
|
270
|
+
datetime(2010, 3, 12, 2, 14, 12, 746), Scale.UTC
|
271
|
+
)
|
272
|
+
assert cdm_object_1_data.recommended_od_span == Duration.days(7.88)
|
273
|
+
assert cdm_object_1_data.actual_od_span == Duration.days(5.50)
|
274
|
+
assert cdm_object_1_data.observations_available == 592
|
275
|
+
assert cdm_object_1_data.observations_used == 579
|
276
|
+
assert cdm_object_1_data.tracks_available == 123
|
277
|
+
assert cdm_object_1_data.tracks_used == 119
|
278
|
+
assert cdm_object_1_data.residuals_accepted == 97.8
|
279
|
+
assert cdm_object_1_data.weighted_rms == 0.864
|
280
|
+
assert cdm_object_1_data.area_pc == 5.2
|
281
|
+
assert cdm_object_1_data.area_drag == 0.0
|
282
|
+
assert cdm_object_1_data.area_srp == 0.0
|
283
|
+
assert cdm_object_1_data.mass == Mass.kilograms(251.6)
|
284
|
+
assert cdm_object_1_data.cd_area_over_mass == 0.0
|
285
|
+
assert cdm_object_1_data.cr_area_over_mass == 0.0
|
286
|
+
assert cdm_object_1_data.thrust_acceleration == 0.0
|
287
|
+
assert cdm_object_1_data.sedr == 0.0
|
288
|
+
|
289
|
+
cdm_object_2_data: CDM.Data = cdm.get_object_data_at(1)
|
290
|
+
|
291
|
+
assert cdm_object_2_data.time_last_observation_start == Instant.date_time(
|
292
|
+
datetime(2010, 3, 12, 2, 14, 12, 746), Scale.UTC
|
293
|
+
)
|
294
|
+
assert cdm_object_2_data.time_last_observation_end == Instant.date_time(
|
295
|
+
datetime(2010, 3, 12, 2, 14, 12, 746), Scale.UTC
|
296
|
+
)
|
297
|
+
assert cdm_object_2_data.recommended_od_span == Duration.days(7.88)
|
298
|
+
assert cdm_object_2_data.actual_od_span == Duration.days(5.50)
|
299
|
+
assert cdm_object_2_data.observations_available == 592
|
300
|
+
assert cdm_object_2_data.observations_used == 579
|
301
|
+
assert cdm_object_2_data.tracks_available == 123
|
302
|
+
assert cdm_object_2_data.tracks_used == 119
|
303
|
+
assert cdm_object_2_data.residuals_accepted == 97.8
|
304
|
+
assert cdm_object_2_data.weighted_rms == 0.864
|
305
|
+
assert cdm_object_2_data.area_pc == 5.2
|
306
|
+
assert cdm_object_2_data.area_drag == 0.0
|
307
|
+
assert cdm_object_2_data.area_srp == 0.0
|
308
|
+
assert cdm_object_2_data.mass == Mass.kilograms(251.6)
|
309
|
+
assert cdm_object_2_data.cd_area_over_mass == 0.0
|
310
|
+
assert cdm_object_2_data.cr_area_over_mass == 0.0
|
311
|
+
assert cdm_object_2_data.thrust_acceleration == 0.0
|
312
|
+
assert cdm_object_2_data.sedr == 0.0
|
313
|
+
|
314
|
+
with pytest.raises(Exception) as e:
|
315
|
+
cdm.get_object_data_at(2)
|
316
|
+
|
317
|
+
def test_get_ccsds_cdm_version(self, cdm: CDM):
|
318
|
+
assert cdm.get_ccsds_cdm_version() == "1.0"
|
319
|
+
|
320
|
+
def test_get_creation_instant(self, cdm: CDM):
|
321
|
+
assert cdm.get_creation_instant() == Instant.date_time(
|
322
|
+
datetime(2010, 3, 12, 22, 31, 12), Scale.UTC
|
323
|
+
)
|
324
|
+
|
325
|
+
def test_get_originator(self, cdm: CDM):
|
326
|
+
assert cdm.get_originator() == "JSPOC"
|
327
|
+
|
328
|
+
def test_get_message_for(self, cdm: CDM):
|
329
|
+
assert cdm.get_message_for() == "SATELLITE A"
|
330
|
+
|
331
|
+
def test_get_message_id(self, cdm: CDM):
|
332
|
+
assert cdm.get_message_id() == "201113719185"
|
333
|
+
|
334
|
+
def test_get_time_of_closest_approach(self, cdm: CDM):
|
335
|
+
assert cdm.get_time_of_closest_approach() == Instant.date_time(
|
336
|
+
datetime(2010, 3, 13, 22, 37, 52, 618), Scale.UTC
|
337
|
+
)
|
338
|
+
|
339
|
+
def test_get_miss_distance(self, cdm: CDM):
|
340
|
+
assert cdm.get_miss_distance() == Length.meters(715.0)
|
341
|
+
|
342
|
+
def test_get_relative_position(self, cdm: CDM):
|
343
|
+
assert cdm.get_relative_position().is_defined() is False
|
344
|
+
|
345
|
+
def test_get_relative_velocity(self, cdm: CDM):
|
346
|
+
assert cdm.get_relative_velocity().is_defined() is False
|
347
|
+
|
348
|
+
def test_get_collision_probability(self, cdm: CDM):
|
349
|
+
assert cdm.get_collision_probability() == 0.0000435
|
350
|
+
|
351
|
+
def test_get_collision_probability_method(self, cdm: CDM):
|
352
|
+
assert cdm.get_collision_probability_method() == "FOSTER-1992"
|
353
|
+
|
354
|
+
def test_undefined(self):
|
355
|
+
assert CDM.undefined().is_defined() is False
|
356
|
+
|
357
|
+
def test_dictionary(self, cdm_spacetrack_dictionary: dict):
|
358
|
+
dictionary = Dictionary(cdm_spacetrack_dictionary)
|
359
|
+
|
360
|
+
cdm: CDM = CDM.dictionary(dictionary)
|
361
|
+
|
362
|
+
assert cdm is not None
|
363
|
+
assert cdm.get_header() is not None
|
364
|
+
assert cdm.get_ccsds_cdm_version() == "1.0"
|
365
|
+
assert cdm.get_creation_instant() == Instant.date_time(
|
366
|
+
datetime(2022, 12, 25, 0, 33, 16), Scale.UTC
|
367
|
+
)
|
368
|
+
assert cdm.get_originator() == "CSpOC"
|
369
|
+
assert cdm.get_message_for() == "YAM-2"
|
370
|
+
assert cdm.get_message_id() == "406320986"
|
371
|
+
assert cdm.get_time_of_closest_approach() == Instant.date_time(
|
372
|
+
datetime(2022, 12, 27, 13, 28, 59, 516000), Scale.UTC
|
373
|
+
)
|
374
|
+
assert cdm.get_miss_distance() == Length.meters(974.0)
|
375
|
+
assert cdm.get_relative_position().is_defined() is False
|
376
|
+
assert cdm.get_relative_velocity().is_defined() is False
|
377
|
+
assert cdm.get_collision_probability() == 5.162516e-16
|
378
|
+
assert cdm.get_collision_probability_method() == "FOSTER-1992"
|
379
|
+
|
380
|
+
object_1_metadata: CDM.Metadata = cdm.get_object_metadata_at(0)
|
381
|
+
|
382
|
+
assert object_1_metadata.object == "OBJECT1"
|
383
|
+
assert object_1_metadata.object_designator == 48911
|
384
|
+
assert object_1_metadata.catalog_name == "SATCAT"
|
385
|
+
assert object_1_metadata.object_name == "YAM-2"
|
386
|
+
assert object_1_metadata.international_designator == "2021-059AJ"
|
387
|
+
assert object_1_metadata.object_type == CDM.ObjectType.Payload
|
388
|
+
assert object_1_metadata.ephemeris_name == "NONE"
|
389
|
+
assert object_1_metadata.covariance_method == "CALCULATED"
|
390
|
+
assert object_1_metadata.maneuverable == "N/A"
|
391
|
+
assert object_1_metadata.reference_frame == "ITRF"
|
392
|
+
|
393
|
+
# object_1_data: CDM.Data = cdm.get_object_data_at(0)
|
394
|
+
|
395
|
+
# assert object_1_data.state == State(
|
396
|
+
# Instant.date_time(datetime(2022, 12, 27, 13, 28, 59, 516000), Scale.UTC),
|
397
|
+
# Position.meters([-4988150.231999999844, -1691825.955000000075, -4469421.481999999844], Frame.ITRF()),
|
398
|
+
# Velocity.meters_per_second([-5122.248844000000, 54.300816000000, 5699.434412000000], Frame.ITRF())
|
399
|
+
# )
|
400
|
+
|
401
|
+
def test_parse(self, cdm_file: File):
|
402
|
+
with open(str(cdm_file.get_path().to_string()), "r") as stream:
|
403
|
+
assert CDM.parse(string=stream.read()) is not None
|
404
|
+
|
405
|
+
def test_load(self, cdm_file: File):
|
406
|
+
assert CDM.load(file=cdm_file) is not None
|
407
|
+
|
408
|
+
def test_object_type_from_string(self):
|
409
|
+
assert CDM.object_type_from_string("PAYLOAD") == CDM.ObjectType.Payload
|
410
|
+
assert CDM.object_type_from_string("ROCKET BODY") == CDM.ObjectType.RocketBody
|
411
|
+
assert CDM.object_type_from_string("DEBRIS") == CDM.ObjectType.Debris
|
412
|
+
assert CDM.object_type_from_string("UNKNOWN") == CDM.ObjectType.Unknown
|
413
|
+
assert CDM.object_type_from_string("OTHER") == CDM.ObjectType.Other
|
414
|
+
|
415
|
+
with pytest.raises(Exception) as e:
|
416
|
+
CDM.object_type_from_string("ANOTHERSUPPORTEDTYPE")
|
@@ -0,0 +1 @@
|
|
1
|
+
# Apache License 2.0
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# Apache License 2.0
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
import numpy as np
|
6
|
+
|
7
|
+
from ostk.mathematics.geometry.d3.objects import Cuboid
|
8
|
+
from ostk.mathematics.geometry.d3.objects import Composite
|
9
|
+
from ostk.mathematics.geometry.d3.objects import Point
|
10
|
+
|
11
|
+
from ostk.physics.units import Mass
|
12
|
+
from ostk.physics.time import Instant
|
13
|
+
from ostk.physics.time import DateTime
|
14
|
+
from ostk.physics.time import Scale
|
15
|
+
from ostk.physics.coordinate import Position
|
16
|
+
from ostk.physics.coordinate import Velocity
|
17
|
+
from ostk.physics.coordinate import Frame
|
18
|
+
from ostk.physics.environment.atmospheric import Earth as EarthAtmosphericModel
|
19
|
+
from ostk.physics.environment.gravitational import Earth as EarthGravitationalModel
|
20
|
+
from ostk.physics.environment.magnetic import Earth as EarthMagneticModel
|
21
|
+
from ostk.physics.environment.objects.celestial_bodies import Earth
|
22
|
+
|
23
|
+
from ostk.astrodynamics.trajectory.state import CoordinatesSubset
|
24
|
+
from ostk.astrodynamics.trajectory.state.coordinates_subset import CartesianPosition
|
25
|
+
from ostk.astrodynamics.trajectory.state.coordinates_subset import CartesianVelocity
|
26
|
+
from ostk.astrodynamics.trajectory.state import CoordinatesBroker
|
27
|
+
|
28
|
+
from ostk.astrodynamics.trajectory import State
|
29
|
+
from ostk.astrodynamics.trajectory.state import CoordinatesSubset, CoordinatesBroker
|
30
|
+
from ostk.astrodynamics.trajectory.state.coordinates_subset import (
|
31
|
+
CartesianPosition,
|
32
|
+
CartesianVelocity,
|
33
|
+
)
|
34
|
+
from ostk.astrodynamics import Dynamics
|
35
|
+
from ostk.astrodynamics.dynamics import AtmosphericDrag
|
36
|
+
|
37
|
+
|
38
|
+
@pytest.fixture
|
39
|
+
def earth() -> Earth:
|
40
|
+
return Earth.from_models(
|
41
|
+
EarthGravitationalModel(EarthGravitationalModel.Type.Undefined),
|
42
|
+
EarthMagneticModel(EarthMagneticModel.Type.Undefined),
|
43
|
+
EarthAtmosphericModel(EarthAtmosphericModel.Type.Exponential),
|
44
|
+
)
|
45
|
+
|
46
|
+
|
47
|
+
@pytest.fixture
|
48
|
+
def dry_mass() -> float:
|
49
|
+
return 100.0
|
50
|
+
|
51
|
+
|
52
|
+
@pytest.fixture
|
53
|
+
def surface_area() -> float:
|
54
|
+
return 500.0
|
55
|
+
|
56
|
+
|
57
|
+
@pytest.fixture
|
58
|
+
def drag_coefficient() -> float:
|
59
|
+
return 2.1
|
60
|
+
|
61
|
+
|
62
|
+
@pytest.fixture
|
63
|
+
def dynamics(earth: Earth) -> AtmosphericDrag:
|
64
|
+
return AtmosphericDrag(earth)
|
65
|
+
|
66
|
+
|
67
|
+
@pytest.fixture
|
68
|
+
def coordinates_broker() -> CoordinatesBroker:
|
69
|
+
return CoordinatesBroker(
|
70
|
+
[
|
71
|
+
CartesianPosition.default(),
|
72
|
+
CartesianVelocity.default(),
|
73
|
+
CoordinatesSubset.mass(),
|
74
|
+
CoordinatesSubset.surface_area(),
|
75
|
+
CoordinatesSubset.drag_coefficient(),
|
76
|
+
]
|
77
|
+
)
|
78
|
+
|
79
|
+
|
80
|
+
@pytest.fixture
|
81
|
+
def instant() -> Instant:
|
82
|
+
return Instant.date_time(DateTime(2021, 3, 20, 12, 0, 0), Scale.UTC)
|
83
|
+
|
84
|
+
|
85
|
+
@pytest.fixture
|
86
|
+
def position_coordinates() -> list:
|
87
|
+
return [7000000.0, 0.0, 0.0]
|
88
|
+
|
89
|
+
|
90
|
+
@pytest.fixture
|
91
|
+
def velocity_coordinates() -> list:
|
92
|
+
return [0.0, 7546.05329, 0.0]
|
93
|
+
|
94
|
+
|
95
|
+
@pytest.fixture
|
96
|
+
def state(
|
97
|
+
instant: Instant,
|
98
|
+
position_coordinates: list,
|
99
|
+
velocity_coordinates: list,
|
100
|
+
dry_mass: float,
|
101
|
+
surface_area: float,
|
102
|
+
drag_coefficient: float,
|
103
|
+
coordinates_broker: CoordinatesBroker,
|
104
|
+
) -> State:
|
105
|
+
coordinates = (
|
106
|
+
position_coordinates
|
107
|
+
+ velocity_coordinates
|
108
|
+
+ [dry_mass, surface_area, drag_coefficient]
|
109
|
+
)
|
110
|
+
return State(instant, coordinates, Frame.GCRF(), coordinates_broker)
|
111
|
+
|
112
|
+
|
113
|
+
class TestAtmosphericDrag:
|
114
|
+
def test_constructors(self, dynamics: AtmosphericDrag):
|
115
|
+
assert dynamics is not None
|
116
|
+
assert isinstance(dynamics, AtmosphericDrag)
|
117
|
+
assert isinstance(dynamics, Dynamics)
|
118
|
+
assert dynamics.is_defined()
|
119
|
+
|
120
|
+
def test_getters(self, dynamics: AtmosphericDrag, earth: Earth):
|
121
|
+
assert dynamics.get_celestial() == earth
|
122
|
+
|
123
|
+
def test_compute_contribution(self, dynamics: AtmosphericDrag, state: State):
|
124
|
+
contribution = dynamics.compute_contribution(
|
125
|
+
state.get_instant(), state.get_coordinates(), state.get_frame()
|
126
|
+
)
|
127
|
+
|
128
|
+
assert len(contribution) == 3
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Apache License 2.0
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
import numpy as np
|
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 Position
|
11
|
+
from ostk.physics.coordinate import Velocity
|
12
|
+
from ostk.physics.coordinate import Frame
|
13
|
+
from ostk.physics.environment.objects.celestial_bodies import Earth
|
14
|
+
|
15
|
+
from ostk.astrodynamics.trajectory import State
|
16
|
+
from ostk.astrodynamics import Dynamics
|
17
|
+
from ostk.astrodynamics.dynamics import CentralBodyGravity
|
18
|
+
|
19
|
+
|
20
|
+
@pytest.fixture
|
21
|
+
def earth() -> Earth:
|
22
|
+
return Earth.spherical()
|
23
|
+
|
24
|
+
|
25
|
+
@pytest.fixture
|
26
|
+
def dynamics(earth: Earth) -> CentralBodyGravity:
|
27
|
+
return CentralBodyGravity(earth)
|
28
|
+
|
29
|
+
|
30
|
+
@pytest.fixture
|
31
|
+
def state() -> State:
|
32
|
+
frame: Frame = Frame.GCRF()
|
33
|
+
position: Position = Position.meters([7000000.0, 0.0, 0.0], frame)
|
34
|
+
velocity: Velocity = Velocity.meters_per_second([0.0, 0.0, 0.0], frame)
|
35
|
+
instant = Instant.date_time(DateTime(2021, 3, 20, 12, 0, 0), Scale.UTC)
|
36
|
+
return State(instant, position, velocity)
|
37
|
+
|
38
|
+
|
39
|
+
class TestCentralBodyGravity:
|
40
|
+
def test_constructors(
|
41
|
+
self,
|
42
|
+
dynamics: CentralBodyGravity,
|
43
|
+
):
|
44
|
+
assert dynamics is not None
|
45
|
+
assert isinstance(dynamics, CentralBodyGravity)
|
46
|
+
assert isinstance(dynamics, Dynamics)
|
47
|
+
assert dynamics.is_defined()
|
48
|
+
|
49
|
+
def test_getters(self, dynamics: CentralBodyGravity, earth: Earth):
|
50
|
+
assert dynamics.get_celestial() == earth
|
51
|
+
|
52
|
+
def test_compute_contribution(self, dynamics: CentralBodyGravity, state: State):
|
53
|
+
contribution = dynamics.compute_contribution(
|
54
|
+
state.get_instant(), state.get_coordinates(), state.get_frame()
|
55
|
+
)
|
56
|
+
|
57
|
+
assert len(contribution) == 3
|
58
|
+
assert contribution == pytest.approx([-8.134702887755102, 0.0, 0.0])
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Apache License 2.0
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from ostk.physics import Environment
|
6
|
+
|
7
|
+
from ostk.astrodynamics import Dynamics
|
8
|
+
from ostk.astrodynamics.trajectory.state.coordinates_subset import CartesianPosition
|
9
|
+
|
10
|
+
|
11
|
+
@pytest.fixture
|
12
|
+
def name() -> str:
|
13
|
+
return "MyDynamics"
|
14
|
+
|
15
|
+
|
16
|
+
@pytest.fixture
|
17
|
+
def environment() -> Environment:
|
18
|
+
return Environment.default()
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.fixture
|
22
|
+
def dynamics(name: str) -> Dynamics:
|
23
|
+
class MyDynamics(Dynamics):
|
24
|
+
def is_defined():
|
25
|
+
return True
|
26
|
+
|
27
|
+
def get_read_coordinates_subsets(self):
|
28
|
+
return [CartesianPosition.default()]
|
29
|
+
|
30
|
+
def get_write_coordinates_subsets(self):
|
31
|
+
return [CartesianPosition.default()]
|
32
|
+
|
33
|
+
def compute_contribution(self, instant, state_vector, frame):
|
34
|
+
return state_vector
|
35
|
+
|
36
|
+
return MyDynamics(name)
|
37
|
+
|
38
|
+
|
39
|
+
class TestDynamics:
|
40
|
+
def test_subclass(self, dynamics: Dynamics):
|
41
|
+
assert dynamics is not None
|
42
|
+
|
43
|
+
def test_get_name(self, dynamics: Dynamics, name: str):
|
44
|
+
assert dynamics.get_name() == name
|
45
|
+
|
46
|
+
def test_from_environment(self, environment: Environment):
|
47
|
+
dynamics: list[Dynamics] = Dynamics.from_environment(environment)
|
48
|
+
|
49
|
+
assert dynamics is not None
|
50
|
+
assert isinstance(dynamics, list)
|