open-space-toolkit-astrodynamics 16.3.0__py312-none-manylinux2014_aarch64.whl → 16.4.0__py312-none-manylinux2014_aarch64.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-16.3.0.dist-info → open_space_toolkit_astrodynamics-16.4.0.dist-info}/METADATA +1 -1
- {open_space_toolkit_astrodynamics-16.3.0.dist-info → open_space_toolkit_astrodynamics-16.4.0.dist-info}/RECORD +19 -14
- ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-312-aarch64-linux-gnu.so +0 -0
- ostk/astrodynamics/__init__.pyi +1 -1
- ostk/astrodynamics/flight/__init__.pyi +18 -9
- ostk/astrodynamics/flight/profile/model.pyi +19 -0
- ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.16 +0 -0
- ostk/astrodynamics/test/flight/profile/model/test_tabulated_profile.py +115 -0
- ostk/astrodynamics/test/flight/test_profile.py +4 -0
- ostk/astrodynamics/test/test_display.py +0 -2
- ostk/astrodynamics/test/test_trajectory.py +28 -7
- ostk/astrodynamics/test/trajectory/model/test_nadir_trajectory.py +87 -0
- ostk/astrodynamics/test/trajectory/model/test_tabulated_trajectory.py +303 -0
- ostk/astrodynamics/test/trajectory/model/test_target_scan_trajectory.py +126 -0
- ostk/astrodynamics/trajectory/__init__.pyi +10 -9
- ostk/astrodynamics/trajectory/model.pyi +259 -0
- {open_space_toolkit_astrodynamics-16.3.0.dist-info → open_space_toolkit_astrodynamics-16.4.0.dist-info}/WHEEL +0 -0
- {open_space_toolkit_astrodynamics-16.3.0.dist-info → open_space_toolkit_astrodynamics-16.4.0.dist-info}/top_level.txt +0 -0
- {open_space_toolkit_astrodynamics-16.3.0.dist-info → open_space_toolkit_astrodynamics-16.4.0.dist-info}/zip-safe +0 -0
@@ -1,7 +1,7 @@
|
|
1
1
|
ostk/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
2
|
-
ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-312-aarch64-linux-gnu.so,sha256=
|
2
|
+
ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-312-aarch64-linux-gnu.so,sha256=VhzMys7OUGtnw-6fJr4uO-2PuDgkS4yR43aHRhpXutQ,2615592
|
3
3
|
ostk/astrodynamics/__init__.py,sha256=3gWyqFIbhAfcdeMhmfBPQPlPQTmaOzm-6flkJe745Zk,251
|
4
|
-
ostk/astrodynamics/__init__.pyi,sha256=
|
4
|
+
ostk/astrodynamics/__init__.pyi,sha256=qOgUb7JOtCGogVdlwKA6lfovXoRC2vLYvegIHrjYROQ,32191
|
5
5
|
ostk/astrodynamics/access.pyi,sha256=t2CF0TU6_6ow_rkV_I4rVKap7ZIdC4jYKL3WkTDHRXg,25157
|
6
6
|
ostk/astrodynamics/converters.py,sha256=luPh30qMp9bzEkN7hUccmxlLf7zRp_AzqmBe8IUjPhU,3314
|
7
7
|
ostk/astrodynamics/converters.pyi,sha256=HrZFyizkc6Hv_K38ZKZ80fX_bAxd6keA_NFWNQygvbs,1745
|
@@ -11,7 +11,7 @@ ostk/astrodynamics/dynamics.pyi,sha256=gZ95KoGex4SB-1z6yMrngkZN1Ir9X6bEmrZgdLxq1
|
|
11
11
|
ostk/astrodynamics/estimator.pyi,sha256=MnahWzp8aACxrNKWlYRsgQr5zpBxogNr-yPm7hJob5k,14000
|
12
12
|
ostk/astrodynamics/event_condition.pyi,sha256=2c_1Sq7tkYKeAA_aRWBi43KDQXXxu6EMSmUpEWz_Fa4,45814
|
13
13
|
ostk/astrodynamics/guidance_law.pyi,sha256=rVmbpV2Y5FsIXejaInxINS67nVHmTIxVEkhaDIn17SA,12171
|
14
|
-
ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.16,sha256=
|
14
|
+
ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.16,sha256=MEfhg-xZLWaMKrzjgnS3iA69EmTF4qfiH42uv0G_954,3930832
|
15
15
|
ostk/astrodynamics/solver.pyi,sha256=sPqyYPXBfFGC24dzzYyFyt01VfMAlWQ5_gh_RpeaBFk,17734
|
16
16
|
ostk/astrodynamics/utilities.py,sha256=y8mr3M46J5z-GhS1oIEnuEJA6otwcyJ9YDhvn_5JxHM,6976
|
17
17
|
ostk/astrodynamics/viewer.py,sha256=SlKyOWKjaF3V9HFB3I7ZgHy7n_GLeHTWM9q2wXkpxe8,27077
|
@@ -20,10 +20,10 @@ ostk/astrodynamics/conjunction/message/__init__.pyi,sha256=5H__sg_QUx7ybf9jtVWvX
|
|
20
20
|
ostk/astrodynamics/conjunction/message/ccsds.pyi,sha256=1Peto19hRqlD7KHf1cyLP3CT4OAKzwtemqvO6_4FZ0g,28162
|
21
21
|
ostk/astrodynamics/data/__init__.pyi,sha256=4l_mfVbnU_L7wImwgTCe8fVI81gK_tUmd0z7BY9lLi8,81
|
22
22
|
ostk/astrodynamics/data/provider.pyi,sha256=O4Lg9FBq9itufgATnic5SMg90pn8vJJJMUdNcWP72NI,1492
|
23
|
-
ostk/astrodynamics/flight/__init__.pyi,sha256=
|
23
|
+
ostk/astrodynamics/flight/__init__.pyi,sha256=f7hDDcisAtBE86w5s0d0M2N_m3Rjlh2pWGWFTdnoaGw,23058
|
24
24
|
ostk/astrodynamics/flight/system.pyi,sha256=WVxy6Oe4q3C81c0AOxSwAmnwUHcpXO7JCEvESjs2g4A,10508
|
25
25
|
ostk/astrodynamics/flight/profile/__init__.pyi,sha256=WBTG17V59UwD-X1r6TOrXT_rA3WjKY-2ML1cWfji_4g,3688
|
26
|
-
ostk/astrodynamics/flight/profile/model.pyi,sha256=
|
26
|
+
ostk/astrodynamics/flight/profile/model.pyi,sha256=wwnVaTjTytxPqKyNo1tpdZRedabQlIHgyxfT0nivO5M,7777
|
27
27
|
ostk/astrodynamics/pytrajectory/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
28
28
|
ostk/astrodynamics/pytrajectory/__init__.pyi,sha256=QWrGyQNiICBEI3pKku2wJYdu-SQCBKXjJ_93XTEgkP8,79
|
29
29
|
ostk/astrodynamics/pytrajectory/pystate.py,sha256=HbWtj1_FXGXTuvSu52ewMaO3ahwLBLStyJ4e5xqL-jw,8415
|
@@ -33,11 +33,11 @@ ostk/astrodynamics/test/conftest.py,sha256=stmQOt7UXjBlXKJzNN6RkS2miv1xXSOX-YNpF
|
|
33
33
|
ostk/astrodynamics/test/test_access.py,sha256=MCBsUPtuVm7NgHZR0z0DpWnPZ_qBu4aRhLI2PnRNUYs,3940
|
34
34
|
ostk/astrodynamics/test/test_converters.py,sha256=mFpDD0YM8o356lj91GGIwYdMk2ut6xZFV3uYcgZepMY,8744
|
35
35
|
ostk/astrodynamics/test/test_dataframe.py,sha256=NddmwnV8R1QgTD_iLXn_h0xK2kP5Qk22Oh93hF6KjT0,38300
|
36
|
-
ostk/astrodynamics/test/test_display.py,sha256=
|
36
|
+
ostk/astrodynamics/test/test_display.py,sha256=CQEz66OZna6W8_ZIEVCPKAH-cM9YjzCOGpoINqC8m40,3840
|
37
37
|
ostk/astrodynamics/test/test_event_condition.py,sha256=fQ-rVYpQsa7xacxRMBOQDyn61CuAGX1QBOGZxGWR0_s,2204
|
38
38
|
ostk/astrodynamics/test/test_import.py,sha256=py_hALBR0IYuUzv9dfgQZzrrLHJIpnyKvt3Oi1XBqCg,1251
|
39
39
|
ostk/astrodynamics/test/test_root_solver.py,sha256=hQ8O6g-WP49gZH_H3Rdufv0F0gQorpzJyIcjBGGUQ34,1831
|
40
|
-
ostk/astrodynamics/test/test_trajectory.py,sha256=
|
40
|
+
ostk/astrodynamics/test/test_trajectory.py,sha256=8J9NAAn5s2SvaIScUoM7GtStI7-4-xffrBwg4ph7Ppw,4096
|
41
41
|
ostk/astrodynamics/test/test_utilities.py,sha256=NNIyzqOxMdsNpK2z0wU0utX06iZNfbMJDE36Upard28,3048
|
42
42
|
ostk/astrodynamics/test/test_viewer.py,sha256=6IxHjSrwnLkmLiTTzRcnwAdEeWdIF_b2Kjz5iCqwctw,10912
|
43
43
|
ostk/astrodynamics/test/access/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
@@ -69,8 +69,9 @@ ostk/astrodynamics/test/event_condition/test_logical_condition.py,sha256=09h5TYW
|
|
69
69
|
ostk/astrodynamics/test/event_condition/test_real_condition.py,sha256=tle6HVzMFMIIkfRY7CuaA0mPtw3riJBG_JQkc1L0dpk,1374
|
70
70
|
ostk/astrodynamics/test/flight/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
71
71
|
ostk/astrodynamics/test/flight/test_maneuver.py,sha256=HonAvD9qtax72lizoDLR6ELI-poC3LWk_umg-WYygYA,5388
|
72
|
-
ostk/astrodynamics/test/flight/test_profile.py,sha256=
|
72
|
+
ostk/astrodynamics/test/flight/test_profile.py,sha256=lfTGy9l2rAhHsmLZCdE-kzy-s_-EgXIZwfGs_7f8UPo,8205
|
73
73
|
ostk/astrodynamics/test/flight/test_system.py,sha256=5kJCULHdpkwAC7i6xLV7vdJnGfOdrOuhi0G22p_L160,1224
|
74
|
+
ostk/astrodynamics/test/flight/profile/model/test_tabulated_profile.py,sha256=NZVa9dXzp4UDmohAlBaYeY594CPbqIv5j3VSEzlbYHk,3168
|
74
75
|
ostk/astrodynamics/test/flight/system/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
75
76
|
ostk/astrodynamics/test/flight/system/test_propulsion_system.py,sha256=SoxOt-fjHvs_86f6Xb3jAsHDOShJ6Puz7eO5wrqibaM,1835
|
76
77
|
ostk/astrodynamics/test/flight/system/test_satellite_system.py,sha256=dCFcl2RKiLxDKLI0sytPBXr3vHOFQIVNNCzpw5WzlAA,2437
|
@@ -91,6 +92,9 @@ ostk/astrodynamics/test/trajectory/test_segment.py,sha256=aXdF5CpNLwN_hKRU5sG3ID
|
|
91
92
|
ostk/astrodynamics/test/trajectory/test_sequence.py,sha256=4piYpMZ9C_eCXxaOcdz2We67wZxhsNBnETgKwvq6dl0,15083
|
92
93
|
ostk/astrodynamics/test/trajectory/test_state.py,sha256=JO-SnUCRZ6sfVNwB5soT5c1f8c5DXuFN5lHZkiiTcYc,18119
|
93
94
|
ostk/astrodynamics/test/trajectory/test_state_builder.py,sha256=LpCCYdCaLu_D2npm9wgA2sMlcekrtbRqP-afe5IE5L4,4871
|
95
|
+
ostk/astrodynamics/test/trajectory/model/test_nadir_trajectory.py,sha256=AzXLO7qqcGnN7Pu7T_ue16wGcLodj9aH-xsZnk5KRMM,2219
|
96
|
+
ostk/astrodynamics/test/trajectory/model/test_tabulated_trajectory.py,sha256=zbjI5mFkJOgyO_e8i0-RN1jhq2nIOs0dAJbkrP9nTYI,8405
|
97
|
+
ostk/astrodynamics/test/trajectory/model/test_target_scan_trajectory.py,sha256=zSIkTP1sggEU58obPjbtdhO5xnWUJQ2XNkK_zUP6jdY,3253
|
94
98
|
ostk/astrodynamics/test/trajectory/orbit/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
95
99
|
ostk/astrodynamics/test/trajectory/orbit/test_model.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
96
100
|
ostk/astrodynamics/test/trajectory/orbit/test_pass.py,sha256=LTHDGW26I0kujifCXFMcUFu9yaHMeUoIM-7jt6kJkJU,2492
|
@@ -119,7 +123,8 @@ ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quatern
|
|
119
123
|
ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_acceleration.py,sha256=1p37_FYN85d9SrOqO3iCkNecovJJayhnFeZ4QCOw2ao,3528
|
120
124
|
ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py,sha256=XvHdk1KjacTwtkgx2jUAc9I9N3nvjPDv03FAanpv8jQ,2702
|
121
125
|
ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py,sha256=-kd5TZO5TICihbkqDTew2i_tDpggdpe3Yf23046FATM,3057
|
122
|
-
ostk/astrodynamics/trajectory/__init__.pyi,sha256=
|
126
|
+
ostk/astrodynamics/trajectory/__init__.pyi,sha256=rp38g9mSH8W-mqYnrZRKw35LGYa1fEKx2vk5y7xTcrI,76429
|
127
|
+
ostk/astrodynamics/trajectory/model.pyi,sha256=SIneZx3pQ6XAo6iBccr4B1OsATbs1PEsCngtaTvja00,10473
|
123
128
|
ostk/astrodynamics/trajectory/orbit/__init__.pyi,sha256=wbuRK7Yp_NYBr3ta5-NpnJYMX4baUl7yIlUWhaRlR4o,12899
|
124
129
|
ostk/astrodynamics/trajectory/orbit/message/__init__.pyi,sha256=-GNBlYPrsjelhKxWorYQYhIWzFsibiIQNZvMXjhRpfM,77
|
125
130
|
ostk/astrodynamics/trajectory/orbit/message/spacex.pyi,sha256=fnUVJGWlSPo8AmLVuu08LubsAuVGo-gFaT86yd4f4CI,10558
|
@@ -129,8 +134,8 @@ ostk/astrodynamics/trajectory/orbit/model/kepler.pyi,sha256=OZMznHuU7e6m1rfqtOgX
|
|
129
134
|
ostk/astrodynamics/trajectory/orbit/model/sgp4.pyi,sha256=OhFzoPPQHlYy7m3LiZ8TXF89M4uBTfNk6tGsBEp0sjI,14235
|
130
135
|
ostk/astrodynamics/trajectory/state/__init__.pyi,sha256=bq__Fii35czVrTeNxc9eQVjXdqwbbQxUdNQWK3vLrMo,17649
|
131
136
|
ostk/astrodynamics/trajectory/state/coordinate_subset.pyi,sha256=kYMfMwEjCqO1NepMYFT4QS6kIPBkVL6sGCLeLbogcMw,10176
|
132
|
-
open_space_toolkit_astrodynamics-16.
|
133
|
-
open_space_toolkit_astrodynamics-16.
|
134
|
-
open_space_toolkit_astrodynamics-16.
|
135
|
-
open_space_toolkit_astrodynamics-16.
|
136
|
-
open_space_toolkit_astrodynamics-16.
|
137
|
+
open_space_toolkit_astrodynamics-16.4.0.dist-info/METADATA,sha256=hmk7loB1mnnlXQ39BmWfd3MqBhiTKzoK0D1jIkGlVfk,1913
|
138
|
+
open_space_toolkit_astrodynamics-16.4.0.dist-info/WHEEL,sha256=R5pNgnt8b9fXaDTmvusPEx11BdzBXjt30_JyyExPv08,111
|
139
|
+
open_space_toolkit_astrodynamics-16.4.0.dist-info/top_level.txt,sha256=zOR18699uDYnafgarhL8WU_LmTZY_5NVqutv-flp_x4,5
|
140
|
+
open_space_toolkit_astrodynamics-16.4.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
141
|
+
open_space_toolkit_astrodynamics-16.4.0.dist-info/RECORD,,
|
Binary file
|
ostk/astrodynamics/__init__.pyi
CHANGED
@@ -682,7 +682,7 @@ class Trajectory:
|
|
682
682
|
celestial_object (Celestial): The celestial object. Defaults to Earth.WGS84().
|
683
683
|
|
684
684
|
Returns:
|
685
|
-
Trajectory: The `Trajectory` object representing the ground strip.
|
685
|
+
Trajectory: The `Trajectory` object representing the ground strip.
|
686
686
|
"""
|
687
687
|
@staticmethod
|
688
688
|
def position(position: ostk.physics.coordinate.Position) -> Trajectory:
|
@@ -252,12 +252,14 @@ class Profile:
|
|
252
252
|
|
253
253
|
GeodeticNadir : Geodetic nadir
|
254
254
|
|
255
|
-
Trajectory :
|
255
|
+
Trajectory : Deprecated - Use TargetPosition instead.
|
256
256
|
|
257
257
|
TargetPosition : Target position
|
258
258
|
|
259
259
|
TargetVelocity : Target velocity
|
260
260
|
|
261
|
+
TargetSlidingGroundVelocity : Target sliding ground velocity
|
262
|
+
|
261
263
|
Sun : Sun
|
262
264
|
|
263
265
|
Moon : Moon
|
@@ -272,16 +274,17 @@ class Profile:
|
|
272
274
|
"""
|
273
275
|
GeocentricNadir: typing.ClassVar[Profile.TargetType] # value = <TargetType.GeocentricNadir: 0>
|
274
276
|
GeodeticNadir: typing.ClassVar[Profile.TargetType] # value = <TargetType.GeodeticNadir: 1>
|
275
|
-
Moon: typing.ClassVar[Profile.TargetType] # value = <TargetType.Moon:
|
276
|
-
OrbitalMomentum: typing.ClassVar[Profile.TargetType] # value = <TargetType.OrbitalMomentum:
|
277
|
-
OrientationProfile: typing.ClassVar[Profile.TargetType] # value = <TargetType.OrientationProfile:
|
278
|
-
Sun: typing.ClassVar[Profile.TargetType] # value = <TargetType.Sun:
|
277
|
+
Moon: typing.ClassVar[Profile.TargetType] # value = <TargetType.Moon: 7>
|
278
|
+
OrbitalMomentum: typing.ClassVar[Profile.TargetType] # value = <TargetType.OrbitalMomentum: 10>
|
279
|
+
OrientationProfile: typing.ClassVar[Profile.TargetType] # value = <TargetType.OrientationProfile: 11>
|
280
|
+
Sun: typing.ClassVar[Profile.TargetType] # value = <TargetType.Sun: 6>
|
279
281
|
TargetPosition: typing.ClassVar[Profile.TargetType] # value = <TargetType.TargetPosition: 3>
|
282
|
+
TargetSlidingGroundVelocity: typing.ClassVar[Profile.TargetType] # value = <TargetType.TargetSlidingGroundVelocity: 5>
|
280
283
|
TargetVelocity: typing.ClassVar[Profile.TargetType] # value = <TargetType.TargetVelocity: 4>
|
281
284
|
Trajectory: typing.ClassVar[Profile.TargetType] # value = <TargetType.Trajectory: 2>
|
282
|
-
VelocityECEF: typing.ClassVar[Profile.TargetType] # value = <TargetType.VelocityECEF:
|
283
|
-
VelocityECI: typing.ClassVar[Profile.TargetType] # value = <TargetType.VelocityECI:
|
284
|
-
__members__: typing.ClassVar[dict[str, Profile.TargetType]] # value = {'GeocentricNadir': <TargetType.GeocentricNadir: 0>, 'GeodeticNadir': <TargetType.GeodeticNadir: 1>, 'Trajectory': <TargetType.Trajectory: 2>, 'TargetPosition': <TargetType.TargetPosition: 3>, 'TargetVelocity': <TargetType.TargetVelocity: 4>, 'Sun': <TargetType.Sun:
|
285
|
+
VelocityECEF: typing.ClassVar[Profile.TargetType] # value = <TargetType.VelocityECEF: 9>
|
286
|
+
VelocityECI: typing.ClassVar[Profile.TargetType] # value = <TargetType.VelocityECI: 8>
|
287
|
+
__members__: typing.ClassVar[dict[str, Profile.TargetType]] # value = {'GeocentricNadir': <TargetType.GeocentricNadir: 0>, 'GeodeticNadir': <TargetType.GeodeticNadir: 1>, 'Trajectory': <TargetType.Trajectory: 2>, 'TargetPosition': <TargetType.TargetPosition: 3>, 'TargetVelocity': <TargetType.TargetVelocity: 4>, 'TargetSlidingGroundVelocity': <TargetType.TargetSlidingGroundVelocity: 5>, 'Sun': <TargetType.Sun: 6>, 'Moon': <TargetType.Moon: 7>, 'VelocityECI': <TargetType.VelocityECI: 8>, 'VelocityECEF': <TargetType.VelocityECEF: 9>, 'OrbitalMomentum': <TargetType.OrbitalMomentum: 10>, 'OrientationProfile': <TargetType.OrientationProfile: 11>}
|
285
288
|
def __eq__(self, other: typing.Any) -> bool:
|
286
289
|
...
|
287
290
|
def __getstate__(self) -> int:
|
@@ -321,9 +324,15 @@ class Profile:
|
|
321
324
|
Create a target, which produces a vector pointing from the observer to the target position.
|
322
325
|
"""
|
323
326
|
@staticmethod
|
327
|
+
def target_sliding_ground_velocity(trajectory: ostk.astrodynamics.Trajectory, axis: Profile.Axis, anti_direction: bool = False) -> Profile.TrajectoryTarget:
|
328
|
+
"""
|
329
|
+
Create a target, which produces a vector pointing along the ground velocity vector (aka the scan direction of the point sliding across the ground).
|
330
|
+
This will compensate for the rotation of the referenced celestial body.
|
331
|
+
"""
|
332
|
+
@staticmethod
|
324
333
|
def target_velocity(trajectory: ostk.astrodynamics.Trajectory, axis: Profile.Axis, anti_direction: bool = False) -> Profile.TrajectoryTarget:
|
325
334
|
"""
|
326
|
-
Create a target, which produces a vector pointing along the
|
335
|
+
Create a target, which produces a vector pointing along the scan direction.
|
327
336
|
"""
|
328
337
|
def __init__(self, trajectory: ostk.astrodynamics.Trajectory, axis: Profile.Axis, anti_direction: bool = False) -> None:
|
329
338
|
"""
|
@@ -3,10 +3,12 @@ import ostk.astrodynamics
|
|
3
3
|
import ostk.astrodynamics.flight.profile
|
4
4
|
import ostk.astrodynamics.trajectory
|
5
5
|
import ostk.core.type
|
6
|
+
import ostk.mathematics.curve_fitting
|
6
7
|
import ostk.mathematics.geometry.d3.transformation.rotation
|
7
8
|
import ostk.physics.coordinate
|
8
9
|
import ostk.physics.coordinate.frame.provider
|
9
10
|
import ostk.physics.time
|
11
|
+
import typing
|
10
12
|
__all__ = ['Tabulated', 'Transform']
|
11
13
|
class Tabulated(ostk.astrodynamics.flight.profile.Model):
|
12
14
|
"""
|
@@ -15,6 +17,7 @@ class Tabulated(ostk.astrodynamics.flight.profile.Model):
|
|
15
17
|
|
16
18
|
|
17
19
|
"""
|
20
|
+
@typing.overload
|
18
21
|
def __init__(self, states: list[ostk.astrodynamics.trajectory.State]) -> None:
|
19
22
|
"""
|
20
23
|
Constructor.
|
@@ -22,6 +25,15 @@ class Tabulated(ostk.astrodynamics.flight.profile.Model):
|
|
22
25
|
Args:
|
23
26
|
states (Array[State]): The states of the model.
|
24
27
|
"""
|
28
|
+
@typing.overload
|
29
|
+
def __init__(self, states: list[ostk.astrodynamics.trajectory.State], interpolator_type: ostk.mathematics.curve_fitting.Interpolator.Type) -> None:
|
30
|
+
"""
|
31
|
+
Constructor.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
states (Array[State]): The states of the model.
|
35
|
+
interpolator_type (Interpolator.Type): The type of interpolator to use for all but the AttitudeQuaternion subset. Attitude quaternions will be interpolated using spherical linear interpolation (SLERP).
|
36
|
+
"""
|
25
37
|
def __repr__(self) -> str:
|
26
38
|
"""
|
27
39
|
Convert the model to a string.
|
@@ -66,6 +78,13 @@ class Tabulated(ostk.astrodynamics.flight.profile.Model):
|
|
66
78
|
Returns:
|
67
79
|
Frame: The body frame of the model with the specified name.
|
68
80
|
"""
|
81
|
+
def get_interpolator_type(self) -> ostk.mathematics.curve_fitting.Interpolator.Type:
|
82
|
+
"""
|
83
|
+
Get the type of interpolator used in the model.
|
84
|
+
|
85
|
+
Returns:
|
86
|
+
Interpolator.Type: The type of interpolator used in the model.
|
87
|
+
"""
|
69
88
|
def get_interval(self) -> ostk.physics.time.Interval:
|
70
89
|
"""
|
71
90
|
Get the interval of the model.
|
Binary file
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Apache License 2.0
|
2
|
+
|
3
|
+
from datetime import datetime
|
4
|
+
|
5
|
+
import pytest
|
6
|
+
|
7
|
+
from ostk.mathematics.geometry.d3.transformation.rotation import Quaternion
|
8
|
+
from ostk.mathematics.curve_fitting import Interpolator
|
9
|
+
|
10
|
+
from ostk.physics.time import Scale
|
11
|
+
from ostk.physics.time import Instant
|
12
|
+
from ostk.physics.coordinate import Position
|
13
|
+
from ostk.physics.coordinate import Velocity
|
14
|
+
from ostk.physics.coordinate import Frame
|
15
|
+
|
16
|
+
from ostk.astrodynamics.trajectory import State
|
17
|
+
from ostk.astrodynamics.flight.profile.model import Tabulated as TabulatedModel
|
18
|
+
|
19
|
+
|
20
|
+
@pytest.fixture
|
21
|
+
def states() -> list[State]:
|
22
|
+
return [
|
23
|
+
State(
|
24
|
+
instant=Instant.date_time(datetime(2020, 1, 1, 0, 0, 0), Scale.UTC),
|
25
|
+
position=Position.meters((0.0, 0.0, 0.0), Frame.GCRF()),
|
26
|
+
velocity=Velocity.meters_per_second((0.0, 0.0, 0.0), Frame.GCRF()),
|
27
|
+
attitude=Quaternion.unit(),
|
28
|
+
angular_velocity=(0.0, 0.0, 0.0),
|
29
|
+
attitude_frame=Frame.GCRF(),
|
30
|
+
),
|
31
|
+
State(
|
32
|
+
instant=Instant.date_time(datetime(2020, 1, 1, 0, 1, 0), Scale.UTC),
|
33
|
+
position=Position.meters((0.0, 0.0, 0.0), Frame.GCRF()),
|
34
|
+
velocity=Velocity.meters_per_second((0.0, 0.0, 0.0), Frame.GCRF()),
|
35
|
+
attitude=Quaternion.unit(),
|
36
|
+
angular_velocity=(0.0, 0.0, 0.0),
|
37
|
+
attitude_frame=Frame.GCRF(),
|
38
|
+
),
|
39
|
+
]
|
40
|
+
|
41
|
+
|
42
|
+
@pytest.fixture
|
43
|
+
def interpolator_type() -> Interpolator.Type:
|
44
|
+
return Interpolator.Type.Linear
|
45
|
+
|
46
|
+
|
47
|
+
@pytest.fixture
|
48
|
+
def tabulated_model(
|
49
|
+
states: list[State],
|
50
|
+
interpolator_type: Interpolator.Type,
|
51
|
+
) -> TabulatedModel:
|
52
|
+
return TabulatedModel(
|
53
|
+
states=states,
|
54
|
+
interpolator_type=interpolator_type,
|
55
|
+
)
|
56
|
+
|
57
|
+
|
58
|
+
class TestTabulatedProfile:
|
59
|
+
def test_constructors(
|
60
|
+
self,
|
61
|
+
tabulated_model: TabulatedModel,
|
62
|
+
):
|
63
|
+
assert tabulated_model is not None
|
64
|
+
assert isinstance(tabulated_model, TabulatedModel)
|
65
|
+
|
66
|
+
def test_is_defined(
|
67
|
+
self,
|
68
|
+
tabulated_model: TabulatedModel,
|
69
|
+
):
|
70
|
+
assert tabulated_model.is_defined() is True
|
71
|
+
|
72
|
+
def test_get_interval(
|
73
|
+
self,
|
74
|
+
tabulated_model: TabulatedModel,
|
75
|
+
):
|
76
|
+
interval = tabulated_model.get_interval()
|
77
|
+
|
78
|
+
assert interval is not None
|
79
|
+
|
80
|
+
def test_get_interpolator_type(
|
81
|
+
self,
|
82
|
+
tabulated_model: TabulatedModel,
|
83
|
+
):
|
84
|
+
interpolator_type = tabulated_model.get_interpolator_type()
|
85
|
+
|
86
|
+
assert interpolator_type is not None
|
87
|
+
|
88
|
+
def test_calculate_state_at(
|
89
|
+
self,
|
90
|
+
tabulated_model: TabulatedModel,
|
91
|
+
states: list[State],
|
92
|
+
):
|
93
|
+
state: State = tabulated_model.calculate_state_at(states[0].get_instant())
|
94
|
+
|
95
|
+
assert state is not None
|
96
|
+
|
97
|
+
def test_get_axes_at(
|
98
|
+
self,
|
99
|
+
tabulated_model: TabulatedModel,
|
100
|
+
states: list[State],
|
101
|
+
):
|
102
|
+
axes = tabulated_model.get_axes_at(states[0].get_instant())
|
103
|
+
|
104
|
+
assert axes is not None
|
105
|
+
|
106
|
+
def test_get_body_frame(
|
107
|
+
self,
|
108
|
+
tabulated_model: TabulatedModel,
|
109
|
+
):
|
110
|
+
if Frame.exists("test"):
|
111
|
+
Frame.destruct("test")
|
112
|
+
|
113
|
+
body_frame = tabulated_model.get_body_frame("test")
|
114
|
+
|
115
|
+
assert body_frame is not None
|
@@ -97,6 +97,10 @@ def profile(request) -> Profile:
|
|
97
97
|
@pytest.fixture(
|
98
98
|
params=[
|
99
99
|
Profile.Target(Profile.TargetType.GeocentricNadir, Profile.Axis.X),
|
100
|
+
Profile.TrajectoryTarget(
|
101
|
+
Trajectory.position(Position.meters((0.0, 0.0, 0.0), Frame.ITRF())),
|
102
|
+
Profile.Axis.X,
|
103
|
+
),
|
100
104
|
Profile.TrajectoryTarget.target_position(
|
101
105
|
Trajectory.position(Position.meters((0.0, 0.0, 0.0), Frame.ITRF())),
|
102
106
|
Profile.Axis.X,
|
@@ -75,19 +75,34 @@ def orbit() -> Orbit:
|
|
75
75
|
|
76
76
|
|
77
77
|
class TestTrajectory:
|
78
|
-
def test_trajectory(
|
78
|
+
def test_trajectory(
|
79
|
+
self,
|
80
|
+
states: list[State],
|
81
|
+
):
|
79
82
|
assert Trajectory(states) is not None
|
80
83
|
|
81
|
-
def test_is_defined(
|
84
|
+
def test_is_defined(
|
85
|
+
self,
|
86
|
+
trajectory: Trajectory,
|
87
|
+
):
|
82
88
|
assert trajectory.is_defined()
|
83
89
|
|
84
|
-
def test_access_model(
|
90
|
+
def test_access_model(
|
91
|
+
self,
|
92
|
+
trajectory: Trajectory,
|
93
|
+
):
|
85
94
|
assert trajectory.access_model() is not None
|
86
95
|
|
87
|
-
def test_get_state_at(
|
96
|
+
def test_get_state_at(
|
97
|
+
self,
|
98
|
+
trajectory: Trajectory,
|
99
|
+
):
|
88
100
|
assert trajectory.get_state_at(Instant.J2000()) is not None
|
89
101
|
|
90
|
-
def test_get_states_at(
|
102
|
+
def test_get_states_at(
|
103
|
+
self,
|
104
|
+
trajectory: Trajectory,
|
105
|
+
):
|
91
106
|
assert (
|
92
107
|
trajectory.get_states_at(
|
93
108
|
[Instant.J2000(), Instant.J2000() + Duration.seconds(10.0)]
|
@@ -102,7 +117,10 @@ class TestTrajectory:
|
|
102
117
|
assert isinstance(trajectory, Trajectory)
|
103
118
|
assert trajectory.is_defined() is False
|
104
119
|
|
105
|
-
def test_trajectory_position(
|
120
|
+
def test_trajectory_position(
|
121
|
+
self,
|
122
|
+
position: Position,
|
123
|
+
):
|
106
124
|
trajectory: Trajectory = Trajectory.position(position)
|
107
125
|
|
108
126
|
assert trajectory is not None
|
@@ -131,7 +149,10 @@ class TestTrajectory:
|
|
131
149
|
assert Trajectory.ground_strip(start_lla, end_lla, instants) is not None
|
132
150
|
|
133
151
|
def test_ground_strip_geodetic_nadir(
|
134
|
-
self,
|
152
|
+
self,
|
153
|
+
orbit: Orbit,
|
154
|
+
instants: list[Instant],
|
155
|
+
earth: Earth,
|
135
156
|
):
|
136
157
|
assert (
|
137
158
|
Trajectory.ground_strip_geodetic_nadir(
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Apache License 2.0
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from ostk.physics.environment.object.celestial import Earth
|
6
|
+
from ostk.physics.time import Instant
|
7
|
+
from ostk.physics.time import DateTime
|
8
|
+
from ostk.physics.time import Scale
|
9
|
+
from ostk.physics.unit import Length
|
10
|
+
from ostk.physics.unit import Angle
|
11
|
+
|
12
|
+
from ostk.astrodynamics.trajectory import Orbit
|
13
|
+
from ostk.astrodynamics.trajectory import State
|
14
|
+
from ostk.astrodynamics.trajectory.model import Nadir
|
15
|
+
from ostk.astrodynamics.trajectory.orbit.model import Kepler
|
16
|
+
from ostk.astrodynamics.trajectory.orbit.model.kepler import COE
|
17
|
+
|
18
|
+
|
19
|
+
@pytest.fixture
|
20
|
+
def orbit() -> Orbit:
|
21
|
+
earth = Earth.WGS84()
|
22
|
+
coe = COE(
|
23
|
+
semi_major_axis=Length.kilometers(7000.0),
|
24
|
+
eccentricity=0.0,
|
25
|
+
inclination=Angle.degrees(98.0),
|
26
|
+
raan=Angle.degrees(0.0),
|
27
|
+
aop=Angle.degrees(0.0),
|
28
|
+
true_anomaly=Angle.degrees(0.0),
|
29
|
+
)
|
30
|
+
keplerian_model = Kepler(
|
31
|
+
coe=coe,
|
32
|
+
epoch=Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC),
|
33
|
+
gravitational_parameter=earth.get_gravitational_parameter(),
|
34
|
+
equatorial_radius=earth.get_equatorial_radius(),
|
35
|
+
j2=earth.get_j2(),
|
36
|
+
j4=earth.get_j4(),
|
37
|
+
perturbation_type=Kepler.PerturbationType.No,
|
38
|
+
)
|
39
|
+
return Orbit(keplerian_model, earth)
|
40
|
+
|
41
|
+
|
42
|
+
@pytest.fixture
|
43
|
+
def nadir(orbit: Orbit) -> Nadir:
|
44
|
+
return Nadir(orbit)
|
45
|
+
|
46
|
+
|
47
|
+
class TestNadir:
|
48
|
+
def test_constructor(
|
49
|
+
self,
|
50
|
+
nadir: Nadir,
|
51
|
+
):
|
52
|
+
assert nadir.is_defined()
|
53
|
+
|
54
|
+
def test_calculate_state_at(
|
55
|
+
self,
|
56
|
+
nadir: Nadir,
|
57
|
+
):
|
58
|
+
instant: Instant = Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
59
|
+
|
60
|
+
state: State = nadir.calculate_state_at(instant)
|
61
|
+
|
62
|
+
assert state is not None
|
63
|
+
|
64
|
+
def test_equality_operator(
|
65
|
+
self,
|
66
|
+
nadir: Nadir,
|
67
|
+
):
|
68
|
+
assert nadir == nadir
|
69
|
+
|
70
|
+
def test_inequality_operator(
|
71
|
+
self,
|
72
|
+
nadir: Nadir,
|
73
|
+
):
|
74
|
+
nadir2 = Nadir(Orbit.undefined())
|
75
|
+
assert nadir != nadir2
|
76
|
+
|
77
|
+
def test_get_orbit(
|
78
|
+
self,
|
79
|
+
nadir: Nadir,
|
80
|
+
):
|
81
|
+
assert nadir.get_orbit() is not None
|
82
|
+
|
83
|
+
def test_get_step_size(
|
84
|
+
self,
|
85
|
+
nadir: Nadir,
|
86
|
+
):
|
87
|
+
assert nadir.get_step_size() is not None
|
@@ -0,0 +1,303 @@
|
|
1
|
+
# Apache License 2.0
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
import numpy as np
|
6
|
+
|
7
|
+
from ostk.mathematics.curve_fitting import Interpolator
|
8
|
+
|
9
|
+
from ostk.physics.time import Instant
|
10
|
+
from ostk.physics.time import DateTime
|
11
|
+
from ostk.physics.time import Scale
|
12
|
+
from ostk.physics.coordinate import Position
|
13
|
+
from ostk.physics.coordinate import Velocity
|
14
|
+
from ostk.physics.coordinate import Frame
|
15
|
+
|
16
|
+
from ostk.astrodynamics.trajectory import State
|
17
|
+
from ostk.astrodynamics.trajectory.model import Tabulated
|
18
|
+
|
19
|
+
|
20
|
+
@pytest.fixture
|
21
|
+
def reference_states() -> list[State]:
|
22
|
+
data = [
|
23
|
+
[
|
24
|
+
"2023-04-18T08:28:32.744064",
|
25
|
+
-3310024.847608758,
|
26
|
+
-6052528.239971979,
|
27
|
+
7626.534641683145,
|
28
|
+
-855.2088930507367,
|
29
|
+
495.9541573743367,
|
30
|
+
7536.520188134902,
|
31
|
+
],
|
32
|
+
[
|
33
|
+
"2023-04-18T08:28:33.744064",
|
34
|
+
-3310878.047628086,
|
35
|
+
-6052028.610429457,
|
36
|
+
15163.0493833017,
|
37
|
+
-851.1838953959017,
|
38
|
+
503.31279367207185,
|
39
|
+
7536.506322816037,
|
40
|
+
],
|
41
|
+
[
|
42
|
+
"2023-04-18T08:28:34.744064",
|
43
|
+
-3311727.222133691,
|
44
|
+
-6051521.622540367,
|
45
|
+
22699.545682944226,
|
46
|
+
-847.1578341126227,
|
47
|
+
510.67087060642456,
|
48
|
+
7536.483268627912,
|
49
|
+
],
|
50
|
+
[
|
51
|
+
"2023-04-18T08:28:35.744064",
|
52
|
+
-3312572.370064364,
|
53
|
+
-6051007.276868478,
|
54
|
+
30236.014351773065,
|
55
|
+
-843.1307141262514,
|
56
|
+
518.0283791399937,
|
57
|
+
7536.451025467619,
|
58
|
+
],
|
59
|
+
[
|
60
|
+
"2023-04-18T08:28:36.744064",
|
61
|
+
-3313413.490363804,
|
62
|
+
-6050485.573986613,
|
63
|
+
37772.44620082258,
|
64
|
+
-839.1025403636198,
|
65
|
+
525.3853102358,
|
66
|
+
7536.40959324377,
|
67
|
+
],
|
68
|
+
[
|
69
|
+
"2023-04-18T08:28:37.744064",
|
70
|
+
-3314250.5819806806,
|
71
|
+
-6049956.514476612,
|
72
|
+
45308.83204108345,
|
73
|
+
-835.0733177529921,
|
74
|
+
532.7416548573802,
|
75
|
+
7536.358971876497,
|
76
|
+
],
|
77
|
+
[
|
78
|
+
"2023-04-18T08:28:38.744064",
|
79
|
+
-3315083.6438685474,
|
80
|
+
-6049420.098929363,
|
81
|
+
52845.16268340493,
|
82
|
+
-831.0430512241197,
|
83
|
+
540.0974039686765,
|
84
|
+
7536.299161297429,
|
85
|
+
],
|
86
|
+
[
|
87
|
+
"2023-04-18T08:28:39.744064",
|
88
|
+
-3315912.6749859042,
|
89
|
+
-6048876.327944793,
|
90
|
+
60381.42893867038,
|
91
|
+
-827.0117457081434,
|
92
|
+
547.4525485342174,
|
93
|
+
7536.23016144972,
|
94
|
+
],
|
95
|
+
[
|
96
|
+
"2023-04-18T08:28:40.744064",
|
97
|
+
-3316737.6742961914,
|
98
|
+
-6048325.2021318525,
|
99
|
+
67917.62161760827,
|
100
|
+
-822.9794061376964,
|
101
|
+
554.8070795189376,
|
102
|
+
7536.1519722880375,
|
103
|
+
],
|
104
|
+
[
|
105
|
+
"2023-04-18T08:28:41.744064",
|
106
|
+
-3317558.640767768,
|
107
|
+
-6047766.722108539,
|
108
|
+
75453.73153099201,
|
109
|
+
-818.9460374467976,
|
110
|
+
562.1609878883643,
|
111
|
+
7536.064593778564,
|
112
|
+
],
|
113
|
+
[
|
114
|
+
"2023-04-18T08:28:42.744064",
|
115
|
+
-3318375.5733739412,
|
116
|
+
-6047200.888501875,
|
117
|
+
82989.7494894997,
|
118
|
+
-814.9116445709234,
|
119
|
+
569.5142646084902,
|
120
|
+
7535.968025898996,
|
121
|
+
],
|
122
|
+
[
|
123
|
+
"2023-04-18T08:28:43.744064",
|
124
|
+
-3319188.471092942,
|
125
|
+
-6046627.7019479135,
|
126
|
+
90525.66630384693,
|
127
|
+
-810.8762324469382,
|
128
|
+
576.866900645898,
|
129
|
+
7535.862268638544,
|
130
|
+
],
|
131
|
+
[
|
132
|
+
"2023-04-18T08:28:44.744064",
|
133
|
+
-3319997.332907958,
|
134
|
+
-6046047.163091751,
|
135
|
+
98061.47278470133,
|
136
|
+
-806.8398060131411,
|
137
|
+
584.2188869676824,
|
138
|
+
7535.747321997941,
|
139
|
+
],
|
140
|
+
[
|
141
|
+
"2023-04-18T08:28:45.744064",
|
142
|
+
-3320802.157807084,
|
143
|
+
-6045459.272587514,
|
144
|
+
105597.15974279115,
|
145
|
+
-802.8023702092072,
|
146
|
+
591.5702145415504,
|
147
|
+
7535.62318598943,
|
148
|
+
],
|
149
|
+
[
|
150
|
+
"2023-04-18T08:28:46.744064",
|
151
|
+
-3321602.9447833803,
|
152
|
+
-6044864.0310983565,
|
153
|
+
113132.71798877101,
|
154
|
+
-798.7639299762548,
|
155
|
+
598.9208743356983,
|
156
|
+
7535.48986063679,
|
157
|
+
],
|
158
|
+
[
|
159
|
+
"2023-04-18T08:28:47.744064",
|
160
|
+
-3322399.692834845,
|
161
|
+
-6044261.439296465,
|
162
|
+
120668.13833342775,
|
163
|
+
-794.7244902567405,
|
164
|
+
606.2708573190106,
|
165
|
+
7535.347345975296,
|
166
|
+
],
|
167
|
+
[
|
168
|
+
"2023-04-18T08:28:48.744064",
|
169
|
+
-3323192.400964402,
|
170
|
+
-6043651.497863061,
|
171
|
+
128203.41158748553,
|
172
|
+
-790.6840559945587,
|
173
|
+
613.6201544608678,
|
174
|
+
7535.195642051765,
|
175
|
+
],
|
176
|
+
[
|
177
|
+
"2023-04-18T08:28:49.744064",
|
178
|
+
-3323981.068179951,
|
179
|
+
-6043034.207488383,
|
180
|
+
135738.52856182377,
|
181
|
+
-786.6426321349277,
|
182
|
+
620.9687567313651,
|
183
|
+
7535.034748924513,
|
184
|
+
],
|
185
|
+
[
|
186
|
+
"2023-04-18T08:28:50.744064",
|
187
|
+
-3324765.6934943097,
|
188
|
+
-6042409.568871722,
|
189
|
+
143273.48006733102,
|
190
|
+
-782.6002236244674,
|
191
|
+
628.3166551011666,
|
192
|
+
7534.864666663388,
|
193
|
+
],
|
194
|
+
[
|
195
|
+
"2023-04-18T08:28:51.744064",
|
196
|
+
-3325546.2759252544,
|
197
|
+
-6041777.582721372,
|
198
|
+
150808.25691495842,
|
199
|
+
-778.5568354111685,
|
200
|
+
635.6638405415614,
|
201
|
+
7534.68539534976,
|
202
|
+
],
|
203
|
+
]
|
204
|
+
return [
|
205
|
+
State(
|
206
|
+
instant=Instant.date_time(DateTime.parse(row[0]), Scale.UTC),
|
207
|
+
position=Position.meters(
|
208
|
+
[float(row[1]), float(row[2]), float(row[3])], Frame.GCRF()
|
209
|
+
),
|
210
|
+
velocity=Velocity.meters_per_second(
|
211
|
+
[float(row[4]), float(row[5]), float(row[6])], Frame.GCRF()
|
212
|
+
),
|
213
|
+
)
|
214
|
+
for row in data
|
215
|
+
]
|
216
|
+
|
217
|
+
|
218
|
+
@pytest.fixture
|
219
|
+
def test_states(reference_states: list[State]) -> list[State]:
|
220
|
+
return reference_states[::4]
|
221
|
+
|
222
|
+
|
223
|
+
@pytest.fixture
|
224
|
+
def interpolation_type() -> Interpolator.Type:
|
225
|
+
return Interpolator.Type.CubicSpline
|
226
|
+
|
227
|
+
|
228
|
+
@pytest.fixture
|
229
|
+
def tabulated(
|
230
|
+
test_states: list[State],
|
231
|
+
interpolation_type: Interpolator.Type,
|
232
|
+
) -> Tabulated:
|
233
|
+
return Tabulated(
|
234
|
+
states=test_states,
|
235
|
+
interpolation_type=interpolation_type,
|
236
|
+
)
|
237
|
+
|
238
|
+
|
239
|
+
class TestTabulatedTrajectory:
|
240
|
+
@pytest.mark.parametrize(
|
241
|
+
"interpolation_type",
|
242
|
+
(
|
243
|
+
(Interpolator.Type.Linear),
|
244
|
+
(Interpolator.Type.CubicSpline),
|
245
|
+
(Interpolator.Type.BarycentricRational),
|
246
|
+
),
|
247
|
+
)
|
248
|
+
def test_constructor(
|
249
|
+
self,
|
250
|
+
test_states: list[State],
|
251
|
+
interpolation_type: Interpolator.Type,
|
252
|
+
):
|
253
|
+
assert (
|
254
|
+
Tabulated(
|
255
|
+
states=test_states,
|
256
|
+
interpolation_type=interpolation_type,
|
257
|
+
)
|
258
|
+
is not None
|
259
|
+
)
|
260
|
+
|
261
|
+
def test_get_interpolation_type(
|
262
|
+
self,
|
263
|
+
test_states: list[State],
|
264
|
+
tabulated: Tabulated,
|
265
|
+
interpolation_type: Interpolator.Type,
|
266
|
+
):
|
267
|
+
assert tabulated.get_interpolation_type() == Interpolator.Type.CubicSpline
|
268
|
+
|
269
|
+
@pytest.mark.parametrize(
|
270
|
+
"interpolation_type,error_tolerance",
|
271
|
+
(
|
272
|
+
(Interpolator.Type.Linear, 420.0),
|
273
|
+
(Interpolator.Type.CubicSpline, 5e-3),
|
274
|
+
(Interpolator.Type.BarycentricRational, 5e-2),
|
275
|
+
),
|
276
|
+
)
|
277
|
+
def test_calculate_state_at(
|
278
|
+
self,
|
279
|
+
test_states: list[State],
|
280
|
+
reference_states: list[State],
|
281
|
+
interpolation_type: Interpolator.Type,
|
282
|
+
error_tolerance: float,
|
283
|
+
):
|
284
|
+
tabulated: Tabulated = Tabulated(
|
285
|
+
states=test_states,
|
286
|
+
interpolation_type=interpolation_type,
|
287
|
+
)
|
288
|
+
|
289
|
+
for reference_state in reference_states:
|
290
|
+
if not tabulated.get_interval().contains_instant(
|
291
|
+
reference_state.get_instant()
|
292
|
+
):
|
293
|
+
continue
|
294
|
+
|
295
|
+
calculated_state: State = tabulated.calculate_state_at(
|
296
|
+
reference_state.get_instant()
|
297
|
+
)
|
298
|
+
assert np.all(
|
299
|
+
np.abs(
|
300
|
+
calculated_state.get_coordinates() - reference_state.get_coordinates()
|
301
|
+
)
|
302
|
+
< error_tolerance
|
303
|
+
)
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# Apache License 2.0
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from ostk.physics.coordinate.spherical import LLA
|
6
|
+
from ostk.physics.environment.object.celestial import Earth
|
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.time import Duration
|
11
|
+
from ostk.physics.unit import Derived
|
12
|
+
from ostk.astrodynamics.trajectory.model import TargetScan
|
13
|
+
from ostk.astrodynamics.trajectory import State
|
14
|
+
|
15
|
+
|
16
|
+
@pytest.fixture
|
17
|
+
def earth() -> Earth:
|
18
|
+
return Earth.WGS84()
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.fixture
|
22
|
+
def start_lla() -> LLA:
|
23
|
+
return LLA.vector([0.0, 0.0, 0.0])
|
24
|
+
|
25
|
+
|
26
|
+
@pytest.fixture
|
27
|
+
def end_lla() -> LLA:
|
28
|
+
return LLA.vector([0.0, 1.0, 0.0])
|
29
|
+
|
30
|
+
|
31
|
+
@pytest.fixture
|
32
|
+
def start_instant() -> Instant:
|
33
|
+
return Instant.date_time(DateTime(2023, 1, 1, 0, 0, 0), Scale.UTC)
|
34
|
+
|
35
|
+
|
36
|
+
@pytest.fixture
|
37
|
+
def end_instant() -> Instant:
|
38
|
+
return Instant.date_time(DateTime(2023, 1, 1, 0, 10, 0), Scale.UTC)
|
39
|
+
|
40
|
+
|
41
|
+
@pytest.fixture
|
42
|
+
def target_scan(
|
43
|
+
earth: Earth,
|
44
|
+
start_lla: LLA,
|
45
|
+
end_lla: LLA,
|
46
|
+
start_instant: Instant,
|
47
|
+
end_instant: Instant,
|
48
|
+
) -> TargetScan:
|
49
|
+
return TargetScan(
|
50
|
+
start_lla=start_lla,
|
51
|
+
end_lla=end_lla,
|
52
|
+
start_instant=start_instant,
|
53
|
+
end_instant=end_instant,
|
54
|
+
celestial=earth,
|
55
|
+
)
|
56
|
+
|
57
|
+
|
58
|
+
class TestTargetScan:
|
59
|
+
def test_constructor(
|
60
|
+
self,
|
61
|
+
target_scan: TargetScan,
|
62
|
+
):
|
63
|
+
assert target_scan.is_defined()
|
64
|
+
|
65
|
+
def test_calculate_state_at(
|
66
|
+
self,
|
67
|
+
target_scan: TargetScan,
|
68
|
+
):
|
69
|
+
instant: Instant = Instant.date_time(DateTime(2023, 1, 1, 0, 5, 0), Scale.UTC)
|
70
|
+
state: State = target_scan.calculate_state_at(instant)
|
71
|
+
assert state is not None
|
72
|
+
|
73
|
+
def test_equality_operator(
|
74
|
+
self,
|
75
|
+
target_scan: TargetScan,
|
76
|
+
):
|
77
|
+
assert target_scan == target_scan
|
78
|
+
|
79
|
+
def test_inequality_operator(
|
80
|
+
self,
|
81
|
+
target_scan: TargetScan,
|
82
|
+
start_lla: LLA,
|
83
|
+
end_lla: LLA,
|
84
|
+
start_instant: Instant,
|
85
|
+
earth: Earth,
|
86
|
+
):
|
87
|
+
target_scan2 = TargetScan(
|
88
|
+
start_lla=start_lla,
|
89
|
+
end_lla=end_lla,
|
90
|
+
start_instant=start_instant,
|
91
|
+
end_instant=Instant.undefined(),
|
92
|
+
celestial=earth,
|
93
|
+
)
|
94
|
+
assert target_scan != target_scan2
|
95
|
+
|
96
|
+
def test_getters(
|
97
|
+
self,
|
98
|
+
target_scan: TargetScan,
|
99
|
+
):
|
100
|
+
assert target_scan.get_start_lla() is not None
|
101
|
+
assert target_scan.get_end_lla() is not None
|
102
|
+
assert target_scan.get_start_instant() is not None
|
103
|
+
assert target_scan.get_end_instant() is not None
|
104
|
+
assert target_scan.get_celestial() is not None
|
105
|
+
assert target_scan.get_step_size() is not None
|
106
|
+
|
107
|
+
def test_from_ground_speed(
|
108
|
+
self,
|
109
|
+
start_lla: LLA,
|
110
|
+
end_lla: LLA,
|
111
|
+
start_instant: Instant,
|
112
|
+
earth: Earth,
|
113
|
+
):
|
114
|
+
ground_speed: Derived = Derived(100.0, Derived.Unit.meter_per_second())
|
115
|
+
step_size: Duration = Duration.seconds(1.0)
|
116
|
+
|
117
|
+
target_scan = TargetScan.from_ground_speed(
|
118
|
+
start_lla=start_lla,
|
119
|
+
end_lla=end_lla,
|
120
|
+
ground_speed=ground_speed,
|
121
|
+
start_instant=start_instant,
|
122
|
+
celestial=earth,
|
123
|
+
step_size=step_size,
|
124
|
+
)
|
125
|
+
|
126
|
+
assert target_scan.is_defined()
|
@@ -10,9 +10,10 @@ import ostk.physics.environment.object
|
|
10
10
|
import ostk.physics.time
|
11
11
|
import ostk.physics.unit
|
12
12
|
import typing
|
13
|
+
from . import model
|
13
14
|
from . import orbit
|
14
15
|
from . import state
|
15
|
-
__all__ = ['LocalOrbitalFrameDirection', 'LocalOrbitalFrameFactory', 'LocalOrbitalFrameTransformProvider', 'Model', 'Orbit', 'Propagator', 'Segment', 'Sequence', 'State', 'StateBuilder', 'orbit', 'state']
|
16
|
+
__all__ = ['LocalOrbitalFrameDirection', 'LocalOrbitalFrameFactory', 'LocalOrbitalFrameTransformProvider', 'Model', 'Orbit', 'Propagator', 'Segment', 'Sequence', 'State', 'StateBuilder', 'model', 'orbit', 'state']
|
16
17
|
class LocalOrbitalFrameDirection:
|
17
18
|
"""
|
18
19
|
|
@@ -323,7 +324,7 @@ class LocalOrbitalFrameTransformProvider:
|
|
323
324
|
class Model:
|
324
325
|
"""
|
325
326
|
|
326
|
-
|
327
|
+
Trajectory model.
|
327
328
|
|
328
329
|
|
329
330
|
"""
|
@@ -1658,7 +1659,7 @@ class StateBuilder:
|
|
1658
1659
|
coordinate_subsets list[CoordinateSubset]: The coordinate subsets.
|
1659
1660
|
|
1660
1661
|
Returns:
|
1661
|
-
StateBuilder
|
1662
|
+
StateBuilder: The new `StateBuilder` object.
|
1662
1663
|
"""
|
1663
1664
|
@typing.overload
|
1664
1665
|
def __init__(self, frame: ostk.physics.coordinate.Frame, coordinate_broker: state.CoordinateBroker) -> None:
|
@@ -1720,18 +1721,18 @@ class StateBuilder:
|
|
1720
1721
|
coordinates (VectorXd): The coordinates of the state.
|
1721
1722
|
|
1722
1723
|
Returns:
|
1723
|
-
State:
|
1724
|
+
State: A `State` object built from the `StateBuilder`.
|
1724
1725
|
"""
|
1725
1726
|
def expand(self, state: State, default_state: State) -> State:
|
1726
1727
|
"""
|
1727
|
-
Expand a `State` object to the `StateBuilder`.
|
1728
|
+
Expand a `State` object to the coordinate subsets of the `StateBuilder`.
|
1728
1729
|
|
1729
1730
|
Arguments:
|
1730
1731
|
state (State): The `State` object to expand.
|
1731
|
-
default_state (State): The
|
1732
|
+
default_state (State): The `State` object used to supply any additional coordinates.
|
1732
1733
|
|
1733
1734
|
Returns:
|
1734
|
-
|
1735
|
+
State: A `State` object with the coordinate subsets of the `StateBuilder`.
|
1735
1736
|
"""
|
1736
1737
|
def get_coordinate_subsets(self) -> list[state.CoordinateSubset]:
|
1737
1738
|
"""
|
@@ -1763,11 +1764,11 @@ class StateBuilder:
|
|
1763
1764
|
"""
|
1764
1765
|
def reduce(self, state: State) -> State:
|
1765
1766
|
"""
|
1766
|
-
Reduce a `State` object to the `StateBuilder`.
|
1767
|
+
Reduce a `State` object to the coordinate subsets of the `StateBuilder`.
|
1767
1768
|
|
1768
1769
|
Arguments:
|
1769
1770
|
state (State): The `State` object to reduce.
|
1770
1771
|
|
1771
1772
|
Returns:
|
1772
|
-
|
1773
|
+
State: A `State` object with the coordinate subsets of the `StateBuilder`.
|
1773
1774
|
"""
|
@@ -0,0 +1,259 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
import ostk.astrodynamics.trajectory
|
3
|
+
import ostk.mathematics.curve_fitting
|
4
|
+
import ostk.physics.coordinate.spherical
|
5
|
+
import ostk.physics.environment.object
|
6
|
+
import ostk.physics.time
|
7
|
+
import ostk.physics.unit
|
8
|
+
import typing
|
9
|
+
__all__ = ['Nadir', 'Tabulated', 'TargetScan']
|
10
|
+
class Nadir(ostk.astrodynamics.trajectory.Model):
|
11
|
+
"""
|
12
|
+
|
13
|
+
Nadir trajectory model.
|
14
|
+
|
15
|
+
This model represents a trajectory that follows the nadir direction of an orbit.
|
16
|
+
|
17
|
+
"""
|
18
|
+
__hash__: typing.ClassVar[None] = None
|
19
|
+
def __eq__(self, arg0: Nadir) -> bool:
|
20
|
+
...
|
21
|
+
def __init__(self, orbit: ostk.astrodynamics.trajectory.Orbit, step_size: ostk.physics.time.Duration = ...) -> None:
|
22
|
+
"""
|
23
|
+
Construct a `Nadir` object from an orbit.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
orbit (Orbit): The orbit.
|
27
|
+
step_size (Duration): The step size for the trajectory. Defaults to 1e-2 seconds.
|
28
|
+
|
29
|
+
Returns:
|
30
|
+
Nadir: The `Nadir` object.
|
31
|
+
"""
|
32
|
+
def __ne__(self, arg0: Nadir) -> bool:
|
33
|
+
...
|
34
|
+
def __repr__(self) -> str:
|
35
|
+
...
|
36
|
+
def __str__(self) -> str:
|
37
|
+
...
|
38
|
+
def calculate_state_at(self, instant: ostk.physics.time.Instant) -> ostk.astrodynamics.trajectory.State:
|
39
|
+
"""
|
40
|
+
Calculate the state at a given instant.
|
41
|
+
|
42
|
+
Args:
|
43
|
+
instant (Instant): The instant.
|
44
|
+
|
45
|
+
Returns:
|
46
|
+
State: The state at the given instant.
|
47
|
+
"""
|
48
|
+
def get_orbit(self) -> ostk.astrodynamics.trajectory.Orbit:
|
49
|
+
"""
|
50
|
+
Get the orbit of the nadir model.
|
51
|
+
|
52
|
+
Returns:
|
53
|
+
Orbit: The orbit of the nadir model.
|
54
|
+
"""
|
55
|
+
def get_step_size(self) -> ostk.physics.time.Duration:
|
56
|
+
"""
|
57
|
+
Get the step size of the nadir model.
|
58
|
+
|
59
|
+
Returns:
|
60
|
+
Duration: The step size of the nadir model.
|
61
|
+
"""
|
62
|
+
def is_defined(self) -> bool:
|
63
|
+
"""
|
64
|
+
Check if the model is defined.
|
65
|
+
|
66
|
+
Returns:
|
67
|
+
bool: True if the model is defined, False otherwise.
|
68
|
+
"""
|
69
|
+
class Tabulated(ostk.astrodynamics.trajectory.Model):
|
70
|
+
"""
|
71
|
+
|
72
|
+
A trajectory model defined by a set of states.
|
73
|
+
|
74
|
+
|
75
|
+
"""
|
76
|
+
def __init__(self, states: list[ostk.astrodynamics.trajectory.State], interpolation_type: ostk.mathematics.curve_fitting.Interpolator.Type = ...) -> None:
|
77
|
+
"""
|
78
|
+
Constructor.
|
79
|
+
|
80
|
+
Args:
|
81
|
+
states (Array[State]): The states of the model.
|
82
|
+
interpolation_type (Interpolator.Type): The type of interpolation to use. Defaults to Linear.
|
83
|
+
"""
|
84
|
+
def __repr__(self) -> str:
|
85
|
+
"""
|
86
|
+
Convert the model to a string.
|
87
|
+
|
88
|
+
Returns:
|
89
|
+
str: The string representation of the model.
|
90
|
+
"""
|
91
|
+
def __str__(self) -> str:
|
92
|
+
"""
|
93
|
+
Convert the model to a string.
|
94
|
+
|
95
|
+
Returns:
|
96
|
+
str: The string representation of the model.
|
97
|
+
"""
|
98
|
+
def calculate_state_at(self, instant: ostk.physics.time.Instant) -> ostk.astrodynamics.trajectory.State:
|
99
|
+
"""
|
100
|
+
Calculate the state of the model at a specific instant.
|
101
|
+
|
102
|
+
Args:
|
103
|
+
instant (Instant): The instant at which to calculate the state.
|
104
|
+
|
105
|
+
Returns:
|
106
|
+
State: The state of the model at the specified instant.
|
107
|
+
"""
|
108
|
+
def calculate_states_at(self, instants: list[ostk.physics.time.Instant]) -> list[ostk.astrodynamics.trajectory.State]:
|
109
|
+
"""
|
110
|
+
Calculate the states of the model at the specified instants.
|
111
|
+
|
112
|
+
Args:
|
113
|
+
instants (list[Instant]): The instants at which to calculate the states.
|
114
|
+
|
115
|
+
Returns:
|
116
|
+
list[State]: The states of the model at the specified instants.
|
117
|
+
"""
|
118
|
+
def get_first_state(self) -> ostk.astrodynamics.trajectory.State:
|
119
|
+
"""
|
120
|
+
Get the first state of the model.
|
121
|
+
|
122
|
+
Returns:
|
123
|
+
State: The first state of the model.
|
124
|
+
"""
|
125
|
+
def get_interpolation_type(self) -> ostk.mathematics.curve_fitting.Interpolator.Type:
|
126
|
+
"""
|
127
|
+
Get the interpolation type of the model.
|
128
|
+
|
129
|
+
Returns:
|
130
|
+
Interpolator.Type: The interpolation type of the model.
|
131
|
+
"""
|
132
|
+
def get_interval(self) -> ostk.physics.time.Interval:
|
133
|
+
"""
|
134
|
+
Get the interval of the model.
|
135
|
+
|
136
|
+
Returns:
|
137
|
+
Interval: The interval of the model.
|
138
|
+
"""
|
139
|
+
def get_last_state(self) -> ostk.astrodynamics.trajectory.State:
|
140
|
+
"""
|
141
|
+
Get the last state of the model.
|
142
|
+
|
143
|
+
Returns:
|
144
|
+
State: The last state of the model.
|
145
|
+
"""
|
146
|
+
def is_defined(self) -> bool:
|
147
|
+
"""
|
148
|
+
Check if the model is defined.
|
149
|
+
|
150
|
+
Returns:
|
151
|
+
bool: True if the model is defined, False otherwise.
|
152
|
+
"""
|
153
|
+
class TargetScan(ostk.astrodynamics.trajectory.Model):
|
154
|
+
"""
|
155
|
+
|
156
|
+
TargetScan trajectory model.
|
157
|
+
|
158
|
+
This model represents a trajectory that scans between two target locations on a celestial body.
|
159
|
+
|
160
|
+
"""
|
161
|
+
__hash__: typing.ClassVar[None] = None
|
162
|
+
@staticmethod
|
163
|
+
def from_ground_speed(start_lla: ostk.physics.coordinate.spherical.LLA, end_lla: ostk.physics.coordinate.spherical.LLA, ground_speed: ostk.physics.unit.Derived, start_instant: ostk.physics.time.Instant, celestial: ostk.physics.environment.object.Celestial = ..., step_size: ostk.physics.time.Duration = ...) -> TargetScan:
|
164
|
+
"""
|
165
|
+
Construct a `TargetScan` object from ground speed.
|
166
|
+
|
167
|
+
Args:
|
168
|
+
start_lla (LLA): The starting location.
|
169
|
+
end_lla (LLA): The ending location.
|
170
|
+
ground_speed (Derived): The ground speed.
|
171
|
+
start_instant (Instant): The starting instant.
|
172
|
+
celestial (Celestial): The celestial body.
|
173
|
+
step_size (Duration): The step size for the trajectory.
|
174
|
+
|
175
|
+
Returns:
|
176
|
+
TargetScan: The `TargetScan` object.
|
177
|
+
"""
|
178
|
+
def __eq__(self, arg0: TargetScan) -> bool:
|
179
|
+
...
|
180
|
+
def __init__(self, start_lla: ostk.physics.coordinate.spherical.LLA, end_lla: ostk.physics.coordinate.spherical.LLA, start_instant: ostk.physics.time.Instant, end_instant: ostk.physics.time.Instant, celestial: ostk.physics.environment.object.Celestial = ..., step_size: ostk.physics.time.Duration = ...) -> None:
|
181
|
+
"""
|
182
|
+
Construct a `TargetScan` object.
|
183
|
+
|
184
|
+
Args:
|
185
|
+
start_lla (LLA): The starting location.
|
186
|
+
end_lla (LLA): The ending location.
|
187
|
+
start_instant (Instant): The starting instant.
|
188
|
+
end_instant (Instant): The ending instant.
|
189
|
+
celestial (Celestial): The celestial body. Defaults to Earth.WGS84().
|
190
|
+
step_size (Duration): The step size for the trajectory. Defaults to 1e-2 seconds.
|
191
|
+
|
192
|
+
Returns:
|
193
|
+
TargetScan: The `TargetScan` object.
|
194
|
+
"""
|
195
|
+
def __ne__(self, arg0: TargetScan) -> bool:
|
196
|
+
...
|
197
|
+
def __repr__(self) -> str:
|
198
|
+
...
|
199
|
+
def __str__(self) -> str:
|
200
|
+
...
|
201
|
+
def calculate_state_at(self, instant: ostk.physics.time.Instant) -> ostk.astrodynamics.trajectory.State:
|
202
|
+
"""
|
203
|
+
Calculate the state at a given instant.
|
204
|
+
|
205
|
+
Args:
|
206
|
+
instant (Instant): The instant.
|
207
|
+
|
208
|
+
Returns:
|
209
|
+
State: The state at the given instant.
|
210
|
+
"""
|
211
|
+
def get_celestial(self) -> ostk.physics.environment.object.Celestial:
|
212
|
+
"""
|
213
|
+
Get the celestial object of the target scan.
|
214
|
+
|
215
|
+
Returns:
|
216
|
+
Celestial: The celestial object.
|
217
|
+
"""
|
218
|
+
def get_end_instant(self) -> ostk.physics.time.Instant:
|
219
|
+
"""
|
220
|
+
Get the ending instant of the target scan.
|
221
|
+
|
222
|
+
Returns:
|
223
|
+
Instant: The ending instant.
|
224
|
+
"""
|
225
|
+
def get_end_lla(self) -> ostk.physics.coordinate.spherical.LLA:
|
226
|
+
"""
|
227
|
+
Get the ending LLA of the target scan.
|
228
|
+
|
229
|
+
Returns:
|
230
|
+
LLA: The ending LLA.
|
231
|
+
"""
|
232
|
+
def get_start_instant(self) -> ostk.physics.time.Instant:
|
233
|
+
"""
|
234
|
+
Get the starting instant of the target scan.
|
235
|
+
|
236
|
+
Returns:
|
237
|
+
Instant: The starting instant.
|
238
|
+
"""
|
239
|
+
def get_start_lla(self) -> ostk.physics.coordinate.spherical.LLA:
|
240
|
+
"""
|
241
|
+
Get the starting LLA of the target scan.
|
242
|
+
|
243
|
+
Returns:
|
244
|
+
LLA: The starting LLA.
|
245
|
+
"""
|
246
|
+
def get_step_size(self) -> ostk.physics.time.Duration:
|
247
|
+
"""
|
248
|
+
Get the step size of the target scan.
|
249
|
+
|
250
|
+
Returns:
|
251
|
+
Duration: The step size.
|
252
|
+
"""
|
253
|
+
def is_defined(self) -> bool:
|
254
|
+
"""
|
255
|
+
Check if the model is defined.
|
256
|
+
|
257
|
+
Returns:
|
258
|
+
bool: True if the model is defined, False otherwise.
|
259
|
+
"""
|
File without changes
|
File without changes
|
File without changes
|