open-space-toolkit-astrodynamics 9.4.1__py38-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 (98) hide show
  1. open_space_toolkit_astrodynamics-9.4.1.dist-info/METADATA +30 -0
  2. open_space_toolkit_astrodynamics-9.4.1.dist-info/RECORD +98 -0
  3. open_space_toolkit_astrodynamics-9.4.1.dist-info/WHEEL +5 -0
  4. open_space_toolkit_astrodynamics-9.4.1.dist-info/top_level.txt +1 -0
  5. open_space_toolkit_astrodynamics-9.4.1.dist-info/zip-safe +1 -0
  6. ostk/__init__.py +1 -0
  7. ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-38-x86_64-linux-gnu.so +0 -0
  8. ostk/astrodynamics/__init__.py +11 -0
  9. ostk/astrodynamics/converters.py +185 -0
  10. ostk/astrodynamics/display.py +220 -0
  11. ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.9 +0 -0
  12. ostk/astrodynamics/pytrajectory/__init__.py +1 -0
  13. ostk/astrodynamics/pytrajectory/pystate.py +36 -0
  14. ostk/astrodynamics/test/__init__.py +1 -0
  15. ostk/astrodynamics/test/access/__init__.py +1 -0
  16. ostk/astrodynamics/test/access/test_generator.py +248 -0
  17. ostk/astrodynamics/test/conftest.py +119 -0
  18. ostk/astrodynamics/test/conjunction/message/ccsds/__init__.py +1 -0
  19. ostk/astrodynamics/test/conjunction/message/ccsds/conftest.py +325 -0
  20. ostk/astrodynamics/test/conjunction/message/ccsds/data/cdm.json +303 -0
  21. ostk/astrodynamics/test/conjunction/message/ccsds/test_cdm.py +416 -0
  22. ostk/astrodynamics/test/dynamics/__init__.py +1 -0
  23. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity.csv +565 -0
  24. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity_Truth.csv +100 -0
  25. ostk/astrodynamics/test/dynamics/test_atmospheric_drag.py +128 -0
  26. ostk/astrodynamics/test/dynamics/test_central_body_gravity.py +58 -0
  27. ostk/astrodynamics/test/dynamics/test_dynamics.py +50 -0
  28. ostk/astrodynamics/test/dynamics/test_position_derivative.py +51 -0
  29. ostk/astrodynamics/test/dynamics/test_tabulated.py +138 -0
  30. ostk/astrodynamics/test/dynamics/test_third_body_gravity.py +67 -0
  31. ostk/astrodynamics/test/dynamics/test_thruster.py +142 -0
  32. ostk/astrodynamics/test/event_condition/test_angular_condition.py +113 -0
  33. ostk/astrodynamics/test/event_condition/test_boolean_condition.py +55 -0
  34. ostk/astrodynamics/test/event_condition/test_coe_condition.py +87 -0
  35. ostk/astrodynamics/test/event_condition/test_instant_condition.py +48 -0
  36. ostk/astrodynamics/test/event_condition/test_logical_condition.py +120 -0
  37. ostk/astrodynamics/test/event_condition/test_real_condition.py +50 -0
  38. ostk/astrodynamics/test/flight/__init__.py +1 -0
  39. ostk/astrodynamics/test/flight/system/__init__.py +1 -0
  40. ostk/astrodynamics/test/flight/system/test_propulsion_system.py +73 -0
  41. ostk/astrodynamics/test/flight/system/test_satellite_system.py +91 -0
  42. ostk/astrodynamics/test/flight/system/test_satellite_system_builder.py +71 -0
  43. ostk/astrodynamics/test/flight/test_maneuver.py +212 -0
  44. ostk/astrodynamics/test/flight/test_profile.py +153 -0
  45. ostk/astrodynamics/test/flight/test_system.py +55 -0
  46. ostk/astrodynamics/test/guidance_law/test_constant_thrust.py +91 -0
  47. ostk/astrodynamics/test/guidance_law/test_qlaw.py +138 -0
  48. ostk/astrodynamics/test/solvers/__init__.py +1 -0
  49. ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +181 -0
  50. ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +153 -0
  51. ostk/astrodynamics/test/test_access.py +128 -0
  52. ostk/astrodynamics/test/test_converters.py +387 -0
  53. ostk/astrodynamics/test/test_display.py +115 -0
  54. ostk/astrodynamics/test/test_event_condition.py +58 -0
  55. ostk/astrodynamics/test/test_import.py +26 -0
  56. ostk/astrodynamics/test/test_root_solver.py +70 -0
  57. ostk/astrodynamics/test/test_trajectory.py +40 -0
  58. ostk/astrodynamics/test/test_utilities.py +121 -0
  59. ostk/astrodynamics/test/test_viewer.py +129 -0
  60. ostk/astrodynamics/test/trajectory/__init__.py +1 -0
  61. ostk/astrodynamics/test/trajectory/orbit/__init__.py +1 -0
  62. ostk/astrodynamics/test/trajectory/orbit/message/__init__.py +1 -0
  63. ostk/astrodynamics/test/trajectory/orbit/message/spacex/__init__.py +1 -0
  64. ostk/astrodynamics/test/trajectory/orbit/message/spacex/conftest.py +18 -0
  65. ostk/astrodynamics/test/trajectory/orbit/message/spacex/data/opm_1.yaml +44 -0
  66. ostk/astrodynamics/test/trajectory/orbit/message/spacex/test_opm.py +108 -0
  67. ostk/astrodynamics/test/trajectory/orbit/models/__init__.py +1 -0
  68. ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py +1 -0
  69. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py +65 -0
  70. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py +102 -0
  71. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py +102 -0
  72. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py +167 -0
  73. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +1 -0
  74. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +331 -0
  75. ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +130 -0
  76. ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +234 -0
  77. ostk/astrodynamics/test/trajectory/orbit/models/test_sgp4.py +1 -0
  78. ostk/astrodynamics/test/trajectory/orbit/models/test_tabulated.py +380 -0
  79. ostk/astrodynamics/test/trajectory/orbit/test_model.py +1 -0
  80. ostk/astrodynamics/test/trajectory/orbit/test_pass.py +72 -0
  81. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity.py +30 -0
  82. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py +18 -0
  83. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py +107 -0
  84. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py +115 -0
  85. ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py +84 -0
  86. ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py +46 -0
  87. ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +314 -0
  88. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py +81 -0
  89. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +76 -0
  90. ostk/astrodynamics/test/trajectory/test_model.py +1 -0
  91. ostk/astrodynamics/test/trajectory/test_orbit.py +174 -0
  92. ostk/astrodynamics/test/trajectory/test_propagator.py +458 -0
  93. ostk/astrodynamics/test/trajectory/test_segment.py +305 -0
  94. ostk/astrodynamics/test/trajectory/test_sequence.py +477 -0
  95. ostk/astrodynamics/test/trajectory/test_state.py +237 -0
  96. ostk/astrodynamics/test/trajectory/test_state_builder.py +171 -0
  97. ostk/astrodynamics/utilities.py +158 -0
  98. ostk/astrodynamics/viewer.py +392 -0
@@ -0,0 +1,91 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import numpy as np
6
+
7
+ import ostk.mathematics as mathematics
8
+
9
+ import ostk.physics as physics
10
+
11
+ import ostk.astrodynamics as astrodynamics
12
+
13
+ Cuboid = mathematics.geometry.d3.object.Cuboid
14
+ Composite = mathematics.geometry.d3.object.Composite
15
+ Point = mathematics.geometry.d3.object.Point
16
+
17
+ Mass = physics.unit.Mass
18
+
19
+ SatelliteSystem = astrodynamics.flight.system.SatelliteSystem
20
+ PropulsionSystem = astrodynamics.flight.system.PropulsionSystem
21
+
22
+
23
+ @pytest.fixture
24
+ def satellite_system_default_inputs():
25
+ mass = Mass(90.0, Mass.Unit.Kilogram)
26
+ satellite_geometry = Composite(
27
+ Cuboid(
28
+ Point(0.0, 0.0, 0.0),
29
+ [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
30
+ [1.0, 0.0, 0.0],
31
+ )
32
+ )
33
+ inertia_tensor = np.ndarray(shape=(3, 3))
34
+ surface_area = 0.8
35
+ drag_coefficient = 2.2
36
+ propulsion_system = PropulsionSystem(
37
+ 1.0,
38
+ 150.0,
39
+ )
40
+
41
+ return (
42
+ mass,
43
+ satellite_geometry,
44
+ inertia_tensor,
45
+ surface_area,
46
+ drag_coefficient,
47
+ propulsion_system,
48
+ )
49
+
50
+
51
+ @pytest.fixture
52
+ def satellite_system(satellite_system_default_inputs) -> SatelliteSystem:
53
+ return SatelliteSystem(*satellite_system_default_inputs)
54
+
55
+
56
+ class TestSatelliteSystem:
57
+ def test_constructors(
58
+ self,
59
+ satellite_system: SatelliteSystem,
60
+ ):
61
+ assert satellite_system is not None
62
+ assert isinstance(satellite_system, SatelliteSystem)
63
+ assert satellite_system.is_defined()
64
+
65
+ def test_comparators(
66
+ self,
67
+ satellite_system: SatelliteSystem,
68
+ ):
69
+ assert (satellite_system == satellite_system) is True
70
+ assert (satellite_system != satellite_system) is False
71
+
72
+ def test_getters(
73
+ self,
74
+ satellite_system_default_inputs,
75
+ satellite_system: SatelliteSystem,
76
+ ):
77
+ (
78
+ mass,
79
+ satellite_geometry,
80
+ inertia_tensor,
81
+ surface_area,
82
+ drag_coefficient,
83
+ propulsion_system,
84
+ ) = satellite_system_default_inputs
85
+
86
+ assert satellite_system.get_mass() == mass
87
+ assert satellite_system.get_geometry() == satellite_geometry
88
+ assert np.array_equal(satellite_system.get_inertia_tensor(), inertia_tensor)
89
+ assert satellite_system.get_cross_sectional_surface_area() == surface_area
90
+ assert satellite_system.get_drag_coefficient() == drag_coefficient
91
+ assert satellite_system.get_propulsion_system() == propulsion_system
@@ -0,0 +1,71 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import numpy as np
6
+
7
+ import ostk.mathematics as mathematics
8
+
9
+ import ostk.physics as physics
10
+
11
+ import ostk.astrodynamics as astrodynamics
12
+
13
+ Cuboid = mathematics.geometry.d3.object.Cuboid
14
+ Composite = mathematics.geometry.d3.object.Composite
15
+ Point = mathematics.geometry.d3.object.Point
16
+
17
+ Mass = physics.unit.Mass
18
+
19
+ SatelliteSystem = astrodynamics.flight.system.SatelliteSystem
20
+ SatelliteSystemBuilder = astrodynamics.flight.system.SatelliteSystemBuilder
21
+ PropulsionSystem = astrodynamics.flight.system.PropulsionSystem
22
+
23
+
24
+ class TestSatelliteSystemBuilder:
25
+ def test_constructors(self):
26
+ builder: SatelliteSystemBuilder = SatelliteSystemBuilder()
27
+ assert builder is not None
28
+ assert isinstance(builder, SatelliteSystemBuilder)
29
+
30
+ default_builder: SatelliteSystemBuilder = SatelliteSystemBuilder.default()
31
+ assert default_builder is not None
32
+ assert isinstance(default_builder, SatelliteSystemBuilder)
33
+
34
+ def test_build(self):
35
+ dry_mass = Mass(90.0, Mass.Unit.Kilogram)
36
+ geometry = Composite(
37
+ Cuboid(
38
+ Point(0.0, 0.0, 0.0),
39
+ [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
40
+ [1.0, 0.0, 0.0],
41
+ )
42
+ )
43
+ inertia_tensor = np.ndarray(shape=(3, 3))
44
+ cross_sectional_surface_area = 0.8
45
+ drag_coefficient = 2.2
46
+ propulsion_system = PropulsionSystem(
47
+ 1.0,
48
+ 150.0,
49
+ )
50
+
51
+ builder: SatelliteSystemBuilder = (
52
+ SatelliteSystemBuilder()
53
+ .with_dry_mass(dry_mass)
54
+ .with_geometry(geometry)
55
+ .with_inertia_tensor(inertia_tensor)
56
+ .with_cross_sectional_surface_area(cross_sectional_surface_area)
57
+ .with_drag_coefficient(drag_coefficient)
58
+ .with_propulsion_system(propulsion_system)
59
+ )
60
+
61
+ satellite_system: SatelliteSystem = builder.build()
62
+
63
+ assert satellite_system.get_mass() == dry_mass
64
+ assert satellite_system.get_geometry() == geometry
65
+ assert np.array_equal(satellite_system.get_inertia_tensor(), inertia_tensor)
66
+ assert (
67
+ satellite_system.get_cross_sectional_surface_area()
68
+ == cross_sectional_surface_area
69
+ )
70
+ assert satellite_system.get_drag_coefficient() == drag_coefficient
71
+ assert satellite_system.get_propulsion_system() == propulsion_system
@@ -0,0 +1,212 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import numpy as np
6
+
7
+
8
+ from ostk.physics.time import Instant
9
+ from ostk.physics.time import Interval
10
+ from ostk.physics.time import Duration
11
+ from ostk.physics.coordinate import Frame
12
+ from ostk.physics.unit import Mass
13
+
14
+ from ostk.astrodynamics.flight import Maneuver
15
+ from ostk.astrodynamics.dynamics import Tabulated as TabulatedDynamics
16
+ from ostk.astrodynamics.trajectory.state import CoordinateSubset
17
+
18
+
19
+ from ..dynamics.test_tabulated import (
20
+ instants as tabulated_instants,
21
+ contribution_profile as tabulated_contribution_profile,
22
+ coordinate_subsets as tabulated_coordinate_subsets,
23
+ )
24
+
25
+
26
+ @pytest.fixture
27
+ def instants() -> list[Instant]:
28
+ return [
29
+ Instant.J2000(),
30
+ Instant.J2000() + Duration.seconds(1.0),
31
+ Instant.J2000() + Duration.seconds(5.0),
32
+ Instant.J2000() + Duration.seconds(7.0),
33
+ ]
34
+
35
+
36
+ @pytest.fixture
37
+ def acceleration_profile() -> list[np.ndarray]:
38
+ return [
39
+ np.array([1.0e-3, 0.0e-3, 0.0e-3]),
40
+ np.array([0.0e-3, 1.0e-3, 0.0e-3]),
41
+ np.array([0.0e-3, 0.0e-3, 1.0e-3]),
42
+ np.array([1.0e-3, 1.0e-3, 1.0e-3]),
43
+ ]
44
+
45
+
46
+ @pytest.fixture
47
+ def frame() -> Frame:
48
+ return Frame.GCRF()
49
+
50
+
51
+ @pytest.fixture
52
+ def mass_flow_rate_profile() -> list[float]:
53
+ return [-1.0e-5, -1.1e-5, -0.9e-5, -1.0e-5]
54
+
55
+
56
+ @pytest.fixture
57
+ def maneuver(
58
+ instants: list[Instant],
59
+ acceleration_profile: list[np.ndarray],
60
+ frame: Frame,
61
+ mass_flow_rate_profile: list[float],
62
+ ) -> Maneuver:
63
+ return Maneuver(instants, acceleration_profile, frame, mass_flow_rate_profile)
64
+
65
+
66
+ @pytest.fixture
67
+ def tabulated_dynamics(
68
+ tabulated_instants: list[Instant],
69
+ tabulated_contribution_profile: np.ndarray,
70
+ tabulated_coordinate_subsets: list[CoordinateSubset],
71
+ frame: Frame,
72
+ ) -> TabulatedDynamics:
73
+ return TabulatedDynamics(
74
+ tabulated_instants,
75
+ tabulated_contribution_profile,
76
+ tabulated_coordinate_subsets,
77
+ frame,
78
+ )
79
+
80
+
81
+ class TestManeuver:
82
+ def test_constructor(
83
+ self,
84
+ maneuver: Maneuver,
85
+ ):
86
+ assert maneuver is not None
87
+ assert isinstance(maneuver, Maneuver)
88
+ assert maneuver.is_defined()
89
+
90
+ def test_comparators(
91
+ self,
92
+ maneuver: Maneuver,
93
+ ):
94
+ assert (maneuver == maneuver) is True
95
+ assert (maneuver != maneuver) is False
96
+
97
+ def test_getters(
98
+ self,
99
+ maneuver: Maneuver,
100
+ instants: list[Instant],
101
+ acceleration_profile: list[np.ndarray],
102
+ mass_flow_rate_profile: list[float],
103
+ ):
104
+ assert maneuver.is_defined()
105
+
106
+ assert maneuver.get_instants() == instants
107
+
108
+ computed_acceleration_profile_default_frame = maneuver.get_acceleration_profile()
109
+ for i in range(len(instants)):
110
+ assert np.array_equal(
111
+ computed_acceleration_profile_default_frame[i], acceleration_profile[i]
112
+ )
113
+
114
+ computed_acceleration_profile_non_default_frame = (
115
+ maneuver.get_acceleration_profile(frame=Frame.ITRF())
116
+ )
117
+ for i in range(len(instants)):
118
+ assert (
119
+ np.array_equal(
120
+ computed_acceleration_profile_non_default_frame[i],
121
+ acceleration_profile[i],
122
+ )
123
+ == False
124
+ )
125
+
126
+ assert maneuver.get_mass_flow_rate_profile() == mass_flow_rate_profile
127
+
128
+ assert maneuver.get_interval() == Interval.closed(instants[0], instants[-1])
129
+
130
+ def test_calculators(
131
+ self,
132
+ maneuver: Maneuver,
133
+ ):
134
+ assert maneuver.calculate_delta_v() is not None
135
+ assert maneuver.calculate_delta_mass().in_kilograms() is not None
136
+ assert (
137
+ maneuver.calculate_average_thrust(
138
+ initial_spacecraft_mass=Mass(100.0, Mass.Unit.Kilogram)
139
+ )
140
+ is not None
141
+ )
142
+ assert (
143
+ maneuver.calculate_average_specific_impulse(
144
+ initial_spacecraft_mass=Mass(100.0, Mass.Unit.Kilogram)
145
+ )
146
+ is not None
147
+ )
148
+
149
+ def test_to_tabulated_dynamics(
150
+ self,
151
+ maneuver: Maneuver,
152
+ instants: list[Instant],
153
+ acceleration_profile: list[np.ndarray],
154
+ frame: Frame,
155
+ mass_flow_rate_profile: list[float],
156
+ ):
157
+ tabulated_dynamics: TabulatedDynamics = maneuver.to_tabulated_dynamics(
158
+ frame=frame
159
+ )
160
+
161
+ assert tabulated_dynamics.is_defined()
162
+ assert tabulated_dynamics.access_instants() == maneuver.get_instants()
163
+
164
+ contribution_profile: np.ndarray = (
165
+ tabulated_dynamics.access_contribution_profile()
166
+ )
167
+
168
+ for i in range(len(instants)):
169
+ assert contribution_profile[i][0:3] == pytest.approx(
170
+ acceleration_profile[i], rel=1e-15
171
+ )
172
+ assert contribution_profile[i][3] == pytest.approx(
173
+ mass_flow_rate_profile[i], rel=1e-15
174
+ )
175
+
176
+ assert tabulated_dynamics.access_frame() == frame
177
+
178
+ def test_from_tabulated_dynamics(
179
+ self,
180
+ tabulated_dynamics: TabulatedDynamics,
181
+ ):
182
+ maneuver = Maneuver.tabulated_dynamics(tabulated_dynamics)
183
+
184
+ assert maneuver.is_defined()
185
+ assert maneuver.get_instants() == tabulated_dynamics.access_instants()
186
+ assert (
187
+ len(maneuver.get_acceleration_profile())
188
+ == tabulated_dynamics.access_contribution_profile().shape[0]
189
+ )
190
+ assert (
191
+ len(maneuver.get_mass_flow_rate_profile())
192
+ == tabulated_dynamics.access_contribution_profile().shape[0]
193
+ )
194
+
195
+ def test_from_constant_mass_flow_rate(
196
+ self,
197
+ instants: list[Instant],
198
+ acceleration_profile: list[np.ndarray],
199
+ frame: Frame,
200
+ ):
201
+ mass_flow_rate: float = -1.0e-5
202
+ maneuver = Maneuver.constant_mass_flow_rate_profile(
203
+ instants=instants,
204
+ acceleration_profile=acceleration_profile,
205
+ frame=frame,
206
+ mass_flow_rate=mass_flow_rate,
207
+ )
208
+
209
+ assert maneuver.is_defined()
210
+ assert maneuver.get_mass_flow_rate_profile() == [
211
+ mass_flow_rate for _ in range(len(instants))
212
+ ]
@@ -0,0 +1,153 @@
1
+ # Apache License 2.0
2
+
3
+ from datetime import datetime
4
+
5
+ import pytest
6
+
7
+ from ostk.mathematics.geometry.d3.transformation.rotation import Quaternion
8
+
9
+ from ostk.physics import Environment
10
+ from ostk.physics.time import DateTime
11
+ from ostk.physics.time import Time
12
+ from ostk.physics.time import Scale
13
+ from ostk.physics.time import Instant
14
+ from ostk.physics.unit import Length
15
+ from ostk.physics.coordinate import Transform
16
+ from ostk.physics.coordinate import Position
17
+ from ostk.physics.coordinate import Velocity
18
+ from ostk.physics.coordinate import Frame
19
+ from ostk.physics.coordinate import Axes
20
+ from ostk.physics.coordinate.frame.provider import Dynamic as DynamicProvider
21
+
22
+ from ostk.astrodynamics import Trajectory
23
+ from ostk.astrodynamics.trajectory import Orbit
24
+ from ostk.astrodynamics.trajectory import State
25
+ from ostk.astrodynamics.flight import Profile
26
+ from ostk.astrodynamics.flight.profile.model import Transform as TransformModel
27
+ from ostk.astrodynamics.flight.profile.model import Tabulated as TabulatedModel
28
+
29
+
30
+ @pytest.fixture
31
+ def instant() -> Instant:
32
+ return Instant.date_time(DateTime(2020, 1, 3), Scale.UTC)
33
+
34
+
35
+ @pytest.fixture
36
+ def profile() -> Profile:
37
+ def dynamic_provider_generator(instant: Instant):
38
+ return Transform.identity(instant)
39
+
40
+ return Profile(
41
+ model=TransformModel(
42
+ dynamic_provider=DynamicProvider(dynamic_provider_generator),
43
+ frame=Frame.GCRF(),
44
+ ),
45
+ )
46
+
47
+
48
+ class TestProfile:
49
+ def test_constructors(self, profile: Profile):
50
+ assert profile is not None
51
+ assert isinstance(profile, Profile)
52
+
53
+ def test_get_state_at(self, profile: Profile, instant: Instant):
54
+ state: State = profile.get_state_at(instant)
55
+
56
+ assert state is not None
57
+ assert isinstance(state, State)
58
+ state.is_defined()
59
+
60
+ def test_get_states_at(self, profile: Profile, instant: Instant):
61
+ states = profile.get_states_at([instant, instant])
62
+
63
+ assert states is not None
64
+
65
+ def test_get_axes_at(self, profile: Profile, instant: Instant):
66
+ axes = profile.get_axes_at(instant)
67
+
68
+ assert axes is not None
69
+ assert isinstance(axes, Axes)
70
+
71
+ def test_get_body_frame(self, profile: Profile, instant: Instant):
72
+ frame = profile.get_body_frame("Name")
73
+
74
+ assert frame is not None
75
+ assert isinstance(frame, Frame)
76
+
77
+ def test_undefined(self):
78
+ profile: Profile = Profile.undefined()
79
+
80
+ assert profile is not None
81
+ assert isinstance(profile, Profile)
82
+ assert profile.is_defined() is False
83
+
84
+ def test_inertial_pointing(self):
85
+ quaternion: Quaternion = Quaternion([0.0, 0.0, 0.0, 1.0], Quaternion.Format.XYZS)
86
+
87
+ trajectory: Trajectory = Trajectory.position(
88
+ Position.meters((0.0, 0.0, 0.0), Frame.GCRF())
89
+ )
90
+
91
+ profile: Profile = Profile.inertial_pointing(trajectory, quaternion)
92
+
93
+ assert profile is not None
94
+ assert isinstance(profile, Profile)
95
+ assert profile.is_defined()
96
+
97
+ def test_nadir_pointing(self):
98
+ environment = Environment.default()
99
+
100
+ orbit = Orbit.sun_synchronous(
101
+ epoch=Instant.date_time(datetime(2020, 1, 1, 0, 0, 0), Scale.UTC),
102
+ altitude=Length.kilometers(500.0),
103
+ local_time_at_descending_node=Time(14, 0, 0),
104
+ celestial_object=environment.access_celestial_object_with_name("Earth"),
105
+ )
106
+
107
+ profile: Profile = Profile.nadir_pointing(orbit, Orbit.FrameType.VVLH)
108
+
109
+ assert profile is not None
110
+ assert isinstance(profile, Profile)
111
+ assert profile.is_defined()
112
+
113
+ def test_tabulated(self):
114
+ profile = Profile(
115
+ model=TabulatedModel(
116
+ states=[
117
+ State(
118
+ instant=Instant.date_time(
119
+ datetime(2020, 1, 1, 0, 0, 0), Scale.UTC
120
+ ),
121
+ position=Position.meters((0.0, 0.0, 0.0), Frame.GCRF()),
122
+ velocity=Velocity.meters_per_second(
123
+ (0.0, 0.0, 0.0), Frame.GCRF()
124
+ ),
125
+ attitude=Quaternion.unit(),
126
+ angular_velocity=(0.0, 0.0, 0.0),
127
+ attitude_frame=Frame.GCRF(),
128
+ ),
129
+ State(
130
+ instant=Instant.date_time(
131
+ datetime(2020, 1, 1, 0, 1, 0), Scale.UTC
132
+ ),
133
+ position=Position.meters((0.0, 0.0, 0.0), Frame.GCRF()),
134
+ velocity=Velocity.meters_per_second(
135
+ (0.0, 0.0, 0.0), Frame.GCRF()
136
+ ),
137
+ attitude=Quaternion.unit(),
138
+ angular_velocity=(0.0, 0.0, 0.0),
139
+ attitude_frame=Frame.GCRF(),
140
+ ),
141
+ ],
142
+ ),
143
+ )
144
+
145
+ assert isinstance(profile, Profile)
146
+ assert profile.is_defined()
147
+
148
+ assert (
149
+ profile.get_state_at(
150
+ Instant.date_time(datetime(2020, 1, 1, 0, 0, 30), Scale.UTC)
151
+ )
152
+ is not None
153
+ )
@@ -0,0 +1,55 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import numpy as np
6
+
7
+ import ostk.mathematics as mathematics
8
+
9
+ import ostk.physics as physics
10
+
11
+ import ostk.astrodynamics as astrodynamics
12
+
13
+ Cuboid = mathematics.geometry.d3.object.Cuboid
14
+ Composite = mathematics.geometry.d3.object.Composite
15
+ Point = mathematics.geometry.d3.object.Point
16
+
17
+ Mass = physics.unit.Mass
18
+
19
+ System = astrodynamics.flight.System
20
+
21
+
22
+ @pytest.fixture
23
+ def system_default_inputs():
24
+ mass = Mass(90.0, Mass.Unit.Kilogram)
25
+ geometry = Composite(
26
+ Cuboid(
27
+ Point(0.0, 0.0, 0.0),
28
+ [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
29
+ [1.0, 0.0, 0.0],
30
+ )
31
+ )
32
+
33
+ return (mass, geometry)
34
+
35
+
36
+ @pytest.fixture
37
+ def system(system_default_inputs) -> System:
38
+ return System(*system_default_inputs)
39
+
40
+
41
+ class TestSatelliteSystem:
42
+ def test_constructors(self, system: System):
43
+ assert system is not None
44
+ assert isinstance(system, System)
45
+ assert system.is_defined()
46
+
47
+ def test_comparators(self, system: System):
48
+ assert (system == system) is True
49
+ assert (system != system) is False
50
+
51
+ def test_getters(self, system_default_inputs, system: System):
52
+ (mass, geometry) = system_default_inputs
53
+
54
+ assert system.get_mass() == mass
55
+ assert system.get_geometry() == geometry
@@ -0,0 +1,91 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics.time import Instant
6
+ from ostk.physics.time import DateTime
7
+ from ostk.physics.time import Scale
8
+ from ostk.physics.coordinate import Frame
9
+
10
+ from ostk.astrodynamics.trajectory import LocalOrbitalFrameFactory
11
+ from ostk.astrodynamics.trajectory import LocalOrbitalFrameDirection
12
+
13
+ from ostk.astrodynamics import GuidanceLaw
14
+ from ostk.astrodynamics.guidance_law import ConstantThrust
15
+
16
+
17
+ @pytest.fixture
18
+ def local_orbital_frame_direction() -> LocalOrbitalFrameDirection:
19
+ return LocalOrbitalFrameDirection(
20
+ vector=[1.0, 0.0, 0.0],
21
+ local_orbital_frame_factory=LocalOrbitalFrameFactory.VNC(Frame.GCRF()),
22
+ )
23
+
24
+
25
+ @pytest.fixture
26
+ def guidance_law(
27
+ local_orbital_frame_direction: LocalOrbitalFrameDirection,
28
+ ) -> ConstantThrust:
29
+ return ConstantThrust(thrust_direction=local_orbital_frame_direction)
30
+
31
+
32
+ @pytest.fixture
33
+ def instant() -> Instant:
34
+ return Instant.date_time(DateTime(2021, 3, 20, 12, 0, 0), Scale.UTC)
35
+
36
+
37
+ @pytest.fixture
38
+ def position_coordinates() -> list[float]:
39
+ return [7000000.0, 0.0, 0.0]
40
+
41
+
42
+ @pytest.fixture
43
+ def velocity_coordinates() -> list[float]:
44
+ return [0.0, 7546.05329, 0.0]
45
+
46
+
47
+ @pytest.fixture
48
+ def thrust_acceleration() -> float:
49
+ return 1.0 / 105.0
50
+
51
+
52
+ @pytest.fixture
53
+ def frame() -> Frame:
54
+ return Frame.GCRF()
55
+
56
+
57
+ class TestConstantThrust:
58
+ def test_constructors(self, guidance_law: ConstantThrust):
59
+ assert guidance_law is not None
60
+ assert isinstance(guidance_law, ConstantThrust)
61
+ assert isinstance(guidance_law, GuidanceLaw)
62
+
63
+ def test_getters(self, guidance_law: ConstantThrust):
64
+ assert guidance_law.get_local_thrust_direction() is not None
65
+
66
+ def test_static_constructors(self):
67
+ assert ConstantThrust.intrack() is not None
68
+
69
+ assert ConstantThrust.intrack(velocity_direction=False) is not None
70
+
71
+ assert ConstantThrust.intrack(velocity_direction=True) is not None
72
+
73
+ def test_compute_acceleration_success(
74
+ self,
75
+ guidance_law: ConstantThrust,
76
+ instant: Instant,
77
+ position_coordinates: list[float],
78
+ velocity_coordinates: list[float],
79
+ thrust_acceleration: float,
80
+ frame: Frame,
81
+ ):
82
+ contribution = guidance_law.calculate_thrust_acceleration_at(
83
+ instant=instant,
84
+ position_coordinates=position_coordinates,
85
+ velocity_coordinates=velocity_coordinates,
86
+ thrust_acceleration=thrust_acceleration,
87
+ output_frame=frame,
88
+ )
89
+
90
+ assert len(contribution) == 3
91
+ assert contribution == pytest.approx([0.0, 0.009523809523809525, 0.0], abs=5e-11)