open-space-toolkit-astrodynamics 17.2.0__py312-none-manylinux2014_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. open_space_toolkit_astrodynamics-17.2.0.dist-info/METADATA +30 -0
  2. open_space_toolkit_astrodynamics-17.2.0.dist-info/RECORD +151 -0
  3. open_space_toolkit_astrodynamics-17.2.0.dist-info/WHEEL +5 -0
  4. open_space_toolkit_astrodynamics-17.2.0.dist-info/top_level.txt +1 -0
  5. open_space_toolkit_astrodynamics-17.2.0.dist-info/zip-safe +1 -0
  6. ostk/__init__.py +1 -0
  7. ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-312-x86_64-linux-gnu.so +0 -0
  8. ostk/astrodynamics/__init__.py +11 -0
  9. ostk/astrodynamics/__init__.pyi +720 -0
  10. ostk/astrodynamics/access.pyi +577 -0
  11. ostk/astrodynamics/conjunction/__init__.pyi +121 -0
  12. ostk/astrodynamics/conjunction/close_approach.pyi +89 -0
  13. ostk/astrodynamics/conjunction/message/__init__.pyi +3 -0
  14. ostk/astrodynamics/conjunction/message/ccsds.pyi +705 -0
  15. ostk/astrodynamics/converters.py +130 -0
  16. ostk/astrodynamics/converters.pyi +58 -0
  17. ostk/astrodynamics/data/__init__.pyi +3 -0
  18. ostk/astrodynamics/data/provider.pyi +22 -0
  19. ostk/astrodynamics/dataframe.py +597 -0
  20. ostk/astrodynamics/display.py +281 -0
  21. ostk/astrodynamics/dynamics.pyi +311 -0
  22. ostk/astrodynamics/eclipse.pyi +70 -0
  23. ostk/astrodynamics/estimator.pyi +268 -0
  24. ostk/astrodynamics/event_condition.pyi +910 -0
  25. ostk/astrodynamics/flight/__init__.pyi +626 -0
  26. ostk/astrodynamics/flight/profile/__init__.pyi +99 -0
  27. ostk/astrodynamics/flight/profile/model.pyi +179 -0
  28. ostk/astrodynamics/flight/system.pyi +268 -0
  29. ostk/astrodynamics/guidance_law.pyi +416 -0
  30. ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.17 +0 -0
  31. ostk/astrodynamics/pytrajectory/__init__.py +1 -0
  32. ostk/astrodynamics/pytrajectory/__init__.pyi +3 -0
  33. ostk/astrodynamics/pytrajectory/pystate.py +263 -0
  34. ostk/astrodynamics/pytrajectory/pystate.pyi +66 -0
  35. ostk/astrodynamics/solver.pyi +432 -0
  36. ostk/astrodynamics/test/__init__.py +1 -0
  37. ostk/astrodynamics/test/access/__init__.py +1 -0
  38. ostk/astrodynamics/test/access/test_generator.py +319 -0
  39. ostk/astrodynamics/test/access/test_visibility_criterion.py +201 -0
  40. ostk/astrodynamics/test/conftest.py +119 -0
  41. ostk/astrodynamics/test/conjunction/close_approach/__init__.py +0 -0
  42. ostk/astrodynamics/test/conjunction/close_approach/test_generator.py +228 -0
  43. ostk/astrodynamics/test/conjunction/message/ccsds/__init__.py +1 -0
  44. ostk/astrodynamics/test/conjunction/message/ccsds/conftest.py +325 -0
  45. ostk/astrodynamics/test/conjunction/message/ccsds/data/cdm.json +303 -0
  46. ostk/astrodynamics/test/conjunction/message/ccsds/test_cdm.py +416 -0
  47. ostk/astrodynamics/test/conjunction/test_close_approach.py +244 -0
  48. ostk/astrodynamics/test/data/provider/test_off_nadir.py +58 -0
  49. ostk/astrodynamics/test/dynamics/__init__.py +1 -0
  50. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity.csv +565 -0
  51. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity_Truth.csv +100 -0
  52. ostk/astrodynamics/test/dynamics/test_atmospheric_drag.py +128 -0
  53. ostk/astrodynamics/test/dynamics/test_central_body_gravity.py +58 -0
  54. ostk/astrodynamics/test/dynamics/test_dynamics.py +50 -0
  55. ostk/astrodynamics/test/dynamics/test_position_derivative.py +51 -0
  56. ostk/astrodynamics/test/dynamics/test_tabulated.py +138 -0
  57. ostk/astrodynamics/test/dynamics/test_third_body_gravity.py +67 -0
  58. ostk/astrodynamics/test/dynamics/test_thruster.py +157 -0
  59. ostk/astrodynamics/test/eclipse/__init__.py +1 -0
  60. ostk/astrodynamics/test/eclipse/test_generator.py +138 -0
  61. ostk/astrodynamics/test/estimator/test_orbit_determination_solver.py +261 -0
  62. ostk/astrodynamics/test/estimator/test_tle_solver.py +216 -0
  63. ostk/astrodynamics/test/event_condition/test_angular_condition.py +113 -0
  64. ostk/astrodynamics/test/event_condition/test_boolean_condition.py +55 -0
  65. ostk/astrodynamics/test/event_condition/test_brouwer_lyddane_mean_long_condition.py +135 -0
  66. ostk/astrodynamics/test/event_condition/test_coe_condition.py +135 -0
  67. ostk/astrodynamics/test/event_condition/test_instant_condition.py +48 -0
  68. ostk/astrodynamics/test/event_condition/test_logical_condition.py +120 -0
  69. ostk/astrodynamics/test/event_condition/test_real_condition.py +50 -0
  70. ostk/astrodynamics/test/flight/__init__.py +1 -0
  71. ostk/astrodynamics/test/flight/profile/model/test_tabulated_profile.py +115 -0
  72. ostk/astrodynamics/test/flight/system/__init__.py +1 -0
  73. ostk/astrodynamics/test/flight/system/test_propulsion_system.py +64 -0
  74. ostk/astrodynamics/test/flight/system/test_satellite_system.py +83 -0
  75. ostk/astrodynamics/test/flight/system/test_satellite_system_builder.py +71 -0
  76. ostk/astrodynamics/test/flight/test_maneuver.py +231 -0
  77. ostk/astrodynamics/test/flight/test_profile.py +293 -0
  78. ostk/astrodynamics/test/flight/test_system.py +45 -0
  79. ostk/astrodynamics/test/guidance_law/test_constant_thrust.py +177 -0
  80. ostk/astrodynamics/test/guidance_law/test_guidance_law.py +60 -0
  81. ostk/astrodynamics/test/guidance_law/test_heterogeneous_guidance_law.py +164 -0
  82. ostk/astrodynamics/test/guidance_law/test_qlaw.py +209 -0
  83. ostk/astrodynamics/test/solvers/__init__.py +1 -0
  84. ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +196 -0
  85. ostk/astrodynamics/test/solvers/test_least_squares_solver.py +334 -0
  86. ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +161 -0
  87. ostk/astrodynamics/test/test_access.py +128 -0
  88. ostk/astrodynamics/test/test_converters.py +290 -0
  89. ostk/astrodynamics/test/test_dataframe.py +1355 -0
  90. ostk/astrodynamics/test/test_display.py +184 -0
  91. ostk/astrodynamics/test/test_event_condition.py +80 -0
  92. ostk/astrodynamics/test/test_import.py +26 -0
  93. ostk/astrodynamics/test/test_root_solver.py +70 -0
  94. ostk/astrodynamics/test/test_trajectory.py +126 -0
  95. ostk/astrodynamics/test/test_utilities.py +338 -0
  96. ostk/astrodynamics/test/test_viewer.py +318 -0
  97. ostk/astrodynamics/test/trajectory/__init__.py +1 -0
  98. ostk/astrodynamics/test/trajectory/model/test_nadir_trajectory.py +87 -0
  99. ostk/astrodynamics/test/trajectory/model/test_tabulated_trajectory.py +303 -0
  100. ostk/astrodynamics/test/trajectory/model/test_target_scan_trajectory.py +126 -0
  101. ostk/astrodynamics/test/trajectory/orbit/__init__.py +1 -0
  102. ostk/astrodynamics/test/trajectory/orbit/message/__init__.py +1 -0
  103. ostk/astrodynamics/test/trajectory/orbit/message/spacex/__init__.py +1 -0
  104. ostk/astrodynamics/test/trajectory/orbit/message/spacex/conftest.py +18 -0
  105. ostk/astrodynamics/test/trajectory/orbit/message/spacex/data/opm_1.yaml +44 -0
  106. ostk/astrodynamics/test/trajectory/orbit/message/spacex/test_opm.py +108 -0
  107. ostk/astrodynamics/test/trajectory/orbit/models/__init__.py +1 -0
  108. ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py +1 -0
  109. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py +65 -0
  110. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py +102 -0
  111. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py +102 -0
  112. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py +305 -0
  113. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +1 -0
  114. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +337 -0
  115. ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +130 -0
  116. ostk/astrodynamics/test/trajectory/orbit/models/test_modified_equinoctial.py +142 -0
  117. ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +234 -0
  118. ostk/astrodynamics/test/trajectory/orbit/models/test_sgp4.py +1 -0
  119. ostk/astrodynamics/test/trajectory/orbit/models/test_tabulated.py +380 -0
  120. ostk/astrodynamics/test/trajectory/orbit/test_model.py +1 -0
  121. ostk/astrodynamics/test/trajectory/orbit/test_pass.py +75 -0
  122. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity.py +30 -0
  123. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py +18 -0
  124. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_acceleration.py +136 -0
  125. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py +107 -0
  126. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py +115 -0
  127. ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py +84 -0
  128. ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py +58 -0
  129. ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +316 -0
  130. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py +81 -0
  131. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +119 -0
  132. ostk/astrodynamics/test/trajectory/test_model.py +1 -0
  133. ostk/astrodynamics/test/trajectory/test_orbit.py +212 -0
  134. ostk/astrodynamics/test/trajectory/test_propagator.py +452 -0
  135. ostk/astrodynamics/test/trajectory/test_segment.py +694 -0
  136. ostk/astrodynamics/test/trajectory/test_sequence.py +550 -0
  137. ostk/astrodynamics/test/trajectory/test_state.py +629 -0
  138. ostk/astrodynamics/test/trajectory/test_state_builder.py +172 -0
  139. ostk/astrodynamics/trajectory/__init__.pyi +1982 -0
  140. ostk/astrodynamics/trajectory/model.pyi +259 -0
  141. ostk/astrodynamics/trajectory/orbit/__init__.pyi +349 -0
  142. ostk/astrodynamics/trajectory/orbit/message/__init__.pyi +3 -0
  143. ostk/astrodynamics/trajectory/orbit/message/spacex.pyi +264 -0
  144. ostk/astrodynamics/trajectory/orbit/model/__init__.pyi +648 -0
  145. ostk/astrodynamics/trajectory/orbit/model/brouwerLyddaneMean.pyi +121 -0
  146. ostk/astrodynamics/trajectory/orbit/model/kepler.pyi +709 -0
  147. ostk/astrodynamics/trajectory/orbit/model/sgp4.pyi +330 -0
  148. ostk/astrodynamics/trajectory/state/__init__.pyi +402 -0
  149. ostk/astrodynamics/trajectory/state/coordinate_subset.pyi +208 -0
  150. ostk/astrodynamics/utilities.py +396 -0
  151. ostk/astrodynamics/viewer.py +851 -0
@@ -0,0 +1,416 @@
1
+ from __future__ import annotations
2
+ import numpy
3
+ import ostk.astrodynamics
4
+ import ostk.astrodynamics.flight
5
+ import ostk.astrodynamics.trajectory
6
+ import ostk.astrodynamics.trajectory.orbit.model.kepler
7
+ import ostk.core.type
8
+ import ostk.physics.coordinate
9
+ import ostk.physics.time
10
+ import ostk.physics.unit
11
+ import typing
12
+ __all__ = ['ConstantThrust', 'HeterogeneousGuidanceLaw', 'QLaw']
13
+ class ConstantThrust(ostk.astrodynamics.GuidanceLaw):
14
+ """
15
+
16
+ Constant Thrust, Constant Direction guidance law.
17
+
18
+
19
+ """
20
+ @staticmethod
21
+ def from_maneuver(maneuver: ostk.astrodynamics.flight.Maneuver, local_orbital_frame_factory: ostk.astrodynamics.trajectory.LocalOrbitalFrameFactory, maximum_allowed_angular_offset: ostk.physics.unit.Angle = ...) -> ConstantThrust:
22
+ """
23
+ Create a constant thrust guidance law from a maneuver.
24
+
25
+ The local orbital frame maneuver's mean thrust direction is calculated and used to create a
26
+ constant thrust guidance law in said direction.
27
+
28
+ If defined, a runtime error will be thrown if the maximum allowed angular offset between the original thrust acceleration
29
+ direction and the mean thrust direction is violated.
30
+
31
+ Args:
32
+ maneuver (Maneuver): The maneuver.
33
+ local_orbital_frame_factory (LocalOrbitalFrameFactory): The local orbital frame factory.
34
+ maximum_allowed_angular_offset (Angle, optional): The maximum allowed angular offset to consider (if any). Defaults to Undefined.
35
+
36
+ Returns:
37
+ ConstantThrust: The constant thrust guidance law.
38
+ """
39
+ @staticmethod
40
+ def intrack(velocity_direction: bool = True) -> ConstantThrust:
41
+ """
42
+ Create a constant thrust guidance law in the in-track direction.
43
+
44
+ Args:
45
+ velocity_direction (bool, optional): If True, the thrust is applied in the velocity direction. Otherwise, it is applied in the opposite direction. Defaults to True.
46
+
47
+ Returns:
48
+ ConstantThrust: The constant thrust guidance law in the in-track direction.
49
+ """
50
+ def __init__(self, thrust_direction: ostk.astrodynamics.trajectory.LocalOrbitalFrameDirection) -> None:
51
+ """
52
+ Constructor.
53
+
54
+ Args:
55
+ thrust_direction (LocalOrbitalFrameDirection): The thrust direction.
56
+ """
57
+ def __repr__(self) -> str:
58
+ ...
59
+ def __str__(self) -> str:
60
+ ...
61
+ def calculate_thrust_acceleration_at(self, instant: ostk.physics.time.Instant, position_coordinates: numpy.ndarray[numpy.float64[3, 1]], velocity_coordinates: numpy.ndarray[numpy.float64[3, 1]], thrust_acceleration: ostk.core.type.Real, output_frame: ostk.physics.coordinate.Frame) -> numpy.ndarray[numpy.float64[3, 1]]:
62
+ """
63
+ Compute the acceleration due to constant thrust.
64
+
65
+ Args:
66
+ instant (Instant): The instant of the state vector.
67
+ position_coordinates (numpy.ndarray): The position coordinates.
68
+ velocity_coordinates (numpy.ndarray): The velocity coordinates.
69
+ thrust_acceleration (float): The thrust acceleration magnitude.
70
+ output_frame (Frame): The frame the acceleration will be expressed in.
71
+
72
+ Returns:
73
+ numpy.ndarray: The contribution of the constant thrust to the state vector.
74
+ """
75
+ def get_local_thrust_direction(self) -> ostk.astrodynamics.trajectory.LocalOrbitalFrameDirection:
76
+ """
77
+ Get the local thrust direction.
78
+
79
+ Returns:
80
+ LocalOrbitalFrameDirection: The local thrust direction.
81
+ """
82
+ class HeterogeneousGuidanceLaw(ostk.astrodynamics.GuidanceLaw):
83
+ """
84
+
85
+ A guidance law that sequences multiple guidance laws over specific time intervals.
86
+
87
+ At each point in time, the applicable guidance law is selected and used to calculate
88
+ the thrust acceleration. Guidance laws don't need to be contiguous, and can be added
89
+ in any order. If the instant does not fall within any of the intervals, the thrust
90
+ acceleration is zero. The guidance law intervals must not intersect each other.
91
+
92
+ """
93
+ def __init__(self, guidance_laws_with_intervals: list[tuple[ostk.astrodynamics.GuidanceLaw, ostk.physics.time.Interval]] = []) -> None:
94
+ """
95
+ Constructor.
96
+
97
+ Args:
98
+ guidance_laws_with_intervals (list[tuple[GuidanceLaw, Interval]], optional): Array of tuples containing the guidance laws and their corresponding intervals. Defaults to empty array.
99
+
100
+ Raises:
101
+ RuntimeError: If any interval is undefined, if the guidance law is null or if the interval intersects with an existing interval.
102
+ """
103
+ def __repr__(self) -> str:
104
+ ...
105
+ def __str__(self) -> str:
106
+ ...
107
+ def add_guidance_law(self, guidance_law: ostk.astrodynamics.GuidanceLaw, interval: ostk.physics.time.Interval) -> None:
108
+ """
109
+ Add a guidance law with its corresponding interval.
110
+
111
+ Args:
112
+ guidance_law (GuidanceLaw): The guidance law to add.
113
+ interval (Interval): The interval during which the guidance law is active.
114
+
115
+ Raises:
116
+ RuntimeError: If the interval is undefined, if the guidance law is null or if the interval intersects with an existing interval.
117
+ """
118
+ def calculate_thrust_acceleration_at(self, instant: ostk.physics.time.Instant, position_coordinates: numpy.ndarray[numpy.float64[3, 1]], velocity_coordinates: numpy.ndarray[numpy.float64[3, 1]], thrust_acceleration: ostk.core.type.Real, output_frame: ostk.physics.coordinate.Frame) -> numpy.ndarray[numpy.float64[3, 1]]:
119
+ """
120
+ Calculate thrust acceleration at a given instant and state.
121
+
122
+ Args:
123
+ instant (Instant): The instant.
124
+ position_coordinates (numpy.ndarray): The position coordinates.
125
+ velocity_coordinates (numpy.ndarray): The velocity coordinates.
126
+ thrust_acceleration (float): The thrust acceleration magnitude.
127
+ output_frame (Frame): The frame in which the acceleration is expressed.
128
+
129
+ Returns:
130
+ numpy.ndarray: The acceleration vector at the provided coordinates.
131
+ """
132
+ def get_guidance_laws_with_intervals(self) -> list[tuple[ostk.astrodynamics.GuidanceLaw, ostk.physics.time.Interval]]:
133
+ """
134
+ Get the guidance laws with their corresponding intervals.
135
+
136
+ Returns:
137
+ list[tuple[GuidanceLaw, Interval]]: Array of tuples containing the guidance laws and their corresponding intervals.
138
+ """
139
+ class QLaw(ostk.astrodynamics.GuidanceLaw):
140
+ """
141
+
142
+ This class implements the Q-law guidance law.
143
+
144
+ - Ref: https://dataverse.jpl.nasa.gov/api/access/datafile/10307?gbrecs=true
145
+ - Ref: https://www.researchgate.net/publication/370849580_Analytic_Calculation_and_Application_of_the_Q-Law_Guidance_Algorithm_Partial_Derivatives
146
+ - Ref for derivations: https://dataverse.jpl.nasa.gov/api/access/datafile/13727?gbrecs=true
147
+
148
+ The Q-law is a Lyapunov feedback control law developed by Petropoulos,
149
+ based on analytic expressions for maximum rates of change of the orbit elements and
150
+ the desired changes in the elements. Q, the proximity quotient, serves as a candidate Lyapunov
151
+ function. As the spacecraft approaches the target orbit, Q decreases monotonically (becoming zero at the target orbit).
152
+
153
+
154
+ """
155
+ class COEDomain:
156
+ """
157
+
158
+ Classical Orbital Elements domain.
159
+
160
+
161
+ Members:
162
+
163
+ Osculating : Osculating
164
+
165
+ BrouwerLyddaneMeanLong : Brouwer Lyddane Mean Long
166
+
167
+ BrouwerLyddaneMeanShort : Brouwer Lyddane Mean Short
168
+ """
169
+ BrouwerLyddaneMeanLong: typing.ClassVar[QLaw.COEDomain] # value = <COEDomain.BrouwerLyddaneMeanLong: 1>
170
+ BrouwerLyddaneMeanShort: typing.ClassVar[QLaw.COEDomain] # value = <COEDomain.BrouwerLyddaneMeanShort: 2>
171
+ Osculating: typing.ClassVar[QLaw.COEDomain] # value = <COEDomain.Osculating: 0>
172
+ __members__: typing.ClassVar[dict[str, QLaw.COEDomain]] # value = {'Osculating': <COEDomain.Osculating: 0>, 'BrouwerLyddaneMeanLong': <COEDomain.BrouwerLyddaneMeanLong: 1>, 'BrouwerLyddaneMeanShort': <COEDomain.BrouwerLyddaneMeanShort: 2>}
173
+ def __eq__(self, other: typing.Any) -> bool:
174
+ ...
175
+ def __getstate__(self) -> int:
176
+ ...
177
+ def __hash__(self) -> int:
178
+ ...
179
+ def __index__(self) -> int:
180
+ ...
181
+ def __init__(self, value: int) -> None:
182
+ ...
183
+ def __int__(self) -> int:
184
+ ...
185
+ def __ne__(self, other: typing.Any) -> bool:
186
+ ...
187
+ def __repr__(self) -> str:
188
+ ...
189
+ def __setstate__(self, state: int) -> None:
190
+ ...
191
+ def __str__(self) -> str:
192
+ ...
193
+ @property
194
+ def name(self) -> str:
195
+ ...
196
+ @property
197
+ def value(self) -> int:
198
+ ...
199
+ class GradientStrategy:
200
+ """
201
+
202
+ Gradient strategy.
203
+
204
+
205
+ Members:
206
+
207
+ Analytical : Analytical
208
+
209
+ FiniteDifference : Finite Differenced
210
+ """
211
+ Analytical: typing.ClassVar[QLaw.GradientStrategy] # value = <GradientStrategy.Analytical: 0>
212
+ FiniteDifference: typing.ClassVar[QLaw.GradientStrategy] # value = <GradientStrategy.FiniteDifference: 1>
213
+ __members__: typing.ClassVar[dict[str, QLaw.GradientStrategy]] # value = {'Analytical': <GradientStrategy.Analytical: 0>, 'FiniteDifference': <GradientStrategy.FiniteDifference: 1>}
214
+ def __eq__(self, other: typing.Any) -> bool:
215
+ ...
216
+ def __getstate__(self) -> int:
217
+ ...
218
+ def __hash__(self) -> int:
219
+ ...
220
+ def __index__(self) -> int:
221
+ ...
222
+ def __init__(self, value: int) -> None:
223
+ ...
224
+ def __int__(self) -> int:
225
+ ...
226
+ def __ne__(self, other: typing.Any) -> bool:
227
+ ...
228
+ def __repr__(self) -> str:
229
+ ...
230
+ def __setstate__(self, state: int) -> None:
231
+ ...
232
+ def __str__(self) -> str:
233
+ ...
234
+ @property
235
+ def name(self) -> str:
236
+ ...
237
+ @property
238
+ def value(self) -> int:
239
+ ...
240
+ class Parameters:
241
+ """
242
+
243
+ Q-law parameters.
244
+
245
+
246
+ """
247
+ def __init__(self, element_weights: dict[ostk.astrodynamics.trajectory.orbit.model.kepler.COE.Element, tuple[float, float]], m: int = 3, n: int = 4, r: int = 2, b: float = 0.01, k: int = 100, periapsis_weight: float = 0.0, minimum_periapsis_radius: ostk.physics.unit.Length = ..., absolute_effectivity_threshold: ostk.core.type.Real = ..., relative_effectivity_threshold: ostk.core.type.Real = ...) -> None:
248
+ """
249
+ Constructor.
250
+
251
+ Args:
252
+ element_weights (dict): Key-value pair of COE elements and the (weights, tolerances) for the targeter.
253
+ m (int): Scaling parameter for Semi-Major Axis delta. Default to 3.
254
+ n (int): Scaling parameter for Semi-Major Axis delta. Default to 4.
255
+ r (int): Scaling parameter for Semi-Major Axis delta. Default to 2.
256
+ b (float): Scaling parameter for Argument of Periapsis maximal change. Default to 0.01.
257
+ k (int): Penalty parameter for periapsis. Default to 100.
258
+ periapsis_weight (float): Periapsis weight. Default to 0.0.
259
+ minimum_periapsis_radius (Length): Minimum periapsis radius. Default to 6578.0 km.
260
+ absolute_effectivity_threshold (Real): Absolute effectivity threshold. Default to undefined (not used).
261
+ relative_effectivity_threshold (Real): Relative effectivity threshold. Default to undefined (not used).
262
+ """
263
+ def get_control_weights(self) -> numpy.ndarray[numpy.float64[5, 1]]:
264
+ """
265
+ Get the control weights.
266
+
267
+ Returns:
268
+ np.array: The control weights.
269
+ """
270
+ def get_convergence_thresholds(self) -> numpy.ndarray[numpy.float64[5, 1]]:
271
+ """
272
+ Get the convergence thresholds.
273
+
274
+ Returns:
275
+ np.array: The convergence thresholds.
276
+ """
277
+ def get_minimum_periapsis_radius(self) -> ostk.physics.unit.Length:
278
+ """
279
+ Get the minimum periapsis radius.
280
+
281
+ Returns:
282
+ Length: The minimum periapsis radius.
283
+ """
284
+ @property
285
+ def absolute_effectivity_threshold(self) -> ostk.core.type.Real:
286
+ """
287
+ Absolute effectivity threshold.
288
+
289
+ Type:
290
+ Real
291
+ """
292
+ @property
293
+ def b(self) -> float:
294
+ """
295
+ Scaling parameter for Argument of Periapsis.
296
+
297
+ Type:
298
+ float
299
+ """
300
+ @property
301
+ def k(self) -> float:
302
+ """
303
+ Penalty parameter for periapsis.
304
+
305
+ Type:
306
+ int
307
+ """
308
+ @property
309
+ def m(self) -> float:
310
+ """
311
+ Scaling parameter for Semi-Major Axis delta.
312
+
313
+ Type:
314
+ int
315
+ """
316
+ @property
317
+ def n(self) -> float:
318
+ """
319
+ Scaling parameter for Semi-Major Axis delta.
320
+
321
+ Type:
322
+ int
323
+ """
324
+ @property
325
+ def periapsis_weight(self) -> float:
326
+ """
327
+ Periapsis weight.
328
+
329
+ Type:
330
+ float
331
+ """
332
+ @property
333
+ def r(self) -> float:
334
+ """
335
+ Scaling parameter for Semi-Major Axis delta.
336
+
337
+ Type:
338
+ int
339
+ """
340
+ @property
341
+ def relative_effectivity_threshold(self) -> ostk.core.type.Real:
342
+ """
343
+ Relative effectivity threshold.
344
+
345
+ Type:
346
+ Real
347
+ """
348
+ def __init__(self, target_coe: ostk.astrodynamics.trajectory.orbit.model.kepler.COE, gravitational_parameter: ostk.physics.unit.Derived, parameters: QLaw.Parameters, coe_domain: QLaw.COEDomain, gradient_strategy: QLaw.GradientStrategy = ...) -> None:
349
+ """
350
+ Constructor.
351
+
352
+ Args:
353
+ coe (COE): The target orbit described by Classical Orbital Elements.
354
+ gravitational_parameter (float): The gravitational parameter of the central body.
355
+ parameters (QLaw.Parameters): A set of parameters for the QLaw.
356
+ coe_domain (QLaw.COEDomain): The domain of the Classical Orbital Elements.
357
+ gradient_strategy (QLaw.GradientStrategy): The strategy used to compute the gradient dQ_dOE. Defaults to FiniteDifference.
358
+ """
359
+ def __repr__(self) -> str:
360
+ ...
361
+ def __str__(self) -> str:
362
+ ...
363
+ def calculate_thrust_acceleration_at(self, instant: ostk.physics.time.Instant, position_coordinates: numpy.ndarray[numpy.float64[3, 1]], velocity_coordinates: numpy.ndarray[numpy.float64[3, 1]], thrust_acceleration: ostk.core.type.Real, output_frame: ostk.physics.coordinate.Frame) -> numpy.ndarray[numpy.float64[3, 1]]:
364
+ """
365
+ Calculate the thrust acceleration at the provided coordinates and instant.
366
+
367
+ Args:
368
+ instant (Instant): Instant of computation.
369
+ position_coordinates (np.array): Position coordinates.
370
+ velocity_coordinates (np.array): Velocity coordinates.
371
+ thrust_acceleration (float): Thrust acceleration magnitude.
372
+ output_frame (Frame): The frame the acceleration is expressed in.
373
+
374
+ Returns:
375
+ np.array: The acceleration.
376
+ """
377
+ def compute_effectivity(self, state: ostk.astrodynamics.trajectory.State, thrust_acceleration: ostk.core.type.Real, discretization_step_count: int = 50) -> tuple[float, float]:
378
+ """
379
+ Compute the relative and absolute effectivity of the guidance law.
380
+
381
+ Args:
382
+ state (State): The state from which to extract orbital elements.
383
+ thrust_acceleration (float): The thrust acceleration.
384
+ discretization_step_count (int): The number of discretization steps for the true anomaly. Default to 50.
385
+
386
+ Returns:
387
+ tuple[float, float]: A tuple containing the relative and absolute effectivity.
388
+ """
389
+ def get_coe_domain(self) -> QLaw.COEDomain:
390
+ """
391
+ Get the COE domain.
392
+
393
+ Returns:
394
+ QLaw.COEDomain: The COE domain.
395
+ """
396
+ def get_gradient_strategy(self) -> QLaw.GradientStrategy:
397
+ """
398
+ Get the gradient strategy.
399
+
400
+ Returns:
401
+ QLaw.GradientStrategy: The gradient strategy.
402
+ """
403
+ def get_parameters(self) -> QLaw.Parameters:
404
+ """
405
+ Get the parameters.
406
+
407
+ Returns:
408
+ QLaw.Parameters: The parameters.
409
+ """
410
+ def get_target_coe(self) -> ostk.astrodynamics.trajectory.orbit.model.kepler.COE:
411
+ """
412
+ Get the target COE.
413
+
414
+ Returns:
415
+ COE: The target COE.
416
+ """
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1,3 @@
1
+ from __future__ import annotations
2
+ from . import pystate
3
+ __all__ = ['pystate']
@@ -0,0 +1,263 @@
1
+ # Apache License 2.0
2
+
3
+ # Python-only State functionality
4
+ import re
5
+
6
+ import numpy as np
7
+
8
+ from ostk.physics.coordinate import Frame
9
+ from ostk.physics.time import Instant
10
+
11
+ from ostk.astrodynamics.trajectory import State, StateBuilder
12
+ from ostk.astrodynamics.trajectory.state import CoordinateSubset
13
+ from ostk.astrodynamics.converters import coerce_to_instant
14
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import (
15
+ CartesianPosition,
16
+ CartesianVelocity,
17
+ AttitudeQuaternion,
18
+ AngularVelocity,
19
+ )
20
+
21
+ POS_VEL_CANONICAL_FORMAT: str = r"(r|v)_(.*?)_(x|y|z)"
22
+
23
+
24
+ def custom_class_generator(frame: Frame, coordinate_subsets: list) -> type:
25
+ """
26
+ Emit a custom class type for States. This is meta-programming syntactic sugar on top of the StateBuilder class.
27
+
28
+ StateType = State.template(frame, coordinate_subsets)
29
+ state = StateType(instant, coordinates)
30
+
31
+ is equivalent to
32
+
33
+ state_builder = StateBuilder(frame, coordinate_subsets)
34
+ state = state_builder.build(instant, coordinates)
35
+ """
36
+
37
+ class StateTemplateType(State):
38
+ state_builder: StateBuilder = StateBuilder(frame, coordinate_subsets)
39
+
40
+ def __init__(self, instant: Instant, coordinates: np.ndarray):
41
+ super().__init__(StateTemplateType.state_builder.build(instant, coordinates))
42
+
43
+ return StateTemplateType
44
+
45
+
46
+ def from_dict(data: dict) -> State:
47
+ """
48
+ Create a State from a dictionary.
49
+
50
+ Note: Implicit assumption that ECEF = ITRF, and ECI = GCRF.
51
+
52
+ The dictionary must contain the following:
53
+ - 'timestamp': The timestamp of the state.
54
+ - 'r_ITRF_x'/'rx'/'rx_eci'/'rx_ecef': The x-coordinate of the position.
55
+ - 'r_ITRF_y'/'ry'/'ry_eci'/'ry_ecef': The y-coordinate of the position.
56
+ - 'r_ITRF_z'/'rz'/'rz_eci'/'rz_ecef': The z-coordinate of the position.
57
+ - 'v_ITRF_x'/'vx'/'vx_eci'/'vx_ecef': The x-coordinate of the velocity.
58
+ - 'v_ITRF_y'/'vy'/'vy_eci'/'vy_ecef': The y-coordinate of the velocity.
59
+ - 'v_ITRF_z'/'vz'/'vz_eci'/'vz_ecef': The z-coordinate of the velocity.
60
+ - 'frame': The frame of the state. Required if 'rx', 'ry', 'rz', 'vx', 'vy', 'vz' are provided.
61
+ - 'q_B_ECI_x': The x-coordinate of the quaternion. Optional.
62
+ - 'q_B_ECI_y': The y-coordinate of the quaternion. Optional.
63
+ - 'q_B_ECI_z': The z-coordinate of the quaternion. Optional.
64
+ - 'q_B_ECI_s': The s-coordinate of the quaternion. Optional.
65
+ - 'w_B_ECI_in_B_x': The x-coordinate of the angular velocity. Optional.
66
+ - 'w_B_ECI_in_B_y': The y-coordinate of the angular velocity. Optional.
67
+ - 'w_B_ECI_in_B_z': The z-coordinate of the angular velocity. Optional.
68
+ - 'drag_coefficient'/'cd': The drag coefficient. Optional.
69
+ - 'cross_sectional_area'/'surface_area': The cross-sectional area. Optional.
70
+ - 'mass': The mass. Optional.
71
+ - 'ballistic_coefficient'/'bc': The ballistic coefficient. Optional.
72
+
73
+ Args:
74
+ data (dict): The dictionary.
75
+
76
+ Returns:
77
+ State: The State.
78
+ """
79
+
80
+ # Position and velocity subsets
81
+
82
+ eci_columns: list[str] = [
83
+ "rx_eci",
84
+ "ry_eci",
85
+ "rz_eci",
86
+ "vx_eci",
87
+ "vy_eci",
88
+ "vz_eci",
89
+ ]
90
+ ecef_columns: list[str] = [
91
+ "rx_ecef",
92
+ "ry_ecef",
93
+ "rz_ecef",
94
+ "vx_ecef",
95
+ "vy_ecef",
96
+ "vz_ecef",
97
+ ]
98
+ generic_columns: list[str] = [
99
+ "rx",
100
+ "ry",
101
+ "rz",
102
+ "vx",
103
+ "vy",
104
+ "vz",
105
+ ]
106
+
107
+ # Replace non-standard position keys with canonical representation
108
+ if all(key in data.keys() for key in ("x_eci", "y_eci", "z_eci")):
109
+ data["rx_eci"] = data["x_eci"]
110
+ data["ry_eci"] = data["y_eci"]
111
+ data["rz_eci"] = data["z_eci"]
112
+
113
+ if all(key in data.keys() for key in ("x_ecef", "y_ecef", "z_ecef")):
114
+ data["rx_ecef"] = data["x_ecef"]
115
+ data["ry_ecef"] = data["y_ecef"]
116
+ data["rz_ecef"] = data["z_ecef"]
117
+
118
+ frame: Frame
119
+ coordinates: np.ndarray
120
+
121
+ coordinate_subsets: list[CoordinateSubset] = [
122
+ CartesianPosition.default(),
123
+ CartesianVelocity.default(),
124
+ ]
125
+
126
+ match_groups: list[re.Match] = [
127
+ re.match(POS_VEL_CANONICAL_FORMAT, column) for column in data.keys()
128
+ ]
129
+
130
+ if len(matches := [match for match in match_groups if match is not None]) == 6:
131
+ frame_name: str = matches[0].group(2)
132
+ try:
133
+ frame: Frame = Frame.with_name(frame_name) or getattr(Frame, frame_name)()
134
+ except Exception:
135
+ raise ValueError(f"No frame exists with name [{frame_name}].")
136
+
137
+ coordinates = np.array([data[match.group(0)] for match in matches])
138
+
139
+ elif all(column in data for column in eci_columns):
140
+ frame: Frame = Frame.GCRF()
141
+ coordinates = np.array(
142
+ [
143
+ data["rx_eci"],
144
+ data["ry_eci"],
145
+ data["rz_eci"],
146
+ data["vx_eci"],
147
+ data["vy_eci"],
148
+ data["vz_eci"],
149
+ ]
150
+ )
151
+
152
+ elif all(column in data for column in ecef_columns):
153
+ frame = Frame.ITRF()
154
+ coordinates = np.array(
155
+ [
156
+ data["rx_ecef"],
157
+ data["ry_ecef"],
158
+ data["rz_ecef"],
159
+ data["vx_ecef"],
160
+ data["vy_ecef"],
161
+ data["vz_ecef"],
162
+ ]
163
+ )
164
+
165
+ elif all(column in data for column in generic_columns):
166
+ if "frame" not in data:
167
+ raise ValueError("Frame must be provided for generic columns.")
168
+
169
+ if isinstance(data["frame"], str):
170
+ if Frame.exists(data["frame"]):
171
+ frame = Frame.with_name(data["frame"])
172
+ else:
173
+ raise ValueError(f"No frame exists with name [{data['frame']}].")
174
+ elif isinstance(data["frame"], Frame):
175
+ frame = data["frame"]
176
+ else:
177
+ raise ValueError(f"Invalid frame data [{data['frame']}].")
178
+
179
+ coordinates = np.array(
180
+ [
181
+ data["rx"],
182
+ data["ry"],
183
+ data["rz"],
184
+ data["vx"],
185
+ data["vy"],
186
+ data["vz"],
187
+ ]
188
+ )
189
+ else:
190
+ raise ValueError("Invalid state data.")
191
+
192
+ # Attitude and angular velocity subsets
193
+
194
+ if all(
195
+ column in data for column in ["q_B_ECI_x", "q_B_ECI_y", "q_B_ECI_z", "q_B_ECI_s"]
196
+ ):
197
+ coordinate_subsets.append(AttitudeQuaternion.default())
198
+ coordinates = np.append(
199
+ coordinates,
200
+ [
201
+ data["q_B_ECI_x"],
202
+ data["q_B_ECI_y"],
203
+ data["q_B_ECI_z"],
204
+ data["q_B_ECI_s"],
205
+ ],
206
+ )
207
+
208
+ if all(
209
+ column in data
210
+ for column in ["w_B_ECI_in_B_x", "w_B_ECI_in_B_y", "w_B_ECI_in_B_z"]
211
+ ):
212
+ coordinate_subsets.append(AngularVelocity.default())
213
+ coordinates = np.append(
214
+ coordinates,
215
+ [
216
+ data["w_B_ECI_in_B_x"],
217
+ data["w_B_ECI_in_B_y"],
218
+ data["w_B_ECI_in_B_z"],
219
+ ],
220
+ )
221
+
222
+ # Extra subsets
223
+
224
+ if (data.get("drag_coefficient") is not None) or (data.get("cd") is not None):
225
+ coordinate_subsets.append(CoordinateSubset.drag_coefficient())
226
+ coordinates = np.append(
227
+ coordinates,
228
+ data.get("drag_coefficient", data.get("cd")),
229
+ )
230
+
231
+ if (data.get("cross_sectional_area") is not None) or (
232
+ data.get("surface_area") is not None
233
+ ):
234
+ coordinate_subsets.append(CoordinateSubset.surface_area())
235
+ coordinates = np.append(
236
+ coordinates,
237
+ data.get("cross_sectional_area", data.get("surface_area")),
238
+ )
239
+
240
+ if data.get("mass") is not None:
241
+ coordinate_subsets.append(CoordinateSubset.mass())
242
+ coordinates = np.append(
243
+ coordinates,
244
+ data["mass"],
245
+ )
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
+
254
+ return State(
255
+ instant=coerce_to_instant(data["timestamp"]),
256
+ coordinates=coordinates,
257
+ frame=frame,
258
+ coordinate_subsets=coordinate_subsets,
259
+ )
260
+
261
+
262
+ State.from_dict = staticmethod(from_dict)
263
+ State.template = staticmethod(custom_class_generator)