open-space-toolkit-astrodynamics 5.2.3__py38-none-any.whl → 6.0.0__py38-none-any.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-5.2.3.dist-info → open_space_toolkit_astrodynamics-6.0.0.dist-info}/METADATA +1 -1
- {open_space_toolkit_astrodynamics-5.2.3.dist-info → open_space_toolkit_astrodynamics-6.0.0.dist-info}/RECORD +13 -13
- ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-38-x86_64-linux-gnu.so +0 -0
- ostk/astrodynamics/{libopen-space-toolkit-astrodynamics.so.5 → libopen-space-toolkit-astrodynamics.so.6} +0 -0
- ostk/astrodynamics/test/test_utilities.py +35 -15
- ostk/astrodynamics/test/trajectory/orbit/test_pass.py +54 -43
- ostk/astrodynamics/test/trajectory/test_orbit.py +66 -10
- ostk/astrodynamics/test/trajectory/test_segment.py +15 -0
- ostk/astrodynamics/test/trajectory/test_sequence.py +19 -1
- ostk/astrodynamics/utilities.py +31 -24
- {open_space_toolkit_astrodynamics-5.2.3.dist-info → open_space_toolkit_astrodynamics-6.0.0.dist-info}/WHEEL +0 -0
- {open_space_toolkit_astrodynamics-5.2.3.dist-info → open_space_toolkit_astrodynamics-6.0.0.dist-info}/top_level.txt +0 -0
- {open_space_toolkit_astrodynamics-5.2.3.dist-info → open_space_toolkit_astrodynamics-6.0.0.dist-info}/zip-safe +0 -0
@@ -1,10 +1,10 @@
|
|
1
1
|
ostk/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
2
|
-
ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-38-x86_64-linux-gnu.so,sha256=
|
2
|
+
ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-38-x86_64-linux-gnu.so,sha256=EGHtnJpd0wKdCpQ473s1yTdLA1dqxkrpXWAhTFFaZ60,2025272
|
3
3
|
ostk/astrodynamics/__init__.py,sha256=3gWyqFIbhAfcdeMhmfBPQPlPQTmaOzm-6flkJe745Zk,251
|
4
4
|
ostk/astrodynamics/converters.py,sha256=IUxJK5qNzDMsqMSiMT6hUThCjncKoIMW0ifu8kwbww0,4680
|
5
5
|
ostk/astrodynamics/display.py,sha256=y9FnoQbPFGM6LzkUdgXgeqtuVGhv57GuTKbeDdcFPgw,6306
|
6
|
-
ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.
|
7
|
-
ostk/astrodynamics/utilities.py,sha256=
|
6
|
+
ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.6,sha256=pcm6fERimZWFhSlMWSmNP481pzxrFX3IMuqed3QVNZI,98626392
|
7
|
+
ostk/astrodynamics/utilities.py,sha256=PDexbTDbx46aYKqK5b4pjLYSY6NGc4Wx9FwafOkJ4EU,4821
|
8
8
|
ostk/astrodynamics/viewer.py,sha256=B5m-eNWQrd4vIBqmT7-400IfHldxU5lFDTLpfHiiHj4,8910
|
9
9
|
ostk/astrodynamics/pytrajectory/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
10
10
|
ostk/astrodynamics/pytrajectory/pystate.py,sha256=ceNZWYCqtsXWJlE6JKDxB5qn5ixTWGOwrYXge21XPmk,1037
|
@@ -17,7 +17,7 @@ ostk/astrodynamics/test/test_event_condition.py,sha256=mhMTH7wAoYFWRYt_8l2d1vjNP
|
|
17
17
|
ostk/astrodynamics/test/test_import.py,sha256=stS8jK9HiXyzRWjtDvaTqUrzCrOVnYVX5CkmQf7MJsA,1201
|
18
18
|
ostk/astrodynamics/test/test_root_solver.py,sha256=hQ8O6g-WP49gZH_H3Rdufv0F0gQorpzJyIcjBGGUQ34,1831
|
19
19
|
ostk/astrodynamics/test/test_trajectory.py,sha256=pvv4GQsvtU0XfWYk-F-oQNgo8ciFQBgzeJ4FojZDW-A,1364
|
20
|
-
ostk/astrodynamics/test/test_utilities.py,sha256=
|
20
|
+
ostk/astrodynamics/test/test_utilities.py,sha256=YnJ7czgRjJ5bkYr33KF5wY5A-P0lJg2q0-_mI7spvYs,3620
|
21
21
|
ostk/astrodynamics/test/test_viewer.py,sha256=i164XnG6n-_FteiO6rjXA7GGsJhMdmT-508DpKaveVY,3957
|
22
22
|
ostk/astrodynamics/test/access/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
23
23
|
ostk/astrodynamics/test/access/test_generator.py,sha256=6cwC5GGvnWLxPXmgRQ-N7tjorGUfPxA8qFcdGaTmpp4,8038
|
@@ -59,15 +59,15 @@ ostk/astrodynamics/test/trajectory/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZI
|
|
59
59
|
ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py,sha256=d72J50UGG9m0Atei0UQ8sITU1WdJmws5xgUiacLZMbw,2515
|
60
60
|
ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py,sha256=FziYh9XxD2FEuj6WhnqOe5mF9twLTQtvcem8KzQZKXg,1864
|
61
61
|
ostk/astrodynamics/test/trajectory/test_model.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
62
|
-
ostk/astrodynamics/test/trajectory/test_orbit.py,sha256=
|
62
|
+
ostk/astrodynamics/test/trajectory/test_orbit.py,sha256=dFZRN2E538lG6ZaiRBWUDMtKzgMIKnFILV3yeofRV1I,5075
|
63
63
|
ostk/astrodynamics/test/trajectory/test_propagator.py,sha256=kEAvrFM4MZouAAnYPi91akPSXWHbGxHTo5uaXQKexII,12631
|
64
|
-
ostk/astrodynamics/test/trajectory/test_segment.py,sha256=
|
65
|
-
ostk/astrodynamics/test/trajectory/test_sequence.py,sha256=
|
64
|
+
ostk/astrodynamics/test/trajectory/test_segment.py,sha256=5XSCPUVrE6_oz8tsZeAb9mzQoLUuyUlfgJ-rWP54-ao,9170
|
65
|
+
ostk/astrodynamics/test/trajectory/test_sequence.py,sha256=N3jPB31P4i13ocYITaVMLiMfczpATmDLVbNdImM68tQ,12909
|
66
66
|
ostk/astrodynamics/test/trajectory/test_state.py,sha256=rW0HH7oy_tZ-34VIhk2rx_v2Kyg3xegBYpKs9_NznSs,6508
|
67
67
|
ostk/astrodynamics/test/trajectory/test_state_builder.py,sha256=3C8JeN8VGgUzEASgh5PfnJQ2JWGkKYTm7eaelE6Lw7E,4815
|
68
68
|
ostk/astrodynamics/test/trajectory/orbit/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
69
69
|
ostk/astrodynamics/test/trajectory/orbit/test_model.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
70
|
-
ostk/astrodynamics/test/trajectory/orbit/test_pass.py,sha256=
|
70
|
+
ostk/astrodynamics/test/trajectory/orbit/test_pass.py,sha256=p6YCtb-QhCS_En3ECaSM2sJsWEnqXzmWaCmai_SuK0U,2191
|
71
71
|
ostk/astrodynamics/test/trajectory/orbit/messages/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
72
72
|
ostk/astrodynamics/test/trajectory/orbit/messages/spacex/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
|
73
73
|
ostk/astrodynamics/test/trajectory/orbit/messages/spacex/conftest.py,sha256=O75ywkPJjoFp0uKptCu4C2tGMRaGN-8NVFVhps85eWE,379
|
@@ -92,8 +92,8 @@ ostk/astrodynamics/test/trajectory/state/coordinates_subset/test_angular_velocit
|
|
92
92
|
ostk/astrodynamics/test/trajectory/state/coordinates_subset/test_attitude_quaternion.py,sha256=B1Tni_YpKB9Fzb0fpXSokw9DjgiZem9uBATMQbcq8P4,394
|
93
93
|
ostk/astrodynamics/test/trajectory/state/coordinates_subset/test_cartesian_position.py,sha256=L3MpDG9MDHbK2HPZejqiY0QJdiEB-FZe0rVGDl379YA,2722
|
94
94
|
ostk/astrodynamics/test/trajectory/state/coordinates_subset/test_cartesian_velocity.py,sha256=k0aNqdMwwt-XSFQ1Si8kDTY79SB7fC0WWm2UNjpaOI0,3077
|
95
|
-
open_space_toolkit_astrodynamics-
|
96
|
-
open_space_toolkit_astrodynamics-
|
97
|
-
open_space_toolkit_astrodynamics-
|
98
|
-
open_space_toolkit_astrodynamics-
|
99
|
-
open_space_toolkit_astrodynamics-
|
95
|
+
open_space_toolkit_astrodynamics-6.0.0.dist-info/METADATA,sha256=S1Y1p4wX6YCRlOm_yajNftMXaoccfzjKuMcGCxvGSTw,1777
|
96
|
+
open_space_toolkit_astrodynamics-6.0.0.dist-info/WHEEL,sha256=LNQH4F1F9_Ua4GgazGQDFGQhQ8B1tSrkPIuEzIRv9nc,93
|
97
|
+
open_space_toolkit_astrodynamics-6.0.0.dist-info/top_level.txt,sha256=zOR18699uDYnafgarhL8WU_LmTZY_5NVqutv-flp_x4,5
|
98
|
+
open_space_toolkit_astrodynamics-6.0.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
99
|
+
open_space_toolkit_astrodynamics-6.0.0.dist-info/RECORD,,
|
Binary file
|
Binary file
|
@@ -23,12 +23,15 @@ State = astrodynamics.flight.profile.State
|
|
23
23
|
|
24
24
|
|
25
25
|
class TestUtilities:
|
26
|
-
def test_lla_from_state(
|
27
|
-
|
26
|
+
def test_lla_from_state(
|
27
|
+
self,
|
28
|
+
state: State,
|
29
|
+
):
|
30
|
+
lla: tuple[float, float, float] = utilities.lla_from_state(state)
|
28
31
|
|
29
32
|
assert lla is not None
|
30
33
|
assert len(lla) == 3
|
31
|
-
assert isinstance(lla,
|
34
|
+
assert isinstance(lla, tuple)
|
32
35
|
assert isinstance(lla[0], float)
|
33
36
|
assert lla[0] >= -90.0 and lla[0] <= 90.0
|
34
37
|
assert isinstance(lla[1], float)
|
@@ -47,13 +50,16 @@ class TestUtilities:
|
|
47
50
|
assert isinstance(lla, LLA)
|
48
51
|
assert lla.is_defined()
|
49
52
|
|
50
|
-
lla_from_state:
|
53
|
+
lla_from_state: tuple[float, float, float] = utilities.lla_from_state(state)
|
51
54
|
|
52
55
|
assert lla.get_latitude().in_degrees() == lla_from_state[0]
|
53
56
|
assert lla.get_longitude().in_degrees() == lla_from_state[1]
|
54
57
|
assert lla.get_altitude().in_meters() == lla_from_state[2]
|
55
58
|
|
56
|
-
def test_position_from_lla(
|
59
|
+
def test_position_from_lla(
|
60
|
+
self,
|
61
|
+
lla: LLA,
|
62
|
+
):
|
57
63
|
position: Position = utilities.position_from_lla(lla)
|
58
64
|
|
59
65
|
assert position is not None
|
@@ -61,20 +67,28 @@ class TestUtilities:
|
|
61
67
|
assert position.is_defined()
|
62
68
|
|
63
69
|
def test_compute_aer(
|
64
|
-
self,
|
70
|
+
self,
|
71
|
+
instant: Instant,
|
72
|
+
position: Position,
|
73
|
+
environment: Environment,
|
65
74
|
):
|
66
|
-
aer:
|
75
|
+
aer: tuple[float, float, float] = utilities.compute_aer(
|
76
|
+
instant, position, position, environment
|
77
|
+
)
|
67
78
|
|
68
79
|
assert aer is not None
|
69
80
|
assert len(aer) == 3
|
70
81
|
assert aer[2] == 0.0
|
71
82
|
|
72
83
|
def test_compute_time_lla_aer_state(
|
73
|
-
self,
|
84
|
+
self,
|
85
|
+
state: State,
|
86
|
+
position: Position,
|
87
|
+
environment: Environment,
|
74
88
|
):
|
75
|
-
time_lla_aer:
|
76
|
-
|
77
|
-
)
|
89
|
+
time_lla_aer: float[
|
90
|
+
Instant, float, float, float, float, float, float
|
91
|
+
] = utilities.compute_time_lla_aer_state(state, position, environment)
|
78
92
|
|
79
93
|
assert time_lla_aer is not None
|
80
94
|
assert len(time_lla_aer) == 7
|
@@ -84,15 +98,21 @@ class TestUtilities:
|
|
84
98
|
assert isinstance(time_lla_aer[i], float)
|
85
99
|
|
86
100
|
def test_compute_trajectory_geometry(
|
87
|
-
self,
|
101
|
+
self,
|
102
|
+
interval: Interval,
|
103
|
+
trajectory: Trajectory,
|
88
104
|
):
|
89
|
-
output: list = utilities.compute_trajectory_geometry(
|
105
|
+
output: list[tuple[float, float, float]] = utilities.compute_trajectory_geometry(
|
106
|
+
trajectory, interval
|
107
|
+
)
|
90
108
|
|
91
109
|
assert output is not None
|
92
110
|
assert len(output) == 2
|
93
111
|
|
94
|
-
def test_convert_state(self,
|
95
|
-
output:
|
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)
|
96
116
|
|
97
117
|
assert output is not None
|
98
118
|
assert len(output) == 11
|
@@ -2,54 +2,65 @@
|
|
2
2
|
|
3
3
|
import pytest
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
Instant = physics.time.Instant
|
13
|
-
Interval = physics.time.Interval
|
14
|
-
DateTime = physics.time.DateTime
|
15
|
-
Position = physics.coordinate.Position
|
16
|
-
Velocity = physics.coordinate.Velocity
|
17
|
-
Frame = physics.coordinate.Frame
|
18
|
-
Environment = physics.Environment
|
19
|
-
|
20
|
-
Trajectory = astrodynamics.Trajectory
|
21
|
-
Model = astrodynamics.trajectory.Model
|
22
|
-
Orbit = astrodynamics.trajectory.Orbit
|
23
|
-
Pass = astrodynamics.trajectory.orbit.Pass
|
24
|
-
Kepler = astrodynamics.trajectory.orbit.models.Kepler
|
25
|
-
COE = astrodynamics.trajectory.orbit.models.kepler.COE
|
26
|
-
SGP4 = astrodynamics.trajectory.orbit.models.SGP4
|
27
|
-
TLE = astrodynamics.trajectory.orbit.models.sgp4.TLE
|
28
|
-
State = astrodynamics.trajectory.State
|
29
|
-
Access = astrodynamics.Access
|
5
|
+
from ostk.physics.time import Scale
|
6
|
+
from ostk.physics.time import Instant
|
7
|
+
from ostk.physics.time import Interval
|
8
|
+
from ostk.physics.time import DateTime
|
9
|
+
from ostk.physics import Environment
|
10
|
+
|
11
|
+
from ostk.astrodynamics.trajectory.orbit import Pass
|
30
12
|
|
31
13
|
earth = Environment.default().access_celestial_object_with_name("Earth")
|
32
14
|
|
33
15
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
16
|
+
@pytest.fixture
|
17
|
+
def pass_() -> Pass:
|
18
|
+
return Pass(
|
19
|
+
123,
|
20
|
+
Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC),
|
21
|
+
Instant.date_time(DateTime(2018, 1, 1, 0, 15, 0), Scale.UTC),
|
22
|
+
Instant.date_time(DateTime(2018, 1, 1, 0, 30, 0), Scale.UTC),
|
23
|
+
Instant.date_time(DateTime(2018, 1, 1, 0, 45, 0), Scale.UTC),
|
24
|
+
Instant.date_time(DateTime(2018, 1, 1, 1, 0, 0), Scale.UTC),
|
25
|
+
)
|
26
|
+
|
27
|
+
|
28
|
+
class TestPass:
|
29
|
+
def test_is_defined(self, pass_: Pass):
|
30
|
+
assert pass_.is_defined()
|
31
|
+
|
32
|
+
def test_is_complete(self, pass_: Pass):
|
33
|
+
assert pass_.is_complete() is not None
|
34
|
+
|
35
|
+
def test_get_type(self, pass_: Pass):
|
36
|
+
assert pass_.get_type() is not None
|
37
|
+
|
38
|
+
def test_get_revolution_number(self, pass_: Pass):
|
39
|
+
assert pass_.get_revolution_number() is not None
|
40
|
+
|
41
|
+
def test_get_duration(self, pass_: Pass):
|
42
|
+
assert pass_.get_duration() is not None
|
43
|
+
|
44
|
+
def test_get_instant_at_ascending_node(self, pass_: Pass):
|
45
|
+
assert pass_.get_instant_at_ascending_node() is not None
|
46
|
+
|
47
|
+
def test_get_instant_at_north_point(self, pass_: Pass):
|
48
|
+
assert pass_.get_instant_at_north_point() is not None
|
49
|
+
|
50
|
+
def test_get_instant_at_descending_node(self, pass_: Pass):
|
51
|
+
assert pass_.get_instant_at_descending_node() is not None
|
52
|
+
|
53
|
+
def test_get_instant_at_south_point(self, pass_: Pass):
|
54
|
+
assert pass_.get_instant_at_south_point() is not None
|
40
55
|
|
41
|
-
|
56
|
+
def test_get_instant_at_pass_break(self, pass_: Pass):
|
57
|
+
assert pass_.get_instant_at_pass_break() is not None
|
42
58
|
|
43
|
-
|
44
|
-
|
59
|
+
def test_undefined(self):
|
60
|
+
assert Pass.undefined().is_defined() is False
|
45
61
|
|
46
|
-
|
47
|
-
|
48
|
-
assert pass_.get_type() is not None
|
49
|
-
assert pass_.get_revolution_number() is not None
|
50
|
-
# Interval conversion to Python type of issue
|
51
|
-
# assert pass_.get_interval() is not None
|
62
|
+
def test_string_from_type(self):
|
63
|
+
assert Pass.string_from_type(Pass.Type.Complete) is not None
|
52
64
|
|
53
|
-
|
54
|
-
|
55
|
-
assert Pass.string_from_quarter(Pass.Quarter.First) is not None
|
65
|
+
def test_string_from_phase(self):
|
66
|
+
assert Pass.string_from_phase(Pass.Phase.Ascending) is not None
|
@@ -2,22 +2,43 @@
|
|
2
2
|
|
3
3
|
import pytest
|
4
4
|
|
5
|
-
from ostk.physics import
|
5
|
+
from ostk.physics.environment.objects.celestial_bodies import Earth
|
6
6
|
from ostk.physics.units import Length, Angle
|
7
|
-
from ostk.physics.time import Scale, Instant, DateTime, Time
|
7
|
+
from ostk.physics.time import Scale, Instant, DateTime, Time, Duration, Interval
|
8
8
|
|
9
9
|
from ostk.astrodynamics.trajectory import Orbit, State
|
10
|
+
from ostk.astrodynamics.trajectory.orbit import Pass
|
11
|
+
from ostk.astrodynamics.trajectory.orbit import Pass
|
10
12
|
from ostk.astrodynamics.trajectory.orbit.models import SGP4
|
11
13
|
from ostk.astrodynamics.trajectory.orbit.models.sgp4 import TLE
|
12
14
|
|
13
15
|
|
14
16
|
@pytest.fixture
|
15
|
-
def earth():
|
16
|
-
return
|
17
|
+
def earth() -> Earth:
|
18
|
+
return Earth.default()
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.fixture
|
22
|
+
def epoch() -> Instant:
|
23
|
+
return Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
24
|
+
|
25
|
+
|
26
|
+
@pytest.fixture
|
27
|
+
def orbit(earth: Earth, epoch: Instant):
|
28
|
+
return Orbit.sun_synchronous(epoch, Length.kilometers(500.0), Time.midnight(), earth)
|
29
|
+
|
30
|
+
|
31
|
+
@pytest.fixture
|
32
|
+
def states(orbit: Orbit, epoch: Instant) -> list[State]:
|
33
|
+
instants: list[Instant] = Interval.closed(
|
34
|
+
epoch, epoch + Duration.days(1.0)
|
35
|
+
).generate_grid(Duration.seconds(20.0))
|
36
|
+
|
37
|
+
return orbit.get_states_at(instants)
|
17
38
|
|
18
39
|
|
19
40
|
class TestOrbit:
|
20
|
-
def
|
41
|
+
def test_constructors(self, earth):
|
21
42
|
# Construct Two-Line Element set
|
22
43
|
tle = TLE(
|
23
44
|
"1 25544U 98067A 18231.17878740 .00000187 00000-0 10196-4 0 9994",
|
@@ -37,14 +58,45 @@ class TestOrbit:
|
|
37
58
|
assert state is not None
|
38
59
|
assert isinstance(state, State)
|
39
60
|
|
40
|
-
def
|
61
|
+
def test_get_revolution_number_at(self, orbit: Orbit):
|
62
|
+
assert (
|
63
|
+
orbit.get_revolution_number_at(
|
64
|
+
Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
65
|
+
)
|
66
|
+
== 1
|
67
|
+
)
|
68
|
+
|
69
|
+
def test_get_pass_at(self, orbit: Orbit):
|
70
|
+
pass_ = orbit.get_pass_at(
|
71
|
+
Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
72
|
+
)
|
73
|
+
|
74
|
+
assert pass_ is not None
|
75
|
+
assert isinstance(pass_, Pass)
|
76
|
+
assert pass_.is_defined()
|
77
|
+
|
78
|
+
def test_get_pass_with_revolution_number(self, orbit: Orbit):
|
79
|
+
pass_ = orbit.get_pass_with_revolution_number(1)
|
80
|
+
|
81
|
+
assert pass_ is not None
|
82
|
+
assert isinstance(pass_, Pass)
|
83
|
+
assert pass_.is_defined()
|
84
|
+
|
85
|
+
def test_undefined(self):
|
86
|
+
assert Orbit.undefined().is_defined() is False
|
87
|
+
|
88
|
+
def test_circular(self, earth):
|
41
89
|
epoch = Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
42
90
|
altitude = Length.kilometers(500.0)
|
43
91
|
inclination = Angle.degrees(45.0)
|
44
92
|
|
45
93
|
orbit: Orbit = Orbit.circular(epoch, altitude, inclination, earth)
|
46
94
|
|
47
|
-
|
95
|
+
assert orbit is not None
|
96
|
+
assert isinstance(orbit, Orbit)
|
97
|
+
assert orbit.is_defined()
|
98
|
+
|
99
|
+
def test_equatorial(self, earth):
|
48
100
|
epoch = Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
49
101
|
apoapsis_altitude = Length.kilometers(500.1)
|
50
102
|
periapsis_altitude = Length.kilometers(499.9)
|
@@ -57,7 +109,7 @@ class TestOrbit:
|
|
57
109
|
assert isinstance(orbit, Orbit)
|
58
110
|
assert orbit.is_defined()
|
59
111
|
|
60
|
-
def
|
112
|
+
def test_circular_equatorial(self, earth):
|
61
113
|
epoch = Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
62
114
|
altitude = Length.kilometers(500.0)
|
63
115
|
|
@@ -67,7 +119,7 @@ class TestOrbit:
|
|
67
119
|
assert isinstance(orbit, Orbit)
|
68
120
|
assert orbit.is_defined()
|
69
121
|
|
70
|
-
def
|
122
|
+
def test_geo_synchronous(self, earth):
|
71
123
|
epoch = Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
72
124
|
inclination = Angle.degrees(45.0)
|
73
125
|
longitude = Angle.degrees(45.0)
|
@@ -78,7 +130,7 @@ class TestOrbit:
|
|
78
130
|
assert isinstance(orbit, Orbit)
|
79
131
|
assert orbit.is_defined()
|
80
132
|
|
81
|
-
def
|
133
|
+
def test_sun_synchronous(self, earth):
|
82
134
|
epoch = Instant.date_time(DateTime(2018, 1, 1, 0, 0, 0), Scale.UTC)
|
83
135
|
altitude = Length.kilometers(500.0)
|
84
136
|
local_time_at_descending_node = Time.midnight()
|
@@ -98,3 +150,7 @@ class TestOrbit:
|
|
98
150
|
celestial_object=earth,
|
99
151
|
argument_of_latitude=Angle.degrees(50.0),
|
100
152
|
).is_defined()
|
153
|
+
|
154
|
+
def test_compute_passes(self, orbit: Orbit, states: list[State]):
|
155
|
+
passes: list[tuple[int, Pass]] = orbit.compute_passes(states, 1)
|
156
|
+
assert passes is not None
|
@@ -121,6 +121,11 @@ def maneuver_segment(
|
|
121
121
|
)
|
122
122
|
|
123
123
|
|
124
|
+
@pytest.fixture
|
125
|
+
def instants(state: State) -> list[Instant]:
|
126
|
+
return [state.get_instant(), state.get_instant() + Duration.minutes(1.0)]
|
127
|
+
|
128
|
+
|
124
129
|
@pytest.fixture
|
125
130
|
def thruster_dynamics() -> Thruster:
|
126
131
|
return Thruster(
|
@@ -212,6 +217,8 @@ class TestSegment:
|
|
212
217
|
state: State,
|
213
218
|
end_instant: Instant,
|
214
219
|
maneuver_segment: Segment,
|
220
|
+
instants: list[Instant],
|
221
|
+
numerical_solver: NumericalSolver,
|
215
222
|
):
|
216
223
|
solution = maneuver_segment.solve(state)
|
217
224
|
|
@@ -241,6 +248,14 @@ class TestSegment:
|
|
241
248
|
|
242
249
|
state_frame: Frame = state.get_frame()
|
243
250
|
|
251
|
+
propagated_states = solution.calculate_states_at(
|
252
|
+
instants,
|
253
|
+
numerical_solver,
|
254
|
+
)
|
255
|
+
|
256
|
+
assert propagated_states is not None
|
257
|
+
assert len(propagated_states) == len(instants)
|
258
|
+
|
244
259
|
first_dynamics_contribution = solution.get_dynamics_contribution(
|
245
260
|
solution.dynamics[0], state_frame
|
246
261
|
)
|
@@ -334,6 +334,11 @@ def segment_solution(
|
|
334
334
|
)
|
335
335
|
|
336
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
|
+
|
337
342
|
class TestSequence:
|
338
343
|
def test_get_segments(
|
339
344
|
self,
|
@@ -424,8 +429,13 @@ class TestSequence:
|
|
424
429
|
repetition_count: int,
|
425
430
|
sequence: Sequence,
|
426
431
|
segments: list[Segment],
|
432
|
+
instants: list[Instant],
|
433
|
+
numerical_solver: NumericalSolver,
|
427
434
|
):
|
428
|
-
solution = sequence.solve(
|
435
|
+
solution = sequence.solve(
|
436
|
+
state=state,
|
437
|
+
repetition_count=repetition_count,
|
438
|
+
)
|
429
439
|
|
430
440
|
assert len(solution.segment_solutions) == len(segments)
|
431
441
|
|
@@ -442,6 +452,14 @@ class TestSequence:
|
|
442
452
|
assert solution.compute_delta_mass() is not None
|
443
453
|
assert solution.compute_delta_v(1500.0) is not None
|
444
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
|
+
|
445
463
|
def test_solve_to_condition(
|
446
464
|
self,
|
447
465
|
state: State,
|
ostk/astrodynamics/utilities.py
CHANGED
@@ -15,18 +15,18 @@ from ostk.physics.environment.objects.celestial_bodies import Earth
|
|
15
15
|
from ostk.physics.environment.gravitational import Earth as EarthGravitationalModel
|
16
16
|
|
17
17
|
|
18
|
-
def lla_from_state(state: trajectory.State) ->
|
18
|
+
def lla_from_state(state: trajectory.State) -> tuple[float, float, float]:
|
19
19
|
"""
|
20
20
|
Return latitude (degrees), longitude (degrees), altitude (meters) float list from a state.
|
21
21
|
"""
|
22
22
|
|
23
|
-
lla = lla_from_position(state.get_position(), state.get_instant())
|
23
|
+
lla: LLA = lla_from_position(state.get_position(), state.get_instant())
|
24
24
|
|
25
|
-
return
|
25
|
+
return (
|
26
26
|
float(lla.get_latitude().in_degrees()),
|
27
27
|
float(lla.get_longitude().in_degrees()),
|
28
28
|
float(lla.get_altitude().in_meters()),
|
29
|
-
|
29
|
+
)
|
30
30
|
|
31
31
|
|
32
32
|
def lla_from_position(
|
@@ -42,7 +42,7 @@ def lla_from_position(
|
|
42
42
|
raise ValueError(
|
43
43
|
"Instant must be provided if position is not expressed in ECEF."
|
44
44
|
)
|
45
|
-
position = position.in_frame(Frame.ITRF(), instant)
|
45
|
+
position: Position = position.in_frame(Frame.ITRF(), instant)
|
46
46
|
|
47
47
|
return LLA.cartesian(
|
48
48
|
position.get_coordinates(),
|
@@ -70,51 +70,54 @@ def compute_aer(
|
|
70
70
|
from_position: Position,
|
71
71
|
to_position: Position,
|
72
72
|
environment: Environment,
|
73
|
-
) ->
|
73
|
+
) -> tuple[float, float, float]:
|
74
74
|
"""
|
75
75
|
Return [azimuth (degrees), elevation (degrees), range (meters)] from Instant and Positions (observer, target).
|
76
76
|
"""
|
77
77
|
|
78
|
-
from_lla = lla_from_position(from_position, instant)
|
78
|
+
from_lla: LLA = lla_from_position(from_position, instant)
|
79
79
|
|
80
|
-
earth = environment.access_celestial_object_with_name("Earth")
|
81
|
-
ned_frame = earth.get_frame_at(from_lla, Earth.FrameType.NED)
|
80
|
+
earth: Earth = environment.access_celestial_object_with_name("Earth")
|
81
|
+
ned_frame: Frame = earth.get_frame_at(from_lla, Earth.FrameType.NED)
|
82
82
|
|
83
|
-
from_position_NED = from_position.in_frame(ned_frame, instant)
|
84
|
-
to_position_NED = to_position.in_frame(ned_frame, instant)
|
83
|
+
from_position_NED: Position = from_position.in_frame(ned_frame, instant)
|
84
|
+
to_position_NED: Position = to_position.in_frame(ned_frame, instant)
|
85
85
|
|
86
|
-
aer = AER.from_position_to_position(from_position_NED, to_position_NED, True)
|
86
|
+
aer: AER = AER.from_position_to_position(from_position_NED, to_position_NED, True)
|
87
87
|
|
88
|
-
return
|
88
|
+
return (
|
89
89
|
float(aer.get_azimuth().in_degrees()),
|
90
90
|
float(aer.get_elevation().in_degrees()),
|
91
91
|
float(aer.get_range().in_meters()),
|
92
|
-
|
92
|
+
)
|
93
93
|
|
94
94
|
|
95
95
|
def compute_time_lla_aer_state(
|
96
96
|
state: trajectory.State,
|
97
97
|
from_position: Position,
|
98
98
|
environment: Environment,
|
99
|
-
) ->
|
99
|
+
) -> tuple[Instant, float, float, float, float, float, float]:
|
100
100
|
"""
|
101
101
|
Return [instant, latitude, longitude, altitude, azimuth, elevation, range] from State and observer Position.
|
102
102
|
"""
|
103
103
|
|
104
|
-
instant = state.get_instant()
|
104
|
+
instant: Instant = state.get_instant()
|
105
105
|
|
106
|
-
lla = lla_from_state(state)
|
107
|
-
aer = compute_aer(
|
106
|
+
lla: tuple[float, float, float] = lla_from_state(state)
|
107
|
+
aer: AER = compute_aer(
|
108
108
|
instant,
|
109
109
|
from_position,
|
110
110
|
state.get_position().in_frame(Frame.ITRF(), state.get_instant()),
|
111
111
|
environment,
|
112
112
|
)
|
113
113
|
|
114
|
-
return
|
114
|
+
return (instant, lla[0], lla[1], lla[2], aer[0], aer[1], aer[2])
|
115
115
|
|
116
116
|
|
117
|
-
def compute_trajectory_geometry(
|
117
|
+
def compute_trajectory_geometry(
|
118
|
+
trajectory: Trajectory,
|
119
|
+
interval: Interval,
|
120
|
+
) -> list[tuple[float, float, float]]:
|
118
121
|
"""
|
119
122
|
Return [latitude (degrees), longitude (degrees), altitude (meters)] values along a Trajectory during Interval.
|
120
123
|
"""
|
@@ -127,12 +130,14 @@ def compute_trajectory_geometry(trajectory: Trajectory, interval: Interval) -> l
|
|
127
130
|
]
|
128
131
|
|
129
132
|
|
130
|
-
def convert_state(
|
133
|
+
def convert_state(
|
134
|
+
state: trajectory.State,
|
135
|
+
) -> tuple[str, float, float, float, float, float, float, float, float, float]:
|
131
136
|
"""
|
132
137
|
Convert an input (Instant, State) into dataframe-ready values.
|
133
138
|
"""
|
134
139
|
|
135
|
-
lla = LLA.cartesian(
|
140
|
+
lla: LLA = LLA.cartesian(
|
136
141
|
state.get_position()
|
137
142
|
.in_frame(Frame.ITRF(), state.get_instant())
|
138
143
|
.get_coordinates(),
|
@@ -140,7 +145,9 @@ def convert_state(instant: Instant, state: trajectory.State) -> list:
|
|
140
145
|
EarthGravitationalModel.EGM2008.flattening,
|
141
146
|
)
|
142
147
|
|
143
|
-
|
148
|
+
instant: Instant = state.get_instant()
|
149
|
+
|
150
|
+
return (
|
144
151
|
repr(instant),
|
145
152
|
float(instant.get_modified_julian_date(Scale.UTC)),
|
146
153
|
*state.get_position().get_coordinates().transpose().tolist(),
|
@@ -148,4 +155,4 @@ def convert_state(instant: Instant, state: trajectory.State) -> list:
|
|
148
155
|
float(lla.get_latitude().in_degrees()),
|
149
156
|
float(lla.get_longitude().in_degrees()),
|
150
157
|
float(lla.get_altitude().in_meters()),
|
151
|
-
|
158
|
+
)
|
File without changes
|
File without changes
|
File without changes
|