open-space-toolkit-astrodynamics 12.2.1__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.
- open_space_toolkit_astrodynamics-12.2.1.dist-info/METADATA +30 -0
- open_space_toolkit_astrodynamics-12.2.1.dist-info/RECORD +100 -0
- open_space_toolkit_astrodynamics-12.2.1.dist-info/WHEEL +5 -0
- open_space_toolkit_astrodynamics-12.2.1.dist-info/top_level.txt +1 -0
- open_space_toolkit_astrodynamics-12.2.1.dist-info/zip-safe +1 -0
- ostk/__init__.py +1 -0
- ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-312-x86_64-linux-gnu.so +0 -0
- ostk/astrodynamics/__init__.py +11 -0
- ostk/astrodynamics/converters.py +128 -0
- ostk/astrodynamics/dataframe.py +477 -0
- ostk/astrodynamics/display.py +220 -0
- ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.12 +0 -0
- ostk/astrodynamics/pytrajectory/__init__.py +1 -0
- ostk/astrodynamics/pytrajectory/pystate.py +220 -0
- ostk/astrodynamics/test/__init__.py +1 -0
- ostk/astrodynamics/test/access/__init__.py +1 -0
- ostk/astrodynamics/test/access/test_generator.py +248 -0
- ostk/astrodynamics/test/conftest.py +119 -0
- ostk/astrodynamics/test/conjunction/message/ccsds/__init__.py +1 -0
- ostk/astrodynamics/test/conjunction/message/ccsds/conftest.py +325 -0
- ostk/astrodynamics/test/conjunction/message/ccsds/data/cdm.json +303 -0
- ostk/astrodynamics/test/conjunction/message/ccsds/test_cdm.py +416 -0
- ostk/astrodynamics/test/dynamics/__init__.py +1 -0
- ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity.csv +565 -0
- ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity_Truth.csv +100 -0
- ostk/astrodynamics/test/dynamics/test_atmospheric_drag.py +128 -0
- ostk/astrodynamics/test/dynamics/test_central_body_gravity.py +58 -0
- ostk/astrodynamics/test/dynamics/test_dynamics.py +50 -0
- ostk/astrodynamics/test/dynamics/test_position_derivative.py +51 -0
- ostk/astrodynamics/test/dynamics/test_tabulated.py +138 -0
- ostk/astrodynamics/test/dynamics/test_third_body_gravity.py +67 -0
- ostk/astrodynamics/test/dynamics/test_thruster.py +142 -0
- ostk/astrodynamics/test/event_condition/test_angular_condition.py +113 -0
- ostk/astrodynamics/test/event_condition/test_boolean_condition.py +55 -0
- ostk/astrodynamics/test/event_condition/test_coe_condition.py +87 -0
- ostk/astrodynamics/test/event_condition/test_instant_condition.py +48 -0
- ostk/astrodynamics/test/event_condition/test_logical_condition.py +120 -0
- ostk/astrodynamics/test/event_condition/test_real_condition.py +50 -0
- ostk/astrodynamics/test/flight/__init__.py +1 -0
- ostk/astrodynamics/test/flight/system/__init__.py +1 -0
- ostk/astrodynamics/test/flight/system/test_propulsion_system.py +73 -0
- ostk/astrodynamics/test/flight/system/test_satellite_system.py +91 -0
- ostk/astrodynamics/test/flight/system/test_satellite_system_builder.py +71 -0
- ostk/astrodynamics/test/flight/test_maneuver.py +212 -0
- ostk/astrodynamics/test/flight/test_profile.py +242 -0
- ostk/astrodynamics/test/flight/test_system.py +55 -0
- ostk/astrodynamics/test/guidance_law/test_constant_thrust.py +91 -0
- ostk/astrodynamics/test/guidance_law/test_qlaw.py +138 -0
- ostk/astrodynamics/test/solvers/__init__.py +1 -0
- ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +181 -0
- ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +153 -0
- ostk/astrodynamics/test/test_access.py +128 -0
- ostk/astrodynamics/test/test_converters.py +290 -0
- ostk/astrodynamics/test/test_dataframe.py +875 -0
- ostk/astrodynamics/test/test_display.py +114 -0
- ostk/astrodynamics/test/test_event_condition.py +58 -0
- ostk/astrodynamics/test/test_import.py +26 -0
- ostk/astrodynamics/test/test_root_solver.py +70 -0
- ostk/astrodynamics/test/test_trajectory.py +118 -0
- ostk/astrodynamics/test/test_utilities.py +106 -0
- ostk/astrodynamics/test/test_viewer.py +129 -0
- ostk/astrodynamics/test/trajectory/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/message/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/message/spacex/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/message/spacex/conftest.py +18 -0
- ostk/astrodynamics/test/trajectory/orbit/message/spacex/data/opm_1.yaml +44 -0
- ostk/astrodynamics/test/trajectory/orbit/message/spacex/test_opm.py +108 -0
- ostk/astrodynamics/test/trajectory/orbit/models/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py +65 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py +102 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py +102 -0
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py +180 -0
- ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +331 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +130 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +234 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_sgp4.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/models/test_tabulated.py +380 -0
- ostk/astrodynamics/test/trajectory/orbit/test_model.py +1 -0
- ostk/astrodynamics/test/trajectory/orbit/test_pass.py +75 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity.py +30 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py +18 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py +107 -0
- ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py +115 -0
- ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py +84 -0
- ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py +46 -0
- ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +314 -0
- ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py +81 -0
- ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +108 -0
- ostk/astrodynamics/test/trajectory/test_model.py +1 -0
- ostk/astrodynamics/test/trajectory/test_orbit.py +196 -0
- ostk/astrodynamics/test/trajectory/test_propagator.py +458 -0
- ostk/astrodynamics/test/trajectory/test_segment.py +305 -0
- ostk/astrodynamics/test/trajectory/test_sequence.py +477 -0
- ostk/astrodynamics/test/trajectory/test_state.py +467 -0
- ostk/astrodynamics/test/trajectory/test_state_builder.py +171 -0
- ostk/astrodynamics/utilities.py +245 -0
- ostk/astrodynamics/viewer.py +392 -0
@@ -0,0 +1,477 @@
|
|
1
|
+
# Apache License 2.0
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
import numpy as np
|
6
|
+
|
7
|
+
from ostk.mathematics.geometry.d3.object import Composite
|
8
|
+
from ostk.mathematics.geometry.d3.object import Cuboid
|
9
|
+
from ostk.mathematics.geometry.d3.object import Point
|
10
|
+
|
11
|
+
from ostk.physics import Environment
|
12
|
+
from ostk.physics.coordinate import Frame
|
13
|
+
from ostk.physics.environment.atmospheric import Earth as EarthAtmosphericModel
|
14
|
+
from ostk.physics.environment.gravitational import Earth as EarthGravitationalModel
|
15
|
+
from ostk.physics.environment.magnetic import Earth as EarthMagneticModel
|
16
|
+
from ostk.physics.environment.object.celestial import Earth
|
17
|
+
from ostk.physics.time import DateTime
|
18
|
+
from ostk.physics.time import Duration
|
19
|
+
from ostk.physics.time import Instant
|
20
|
+
from ostk.physics.time import Scale
|
21
|
+
from ostk.physics.unit import Derived
|
22
|
+
from ostk.physics.unit import Length
|
23
|
+
from ostk.physics.unit import Mass
|
24
|
+
|
25
|
+
from ostk.astrodynamics.event_condition import COECondition
|
26
|
+
from ostk.astrodynamics.event_condition import InstantCondition
|
27
|
+
from ostk.astrodynamics.event_condition import RealCondition
|
28
|
+
from ostk.astrodynamics import Dynamics
|
29
|
+
from ostk.astrodynamics import EventCondition
|
30
|
+
from ostk.astrodynamics.dynamics import Thruster
|
31
|
+
from ostk.astrodynamics.guidance_law import ConstantThrust
|
32
|
+
from ostk.astrodynamics.flight.system import PropulsionSystem
|
33
|
+
from ostk.astrodynamics.flight.system import SatelliteSystem
|
34
|
+
from ostk.astrodynamics.trajectory import LocalOrbitalFrameDirection
|
35
|
+
from ostk.astrodynamics.trajectory import LocalOrbitalFrameFactory
|
36
|
+
from ostk.astrodynamics.trajectory import Segment
|
37
|
+
from ostk.astrodynamics.trajectory import Sequence
|
38
|
+
from ostk.astrodynamics.trajectory import State
|
39
|
+
from ostk.astrodynamics.trajectory.state import CoordinateBroker
|
40
|
+
from ostk.astrodynamics.trajectory.state import CoordinateSubset
|
41
|
+
from ostk.astrodynamics.trajectory.state import NumericalSolver
|
42
|
+
from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianPosition
|
43
|
+
from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianVelocity
|
44
|
+
|
45
|
+
|
46
|
+
@pytest.fixture
|
47
|
+
def propulsion_system() -> PropulsionSystem:
|
48
|
+
return PropulsionSystem(
|
49
|
+
1.0,
|
50
|
+
1500.0,
|
51
|
+
)
|
52
|
+
|
53
|
+
|
54
|
+
@pytest.fixture
|
55
|
+
def dry_mass() -> Mass:
|
56
|
+
return Mass.kilograms(100.0)
|
57
|
+
|
58
|
+
|
59
|
+
@pytest.fixture
|
60
|
+
def wet_mass() -> Mass:
|
61
|
+
return Mass.kilograms(10.0)
|
62
|
+
|
63
|
+
|
64
|
+
@pytest.fixture
|
65
|
+
def cross_sectional_surface_area() -> float:
|
66
|
+
return 1.0
|
67
|
+
|
68
|
+
|
69
|
+
@pytest.fixture
|
70
|
+
def drag_coefficient() -> float:
|
71
|
+
return 2.2
|
72
|
+
|
73
|
+
|
74
|
+
@pytest.fixture
|
75
|
+
def satellite_system(
|
76
|
+
dry_mass: Mass,
|
77
|
+
cross_sectional_surface_area: float,
|
78
|
+
drag_coefficient: float,
|
79
|
+
propulsion_system: PropulsionSystem,
|
80
|
+
) -> SatelliteSystem:
|
81
|
+
satellite_geometry = Composite(
|
82
|
+
Cuboid(
|
83
|
+
Point(0.0, 0.0, 0.0),
|
84
|
+
[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
|
85
|
+
[1.0, 0.0, 0.0],
|
86
|
+
)
|
87
|
+
)
|
88
|
+
inertia_tensor = np.ndarray(shape=(3, 3))
|
89
|
+
|
90
|
+
return SatelliteSystem(
|
91
|
+
dry_mass,
|
92
|
+
satellite_geometry,
|
93
|
+
inertia_tensor,
|
94
|
+
cross_sectional_surface_area,
|
95
|
+
drag_coefficient,
|
96
|
+
propulsion_system,
|
97
|
+
)
|
98
|
+
|
99
|
+
|
100
|
+
@pytest.fixture
|
101
|
+
def environment() -> Environment:
|
102
|
+
return Environment(
|
103
|
+
Instant.J2000(),
|
104
|
+
[
|
105
|
+
Earth.from_models(
|
106
|
+
EarthGravitationalModel(EarthGravitationalModel.Type.Spherical),
|
107
|
+
EarthMagneticModel(EarthMagneticModel.Type.Undefined),
|
108
|
+
EarthAtmosphericModel(EarthAtmosphericModel.Type.Exponential),
|
109
|
+
)
|
110
|
+
],
|
111
|
+
)
|
112
|
+
|
113
|
+
|
114
|
+
@pytest.fixture
|
115
|
+
def coordinate_broker() -> CoordinateBroker:
|
116
|
+
return CoordinateBroker(
|
117
|
+
[
|
118
|
+
CartesianPosition.default(),
|
119
|
+
CartesianVelocity.default(),
|
120
|
+
CoordinateSubset.mass(),
|
121
|
+
CoordinateSubset.surface_area(),
|
122
|
+
CoordinateSubset.drag_coefficient(),
|
123
|
+
]
|
124
|
+
)
|
125
|
+
|
126
|
+
|
127
|
+
@pytest.fixture
|
128
|
+
def cartesian_coordinates() -> list[float]:
|
129
|
+
return [
|
130
|
+
717094.039086306,
|
131
|
+
-6872433.2241124,
|
132
|
+
46175.9696673281,
|
133
|
+
-970.650826004612,
|
134
|
+
-45.4598114773158,
|
135
|
+
7529.82424886455,
|
136
|
+
]
|
137
|
+
|
138
|
+
|
139
|
+
@pytest.fixture
|
140
|
+
def state(
|
141
|
+
cartesian_coordinates: list[float],
|
142
|
+
dry_mass: Mass,
|
143
|
+
wet_mass: Mass,
|
144
|
+
cross_sectional_surface_area: float,
|
145
|
+
drag_coefficient: float,
|
146
|
+
coordinate_broker: CoordinateBroker,
|
147
|
+
) -> State:
|
148
|
+
frame: Frame = Frame.GCRF()
|
149
|
+
instant: Instant = Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
150
|
+
coordinates = [
|
151
|
+
*cartesian_coordinates,
|
152
|
+
dry_mass.in_kilograms() + wet_mass.in_kilograms(),
|
153
|
+
cross_sectional_surface_area,
|
154
|
+
drag_coefficient,
|
155
|
+
]
|
156
|
+
|
157
|
+
return State(
|
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
|
+
],
|
170
|
+
frame,
|
171
|
+
coordinate_broker,
|
172
|
+
)
|
173
|
+
|
174
|
+
|
175
|
+
@pytest.fixture
|
176
|
+
def dynamics(environment: Environment) -> list:
|
177
|
+
return Dynamics.from_environment(environment)
|
178
|
+
|
179
|
+
|
180
|
+
@pytest.fixture
|
181
|
+
def numerical_solver() -> NumericalSolver:
|
182
|
+
return NumericalSolver.default_conditional()
|
183
|
+
|
184
|
+
|
185
|
+
@pytest.fixture
|
186
|
+
def duration() -> Duration:
|
187
|
+
return Duration.minutes(5.0)
|
188
|
+
|
189
|
+
|
190
|
+
@pytest.fixture
|
191
|
+
def instant_condition(state: State, duration: Duration) -> InstantCondition:
|
192
|
+
return InstantCondition(
|
193
|
+
RealCondition.Criterion.AnyCrossing, state.get_instant() + duration
|
194
|
+
)
|
195
|
+
|
196
|
+
|
197
|
+
@pytest.fixture
|
198
|
+
def sma() -> Length:
|
199
|
+
return Length.kilometers(6907.000)
|
200
|
+
|
201
|
+
|
202
|
+
@pytest.fixture
|
203
|
+
def gravitational_parameter() -> Derived:
|
204
|
+
return EarthGravitationalModel.spherical.gravitational_parameter
|
205
|
+
|
206
|
+
|
207
|
+
@pytest.fixture
|
208
|
+
def constant_thrust() -> ConstantThrust:
|
209
|
+
return ConstantThrust(
|
210
|
+
thrust_direction=LocalOrbitalFrameDirection(
|
211
|
+
vector=[1.0, 0.0, 0.0],
|
212
|
+
local_orbital_frame_factory=LocalOrbitalFrameFactory.VNC(Frame.GCRF()),
|
213
|
+
)
|
214
|
+
)
|
215
|
+
|
216
|
+
|
217
|
+
@pytest.fixture
|
218
|
+
def thruster_dynamics(
|
219
|
+
satellite_system: SatelliteSystem, constant_thrust: ConstantThrust
|
220
|
+
) -> ConstantThrust:
|
221
|
+
return Thruster(
|
222
|
+
satellite_system=satellite_system,
|
223
|
+
guidance_law=constant_thrust,
|
224
|
+
)
|
225
|
+
|
226
|
+
|
227
|
+
@pytest.fixture
|
228
|
+
def sma_target(sma: Length) -> EventCondition.Target:
|
229
|
+
return EventCondition.Target(sma)
|
230
|
+
|
231
|
+
|
232
|
+
@pytest.fixture
|
233
|
+
def sma_condition(
|
234
|
+
sma_target: EventCondition.Target, gravitational_parameter: Derived
|
235
|
+
) -> COECondition:
|
236
|
+
return COECondition.semi_major_axis(
|
237
|
+
criterion=RealCondition.Criterion.AnyCrossing,
|
238
|
+
frame=Frame.GCRF(),
|
239
|
+
semi_major_axis=sma_target,
|
240
|
+
gravitational_parameter=gravitational_parameter,
|
241
|
+
)
|
242
|
+
|
243
|
+
|
244
|
+
@pytest.fixture
|
245
|
+
def coast_duration_segment(
|
246
|
+
instant_condition: InstantCondition,
|
247
|
+
dynamics: list[Dynamics],
|
248
|
+
numerical_solver: NumericalSolver,
|
249
|
+
):
|
250
|
+
return Segment.coast(
|
251
|
+
name="duration coast",
|
252
|
+
event_condition=instant_condition,
|
253
|
+
dynamics=dynamics,
|
254
|
+
numerical_solver=numerical_solver,
|
255
|
+
)
|
256
|
+
|
257
|
+
|
258
|
+
@pytest.fixture
|
259
|
+
def coast_sma_segment(
|
260
|
+
sma_condition: COECondition,
|
261
|
+
dynamics: list[Dynamics],
|
262
|
+
numerical_solver: NumericalSolver,
|
263
|
+
):
|
264
|
+
return Segment.coast(
|
265
|
+
name="sma coast",
|
266
|
+
event_condition=sma_condition,
|
267
|
+
dynamics=dynamics,
|
268
|
+
numerical_solver=numerical_solver,
|
269
|
+
)
|
270
|
+
|
271
|
+
|
272
|
+
@pytest.fixture
|
273
|
+
def thrust_segment(
|
274
|
+
sma_condition: RealCondition,
|
275
|
+
thruster_dynamics: Thruster,
|
276
|
+
dynamics: list[Dynamics],
|
277
|
+
numerical_solver: NumericalSolver,
|
278
|
+
):
|
279
|
+
return Segment.maneuver(
|
280
|
+
name="duration thrust",
|
281
|
+
event_condition=sma_condition,
|
282
|
+
thruster_dynamics=thruster_dynamics,
|
283
|
+
dynamics=dynamics,
|
284
|
+
numerical_solver=numerical_solver,
|
285
|
+
)
|
286
|
+
|
287
|
+
|
288
|
+
@pytest.fixture
|
289
|
+
def segments(
|
290
|
+
coast_duration_segment: Segment,
|
291
|
+
thrust_segment: Segment,
|
292
|
+
) -> list[Segment]:
|
293
|
+
return [coast_duration_segment, thrust_segment]
|
294
|
+
|
295
|
+
|
296
|
+
@pytest.fixture
|
297
|
+
def maximum_propagation_duration() -> Duration:
|
298
|
+
return Duration.days(2.0)
|
299
|
+
|
300
|
+
|
301
|
+
@pytest.fixture
|
302
|
+
def repetition_count() -> int:
|
303
|
+
return 1
|
304
|
+
|
305
|
+
|
306
|
+
@pytest.fixture
|
307
|
+
def sequence(
|
308
|
+
segments: list[Segment],
|
309
|
+
numerical_solver: NumericalSolver,
|
310
|
+
dynamics: list,
|
311
|
+
maximum_propagation_duration: Duration,
|
312
|
+
):
|
313
|
+
return Sequence(
|
314
|
+
segments=segments,
|
315
|
+
dynamics=dynamics,
|
316
|
+
numerical_solver=numerical_solver,
|
317
|
+
maximum_propagation_duration=maximum_propagation_duration,
|
318
|
+
)
|
319
|
+
|
320
|
+
|
321
|
+
@pytest.fixture
|
322
|
+
def segment_solution(
|
323
|
+
dynamics: list,
|
324
|
+
state: State,
|
325
|
+
):
|
326
|
+
return Segment.Solution(
|
327
|
+
name="A Segment Solution",
|
328
|
+
dynamics=dynamics,
|
329
|
+
states=[
|
330
|
+
state,
|
331
|
+
],
|
332
|
+
condition_is_satisfied=True,
|
333
|
+
segment_type=Segment.Type.Maneuver,
|
334
|
+
)
|
335
|
+
|
336
|
+
|
337
|
+
@pytest.fixture
|
338
|
+
def instants(state: State) -> list[Instant]:
|
339
|
+
return [state.get_instant(), state.get_instant() + Duration.minutes(1.0)]
|
340
|
+
|
341
|
+
|
342
|
+
class TestSequence:
|
343
|
+
def test_get_segments(
|
344
|
+
self,
|
345
|
+
sequence: Sequence,
|
346
|
+
segments: list[Segment],
|
347
|
+
):
|
348
|
+
assert len(sequence.get_segments()) == len(segments)
|
349
|
+
|
350
|
+
def test_get_numerical_solver(
|
351
|
+
self,
|
352
|
+
sequence: Sequence,
|
353
|
+
numerical_solver: NumericalSolver,
|
354
|
+
):
|
355
|
+
assert sequence.get_numerical_solver() == numerical_solver
|
356
|
+
|
357
|
+
def test_get_dynamics(
|
358
|
+
self,
|
359
|
+
sequence: Sequence,
|
360
|
+
dynamics: list,
|
361
|
+
):
|
362
|
+
assert len(sequence.get_dynamics()) == len(dynamics)
|
363
|
+
|
364
|
+
def test_get_maximum_propagation_duration(
|
365
|
+
self,
|
366
|
+
sequence: Sequence,
|
367
|
+
maximum_propagation_duration: Duration,
|
368
|
+
):
|
369
|
+
assert sequence.get_maximum_propagation_duration() == maximum_propagation_duration
|
370
|
+
|
371
|
+
def test_add_segment(
|
372
|
+
self,
|
373
|
+
sequence: Sequence,
|
374
|
+
coast_duration_segment: Segment,
|
375
|
+
):
|
376
|
+
segments_count: int = len(sequence.get_segments())
|
377
|
+
|
378
|
+
sequence.add_segment(coast_duration_segment)
|
379
|
+
|
380
|
+
assert len(sequence.get_segments()) == segments_count + 1
|
381
|
+
|
382
|
+
segments_count = len(sequence.get_segments())
|
383
|
+
|
384
|
+
sequence.add_segments([coast_duration_segment, coast_duration_segment])
|
385
|
+
|
386
|
+
assert len(sequence.get_segments()) == segments_count + 2
|
387
|
+
|
388
|
+
def test_add_coast_segment(
|
389
|
+
self,
|
390
|
+
sequence: Sequence,
|
391
|
+
instant_condition: InstantCondition,
|
392
|
+
):
|
393
|
+
segments_count: int = len(sequence.get_segments())
|
394
|
+
|
395
|
+
sequence.add_coast_segment(instant_condition)
|
396
|
+
|
397
|
+
assert len(sequence.get_segments()) == segments_count + 1
|
398
|
+
|
399
|
+
def test_add_maneuver_segment(
|
400
|
+
self,
|
401
|
+
sequence: Sequence,
|
402
|
+
instant_condition: InstantCondition,
|
403
|
+
thruster_dynamics: Thruster,
|
404
|
+
):
|
405
|
+
segments_count: int = len(sequence.get_segments())
|
406
|
+
|
407
|
+
sequence.add_maneuver_segment(instant_condition, thruster_dynamics)
|
408
|
+
|
409
|
+
assert len(sequence.get_segments()) == segments_count + 1
|
410
|
+
|
411
|
+
def test_create_sequence_solution(
|
412
|
+
self,
|
413
|
+
segment_solution: Segment.Solution,
|
414
|
+
):
|
415
|
+
solution: Sequence.Solution = Sequence.Solution(
|
416
|
+
segment_solutions=[
|
417
|
+
segment_solution,
|
418
|
+
],
|
419
|
+
execution_is_complete=True,
|
420
|
+
)
|
421
|
+
|
422
|
+
assert solution is not None
|
423
|
+
assert len(solution.segment_solutions) == 1
|
424
|
+
assert solution.execution_is_complete
|
425
|
+
|
426
|
+
def test_solve(
|
427
|
+
self,
|
428
|
+
state: State,
|
429
|
+
repetition_count: int,
|
430
|
+
sequence: Sequence,
|
431
|
+
segments: list[Segment],
|
432
|
+
instants: list[Instant],
|
433
|
+
numerical_solver: NumericalSolver,
|
434
|
+
):
|
435
|
+
solution = sequence.solve(
|
436
|
+
state=state,
|
437
|
+
repetition_count=repetition_count,
|
438
|
+
)
|
439
|
+
|
440
|
+
assert len(solution.segment_solutions) == len(segments)
|
441
|
+
|
442
|
+
assert solution.execution_is_complete
|
443
|
+
|
444
|
+
assert solution.access_start_instant() is not None
|
445
|
+
assert solution.access_end_instant() is not None
|
446
|
+
|
447
|
+
assert solution.get_states() is not None
|
448
|
+
assert solution.get_initial_mass() is not None
|
449
|
+
assert solution.get_final_mass() is not None
|
450
|
+
assert solution.get_propagation_duration() is not None
|
451
|
+
|
452
|
+
assert solution.compute_delta_mass() is not None
|
453
|
+
assert solution.compute_delta_v(1500.0) is not None
|
454
|
+
|
455
|
+
propagated_states = solution.calculate_states_at(
|
456
|
+
instants,
|
457
|
+
numerical_solver,
|
458
|
+
)
|
459
|
+
|
460
|
+
assert propagated_states is not None
|
461
|
+
assert len(propagated_states) == len(instants)
|
462
|
+
|
463
|
+
def test_solve_to_condition(
|
464
|
+
self,
|
465
|
+
state: State,
|
466
|
+
sequence: Sequence,
|
467
|
+
instant_condition: InstantCondition,
|
468
|
+
):
|
469
|
+
assert sequence.solve_to_condition(state, instant_condition) is not None
|
470
|
+
assert (
|
471
|
+
sequence.solve_to_condition(
|
472
|
+
state=state,
|
473
|
+
event_condition=instant_condition,
|
474
|
+
maximum_propagation_duration_limit=Duration.hours(1.0),
|
475
|
+
)
|
476
|
+
is not None
|
477
|
+
)
|