open-space-toolkit-astrodynamics 15.6.0__py39-none-manylinux2014_x86_64.whl → 16.1.0__py39-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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: open-space-toolkit-astrodynamics
3
- Version: 15.6.0
3
+ Version: 16.1.0
4
4
  Summary: Orbit, attitude, access.
5
5
  Author: Open Space Collective
6
6
  Author-email: contact@open-space-collective.org
@@ -1,7 +1,7 @@
1
1
  ostk/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
2
- ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-39-x86_64-linux-gnu.so,sha256=EAp97vglXjLnBu4dq6QumO26Ii_9wlg_pQgawlbOnpg,2783456
2
+ ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-39-x86_64-linux-gnu.so,sha256=hYcv26NaK9AHaPkJh3rLogej1VLlxftOHxQ_pnvEXAE,2836704
3
3
  ostk/astrodynamics/__init__.py,sha256=3gWyqFIbhAfcdeMhmfBPQPlPQTmaOzm-6flkJe745Zk,251
4
- ostk/astrodynamics/__init__.pyi,sha256=YZjTrv06Z4Ns_NfF1_uhJutkYkQdVnJjYLVSiHCgby0,31428
4
+ ostk/astrodynamics/__init__.pyi,sha256=zD5K2CDpIoulVPA2rVR4ArSPYkMjF-4sgMb-8UydGVE,32193
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
@@ -9,12 +9,12 @@ ostk/astrodynamics/dataframe.py,sha256=v-36rBHKdf7kQw1jdvJWrvkR-ZjW5DKRchtTEJWhd
9
9
  ostk/astrodynamics/display.py,sha256=LZESZgx2wlrFO4cwAGMb3VPJfdtcjNgCgKFrqot0NYU,6339
10
10
  ostk/astrodynamics/dynamics.pyi,sha256=gZ95KoGex4SB-1z6yMrngkZN1Ir9X6bEmrZgdLxq1ZE,13270
11
11
  ostk/astrodynamics/estimator.pyi,sha256=MnahWzp8aACxrNKWlYRsgQr5zpBxogNr-yPm7hJob5k,14000
12
- ostk/astrodynamics/event_condition.pyi,sha256=LXvZCbKnX6kzES7iMG51lJRnIA64YFsU5mUY2RW9fkM,24798
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.15,sha256=wiX7NXvgBVERrXHEVvMrk_ckQiTd-JMebV4jAkJWLqs,120497008
14
+ ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.16,sha256=K8Pnig_cKlxFlypbFxHQAIRtFp1_3pI_9ezyr5jjOR4,122033672
15
15
  ostk/astrodynamics/solver.pyi,sha256=sPqyYPXBfFGC24dzzYyFyt01VfMAlWQ5_gh_RpeaBFk,17734
16
16
  ostk/astrodynamics/utilities.py,sha256=y8mr3M46J5z-GhS1oIEnuEJA6otwcyJ9YDhvn_5JxHM,6976
17
- ostk/astrodynamics/viewer.py,sha256=-Q4migLFOB9dNzs6TRPIXHNewyV5udsDSpcSma0kv8A,16376
17
+ ostk/astrodynamics/viewer.py,sha256=PLznIOEArRlx-pfMHpGoszNRf2F8mf2SHe8CGvZrVnw,16740
18
18
  ostk/astrodynamics/conjunction/__init__.pyi,sha256=HFvWl8bCmrq3cBkUh5X5RGIh8webmVGxaZdpsz3WN-E,79
19
19
  ostk/astrodynamics/conjunction/message/__init__.pyi,sha256=5H__sg_QUx7ybf9jtVWvXzrUHeK3ECotfhddAdHjJUc,75
20
20
  ostk/astrodynamics/conjunction/message/ccsds.pyi,sha256=1Peto19hRqlD7KHf1cyLP3CT4OAKzwtemqvO6_4FZ0g,28162
@@ -26,8 +26,8 @@ ostk/astrodynamics/flight/profile/__init__.pyi,sha256=WBTG17V59UwD-X1r6TOrXT_rA3
26
26
  ostk/astrodynamics/flight/profile/model.pyi,sha256=g5Uy2ZLxImuETrMP4jqXr5FXl2dGAoKuNgzOH07EdBo,6807
27
27
  ostk/astrodynamics/pytrajectory/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
28
28
  ostk/astrodynamics/pytrajectory/__init__.pyi,sha256=QWrGyQNiICBEI3pKku2wJYdu-SQCBKXjJ_93XTEgkP8,79
29
- ostk/astrodynamics/pytrajectory/pystate.py,sha256=c0wR5OJn070ImwVJtW25XhEW7d2_8jkAd168Fo9u6K8,7959
30
- ostk/astrodynamics/pytrajectory/pystate.pyi,sha256=dbYwAoyZo9ZgLjms8nH9s_OhxlmxMLLILR-wXGqphbw,3320
29
+ ostk/astrodynamics/pytrajectory/pystate.py,sha256=HbWtj1_FXGXTuvSu52ewMaO3ahwLBLStyJ4e5xqL-jw,8415
30
+ ostk/astrodynamics/pytrajectory/pystate.pyi,sha256=ljE5Q9Y56dpWgxY75ji9ibrTWIJTXeO29_foHBPxGs4,3413
31
31
  ostk/astrodynamics/test/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
32
32
  ostk/astrodynamics/test/conftest.py,sha256=stmQOt7UXjBlXKJzNN6RkS2miv1xXSOX-YNpFhaHTqI,2771
33
33
  ostk/astrodynamics/test/test_access.py,sha256=MCBsUPtuVm7NgHZR0z0DpWnPZ_qBu4aRhLI2PnRNUYs,3940
@@ -37,7 +37,7 @@ ostk/astrodynamics/test/test_display.py,sha256=6giw_i08YMOSRgqNpdVWtzDu6fFalEVKz
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=0sgGPkMFy-u-33z6SF-sTvaBb_NU7OvaeMTVF6wevfY,3148
40
+ ostk/astrodynamics/test/test_trajectory.py,sha256=GzH7RNRiL088nFeeMm1lhpG4-HEFz15cnWcbD-8VAow,3933
41
41
  ostk/astrodynamics/test/test_utilities.py,sha256=NNIyzqOxMdsNpK2z0wU0utX06iZNfbMJDE36Upard28,3048
42
42
  ostk/astrodynamics/test/test_viewer.py,sha256=kDstRH_WKufN_0JPSXttzLMk3Afv_ylcEBfHxc35yrA,8946
43
43
  ostk/astrodynamics/test/access/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
@@ -62,7 +62,8 @@ ostk/astrodynamics/test/estimator/test_orbit_determination_solver.py,sha256=Vg_y
62
62
  ostk/astrodynamics/test/estimator/test_tle_solver.py,sha256=hANdRtaVvlOShXeyUqMpDk7kJINxdwstZodxJzAAWwk,7277
63
63
  ostk/astrodynamics/test/event_condition/test_angular_condition.py,sha256=MDRwjU5zXIRBaIFZA3jG3hcnyIIFo_0QyBRtNIfH2aQ,3119
64
64
  ostk/astrodynamics/test/event_condition/test_boolean_condition.py,sha256=Ng6FLKD8XoUHUz6-gi3wvrYhSGNSB_iJ_n89ajN4O3s,1580
65
- ostk/astrodynamics/test/event_condition/test_coe_condition.py,sha256=AM0olK1s4jDRs_dJs0sk9raY9Nm1eZpdEEso6wyvipk,2580
65
+ ostk/astrodynamics/test/event_condition/test_brouwer_lyddane_mean_long_condition.py,sha256=H5tXsj-oQRxaLS3CWvtFruUZp1LnvQGu4id3mBu4RJc,4440
66
+ ostk/astrodynamics/test/event_condition/test_coe_condition.py,sha256=dAADq0WEIcA-CvUyhH_6c917bwoaqCQ-XT_ru06Pcqc,4098
66
67
  ostk/astrodynamics/test/event_condition/test_instant_condition.py,sha256=Qr5dN6nrK7XDff7L4vnGCqasMK-Fa6qvxwy_U0xgH5M,1438
67
68
  ostk/astrodynamics/test/event_condition/test_logical_condition.py,sha256=09h5TYWtwGt4NQW3k_tziiVs0Q2981rNII9wyKg7p2Q,3321
68
69
  ostk/astrodynamics/test/event_condition/test_real_condition.py,sha256=tle6HVzMFMIIkfRY7CuaA0mPtw3riJBG_JQkc1L0dpk,1374
@@ -87,8 +88,8 @@ ostk/astrodynamics/test/trajectory/test_model.py,sha256=epnVn2PwdQkUDZ1msqBRO5nE
87
88
  ostk/astrodynamics/test/trajectory/test_orbit.py,sha256=vp7gDMtjO7nqERe0yq1OQZ0p4QRtxGTjGKN5-I3LWZM,6739
88
89
  ostk/astrodynamics/test/trajectory/test_propagator.py,sha256=ALjMvzndO9r6dVVXllk0iqu61tEoqu2j25MtzEitDIQ,14076
89
90
  ostk/astrodynamics/test/trajectory/test_segment.py,sha256=aXdF5CpNLwN_hKRU5sG3ID3hJR-NZ1_kgtNA-xHMBkM,12223
90
- ostk/astrodynamics/test/trajectory/test_sequence.py,sha256=iCNDDqEGoo4WZIOOov0qKGzrxjg7yWVIk8ajfKMhgI4,14503
91
- ostk/astrodynamics/test/trajectory/test_state.py,sha256=th1BvTIhmgsPPFTbVnpR3URvqYFrf0oyluJyoPP7TPI,17135
91
+ ostk/astrodynamics/test/trajectory/test_sequence.py,sha256=4piYpMZ9C_eCXxaOcdz2We67wZxhsNBnETgKwvq6dl0,15083
92
+ ostk/astrodynamics/test/trajectory/test_state.py,sha256=JO-SnUCRZ6sfVNwB5soT5c1f8c5DXuFN5lHZkiiTcYc,18119
92
93
  ostk/astrodynamics/test/trajectory/test_state_builder.py,sha256=LpCCYdCaLu_D2npm9wgA2sMlcekrtbRqP-afe5IE5L4,4871
93
94
  ostk/astrodynamics/test/trajectory/orbit/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
94
95
  ostk/astrodynamics/test/trajectory/orbit/test_model.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
@@ -118,18 +119,18 @@ ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quatern
118
119
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_acceleration.py,sha256=1p37_FYN85d9SrOqO3iCkNecovJJayhnFeZ4QCOw2ao,3528
119
120
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py,sha256=XvHdk1KjacTwtkgx2jUAc9I9N3nvjPDv03FAanpv8jQ,2702
120
121
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py,sha256=-kd5TZO5TICihbkqDTew2i_tDpggdpe3Yf23046FATM,3057
121
- ostk/astrodynamics/trajectory/__init__.pyi,sha256=sxwiGWbo6b4KgJFDUnz4YX2mn0__NXKMUhkWf-cq7q8,75487
122
+ ostk/astrodynamics/trajectory/__init__.pyi,sha256=uC9WD4s1XZpnJy8GhSTap818vHPMgMNieusLaxlzh4U,76264
122
123
  ostk/astrodynamics/trajectory/orbit/__init__.pyi,sha256=wbuRK7Yp_NYBr3ta5-NpnJYMX4baUl7yIlUWhaRlR4o,12899
123
124
  ostk/astrodynamics/trajectory/orbit/message/__init__.pyi,sha256=-GNBlYPrsjelhKxWorYQYhIWzFsibiIQNZvMXjhRpfM,77
124
125
  ostk/astrodynamics/trajectory/orbit/message/spacex.pyi,sha256=fnUVJGWlSPo8AmLVuu08LubsAuVGo-gFaT86yd4f4CI,10558
125
126
  ostk/astrodynamics/trajectory/orbit/model/__init__.pyi,sha256=DYgjafm4rMV9Cqzg6dciwqsJdzuyE8JJgzW8up8qUeE,20370
126
127
  ostk/astrodynamics/trajectory/orbit/model/brouwerLyddaneMean.pyi,sha256=t1jbWsK8JgXkx-l_WSg96xfEG9fsddZ_CjqLpC3GBVY,5874
127
- ostk/astrodynamics/trajectory/orbit/model/kepler.pyi,sha256=KZH_m7mqwXNKFTu4zLRMl_pG7ADQ9Zo6j3FYuVNnLwQ,26955
128
+ ostk/astrodynamics/trajectory/orbit/model/kepler.pyi,sha256=OZMznHuU7e6m1rfqtOgXbgBguimv4tg1RRvxRFQVAlw,27171
128
129
  ostk/astrodynamics/trajectory/orbit/model/sgp4.pyi,sha256=OhFzoPPQHlYy7m3LiZ8TXF89M4uBTfNk6tGsBEp0sjI,14235
129
130
  ostk/astrodynamics/trajectory/state/__init__.pyi,sha256=bq__Fii35czVrTeNxc9eQVjXdqwbbQxUdNQWK3vLrMo,17649
130
131
  ostk/astrodynamics/trajectory/state/coordinate_subset.pyi,sha256=kYMfMwEjCqO1NepMYFT4QS6kIPBkVL6sGCLeLbogcMw,10176
131
- open_space_toolkit_astrodynamics-15.6.0.dist-info/METADATA,sha256=5Nm6f5thffoDOhAlypysgUY8KnkhTGONPBbGR8LSJOI,1913
132
- open_space_toolkit_astrodynamics-15.6.0.dist-info/WHEEL,sha256=Lf7t-kOlAeOyExg08NFEPC9xn1Q2CLFgwDRGfj0NsM4,109
133
- open_space_toolkit_astrodynamics-15.6.0.dist-info/top_level.txt,sha256=zOR18699uDYnafgarhL8WU_LmTZY_5NVqutv-flp_x4,5
134
- open_space_toolkit_astrodynamics-15.6.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
135
- open_space_toolkit_astrodynamics-15.6.0.dist-info/RECORD,,
132
+ open_space_toolkit_astrodynamics-16.1.0.dist-info/METADATA,sha256=-oOEr23wSU5vy8jOZpmEflURSXpN7wm-K4nMa6S9JPc,1913
133
+ open_space_toolkit_astrodynamics-16.1.0.dist-info/WHEEL,sha256=Lf7t-kOlAeOyExg08NFEPC9xn1Q2CLFgwDRGfj0NsM4,109
134
+ open_space_toolkit_astrodynamics-16.1.0.dist-info/top_level.txt,sha256=zOR18699uDYnafgarhL8WU_LmTZY_5NVqutv-flp_x4,5
135
+ open_space_toolkit_astrodynamics-16.1.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
136
+ open_space_toolkit_astrodynamics-16.1.0.dist-info/RECORD,,
@@ -5,8 +5,8 @@ from ostk.astrodynamics.trajectory import State as PyState
5
5
  from ostk import core as OpenSpaceToolkitCorePy
6
6
  from ostk.core import container
7
7
  from ostk.core import filesystem
8
- import ostk.core.type
9
8
  from ostk.core import type
9
+ import ostk.core.type
10
10
  from ostk import io as OpenSpaceToolkitIOPy
11
11
  from ostk.io import URL
12
12
  from ostk.io import ip
@@ -24,10 +24,10 @@ from ostk.physics import coordinate
24
24
  import ostk.physics.coordinate.spherical
25
25
  from ostk.physics import environment
26
26
  import ostk.physics.environment.object
27
- import ostk.physics.time
28
27
  from ostk.physics import time
29
- import ostk.physics.unit
28
+ import ostk.physics.time
30
29
  from ostk.physics import unit
30
+ import ostk.physics.unit
31
31
  import typing
32
32
  from . import access
33
33
  from . import conjunction
@@ -672,6 +672,19 @@ class Trajectory:
672
672
  Trajectory: The `Trajectory` object representing the ground strip.
673
673
  """
674
674
  @staticmethod
675
+ def ground_strip_geodetic_nadir(orbit: typing.Any, instants: list[ostk.physics.time.Instant], celestial_object: ostk.physics.environment.object.Celestial = ...) -> Trajectory:
676
+ """
677
+ Create a `Trajectory` object representing a ground strip that follows the geodetic nadir of the provided orbit.
678
+
679
+ Args:
680
+ orbit (Orbit): The orbit.
681
+ instants (list[Instant]): The instants.
682
+ celestial_object (Celestial): The celestial object. Defaults to Earth.WGS84().
683
+
684
+ Returns:
685
+ Trajectory: The `Trajectory` object representing the ground strip.
686
+ """
687
+ @staticmethod
675
688
  def position(position: ostk.physics.coordinate.Position) -> Trajectory:
676
689
  """
677
690
  Create a `Trajectory` object representing a position.
@@ -6,7 +6,7 @@ import ostk.physics.coordinate
6
6
  import ostk.physics.time
7
7
  import ostk.physics.unit
8
8
  import typing
9
- __all__ = ['AngularCondition', 'BooleanCondition', 'COECondition', 'InstantCondition', 'LogicalCondition', 'RealCondition']
9
+ __all__ = ['AngularCondition', 'BooleanCondition', 'BrouwerLyddaneMeanLongCondition', 'COECondition', 'InstantCondition', 'LogicalCondition', 'RealCondition']
10
10
  class AngularCondition(ostk.astrodynamics.EventCondition):
11
11
  """
12
12
 
@@ -193,6 +193,244 @@ class BooleanCondition(RealCondition):
193
193
  Returns:
194
194
  bool: True if the condition is satisfied, False otherwise.
195
195
  """
196
+ class BrouwerLyddaneMeanLongCondition:
197
+ """
198
+
199
+ A Brouwer-Lyddane Mean Long Event Condition.
200
+
201
+
202
+ """
203
+ @staticmethod
204
+ @typing.overload
205
+ def aop(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, aop: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
206
+ """
207
+ Create a Brouwer-Lyddane Mean Long condition based on the argument of perigee.
208
+
209
+ Args:
210
+ criterion (Criterion): The criterion.
211
+ frame (Frame): The reference frame.
212
+ aop (EventConditionTarget): The argument of perigee.
213
+ gravitational_parameter (Derived): The gravitational parameter.
214
+
215
+ Returns:
216
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
217
+ """
218
+ @staticmethod
219
+ @typing.overload
220
+ def aop(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
221
+ """
222
+ Create a Brouwer-Lyddane Mean Long condition based on the argument of perigee being within a range.
223
+
224
+ Args:
225
+ frame (Frame): The reference frame.
226
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
227
+ gravitational_parameter (Derived): The gravitational parameter.
228
+
229
+ Returns:
230
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
231
+ """
232
+ @staticmethod
233
+ @typing.overload
234
+ def argument_of_latitude(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, argument_of_latitude: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
235
+ """
236
+ Create a Brouwer-Lyddane Mean Long condition based on the argument of latitude.
237
+
238
+ Args:
239
+ criterion (Criterion): The criterion.
240
+ frame (Frame): The reference frame.
241
+ argument_of_latitude (EventConditionTarget): The argument of latitude.
242
+ gravitational_parameter (Derived): The gravitational parameter.
243
+
244
+ Returns:
245
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
246
+ """
247
+ @staticmethod
248
+ @typing.overload
249
+ def argument_of_latitude(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
250
+ """
251
+ Create a Brouwer-Lyddane Mean Long condition based on the argument of latitude being within a range.
252
+
253
+ Args:
254
+ frame (Frame): The reference frame.
255
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
256
+ gravitational_parameter (Derived): The gravitational parameter.
257
+
258
+ Returns:
259
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
260
+ """
261
+ @staticmethod
262
+ @typing.overload
263
+ def eccentric_anomaly(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, eccentric_anomaly: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
264
+ """
265
+ Create a Brouwer-Lyddane Mean Long condition based on the eccentric anomaly.
266
+
267
+ Args:
268
+ criterion (Criterion): The criterion.
269
+ frame (Frame): The reference frame.
270
+ eccentric_anomaly (EventConditionTarget): The eccentric anomaly.
271
+ gravitational_parameter (Derived): The gravitational parameter.
272
+
273
+ Returns:
274
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
275
+ """
276
+ @staticmethod
277
+ @typing.overload
278
+ def eccentric_anomaly(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
279
+ """
280
+ Create a Brouwer-Lyddane Mean Long condition based on the eccentric anomaly being within a range.
281
+
282
+ Args:
283
+ frame (Frame): The reference frame.
284
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
285
+ gravitational_parameter (Derived): The gravitational parameter.
286
+
287
+ Returns:
288
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
289
+ """
290
+ @staticmethod
291
+ def eccentricity(criterion: RealCondition.Criterion, frame: ostk.physics.coordinate.Frame, eccentricity: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> RealCondition:
292
+ """
293
+ Create a Brouwer-Lyddane Mean Long condition based on the eccentricity.
294
+
295
+ Args:
296
+ criterion (Criterion): The criterion.
297
+ frame (Frame): The reference frame.
298
+ eccentricity (EventConditionTarget): The eccentricity.
299
+ gravitational_parameter (Derived): The gravitational parameter.
300
+
301
+ Returns:
302
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
303
+ """
304
+ @staticmethod
305
+ @typing.overload
306
+ def inclination(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, inclination: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
307
+ """
308
+ Create a Brouwer-Lyddane Mean Long condition based on the inclination.
309
+
310
+ Args:
311
+ criterion (Criterion): The criterion.
312
+ frame (Frame): The reference frame.
313
+ inclination (EventConditionTarget): The inclination.
314
+ gravitational_parameter (Derived): The gravitational parameter.
315
+
316
+ Returns:
317
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
318
+ """
319
+ @staticmethod
320
+ @typing.overload
321
+ def inclination(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
322
+ """
323
+ Create a Brouwer-Lyddane Mean Long condition based on the inclination being within a range.
324
+
325
+ Args:
326
+ frame (Frame): The reference frame.
327
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
328
+ gravitational_parameter (Derived): The gravitational parameter.
329
+
330
+ Returns:
331
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
332
+ """
333
+ @staticmethod
334
+ @typing.overload
335
+ def mean_anomaly(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, mean_anomaly: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
336
+ """
337
+ Create a Brouwer-Lyddane Mean Long condition based on the mean anomaly.
338
+
339
+ Args:
340
+ criterion (Criterion): The criterion.
341
+ frame (Frame): The reference frame.
342
+ mean_anomaly (EventConditionTarget): The mean anomaly.
343
+ gravitational_parameter (Derived): The gravitational parameter.
344
+
345
+ Returns:
346
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
347
+ """
348
+ @staticmethod
349
+ @typing.overload
350
+ def mean_anomaly(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
351
+ """
352
+ Create a Brouwer-Lyddane Mean Long condition based on the mean anomaly being within a range.
353
+
354
+ Args:
355
+ frame (Frame): The reference frame.
356
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
357
+ gravitational_parameter (Derived): The gravitational parameter.
358
+
359
+ Returns:
360
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
361
+ """
362
+ @staticmethod
363
+ @typing.overload
364
+ def raan(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, raan: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
365
+ """
366
+ Create a Brouwer-Lyddane Mean Long condition based on the right ascension of the ascending node.
367
+
368
+ Args:
369
+ criterion (Criterion): The criterion.
370
+ frame (Frame): The reference frame.
371
+ raan (EventConditionTarget): The right ascension of the ascending node.
372
+ gravitational_parameter (Derived): The gravitational parameter.
373
+
374
+ Returns:
375
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
376
+ """
377
+ @staticmethod
378
+ @typing.overload
379
+ def raan(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
380
+ """
381
+ Create a Brouwer-Lyddane Mean Long condition based on the right ascension of the ascending node being within a range.
382
+
383
+ Args:
384
+ frame (Frame): The reference frame.
385
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
386
+ gravitational_parameter (Derived): The gravitational parameter.
387
+
388
+ Returns:
389
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
390
+ """
391
+ @staticmethod
392
+ def semi_major_axis(criterion: RealCondition.Criterion, frame: ostk.physics.coordinate.Frame, semi_major_axis: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> RealCondition:
393
+ """
394
+ Create a Brouwer-Lyddane Mean Long condition based on the semi-major axis.
395
+
396
+ Args:
397
+ criterion (Criterion): The criterion.
398
+ frame (Frame): The reference frame.
399
+ semi_major_axis (EventConditionTarget): The semi-major axis.
400
+ gravitational_parameter (Derived): The gravitational parameter.
401
+
402
+ Returns:
403
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
404
+ """
405
+ @staticmethod
406
+ @typing.overload
407
+ def true_anomaly(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, true_anomaly: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
408
+ """
409
+ Create a Brouwer-Lyddane Mean Long condition based on the true anomaly.
410
+
411
+ Args:
412
+ criterion (Criterion): The criterion.
413
+ frame (Frame): The reference frame.
414
+ true_anomaly (EventConditionTarget): The true anomaly.
415
+ gravitational_parameter (Derived): The gravitational parameter.
416
+
417
+ Returns:
418
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
419
+ """
420
+ @staticmethod
421
+ @typing.overload
422
+ def true_anomaly(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
423
+ """
424
+ Create a Brouwer-Lyddane Mean Long condition based on the true anomaly being within a range.
425
+
426
+ Args:
427
+ frame (Frame): The reference frame.
428
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
429
+ gravitational_parameter (Derived): The gravitational parameter.
430
+
431
+ Returns:
432
+ BrouwerLyddaneMeanLongCondition: The Brouwer-Lyddane Mean Long condition.
433
+ """
196
434
  class COECondition:
197
435
  """
198
436
 
@@ -201,6 +439,7 @@ class COECondition:
201
439
 
202
440
  """
203
441
  @staticmethod
442
+ @typing.overload
204
443
  def aop(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, aop: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
205
444
  """
206
445
  Create a COE condition based on the argument of perigee.
@@ -209,12 +448,56 @@ class COECondition:
209
448
  criterion (Criterion): The criterion.
210
449
  frame (Frame): The reference frame.
211
450
  aop (EventConditionTarget): The argument of perigee.
212
- gravitational_parameter (float): The gravitational parameter.
451
+ gravitational_parameter (Derived): The gravitational parameter.
452
+
453
+ Returns:
454
+ COECondition: The COE condition.
455
+ """
456
+ @staticmethod
457
+ @typing.overload
458
+ def aop(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
459
+ """
460
+ Create a COE condition based on the argument of perigee being within a range.
461
+
462
+ Args:
463
+ frame (Frame): The reference frame.
464
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
465
+ gravitational_parameter (Derived): The gravitational parameter.
466
+
467
+ Returns:
468
+ COECondition: The COE condition.
469
+ """
470
+ @staticmethod
471
+ @typing.overload
472
+ def argument_of_latitude(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, argument_of_latitude: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
473
+ """
474
+ Create a COE condition based on the argument of latitude.
475
+
476
+ Args:
477
+ criterion (Criterion): The criterion.
478
+ frame (Frame): The reference frame.
479
+ argument_of_latitude (EventConditionTarget): The argument of latitude.
480
+ gravitational_parameter (Derived): The gravitational parameter.
213
481
 
214
482
  Returns:
215
483
  COECondition: The COE condition.
216
484
  """
217
485
  @staticmethod
486
+ @typing.overload
487
+ def argument_of_latitude(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
488
+ """
489
+ Create a COE condition based on the argument of latitude being within a range.
490
+
491
+ Args:
492
+ frame (Frame): The reference frame.
493
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
494
+ gravitational_parameter (Derived): The gravitational parameter.
495
+
496
+ Returns:
497
+ COECondition: The COE condition.
498
+ """
499
+ @staticmethod
500
+ @typing.overload
218
501
  def eccentric_anomaly(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, eccentric_anomaly: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
219
502
  """
220
503
  Create a COE condition based on the eccentric anomaly.
@@ -223,7 +506,21 @@ class COECondition:
223
506
  criterion (Criterion): The criterion.
224
507
  frame (Frame): The reference frame.
225
508
  eccentric_anomaly (EventConditionTarget): The eccentric anomaly.
226
- gravitational_parameter (float): The gravitational parameter.
509
+ gravitational_parameter (Derived): The gravitational parameter.
510
+
511
+ Returns:
512
+ COECondition: The COE condition.
513
+ """
514
+ @staticmethod
515
+ @typing.overload
516
+ def eccentric_anomaly(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
517
+ """
518
+ Create a COE condition based on the eccentric anomaly being within a range.
519
+
520
+ Args:
521
+ frame (Frame): The reference frame.
522
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
523
+ gravitational_parameter (Derived): The gravitational parameter.
227
524
 
228
525
  Returns:
229
526
  COECondition: The COE condition.
@@ -237,12 +534,13 @@ class COECondition:
237
534
  criterion (Criterion): The criterion.
238
535
  frame (Frame): The reference frame.
239
536
  eccentricity (EventConditionTarget): The eccentricity.
240
- gravitational_parameter (float): The gravitational parameter.
537
+ gravitational_parameter (Derived): The gravitational parameter.
241
538
 
242
539
  Returns:
243
540
  COECondition: The COE condition.
244
541
  """
245
542
  @staticmethod
543
+ @typing.overload
246
544
  def inclination(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, inclination: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
247
545
  """
248
546
  Create a COE condition based on the inclination.
@@ -251,12 +549,27 @@ class COECondition:
251
549
  criterion (Criterion): The criterion.
252
550
  frame (Frame): The reference frame.
253
551
  inclination (EventConditionTarget): The inclination.
254
- gravitational_parameter (float): The gravitational parameter.
552
+ gravitational_parameter (Derived): The gravitational parameter.
553
+
554
+ Returns:
555
+ COECondition: The COE condition.
556
+ """
557
+ @staticmethod
558
+ @typing.overload
559
+ def inclination(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
560
+ """
561
+ Create a COE condition based on the inclination being within a range.
562
+
563
+ Args:
564
+ frame (Frame): The reference frame.
565
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
566
+ gravitational_parameter (Derived): The gravitational parameter.
255
567
 
256
568
  Returns:
257
569
  COECondition: The COE condition.
258
570
  """
259
571
  @staticmethod
572
+ @typing.overload
260
573
  def mean_anomaly(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, mean_anomaly: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
261
574
  """
262
575
  Create a COE condition based on the mean anomaly.
@@ -265,12 +578,27 @@ class COECondition:
265
578
  criterion (Criterion): The criterion.
266
579
  frame (Frame): The reference frame.
267
580
  mean_anomaly (EventConditionTarget): The mean anomaly.
268
- gravitational_parameter (float): The gravitational parameter.
581
+ gravitational_parameter (Derived): The gravitational parameter.
269
582
 
270
583
  Returns:
271
584
  COECondition: The COE condition.
272
585
  """
273
586
  @staticmethod
587
+ @typing.overload
588
+ def mean_anomaly(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
589
+ """
590
+ Create a COE condition based on the mean anomaly being within a range.
591
+
592
+ Args:
593
+ frame (Frame): The reference frame.
594
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
595
+ gravitational_parameter (Derived): The gravitational parameter.
596
+
597
+ Returns:
598
+ COECondition: The COE condition.
599
+ """
600
+ @staticmethod
601
+ @typing.overload
274
602
  def raan(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, raan: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
275
603
  """
276
604
  Create a COE condition based on the right ascension of the ascending node.
@@ -279,7 +607,21 @@ class COECondition:
279
607
  criterion (Criterion): The criterion.
280
608
  frame (Frame): The reference frame.
281
609
  raan (EventConditionTarget): The right ascension of the ascending node.
282
- gravitational_parameter (float): The gravitational parameter.
610
+ gravitational_parameter (Derived): The gravitational parameter.
611
+
612
+ Returns:
613
+ COECondition: The COE condition.
614
+ """
615
+ @staticmethod
616
+ @typing.overload
617
+ def raan(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
618
+ """
619
+ Create a COE condition based on the right ascension of the ascending node being within a range.
620
+
621
+ Args:
622
+ frame (Frame): The reference frame.
623
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
624
+ gravitational_parameter (Derived): The gravitational parameter.
283
625
 
284
626
  Returns:
285
627
  COECondition: The COE condition.
@@ -293,12 +635,13 @@ class COECondition:
293
635
  criterion (Criterion): The criterion.
294
636
  frame (Frame): The reference frame.
295
637
  semi_major_axis (EventConditionTarget): The semi-major axis.
296
- gravitational_parameter (float): The gravitational parameter.
638
+ gravitational_parameter (Derived): The gravitational parameter.
297
639
 
298
640
  Returns:
299
641
  COECondition: The COE condition.
300
642
  """
301
643
  @staticmethod
644
+ @typing.overload
302
645
  def true_anomaly(criterion: AngularCondition.Criterion, frame: ostk.physics.coordinate.Frame, true_anomaly: ostk.astrodynamics.EventCondition.Target, gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
303
646
  """
304
647
  Create a COE condition based on the true anomaly.
@@ -307,7 +650,21 @@ class COECondition:
307
650
  criterion (Criterion): The criterion.
308
651
  frame (Frame): The reference frame.
309
652
  true_anomaly (EventConditionTarget): The true anomaly.
310
- gravitational_parameter (float): The gravitational parameter.
653
+ gravitational_parameter (Derived): The gravitational parameter.
654
+
655
+ Returns:
656
+ COECondition: The COE condition.
657
+ """
658
+ @staticmethod
659
+ @typing.overload
660
+ def true_anomaly(frame: ostk.physics.coordinate.Frame, target_range: tuple[ostk.physics.unit.Angle, ostk.physics.unit.Angle], gravitational_parameter: ostk.physics.unit.Derived) -> AngularCondition:
661
+ """
662
+ Create a COE condition based on the true anomaly being within a range.
663
+
664
+ Args:
665
+ frame (Frame): The reference frame.
666
+ target_range (tuple[Angle, Angle]): A tuple of two angles defining the range.
667
+ gravitational_parameter (Derived): The gravitational parameter.
311
668
 
312
669
  Returns:
313
670
  COECondition: The COE condition.
@@ -18,7 +18,7 @@ from ostk.astrodynamics.trajectory.state.coordinate_subset import (
18
18
  AngularVelocity,
19
19
  )
20
20
 
21
- CANONICAL_FORMAT: str = r"(r|v)_(.*?)_(x|y|z)"
21
+ POS_VEL_CANONICAL_FORMAT: str = r"(r|v)_(.*?)_(x|y|z)"
22
22
 
23
23
 
24
24
  def custom_class_generator(frame: Frame, coordinate_subsets: list) -> type:
@@ -68,6 +68,7 @@ def from_dict(data: dict) -> State:
68
68
  - 'drag_coefficient'/'cd': The drag coefficient. Optional.
69
69
  - 'cross_sectional_area'/'surface_area': The cross-sectional area. Optional.
70
70
  - 'mass': The mass. Optional.
71
+ - 'ballistic_coefficient'/'bc': The ballistic coefficient. Optional.
71
72
 
72
73
  Args:
73
74
  data (dict): The dictionary.
@@ -76,7 +77,7 @@ def from_dict(data: dict) -> State:
76
77
  State: The State.
77
78
  """
78
79
 
79
- instant: Instant = coerce_to_instant(data["timestamp"])
80
+ # Position and velocity subsets
80
81
 
81
82
  eci_columns: list[str] = [
82
83
  "rx_eci",
@@ -123,7 +124,7 @@ def from_dict(data: dict) -> State:
123
124
  ]
124
125
 
125
126
  match_groups: list[re.Match] = [
126
- re.match(CANONICAL_FORMAT, column) for column in data.keys()
127
+ re.match(POS_VEL_CANONICAL_FORMAT, column) for column in data.keys()
127
128
  ]
128
129
 
129
130
  if len(matches := [match for match in match_groups if match is not None]) == 6:
@@ -188,6 +189,8 @@ def from_dict(data: dict) -> State:
188
189
  else:
189
190
  raise ValueError("Invalid state data.")
190
191
 
192
+ # Attitude and angular velocity subsets
193
+
191
194
  if all(
192
195
  column in data for column in ["q_B_ECI_x", "q_B_ECI_y", "q_B_ECI_z", "q_B_ECI_s"]
193
196
  ):
@@ -216,6 +219,8 @@ def from_dict(data: dict) -> State:
216
219
  ],
217
220
  )
218
221
 
222
+ # Extra subsets
223
+
219
224
  if (data.get("drag_coefficient") is not None) or (data.get("cd") is not None):
220
225
  coordinate_subsets.append(CoordinateSubset.drag_coefficient())
221
226
  coordinates = np.append(
@@ -239,8 +244,15 @@ def from_dict(data: dict) -> State:
239
244
  data["mass"],
240
245
  )
241
246
 
247
+ if (data.get("ballistic_coefficient") is not None) or (data.get("bc") is not None):
248
+ coordinate_subsets.append(CoordinateSubset.ballistic_coefficient())
249
+ coordinates = np.append(
250
+ coordinates,
251
+ data.get("ballistic_coefficient", data.get("bc")),
252
+ )
253
+
242
254
  return State(
243
- instant=instant,
255
+ instant=coerce_to_instant(data["timestamp"]),
244
256
  coordinates=coordinates,
245
257
  frame=frame,
246
258
  coordinate_subsets=coordinate_subsets,
@@ -13,7 +13,7 @@ import ostk.physics.coordinate
13
13
  from ostk.physics.coordinate import Frame
14
14
  from ostk.physics.time import Instant
15
15
  import re as re
16
- __all__ = ['AngularVelocity', 'AttitudeQuaternion', 'CANONICAL_FORMAT', 'CartesianPosition', 'CartesianVelocity', 'CoordinateSubset', 'Frame', 'Instant', 'State', 'StateBuilder', 'coerce_to_instant', 'custom_class_generator', 'from_dict', 'np', 're']
16
+ __all__ = ['AngularVelocity', 'AttitudeQuaternion', 'CartesianPosition', 'CartesianVelocity', 'CoordinateSubset', 'Frame', 'Instant', 'POS_VEL_CANONICAL_FORMAT', 'State', 'StateBuilder', 'coerce_to_instant', 'custom_class_generator', 'from_dict', 'np', 're']
17
17
  def custom_class_generator(frame: ostk.physics.coordinate.Frame, coordinate_subsets: list) -> type:
18
18
  """
19
19
 
@@ -54,6 +54,7 @@ def from_dict(data: dict) -> ostk.astrodynamics.trajectory.State:
54
54
  - 'drag_coefficient'/'cd': The drag coefficient. Optional.
55
55
  - 'cross_sectional_area'/'surface_area': The cross-sectional area. Optional.
56
56
  - 'mass': The mass. Optional.
57
+ - 'ballistic_coefficient'/'bc': The ballistic coefficient. Optional.
57
58
 
58
59
  Args:
59
60
  data (dict): The dictionary.
@@ -62,4 +63,4 @@ def from_dict(data: dict) -> ostk.astrodynamics.trajectory.State:
62
63
  State: The State.
63
64
 
64
65
  """
65
- CANONICAL_FORMAT: str = '(r|v)_(.*?)_(x|y|z)'
66
+ POS_VEL_CANONICAL_FORMAT: str = '(r|v)_(.*?)_(x|y|z)'
@@ -0,0 +1,135 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics.environment.gravitational import Earth
6
+ from ostk.physics.unit import Derived, Length, Angle
7
+ from ostk.physics.coordinate import Frame
8
+
9
+ from ostk.astrodynamics import EventCondition
10
+ from ostk.astrodynamics.event_condition import (
11
+ BrouwerLyddaneMeanLongCondition,
12
+ AngularCondition,
13
+ RealCondition,
14
+ )
15
+
16
+
17
+ @pytest.fixture
18
+ def criterion() -> AngularCondition.Criterion:
19
+ return AngularCondition.Criterion.AnyCrossing
20
+
21
+
22
+ @pytest.fixture
23
+ def gravitational_parameter() -> Derived:
24
+ return Earth.spherical.gravitational_parameter
25
+
26
+
27
+ @pytest.fixture
28
+ def frame() -> Frame:
29
+ return Frame.GCRF()
30
+
31
+
32
+ class TestBrouwerLyddaneMeanLongCondition:
33
+ @pytest.mark.parametrize(
34
+ "static_constructor,target,criterion",
35
+ (
36
+ (
37
+ BrouwerLyddaneMeanLongCondition.semi_major_axis,
38
+ EventCondition.Target(Length.meters(7e6)),
39
+ RealCondition.Criterion.PositiveCrossing,
40
+ ),
41
+ (
42
+ BrouwerLyddaneMeanLongCondition.eccentricity,
43
+ EventCondition.Target(0.1),
44
+ RealCondition.Criterion.PositiveCrossing,
45
+ ),
46
+ (
47
+ BrouwerLyddaneMeanLongCondition.inclination,
48
+ EventCondition.Target(Angle.degrees(0.0)),
49
+ AngularCondition.Criterion.PositiveCrossing,
50
+ ),
51
+ (
52
+ BrouwerLyddaneMeanLongCondition.aop,
53
+ EventCondition.Target(Angle.degrees(0.0)),
54
+ AngularCondition.Criterion.PositiveCrossing,
55
+ ),
56
+ (
57
+ BrouwerLyddaneMeanLongCondition.raan,
58
+ EventCondition.Target(Angle.degrees(0.0)),
59
+ AngularCondition.Criterion.PositiveCrossing,
60
+ ),
61
+ (
62
+ BrouwerLyddaneMeanLongCondition.true_anomaly,
63
+ EventCondition.Target(Angle.degrees(0.0)),
64
+ AngularCondition.Criterion.PositiveCrossing,
65
+ ),
66
+ (
67
+ BrouwerLyddaneMeanLongCondition.mean_anomaly,
68
+ EventCondition.Target(Angle.degrees(0.0)),
69
+ AngularCondition.Criterion.PositiveCrossing,
70
+ ),
71
+ (
72
+ BrouwerLyddaneMeanLongCondition.eccentric_anomaly,
73
+ EventCondition.Target(Angle.degrees(0.0)),
74
+ AngularCondition.Criterion.PositiveCrossing,
75
+ ),
76
+ (
77
+ BrouwerLyddaneMeanLongCondition.argument_of_latitude,
78
+ EventCondition.Target(Angle.degrees(0.0)),
79
+ AngularCondition.Criterion.PositiveCrossing,
80
+ ),
81
+ ),
82
+ )
83
+ def test_static_constructors(
84
+ self,
85
+ static_constructor,
86
+ target,
87
+ criterion,
88
+ frame: Frame,
89
+ gravitational_parameter: Derived,
90
+ ):
91
+ condition = static_constructor(criterion, frame, target, gravitational_parameter)
92
+ assert condition is not None
93
+
94
+ @pytest.mark.parametrize(
95
+ "static_constructor,target_range",
96
+ (
97
+ (
98
+ BrouwerLyddaneMeanLongCondition.inclination,
99
+ (Angle.degrees(10.0), Angle.degrees(20.0)),
100
+ ),
101
+ (
102
+ BrouwerLyddaneMeanLongCondition.aop,
103
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
104
+ ),
105
+ (
106
+ BrouwerLyddaneMeanLongCondition.raan,
107
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
108
+ ),
109
+ (
110
+ BrouwerLyddaneMeanLongCondition.true_anomaly,
111
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
112
+ ),
113
+ (
114
+ BrouwerLyddaneMeanLongCondition.mean_anomaly,
115
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
116
+ ),
117
+ (
118
+ BrouwerLyddaneMeanLongCondition.eccentric_anomaly,
119
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
120
+ ),
121
+ (
122
+ BrouwerLyddaneMeanLongCondition.argument_of_latitude,
123
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
124
+ ),
125
+ ),
126
+ )
127
+ def test_static_constructors_within_range(
128
+ self,
129
+ static_constructor,
130
+ target_range,
131
+ frame: Frame,
132
+ gravitational_parameter: Derived,
133
+ ):
134
+ condition = static_constructor(frame, target_range, gravitational_parameter)
135
+ assert condition is not None
@@ -73,6 +73,11 @@ class TestCOECondition:
73
73
  EventCondition.Target(Angle.degrees(0.0)),
74
74
  AngularCondition.Criterion.PositiveCrossing,
75
75
  ),
76
+ (
77
+ COECondition.argument_of_latitude,
78
+ EventCondition.Target(Angle.degrees(0.0)),
79
+ AngularCondition.Criterion.PositiveCrossing,
80
+ ),
76
81
  ),
77
82
  )
78
83
  def test_static_constructors(
@@ -85,3 +90,46 @@ class TestCOECondition:
85
90
  ):
86
91
  condition = static_constructor(criterion, frame, target, gravitational_parameter)
87
92
  assert condition is not None
93
+
94
+ @pytest.mark.parametrize(
95
+ "static_constructor,target_range",
96
+ (
97
+ (
98
+ COECondition.inclination,
99
+ (Angle.degrees(10.0), Angle.degrees(20.0)),
100
+ ),
101
+ (
102
+ COECondition.aop,
103
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
104
+ ),
105
+ (
106
+ COECondition.raan,
107
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
108
+ ),
109
+ (
110
+ COECondition.true_anomaly,
111
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
112
+ ),
113
+ (
114
+ COECondition.mean_anomaly,
115
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
116
+ ),
117
+ (
118
+ COECondition.eccentric_anomaly,
119
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
120
+ ),
121
+ (
122
+ COECondition.argument_of_latitude,
123
+ (Angle.degrees(0.0), Angle.degrees(90.0)),
124
+ ),
125
+ ),
126
+ )
127
+ def test_static_constructors_within_range(
128
+ self,
129
+ static_constructor,
130
+ target_range,
131
+ frame: Frame,
132
+ gravitational_parameter: Derived,
133
+ ):
134
+ condition = static_constructor(frame, target_range, gravitational_parameter)
135
+ assert condition is not None
@@ -9,9 +9,12 @@ from ostk.physics.coordinate import Frame
9
9
  from ostk.physics.time import Instant
10
10
  from ostk.physics.time import Duration
11
11
  from ostk.physics.unit import Derived
12
+ from ostk.physics.unit import Length
13
+ from ostk.physics.unit import Angle
12
14
 
13
15
  from ostk.astrodynamics import Trajectory
14
16
  from ostk.astrodynamics.trajectory import State
17
+ from ostk.astrodynamics.trajectory import Orbit
15
18
 
16
19
 
17
20
  @pytest.fixture
@@ -61,6 +64,16 @@ def states(trajectory: Trajectory) -> list[State]:
61
64
  )
62
65
 
63
66
 
67
+ @pytest.fixture
68
+ def orbit() -> Orbit:
69
+ return Orbit.circular(
70
+ epoch=Instant.J2000(),
71
+ altitude=Length.meters(545000.0),
72
+ inclination=Angle.degrees(0.0),
73
+ celestial_object=Earth.WGS84(),
74
+ )
75
+
76
+
64
77
  class TestTrajectory:
65
78
  def test_trajectory(self, states: list[State]):
66
79
  assert Trajectory(states) is not None
@@ -116,3 +129,17 @@ class TestTrajectory:
116
129
 
117
130
  assert Trajectory.ground_strip(start_lla, end_lla, instants, earth) is not None
118
131
  assert Trajectory.ground_strip(start_lla, end_lla, instants) is not None
132
+
133
+ def test_ground_strip_geodetic_nadir(
134
+ self, orbit: Orbit, instants: list[Instant], earth: Earth
135
+ ):
136
+ assert (
137
+ Trajectory.ground_strip_geodetic_nadir(
138
+ orbit=orbit, instants=instants, celestial_object=earth
139
+ )
140
+ is not None
141
+ )
142
+ assert (
143
+ Trajectory.ground_strip_geodetic_nadir(orbit=orbit, instants=instants)
144
+ is not None
145
+ )
@@ -156,17 +156,7 @@ def state(
156
156
 
157
157
  return State(
158
158
  instant,
159
- [
160
- 717094.039086306,
161
- -6872433.2241124,
162
- 46175.9696673281,
163
- -970.650826004612,
164
- -45.4598114773158,
165
- 7529.82424886455,
166
- dry_mass.in_kilograms() + wet_mass.in_kilograms(),
167
- cross_sectional_surface_area,
168
- drag_coefficient,
169
- ],
159
+ coordinates,
170
160
  frame,
171
161
  coordinate_broker,
172
162
  )
@@ -351,6 +341,28 @@ def sequence_solution(
351
341
  )
352
342
 
353
343
 
344
+ @pytest.fixture
345
+ def minimum_maneuver_duration():
346
+ return Duration.minutes(1.0)
347
+
348
+
349
+ @pytest.fixture
350
+ def sequence_with_minimum_maneuver_duration(
351
+ segments: list[Segment],
352
+ numerical_solver: NumericalSolver,
353
+ dynamics: list,
354
+ maximum_propagation_duration: Duration,
355
+ minimum_maneuver_duration: Duration,
356
+ ):
357
+ return Sequence(
358
+ segments=segments,
359
+ dynamics=dynamics,
360
+ numerical_solver=numerical_solver,
361
+ maximum_propagation_duration=maximum_propagation_duration,
362
+ minimum_maneuver_duration=minimum_maneuver_duration,
363
+ )
364
+
365
+
354
366
  class TestSequenceSolution:
355
367
  def test_properties(
356
368
  self,
@@ -421,6 +433,16 @@ class TestSequence:
421
433
  ):
422
434
  assert sequence.get_maximum_propagation_duration() == maximum_propagation_duration
423
435
 
436
+ def test_get_minimum_maneuver_duration(
437
+ self,
438
+ sequence_with_minimum_maneuver_duration: Sequence,
439
+ minimum_maneuver_duration: Duration,
440
+ ):
441
+ assert (
442
+ sequence_with_minimum_maneuver_duration.get_minimum_maneuver_duration()
443
+ == minimum_maneuver_duration
444
+ )
445
+
424
446
  def test_add_segment(
425
447
  self,
426
448
  sequence: Sequence,
@@ -458,6 +458,41 @@ class TestState:
458
458
  assert isinstance(state, State)
459
459
  assert state.get_size() == 6
460
460
 
461
+ def test_from_dict_with_ballistic_coefficient(self):
462
+ data: dict = {
463
+ "timestamp": datetime.now(timezone.utc).isoformat(),
464
+ "rx_eci": 7000.0,
465
+ "ry_eci": 0.0,
466
+ "rz_eci": 0.0,
467
+ "vx_eci": 0.0,
468
+ "vy_eci": 7.5,
469
+ "vz_eci": 0.0,
470
+ "ballistic_coefficient": 2.2,
471
+ }
472
+
473
+ state: State = State.from_dict(data)
474
+
475
+ assert state is not None
476
+ assert isinstance(state, State)
477
+ assert state.get_size() == 7
478
+
479
+ data: dict = {
480
+ "timestamp": datetime.now(timezone.utc).isoformat(),
481
+ "rx_eci": 7000.0,
482
+ "ry_eci": 0.0,
483
+ "rz_eci": 0.0,
484
+ "vx_eci": 0.0,
485
+ "vy_eci": 7.5,
486
+ "vz_eci": 0.0,
487
+ "ballistic_coefficient": None,
488
+ }
489
+
490
+ state: State = State.from_dict(data)
491
+
492
+ assert state is not None
493
+ assert isinstance(state, State)
494
+ assert state.get_size() == 6
495
+
461
496
  @pytest.mark.parametrize(
462
497
  ("data", "expected_length", "expected_frame"),
463
498
  [
@@ -1270,16 +1270,17 @@ class Sequence:
1270
1270
 
1271
1271
  :type: list[SegmentSolution]
1272
1272
  """
1273
- def __init__(self: typing.Sequence, segments: list[Segment] = [], numerical_solver: state.NumericalSolver = ..., dynamics: list[...] = [], maximum_propagation_duration: ostk.physics.time.Duration = ..., verbosity: int = 1) -> None:
1273
+ def __init__(self: typing.Sequence, segments: list[Segment] = [], numerical_solver: state.NumericalSolver = ..., dynamics: list[...] = [], maximum_propagation_duration: ostk.physics.time.Duration = ..., minimum_maneuver_duration: ostk.physics.time.Duration = ..., verbosity: int = 1) -> None:
1274
1274
  """
1275
1275
  Construct a new `Sequence` object.
1276
1276
 
1277
1277
  Args:
1278
- segments (list[Segment], optional): The segments.
1279
- numerical_solver (NumericalSolver, optional): The numerical solver.
1280
- dynamics (list[Dynamics], optional): The dynamics.
1281
- maximum_propagation_duration (Duration, optional): The maximum propagation duration.
1282
- verbosity (int, optional): The verbosity level.
1278
+ segments (list[Segment], optional): The segments. Defaults to an empty list.
1279
+ numerical_solver (NumericalSolver, optional): The numerical solver. Defaults to the default conditional numerical solver.
1280
+ dynamics (list[Dynamics], optional): The dynamics. Defaults to an empty list.
1281
+ maximum_propagation_duration (Duration, optional): The maximum propagation duration. Defaults to 30 days.
1282
+ minimum_maneuver_duration (Duration, optional): The minimum maneuver duration. Defaults to Undefined. If defined, maneuvers less than this duration will be skipped.
1283
+ verbosity (int, optional): The verbosity level. Defaults to 1.
1283
1284
 
1284
1285
  Returns:
1285
1286
  Sequence: The new `Sequence` object.
@@ -1331,6 +1332,13 @@ class Sequence:
1331
1332
  Returns:
1332
1333
  Duration: The maximum propagation duration.
1333
1334
  """
1335
+ def get_minimum_maneuver_duration(self: typing.Sequence) -> ostk.physics.time.Duration:
1336
+ """
1337
+ Get the minimum maneuver duration.
1338
+
1339
+ Returns:
1340
+ Duration: The minimum maneuver duration.
1341
+ """
1334
1342
  def get_numerical_solver(self: typing.Sequence) -> state.NumericalSolver:
1335
1343
  """
1336
1344
  Get the numerical solver.
@@ -1406,6 +1414,7 @@ class State:
1406
1414
  - 'drag_coefficient'/'cd': The drag coefficient. Optional.
1407
1415
  - 'cross_sectional_area'/'surface_area': The cross-sectional area. Optional.
1408
1416
  - 'mass': The mass. Optional.
1417
+ - 'ballistic_coefficient'/'bc': The ballistic coefficient. Optional.
1409
1418
 
1410
1419
  Args:
1411
1420
  data (dict): The dictionary.
@@ -100,8 +100,11 @@ class COE:
100
100
  MeanAnomaly : Mean Anomaly
101
101
 
102
102
  EccentricAnomaly : Eccentric Anomaly
103
+
104
+ ArgumentOfLatitude : Argument of Latitude
103
105
  """
104
106
  Aop: typing.ClassVar[COE.Element] # value = <Element.Aop: 4>
107
+ ArgumentOfLatitude: typing.ClassVar[COE.Element] # value = <Element.ArgumentOfLatitude: 8>
105
108
  EccentricAnomaly: typing.ClassVar[COE.Element] # value = <Element.EccentricAnomaly: 7>
106
109
  Eccentricity: typing.ClassVar[COE.Element] # value = <Element.Eccentricity: 1>
107
110
  Inclination: typing.ClassVar[COE.Element] # value = <Element.Inclination: 2>
@@ -109,7 +112,7 @@ class COE:
109
112
  Raan: typing.ClassVar[COE.Element] # value = <Element.Raan: 3>
110
113
  SemiMajorAxis: typing.ClassVar[COE.Element] # value = <Element.SemiMajorAxis: 0>
111
114
  TrueAnomaly: typing.ClassVar[COE.Element] # value = <Element.TrueAnomaly: 5>
112
- __members__: typing.ClassVar[dict[str, COE.Element]] # value = {'SemiMajorAxis': <Element.SemiMajorAxis: 0>, 'Eccentricity': <Element.Eccentricity: 1>, 'Inclination': <Element.Inclination: 2>, 'Aop': <Element.Aop: 4>, 'Raan': <Element.Raan: 3>, 'TrueAnomaly': <Element.TrueAnomaly: 5>, 'MeanAnomaly': <Element.MeanAnomaly: 6>, 'EccentricAnomaly': <Element.EccentricAnomaly: 7>}
115
+ __members__: typing.ClassVar[dict[str, COE.Element]] # value = {'SemiMajorAxis': <Element.SemiMajorAxis: 0>, 'Eccentricity': <Element.Eccentricity: 1>, 'Inclination': <Element.Inclination: 2>, 'Aop': <Element.Aop: 4>, 'Raan': <Element.Raan: 3>, 'TrueAnomaly': <Element.TrueAnomaly: 5>, 'MeanAnomaly': <Element.MeanAnomaly: 6>, 'EccentricAnomaly': <Element.EccentricAnomaly: 7>, 'ArgumentOfLatitude': <Element.ArgumentOfLatitude: 8>}
113
116
  def __eq__(self, other: typing.Any) -> bool:
114
117
  ...
115
118
  def __getstate__(self) -> int:
@@ -105,7 +105,7 @@ class Viewer:
105
105
  show_orbital_track: bool = False,
106
106
  color: str | None = None,
107
107
  image: str | None = None,
108
- ) -> None:
108
+ ) -> Viewer:
109
109
  """
110
110
  Add Orbit to Viewer.
111
111
 
@@ -116,6 +116,9 @@ class Viewer:
116
116
  show_orbital_track (bool, optional): Whether to show the orbital track. Defaults to False.
117
117
  color (str, optional): Color of the orbit. Defaults to None.
118
118
  image (str, optional): Logo to be added. Defaults to None.
119
+
120
+ Returns:
121
+ Viewer: The Viewer.
119
122
  """
120
123
  instants: list[Instant] = self._interval.generate_grid(step)
121
124
  states: list[State] = orbit.get_states_at(instants)
@@ -164,6 +167,8 @@ class Viewer:
164
167
  )
165
168
  )
166
169
 
170
+ return self
171
+
167
172
  def add_profile(
168
173
  self,
169
174
  profile: Profile,
@@ -172,7 +177,7 @@ class Viewer:
172
177
  cesium_asset_id: int | None = None,
173
178
  sensors: list[Sensor] | None = None,
174
179
  show_xyz_axes: bool = False,
175
- ) -> None:
180
+ ) -> Viewer:
176
181
  """
177
182
  Add Profile to Viewer.
178
183
 
@@ -183,6 +188,9 @@ class Viewer:
183
188
  cesium_asset_id (int, optional): The Cesium asset ID. Defaults to None.
184
189
  sensors (list[Sensor], optional): Sensors to be added to the asset. Defaults to None.
185
190
  show_xyz_axes (bool, optional): Whether to show the XYZ axes. Defaults to False.
191
+
192
+ Returns:
193
+ Viewer: The Viewer.
186
194
  """
187
195
 
188
196
  instants: list[Instant] = self._interval.generate_grid(step)
@@ -257,13 +265,15 @@ class Viewer:
257
265
  )
258
266
  )
259
267
 
268
+ return self
269
+
260
270
  def add_target(
261
271
  self,
262
272
  position: Position,
263
273
  size: int | None = None,
264
274
  color: str | None = None,
265
275
  label: str | None = None,
266
- ) -> None:
276
+ ) -> Viewer:
267
277
  """
268
278
  Add target to Viewer.
269
279
 
@@ -272,6 +282,9 @@ class Viewer:
272
282
  size (int, optional): Target size. Defaults to None.
273
283
  color (str, optional): Target color. Defaults to None.
274
284
  label (str, optional): Target label. Defaults to None.
285
+
286
+ Returns:
287
+ Viewer: The Viewer.
275
288
  """
276
289
 
277
290
  self._viewer.entities.add(
@@ -285,12 +298,14 @@ class Viewer:
285
298
  if label:
286
299
  self.add_label(position, label, size, color)
287
300
 
301
+ return self
302
+
288
303
  def add_line(
289
304
  self,
290
305
  positions: list[Position],
291
306
  size: int | None = None,
292
307
  color: str | None = None,
293
- ) -> None:
308
+ ) -> Viewer:
294
309
  """
295
310
  Add line to Viewer.
296
311
 
@@ -298,6 +313,9 @@ class Viewer:
298
313
  positions (list[Position]): Line positions.
299
314
  size (int, optional): Line size. Defaults to None.
300
315
  color (str, optional): Line color. Defaults to None.
316
+
317
+ Returns:
318
+ Viewer: The Viewer.
301
319
  """
302
320
 
303
321
  self._viewer.entities.add(
@@ -321,13 +339,15 @@ class Viewer:
321
339
  )
322
340
  )
323
341
 
342
+ return self
343
+
324
344
  def add_label(
325
345
  self,
326
346
  position: Position,
327
347
  text: str,
328
348
  size: int | None = None,
329
349
  color: str | None = None,
330
- ) -> None:
350
+ ) -> Viewer:
331
351
  """
332
352
  Add label to Viewer.
333
353
 
@@ -337,6 +357,8 @@ class Viewer:
337
357
  size (int, optional): Label size. Defaults to None.
338
358
  color (str, optional): Label color. Defaults to None.
339
359
 
360
+ Returns:
361
+ Viewer: The Viewer.
340
362
  """
341
363
 
342
364
  self._viewer.entities.add(
@@ -348,6 +370,8 @@ class Viewer:
348
370
  )
349
371
  )
350
372
 
373
+ return self
374
+
351
375
  def render(self) -> str:
352
376
  """
353
377
  Render Viewer as HTML string.