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,121 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import ostk.physics as physics
6
+ import ostk.astrodynamics as astrodynamics
7
+ from ostk.astrodynamics import utilities
8
+
9
+ Length = physics.unit.Length
10
+ Angle = physics.unit.Angle
11
+ DateTime = physics.time.DateTime
12
+ Scale = physics.time.Scale
13
+ Instant = physics.time.Instant
14
+ Interval = physics.time.Interval
15
+ Position = physics.coordinate.Position
16
+ Velocity = physics.coordinate.Velocity
17
+ Frame = physics.coordinate.Frame
18
+ LLA = physics.coordinate.spherical.LLA
19
+ AER = physics.coordinate.spherical.AER
20
+ Environment = physics.Environment
21
+ Trajectory = astrodynamics.Trajectory
22
+ State = astrodynamics.trajectory.State
23
+
24
+
25
+ class TestUtility:
26
+ def test_lla_from_state(
27
+ self,
28
+ state: State,
29
+ ):
30
+ lla: tuple[float, float, float] = utilities.lla_from_state(state)
31
+
32
+ assert lla is not None
33
+ assert len(lla) == 3
34
+ assert isinstance(lla, tuple)
35
+ assert isinstance(lla[0], float)
36
+ assert lla[0] >= -90.0 and lla[0] <= 90.0
37
+ assert isinstance(lla[1], float)
38
+ assert lla[0] >= -180.0 and lla[0] <= 180.0
39
+ assert isinstance(lla[2], float)
40
+
41
+ def test_lla_from_position(
42
+ self,
43
+ instant: Instant,
44
+ position: Position,
45
+ state: State,
46
+ ):
47
+ lla: LLA = utilities.lla_from_position(position, instant)
48
+
49
+ assert lla is not None
50
+ assert isinstance(lla, LLA)
51
+ assert lla.is_defined()
52
+
53
+ lla_from_state: tuple[float, float, float] = utilities.lla_from_state(state)
54
+
55
+ assert lla.get_latitude().in_degrees() == lla_from_state[0]
56
+ assert lla.get_longitude().in_degrees() == lla_from_state[1]
57
+ assert lla.get_altitude().in_meters() == lla_from_state[2]
58
+
59
+ def test_position_from_lla(
60
+ self,
61
+ lla: LLA,
62
+ ):
63
+ position: Position = utilities.position_from_lla(lla)
64
+
65
+ assert position is not None
66
+ assert isinstance(position, Position)
67
+ assert position.is_defined()
68
+
69
+ def test_compute_aer(
70
+ self,
71
+ instant: Instant,
72
+ position: Position,
73
+ environment: Environment,
74
+ ):
75
+ aer: tuple[float, float, float] = utilities.compute_aer(
76
+ instant, position, position, environment
77
+ )
78
+
79
+ assert aer is not None
80
+ assert len(aer) == 3
81
+ assert aer[2] == 0.0
82
+
83
+ def test_compute_time_lla_aer_state(
84
+ self,
85
+ state: State,
86
+ position: Position,
87
+ environment: Environment,
88
+ ):
89
+ time_lla_aer: float[Instant, float, float, float, float, float, float] = (
90
+ utilities.compute_time_lla_aer_state(state, position, environment)
91
+ )
92
+
93
+ assert time_lla_aer is not None
94
+ assert len(time_lla_aer) == 7
95
+ assert isinstance(time_lla_aer[0], Instant)
96
+ assert time_lla_aer[0] == state.get_instant()
97
+ for i in range(1, 7):
98
+ assert isinstance(time_lla_aer[i], float)
99
+
100
+ def test_compute_trajectory_geometry(
101
+ self,
102
+ interval: Interval,
103
+ trajectory: Trajectory,
104
+ ):
105
+ output: list[tuple[float, float, float]] = utilities.compute_trajectory_geometry(
106
+ trajectory, interval
107
+ )
108
+
109
+ assert output is not None
110
+ assert len(output) == 2
111
+
112
+ def test_convert_state(self, state: State):
113
+ output: tuple[
114
+ str, float, float, float, float, float, float, float, float, float
115
+ ] = utilities.convert_state(state)
116
+
117
+ assert output is not None
118
+ assert len(output) == 11
119
+ assert isinstance(output[0], str)
120
+ for i in range(1, 11):
121
+ assert isinstance(output[i], float)
@@ -0,0 +1,129 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics import Environment
6
+ from ostk.physics.unit import Length
7
+ from ostk.physics.unit import Angle
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.time import DateTime
12
+ from ostk.physics.time import Time
13
+ from ostk.physics.time import Scale
14
+ from ostk.physics.unit import Length
15
+ from ostk.physics.coordinate import Position
16
+ from ostk.physics.coordinate import Frame
17
+
18
+ from ostk.astrodynamics.trajectory import Orbit
19
+ from ostk.astrodynamics.flight import Profile
20
+ from ostk.astrodynamics.viewer import Viewer
21
+ from ostk.astrodynamics.viewer import ConicSensor
22
+
23
+
24
+ @pytest.fixture
25
+ def environment() -> Environment:
26
+ return Environment.default()
27
+
28
+
29
+ @pytest.fixture
30
+ def orbit(environment: Environment) -> Orbit:
31
+ return Orbit.sun_synchronous(
32
+ epoch=Instant.date_time(DateTime(2020, 1, 1, 0, 0, 0), Scale.UTC),
33
+ altitude=Length.kilometers(500.0),
34
+ local_time_at_descending_node=Time(14, 0, 0),
35
+ celestial_object=environment.access_celestial_object_with_name("Earth"),
36
+ )
37
+
38
+
39
+ @pytest.fixture
40
+ def profile(orbit: Orbit) -> Profile:
41
+ return Profile.nadir_pointing(
42
+ orbit=orbit,
43
+ orbital_frame_type=Orbit.FrameType.VVLH,
44
+ )
45
+
46
+
47
+ @pytest.fixture
48
+ def interval() -> Interval:
49
+ return Interval.closed(
50
+ start_instant=Instant.date_time(DateTime(2020, 1, 1, 0, 0, 0), Scale.UTC),
51
+ end_instant=Instant.date_time(DateTime(2020, 1, 1, 0, 10, 0), Scale.UTC),
52
+ )
53
+
54
+
55
+ @pytest.fixture
56
+ def viewer(interval: Interval) -> Viewer:
57
+ return Viewer(
58
+ interval=interval,
59
+ )
60
+
61
+
62
+ class TestViewer:
63
+ def test_constructor_success(self, interval: Interval):
64
+ viewer = Viewer(
65
+ interval=interval,
66
+ )
67
+
68
+ assert viewer is not None
69
+ assert viewer.interval == interval
70
+
71
+ rendered_html: str = viewer.render()
72
+
73
+ assert rendered_html.startswith('<meta charset="utf-8">')
74
+ assert "var widget = new Cesium.Viewer" in rendered_html
75
+ assert rendered_html.endswith("</script>")
76
+
77
+ def test_add_profile_success(
78
+ self,
79
+ viewer: Viewer,
80
+ profile: Profile,
81
+ ):
82
+ viewer.add_profile(
83
+ profile=profile,
84
+ step=Duration.seconds(30.0),
85
+ show_orbital_track=True,
86
+ cesium_asset_id=123,
87
+ sensors=[
88
+ ConicSensor(
89
+ name="star_tracker",
90
+ direction=(1.0, 0.0, 0.0),
91
+ half_angle=Angle.degrees(8.0),
92
+ length=Length.meters(0.1),
93
+ color="red",
94
+ ),
95
+ ],
96
+ show_xyz_axes=True,
97
+ )
98
+
99
+ rendered_html: str = viewer.render()
100
+
101
+ assert rendered_html.startswith('<meta charset="utf-8">')
102
+ assert "var widget = new Cesium.Viewer" in rendered_html
103
+ assert " widget.entities.add({position: widget" in rendered_html
104
+ assert "Cesium.IonResource.fromAssetId(123)" in rendered_html
105
+ assert "widget.entities.add({polyline:" in rendered_html
106
+ assert (
107
+ "widget.entities.add({position: widget.star_tracker_position" in rendered_html
108
+ )
109
+ assert rendered_html.endswith("</script>")
110
+
111
+ def test_add_target_success(
112
+ self,
113
+ viewer: Viewer,
114
+ ):
115
+ viewer.add_target(
116
+ position=Position.meters([1.0, 2.0, 3.0], Frame.ITRF()),
117
+ size=123,
118
+ color="red",
119
+ )
120
+
121
+ rendered_html: str = viewer.render()
122
+
123
+ assert rendered_html.startswith('<meta charset="utf-8">')
124
+ assert "var widget = new Cesium.Viewer" in rendered_html
125
+ assert (
126
+ "widget.entities.add({position: Cesium.Cartesian3.fromDegrees(63.43494882292201, 18.22447811510915, -6376045.535225509), point: {pixelSize: 123.0, color: Cesium.Color.RED}});"
127
+ in rendered_html
128
+ )
129
+ assert rendered_html.endswith("</script>")
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1,18 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ import pathlib
6
+
7
+ from ostk.core.filesystem import Path
8
+ from ostk.core.filesystem import File
9
+
10
+
11
+ @pytest.fixture
12
+ def data_directory_path() -> str:
13
+ return f"{pathlib.Path(__file__).parent.absolute()}/data"
14
+
15
+
16
+ @pytest.fixture
17
+ def opm_file(data_directory_path: str) -> File:
18
+ return File.path(Path.parse(f"{data_directory_path}/opm_1.yaml"))
@@ -0,0 +1,44 @@
1
+ # Dummy SpaceX OPM output
2
+
3
+ # Notes:
4
+ # - ECEF velocity is Earth relative
5
+ # - Apogee/Perigee altitude assumes a spherical Earth, 6378.137 km radius
6
+ # - Orbital elements are computed in an inertial frame realized by inertially
7
+ # freezing the WGS84 ECEF frame at time of current state
8
+ # - State is post-deployment, so includes separation delta-velocity
9
+
10
+
11
+ header:
12
+ generation_date: 2020-01-01T12:34:56.789Z
13
+ launch_date: 2020-01-02T12:34:56.789Z
14
+
15
+
16
+ deployments:
17
+
18
+ - name: satellite_a
19
+ sequence_number: 1
20
+ mission_time_s: 3600.0
21
+ date: 2020-01-02T13:34:56.789Z
22
+ r_ecef_m: [693289.644, 6876578.628, -133035.288]
23
+ v_ecef_m_per_s: [1305.783, 39.783, 7525.920]
24
+ mean_perigee_altitude_km: 526.768
25
+ mean_apogee_altitude_km: 568.430
26
+ mean_inclination_deg: 97.123
27
+ mean_argument_of_perigee_deg: -179.513
28
+ mean_longitude_ascending_node_deg: 85.057
29
+ mean_mean_anomaly_deg: 179.263
30
+ ballistic_coef_kg_per_m2: 47.55
31
+
32
+ - name: satellite_b
33
+ sequence_number: 2
34
+ mission_time_s: 7200.0
35
+ date: 2020-01-02T14:34:56.789Z
36
+ r_ecef_m: [699863.059, 6875647.517, -123777.595]
37
+ v_ecef_m_per_s: [1504.658, 6.705, 7538.669]
38
+ mean_perigee_altitude_km: 536.779
39
+ mean_apogee_altitude_km: 529.851
40
+ mean_inclination_deg: 97.124
41
+ mean_argument_of_perigee_deg: 136.875
42
+ mean_longitude_ascending_node_deg: 85.032
43
+ mean_mean_anomaly_deg: -127.164
44
+ ballistic_coef_kg_per_m2: 44.26
@@ -0,0 +1,108 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from datetime import datetime
6
+
7
+ from ostk.core.container import Dictionary
8
+ from ostk.core.filesystem import Path
9
+ from ostk.core.filesystem import File
10
+
11
+ from ostk.physics.unit import Length
12
+ from ostk.physics.unit import Angle
13
+ from ostk.physics.time import Instant
14
+ from ostk.physics.time import Scale
15
+ from ostk.physics.time import Duration
16
+ from ostk.physics.coordinate import Position
17
+ from ostk.physics.coordinate import Velocity
18
+ from ostk.physics.coordinate import Frame
19
+
20
+ from ostk.astrodynamics.trajectory.orbit.message.spacex import OPM
21
+
22
+
23
+ @pytest.fixture
24
+ def opm() -> OPM:
25
+ return OPM(
26
+ header=OPM.Header(
27
+ generation_date=Instant.date_time(datetime(2020, 1, 2, 3, 4, 5), Scale.UTC),
28
+ launch_date=Instant.date_time(datetime(2020, 1, 3, 3, 4, 5), Scale.UTC),
29
+ ),
30
+ deployments=[
31
+ OPM.Deployment(
32
+ name="A",
33
+ sequence_number=1,
34
+ mission_time=Duration.hours(3600.0),
35
+ date=Instant.date_time(datetime(2020, 1, 4, 3, 4, 5), Scale.UTC),
36
+ position=Position.meters((1.0, 2.0, 3.0), Frame.ITRF()),
37
+ velocity=Velocity.meters_per_second((4.0, 5.0, 6.0), Frame.ITRF()),
38
+ mean_perigee_altitude=Length.kilometers(500.0),
39
+ mean_apogee_altitude=Length.kilometers(500.0),
40
+ mean_inclination=Angle.degrees(1.0),
41
+ mean_argument_of_perigee=Angle.degrees(2.0),
42
+ mean_longitude_ascending_node=Angle.degrees(3.0),
43
+ mean_mean_anomaly=Angle.degrees(4.0),
44
+ ballistic_coefficient=123.456,
45
+ ),
46
+ ],
47
+ )
48
+
49
+
50
+ class TestOPM:
51
+ def test_constructor(self, opm: OPM):
52
+ assert opm is not None
53
+
54
+ def test_get_header(self, opm: OPM):
55
+ assert opm.get_header() is not None
56
+
57
+ def test_get_deployments(self, opm: OPM):
58
+ assert len(opm.get_deployments()) == 1
59
+
60
+ def test_get_deployment_at(self, opm: OPM):
61
+ assert opm.get_deployment_at(index=0).name == "A"
62
+
63
+ def test_get_deployment_with_name(self, opm: OPM):
64
+ assert opm.get_deployment_with_name(name="A").name == "A"
65
+
66
+ def test_undefined(self):
67
+ assert OPM.undefined().is_defined() is False
68
+
69
+ def test_dictionary(self):
70
+ dictionary = Dictionary(
71
+ {
72
+ "header": {
73
+ "generation_date": "2020-01-01T12:34:56.789Z",
74
+ "launch_date": "2020-01-02T12:34:56.789Z",
75
+ },
76
+ "deployments": [
77
+ {
78
+ "name": "satellite_a",
79
+ "sequence_number": 1,
80
+ "mission_time_s": 3600.0,
81
+ "date": "2020-01-02T13:34:56.789Z",
82
+ "r_ecef_m": [693289.644, 6876578.628, -133035.288],
83
+ "v_ecef_m_per_s": [1305.783, 39.783, 7525.920],
84
+ "mean_perigee_altitude_km": 526.768,
85
+ "mean_apogee_altitude_km": 568.430,
86
+ "mean_inclination_deg": 97.123,
87
+ "mean_argument_of_perigee_deg": -179.513,
88
+ "mean_longitude_ascending_node_deg": 85.057,
89
+ "mean_mean_anomaly_deg": 179.263,
90
+ "ballistic_coef_kg_per_m2": 47.55,
91
+ }
92
+ ],
93
+ }
94
+ )
95
+
96
+ assert OPM.dictionary(dictionary) is not None
97
+
98
+ def test_parse(self, opm_file: File):
99
+ with open(str(opm_file.get_path().to_string()), "r") as stream:
100
+ assert OPM.parse(string=stream.read()) is not None
101
+
102
+ def test_load(self, opm_file: File):
103
+ assert OPM.load(file=opm_file) is not None
104
+
105
+
106
+ class TestOPMDeployment:
107
+ def test_to_state(self, opm: OPM):
108
+ assert opm.get_deployment_with_name(name="A").to_state() is not None
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1 @@
1
+ # Apache License 2.0
@@ -0,0 +1,65 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics.unit import Length
6
+ from ostk.physics.unit import Angle
7
+
8
+ from ostk.astrodynamics.trajectory.orbit.model import BrouwerLyddaneMean
9
+
10
+
11
+ @pytest.fixture
12
+ def semi_major_axis() -> Length:
13
+ return Length.kilometers(7000.0)
14
+
15
+
16
+ @pytest.fixture
17
+ def eccentricity() -> float:
18
+ return 1e-3
19
+
20
+
21
+ @pytest.fixture
22
+ def inclination() -> Angle:
23
+ return Angle.degrees(35.0)
24
+
25
+
26
+ @pytest.fixture
27
+ def raan() -> Angle:
28
+ return Angle.degrees(40.0)
29
+
30
+
31
+ @pytest.fixture
32
+ def aop() -> Angle:
33
+ return Angle.degrees(50.0)
34
+
35
+
36
+ @pytest.fixture
37
+ def mean_anomaly() -> Angle:
38
+ return Angle.degrees(60.0)
39
+
40
+
41
+ @pytest.fixture
42
+ def brouwer_lyddane_mean(
43
+ semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
44
+ ):
45
+ class BrouwerLyddaneMeanMock(BrouwerLyddaneMean):
46
+ def __init__(
47
+ self, semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
48
+ ):
49
+ super().__init__(
50
+ semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
51
+ )
52
+
53
+ def to_coe():
54
+ return 0.0
55
+
56
+ return BrouwerLyddaneMeanMock(
57
+ semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
58
+ )
59
+
60
+
61
+ class TestBrouwerLyddaneMean:
62
+ def test_getters(self, brouwer_lyddane_mean: BrouwerLyddaneMean):
63
+ assert isinstance(brouwer_lyddane_mean.get_mean_anomaly(), Angle)
64
+ assert isinstance(brouwer_lyddane_mean.get_true_anomaly(), Angle)
65
+ assert isinstance(brouwer_lyddane_mean.get_eccentric_anomaly(), Angle)
@@ -0,0 +1,102 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics.unit import Length
6
+ from ostk.physics.unit import Angle
7
+ from ostk.physics.environment.gravitational import Earth
8
+
9
+ from ostk.physics.coordinate import Frame
10
+ from ostk.physics.coordinate import Position
11
+ from ostk.physics.coordinate import Velocity
12
+
13
+ from ostk.astrodynamics.trajectory.orbit.model.kepler import COE
14
+ from ostk.astrodynamics.trajectory.orbit.model.brouwerLyddaneMean import (
15
+ BrouwerLyddaneMeanLong,
16
+ )
17
+
18
+
19
+ @pytest.fixture
20
+ def semi_major_axis() -> Length:
21
+ return Length.kilometers(7000.0)
22
+
23
+
24
+ @pytest.fixture
25
+ def eccentricity() -> float:
26
+ return 1e-3
27
+
28
+
29
+ @pytest.fixture
30
+ def inclination() -> Angle:
31
+ return Angle.degrees(35.0)
32
+
33
+
34
+ @pytest.fixture
35
+ def raan() -> Angle:
36
+ return Angle.degrees(40.0)
37
+
38
+
39
+ @pytest.fixture
40
+ def aop() -> Angle:
41
+ return Angle.degrees(50.0)
42
+
43
+
44
+ @pytest.fixture
45
+ def mean_anomaly() -> Angle:
46
+ return Angle.degrees(60.0)
47
+
48
+
49
+ @pytest.fixture
50
+ def coe(
51
+ semi_major_axis: Length,
52
+ eccentricity: float,
53
+ inclination: Angle,
54
+ raan: Angle,
55
+ aop: Angle,
56
+ mean_anomaly: Angle,
57
+ ) -> COE:
58
+ return COE(semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly)
59
+
60
+
61
+ @pytest.fixture
62
+ def cartesian_state() -> tuple[Position, Velocity]:
63
+ return (
64
+ Position.meters(
65
+ [6596407.223662058, 2281266.582975321, -10540.61521486086], Frame.GCRF()
66
+ ),
67
+ Velocity.meters_per_second(
68
+ [337.7269674273224, -969.7192552349448, 7488.702816619139], Frame.GCRF()
69
+ ),
70
+ )
71
+
72
+
73
+ @pytest.fixture
74
+ def gravitational_parameter():
75
+ return Earth.EGM2008.gravitational_parameter
76
+
77
+
78
+ @pytest.fixture
79
+ def brouwer_lyddane_mean_long(
80
+ semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
81
+ ):
82
+ return BrouwerLyddaneMeanLong(
83
+ semi_major_axis, eccentricity, inclination, raan, aop, mean_anomaly
84
+ )
85
+
86
+
87
+ class TestBrouwerLyddaneMeanLong:
88
+ def test_to_coe(self, brouwer_lyddane_mean_long: BrouwerLyddaneMeanLong):
89
+ assert brouwer_lyddane_mean_long.to_coe().is_defined()
90
+
91
+ def test_coe(self, coe: COE):
92
+ assert BrouwerLyddaneMeanLong.COE(coe).is_defined()
93
+
94
+ def test_cartesian(
95
+ self, cartesian_state: tuple[Position, Velocity], gravitational_parameter
96
+ ):
97
+ assert BrouwerLyddaneMeanLong.cartesian(
98
+ cartesian_state, gravitational_parameter
99
+ ).is_defined()
100
+
101
+ def test_undefined(self):
102
+ assert BrouwerLyddaneMeanLong.undefined().is_defined() is False