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.
- open_space_toolkit_astrodynamics-9.4.1.dist-info/METADATA +30 -0
- open_space_toolkit_astrodynamics-9.4.1.dist-info/RECORD +98 -0
- open_space_toolkit_astrodynamics-9.4.1.dist-info/WHEEL +5 -0
- open_space_toolkit_astrodynamics-9.4.1.dist-info/top_level.txt +1 -0
- open_space_toolkit_astrodynamics-9.4.1.dist-info/zip-safe +1 -0
- ostk/__init__.py +1 -0
- ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-38-x86_64-linux-gnu.so +0 -0
- ostk/astrodynamics/__init__.py +11 -0
- ostk/astrodynamics/converters.py +185 -0
- ostk/astrodynamics/display.py +220 -0
- ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.9 +0 -0
- ostk/astrodynamics/pytrajectory/__init__.py +1 -0
- ostk/astrodynamics/pytrajectory/pystate.py +36 -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 +153 -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 +387 -0
- ostk/astrodynamics/test/test_display.py +115 -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 +40 -0
- ostk/astrodynamics/test/test_utilities.py +121 -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 +167 -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 +72 -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 +76 -0
- ostk/astrodynamics/test/trajectory/test_model.py +1 -0
- ostk/astrodynamics/test/trajectory/test_orbit.py +174 -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 +237 -0
- ostk/astrodynamics/test/trajectory/test_state_builder.py +171 -0
- ostk/astrodynamics/utilities.py +158 -0
- 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
|