open-space-toolkit-astrodynamics 13.1.0__py313-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 (100) hide show
  1. open_space_toolkit_astrodynamics-13.1.0.dist-info/METADATA +30 -0
  2. open_space_toolkit_astrodynamics-13.1.0.dist-info/RECORD +100 -0
  3. open_space_toolkit_astrodynamics-13.1.0.dist-info/WHEEL +5 -0
  4. open_space_toolkit_astrodynamics-13.1.0.dist-info/top_level.txt +1 -0
  5. open_space_toolkit_astrodynamics-13.1.0.dist-info/zip-safe +1 -0
  6. ostk/__init__.py +1 -0
  7. ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-313-x86_64-linux-gnu.so +0 -0
  8. ostk/astrodynamics/__init__.py +11 -0
  9. ostk/astrodynamics/converters.py +130 -0
  10. ostk/astrodynamics/dataframe.py +479 -0
  11. ostk/astrodynamics/display.py +222 -0
  12. ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.13 +0 -0
  13. ostk/astrodynamics/pytrajectory/__init__.py +1 -0
  14. ostk/astrodynamics/pytrajectory/pystate.py +251 -0
  15. ostk/astrodynamics/test/__init__.py +1 -0
  16. ostk/astrodynamics/test/access/__init__.py +1 -0
  17. ostk/astrodynamics/test/access/test_generator.py +248 -0
  18. ostk/astrodynamics/test/conftest.py +119 -0
  19. ostk/astrodynamics/test/conjunction/message/ccsds/__init__.py +1 -0
  20. ostk/astrodynamics/test/conjunction/message/ccsds/conftest.py +325 -0
  21. ostk/astrodynamics/test/conjunction/message/ccsds/data/cdm.json +303 -0
  22. ostk/astrodynamics/test/conjunction/message/ccsds/test_cdm.py +416 -0
  23. ostk/astrodynamics/test/dynamics/__init__.py +1 -0
  24. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity.csv +565 -0
  25. ostk/astrodynamics/test/dynamics/data/Tabulated_Earth_Gravity_Truth.csv +100 -0
  26. ostk/astrodynamics/test/dynamics/test_atmospheric_drag.py +128 -0
  27. ostk/astrodynamics/test/dynamics/test_central_body_gravity.py +58 -0
  28. ostk/astrodynamics/test/dynamics/test_dynamics.py +50 -0
  29. ostk/astrodynamics/test/dynamics/test_position_derivative.py +51 -0
  30. ostk/astrodynamics/test/dynamics/test_tabulated.py +138 -0
  31. ostk/astrodynamics/test/dynamics/test_third_body_gravity.py +67 -0
  32. ostk/astrodynamics/test/dynamics/test_thruster.py +142 -0
  33. ostk/astrodynamics/test/event_condition/test_angular_condition.py +113 -0
  34. ostk/astrodynamics/test/event_condition/test_boolean_condition.py +55 -0
  35. ostk/astrodynamics/test/event_condition/test_coe_condition.py +87 -0
  36. ostk/astrodynamics/test/event_condition/test_instant_condition.py +48 -0
  37. ostk/astrodynamics/test/event_condition/test_logical_condition.py +120 -0
  38. ostk/astrodynamics/test/event_condition/test_real_condition.py +50 -0
  39. ostk/astrodynamics/test/flight/__init__.py +1 -0
  40. ostk/astrodynamics/test/flight/system/__init__.py +1 -0
  41. ostk/astrodynamics/test/flight/system/test_propulsion_system.py +73 -0
  42. ostk/astrodynamics/test/flight/system/test_satellite_system.py +91 -0
  43. ostk/astrodynamics/test/flight/system/test_satellite_system_builder.py +71 -0
  44. ostk/astrodynamics/test/flight/test_maneuver.py +212 -0
  45. ostk/astrodynamics/test/flight/test_profile.py +253 -0
  46. ostk/astrodynamics/test/flight/test_system.py +55 -0
  47. ostk/astrodynamics/test/guidance_law/test_constant_thrust.py +91 -0
  48. ostk/astrodynamics/test/guidance_law/test_qlaw.py +138 -0
  49. ostk/astrodynamics/test/solvers/__init__.py +1 -0
  50. ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +181 -0
  51. ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +153 -0
  52. ostk/astrodynamics/test/test_access.py +128 -0
  53. ostk/astrodynamics/test/test_converters.py +290 -0
  54. ostk/astrodynamics/test/test_dataframe.py +875 -0
  55. ostk/astrodynamics/test/test_display.py +114 -0
  56. ostk/astrodynamics/test/test_event_condition.py +78 -0
  57. ostk/astrodynamics/test/test_import.py +26 -0
  58. ostk/astrodynamics/test/test_root_solver.py +70 -0
  59. ostk/astrodynamics/test/test_trajectory.py +118 -0
  60. ostk/astrodynamics/test/test_utilities.py +106 -0
  61. ostk/astrodynamics/test/test_viewer.py +129 -0
  62. ostk/astrodynamics/test/trajectory/__init__.py +1 -0
  63. ostk/astrodynamics/test/trajectory/orbit/__init__.py +1 -0
  64. ostk/astrodynamics/test/trajectory/orbit/message/__init__.py +1 -0
  65. ostk/astrodynamics/test/trajectory/orbit/message/spacex/__init__.py +1 -0
  66. ostk/astrodynamics/test/trajectory/orbit/message/spacex/conftest.py +18 -0
  67. ostk/astrodynamics/test/trajectory/orbit/message/spacex/data/opm_1.yaml +44 -0
  68. ostk/astrodynamics/test/trajectory/orbit/message/spacex/test_opm.py +108 -0
  69. ostk/astrodynamics/test/trajectory/orbit/models/__init__.py +1 -0
  70. ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py +1 -0
  71. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py +65 -0
  72. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py +102 -0
  73. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py +102 -0
  74. ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py +201 -0
  75. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py +1 -0
  76. ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py +331 -0
  77. ostk/astrodynamics/test/trajectory/orbit/models/test_kepler.py +130 -0
  78. ostk/astrodynamics/test/trajectory/orbit/models/test_propagated.py +234 -0
  79. ostk/astrodynamics/test/trajectory/orbit/models/test_sgp4.py +1 -0
  80. ostk/astrodynamics/test/trajectory/orbit/models/test_tabulated.py +380 -0
  81. ostk/astrodynamics/test/trajectory/orbit/test_model.py +1 -0
  82. ostk/astrodynamics/test/trajectory/orbit/test_pass.py +75 -0
  83. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity.py +30 -0
  84. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py +18 -0
  85. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py +107 -0
  86. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py +115 -0
  87. ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py +84 -0
  88. ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py +46 -0
  89. ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +314 -0
  90. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_direction.py +81 -0
  91. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +108 -0
  92. ostk/astrodynamics/test/trajectory/test_model.py +1 -0
  93. ostk/astrodynamics/test/trajectory/test_orbit.py +205 -0
  94. ostk/astrodynamics/test/trajectory/test_propagator.py +458 -0
  95. ostk/astrodynamics/test/trajectory/test_segment.py +403 -0
  96. ostk/astrodynamics/test/trajectory/test_sequence.py +530 -0
  97. ostk/astrodynamics/test/trajectory/test_state.py +543 -0
  98. ostk/astrodynamics/test/trajectory/test_state_builder.py +171 -0
  99. ostk/astrodynamics/utilities.py +247 -0
  100. ostk/astrodynamics/viewer.py +392 -0
@@ -0,0 +1,114 @@
1
+ # Apache License 2.0
2
+
3
+ from ostk.mathematics.object import RealInterval
4
+
5
+ from ostk.physics import Environment
6
+ from ostk.physics.coordinate import Position
7
+ from ostk.physics.coordinate import Frame
8
+ from ostk.physics.coordinate.spherical import LLA
9
+ from ostk.physics.environment.object import Celestial
10
+ from ostk.physics.time import DateTime
11
+ from ostk.physics.time import Duration
12
+ from ostk.physics.time import Instant
13
+ from ostk.physics.time import Interval
14
+ from ostk.physics.time import Scale
15
+ from ostk.physics.unit import Length
16
+ from ostk.physics.unit import Angle
17
+
18
+ from ostk.astrodynamics import Trajectory
19
+ from ostk.astrodynamics import display
20
+ from ostk.astrodynamics.access import Generator as AccessGenerator
21
+ from ostk.astrodynamics.trajectory import Orbit
22
+ from ostk.astrodynamics.trajectory.orbit.model import SGP4
23
+ from ostk.astrodynamics.trajectory.orbit.model.sgp4 import TLE
24
+
25
+
26
+ class TestDisplay:
27
+ def test_accesses_plot(self):
28
+ start_instant: Instant = Instant.date_time(
29
+ DateTime(2023, 1, 3, 0, 0, 0),
30
+ Scale.UTC,
31
+ )
32
+ duration: Duration = Duration.hours(12.0)
33
+ step: Duration = Duration.seconds(10.0)
34
+ tolerance: Duration = Duration.seconds(1.0)
35
+
36
+ ground_station_lla: LLA = LLA(
37
+ Angle.degrees(70.0),
38
+ Angle.degrees(160.0),
39
+ Length.meters(0.0),
40
+ )
41
+
42
+ tle_1 = TLE(
43
+ "1 55076U 23001BV 23146.17959645 .00004328 00000-0 23719-3 0 9993",
44
+ "2 55076 97.4793 205.9529 0016244 89.9523 270.3571 15.14609100 21723",
45
+ )
46
+
47
+ tle_2 = TLE(
48
+ "1 48915U 21059AN 23146.32782040 .00004955 00000-0 24678-3 0 9999",
49
+ "2 48915 97.5954 279.7041 0010303 354.9434 5.1694 15.18004448105867",
50
+ )
51
+
52
+ environment: Environment = Environment.default()
53
+ earth: Celestial = environment.access_celestial_object_with_name("Earth")
54
+
55
+ ground_station_trajectory: Trajectory = Trajectory.position(
56
+ Position.meters(
57
+ ground_station_lla.to_cartesian(
58
+ earth.get_equatorial_radius(),
59
+ earth.get_flattening(),
60
+ ),
61
+ Frame.ITRF(),
62
+ ),
63
+ )
64
+
65
+ stop_instant: Instant = start_instant + duration
66
+ search_interval: RealInterval = Interval.closed(start_instant, stop_instant)
67
+
68
+ orbit_1: Orbit = Orbit(SGP4(tle_1), earth)
69
+ orbit_2: Orbit = Orbit(SGP4(tle_2), earth)
70
+
71
+ generator = AccessGenerator(
72
+ environment=environment,
73
+ step=step,
74
+ tolerance=tolerance,
75
+ )
76
+
77
+ accesses_1 = generator.compute_accesses(
78
+ interval=search_interval,
79
+ from_trajectory=ground_station_trajectory,
80
+ to_trajectory=orbit_1,
81
+ )
82
+
83
+ assert len(accesses_1) > 0
84
+
85
+ accesses_2 = generator.compute_accesses(
86
+ interval=search_interval,
87
+ from_trajectory=ground_station_trajectory,
88
+ to_trajectory=orbit_2,
89
+ )
90
+
91
+ assert len(accesses_2) > 0
92
+
93
+ accesses_plot = display.AccessesPlot(
94
+ earth=earth,
95
+ interval=search_interval,
96
+ trajectory_step=Duration.minutes(5.0),
97
+ access_step=Duration.seconds(10.0),
98
+ ground_station_lla=ground_station_lla,
99
+ color="green",
100
+ )
101
+
102
+ accesses_plot.add_satellite(
103
+ trajectory=orbit_1,
104
+ accesses=accesses_1,
105
+ rgb=[180, 0, 0],
106
+ )
107
+
108
+ accesses_plot.add_satellite(
109
+ trajectory=orbit_2,
110
+ accesses=accesses_2,
111
+ rgb=[0, 0, 180],
112
+ )
113
+
114
+ accesses_plot.show()
@@ -0,0 +1,78 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics.time import Instant
6
+ from ostk.physics.coordinate import Position, Velocity, Frame
7
+
8
+ from ostk.astrodynamics.trajectory import State
9
+ from ostk.astrodynamics import EventCondition
10
+
11
+
12
+ @pytest.fixture
13
+ def name() -> str:
14
+ return "MyEvent"
15
+
16
+
17
+ @pytest.fixture
18
+ def evaluator() -> callable:
19
+ return lambda state: 5.0
20
+
21
+
22
+ @pytest.fixture
23
+ def target_value() -> float:
24
+ return 0.0
25
+
26
+
27
+ @pytest.fixture
28
+ def target(target_value: float) -> EventCondition.Target:
29
+ return EventCondition.Target(target_value, EventCondition.Target.Type.Relative)
30
+
31
+
32
+ @pytest.fixture
33
+ def event_condition(
34
+ name: str, evaluator: callable, target: EventCondition.Target
35
+ ) -> EventCondition:
36
+ class MyEventCondition(EventCondition):
37
+ def is_satisfied(
38
+ self,
39
+ current_state,
40
+ previous_state,
41
+ ):
42
+ return (
43
+ current_state.get_position().get_coordinates()[2] > 0.0
44
+ and previous_state.get_position().get_coordinates()[2] < 0.0
45
+ )
46
+
47
+ return MyEventCondition(name, evaluator, target)
48
+
49
+
50
+ class TestEventCondition:
51
+ def test_subclass(self, event_condition: EventCondition):
52
+ assert event_condition is not None
53
+
54
+ def test_get_name(self, event_condition: EventCondition, name: str):
55
+ assert event_condition.get_name() == name
56
+
57
+ def test_get_evaluator(self, event_condition: EventCondition):
58
+ assert event_condition.get_evaluator() is not None
59
+
60
+ def test_get_target(
61
+ self, event_condition: EventCondition, target: EventCondition.Target
62
+ ):
63
+ assert event_condition.get_target() == target
64
+
65
+ def test_update_target(
66
+ self,
67
+ event_condition: EventCondition,
68
+ ):
69
+ current_target_value_offset: float = event_condition.get_target().value_offset
70
+ event_condition.update_target(
71
+ State(
72
+ Instant.J2000(),
73
+ Position.meters([0.0, 0.0, 0.0], Frame.GCRF()),
74
+ Velocity.meters_per_second([0.0, 0.0, 0.0], Frame.GCRF()),
75
+ )
76
+ )
77
+
78
+ assert event_condition.get_target().value_offset != current_target_value_offset
@@ -0,0 +1,26 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+
6
+ class TestImport:
7
+ def test_import(self):
8
+ from ostk.astrodynamics import Trajectory
9
+ from ostk.astrodynamics.trajectory import State
10
+ from ostk.astrodynamics.trajectory import Orbit
11
+ from ostk.astrodynamics.trajectory import Model
12
+ from ostk.astrodynamics.trajectory.orbit import Pass
13
+ from ostk.astrodynamics.trajectory.orbit.model import Kepler
14
+ from ostk.astrodynamics.trajectory.orbit.model.kepler import COE
15
+ from ostk.astrodynamics.trajectory.orbit.model import SGP4
16
+ from ostk.astrodynamics.trajectory.orbit.model.sgp4 import TLE
17
+ from ostk.astrodynamics.trajectory.orbit.model import Propagated
18
+ from ostk.astrodynamics.flight import Profile
19
+ from ostk.astrodynamics.flight import System
20
+ from ostk.astrodynamics.flight import Maneuver
21
+ from ostk.astrodynamics.flight.system import SatelliteSystem
22
+ from ostk.astrodynamics.dynamics import CentralBodyGravity
23
+ from ostk.astrodynamics.dynamics import AtmosphericDrag
24
+ from ostk.astrodynamics import Access
25
+ from ostk.astrodynamics.access import Generator
26
+ from ostk.astrodynamics.trajectory.state import NumericalSolver
@@ -0,0 +1,70 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.astrodynamics import RootSolver
6
+
7
+
8
+ def quadratic_function(x):
9
+ return x**2 - 4
10
+
11
+
12
+ @pytest.fixture
13
+ def maximum_iteration_count() -> int:
14
+ return 100
15
+
16
+
17
+ @pytest.fixture
18
+ def tolerance() -> float:
19
+ return 1e-15
20
+
21
+
22
+ @pytest.fixture
23
+ def root_solver(maximum_iteration_count: int, tolerance: float) -> RootSolver:
24
+ return RootSolver(maximum_iteration_count, tolerance)
25
+
26
+
27
+ class TestRootSolver:
28
+ def test_constructor(self, maximum_iteration_count: int, tolerance: float):
29
+ assert (
30
+ RootSolver(
31
+ maximum_iteration_count=maximum_iteration_count, tolerance=tolerance
32
+ )
33
+ is not None
34
+ )
35
+
36
+ def test_getters(
37
+ self,
38
+ root_solver: RootSolver,
39
+ maximum_iteration_count: int,
40
+ tolerance: float,
41
+ ):
42
+ assert root_solver.get_tolerance() == tolerance
43
+ assert root_solver.get_maximum_iteration_count() == maximum_iteration_count
44
+
45
+ def test_bracket_and_solve(self, root_solver):
46
+ solution = root_solver.bracket_and_solve(
47
+ function=quadratic_function,
48
+ initial_guess=1.0,
49
+ is_rising=True,
50
+ )
51
+ assert pytest.approx(solution.root, abs=1e-15) == 2.0
52
+
53
+ def test_solve(self, root_solver):
54
+ solution = root_solver.solve(
55
+ function=quadratic_function,
56
+ lower_bound=1.0,
57
+ upper_bound=3.0,
58
+ )
59
+ assert pytest.approx(solution.root, abs=1e-15) == 2.0
60
+
61
+ def test_bisection(self, root_solver):
62
+ solution = root_solver.bisection(
63
+ function=quadratic_function,
64
+ lower_bound=1.0,
65
+ upper_bound=3.0,
66
+ )
67
+ assert pytest.approx(solution.root, abs=1e-15) == 2.0
68
+
69
+ def test_default(self):
70
+ assert RootSolver.default() is not None
@@ -0,0 +1,118 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics.environment.object.celestial import Earth
6
+ from ostk.physics.coordinate.spherical import LLA
7
+ from ostk.physics.coordinate import Position
8
+ from ostk.physics.coordinate import Frame
9
+ from ostk.physics.time import Instant
10
+ from ostk.physics.time import Duration
11
+ from ostk.physics.unit import Derived
12
+
13
+ from ostk.astrodynamics import Trajectory
14
+ from ostk.astrodynamics.trajectory import State
15
+
16
+
17
+ @pytest.fixture
18
+ def start_lla() -> LLA:
19
+ return LLA.vector([0.0, 0.0, 0.0])
20
+
21
+
22
+ @pytest.fixture
23
+ def end_lla() -> LLA:
24
+ return LLA.vector([1.0, 0.0, 0.0])
25
+
26
+
27
+ @pytest.fixture
28
+ def start_instant() -> Instant:
29
+ return Instant.J2000()
30
+
31
+
32
+ @pytest.fixture
33
+ def ground_speed() -> Derived:
34
+ return Derived(7000.0, Derived.Unit.meter_per_second())
35
+
36
+
37
+ @pytest.fixture
38
+ def earth() -> Earth:
39
+ return Earth.WGS84()
40
+
41
+
42
+ @pytest.fixture
43
+ def instants() -> list[Instant]:
44
+ return [Instant.J2000(), Instant.J2000() + Duration.seconds(10.0)]
45
+
46
+
47
+ @pytest.fixture
48
+ def position() -> Position:
49
+ return Position.meters([0.0, 0.0, 0.0], Frame.ITRF())
50
+
51
+
52
+ @pytest.fixture
53
+ def trajectory(position: Position) -> Trajectory:
54
+ return Trajectory.position(position)
55
+
56
+
57
+ @pytest.fixture
58
+ def states(trajectory: Trajectory) -> list[State]:
59
+ return trajectory.get_states_at(
60
+ [Instant.J2000(), Instant.J2000() + Duration.seconds(10.0)]
61
+ )
62
+
63
+
64
+ class TestTrajectory:
65
+ def test_trajectory(self, states: list[State]):
66
+ assert Trajectory(states) is not None
67
+
68
+ def test_is_defined(self, trajectory: Trajectory):
69
+ assert trajectory.is_defined()
70
+
71
+ def test_access_model(self, trajectory: Trajectory):
72
+ assert trajectory.access_model() is not None
73
+
74
+ def test_get_state_at(self, trajectory: Trajectory):
75
+ assert trajectory.get_state_at(Instant.J2000()) is not None
76
+
77
+ def test_get_states_at(self, trajectory: Trajectory):
78
+ assert (
79
+ trajectory.get_states_at(
80
+ [Instant.J2000(), Instant.J2000() + Duration.seconds(10.0)]
81
+ )
82
+ is not None
83
+ )
84
+
85
+ def test_trajectory_undefined(self):
86
+ trajectory: Trajectory = Trajectory.undefined()
87
+
88
+ assert trajectory is not None
89
+ assert isinstance(trajectory, Trajectory)
90
+ assert trajectory.is_defined() is False
91
+
92
+ def test_trajectory_position(self, position: Position):
93
+ trajectory: Trajectory = Trajectory.position(position)
94
+
95
+ assert trajectory is not None
96
+
97
+ def test_ground_strip(
98
+ self,
99
+ start_lla: LLA,
100
+ end_lla: LLA,
101
+ ground_speed: Derived,
102
+ start_instant: Instant,
103
+ earth: Earth,
104
+ instants: list[Instant],
105
+ ):
106
+ assert (
107
+ Trajectory.ground_strip(
108
+ start_lla, end_lla, ground_speed, start_instant, earth
109
+ )
110
+ is not None
111
+ )
112
+ assert (
113
+ Trajectory.ground_strip(start_lla, end_lla, ground_speed, start_instant)
114
+ is not None
115
+ )
116
+
117
+ assert Trajectory.ground_strip(start_lla, end_lla, instants, earth) is not None
118
+ assert Trajectory.ground_strip(start_lla, end_lla, instants) is not None
@@ -0,0 +1,106 @@
1
+ # Apache License 2.0
2
+
3
+ from datetime import datetime
4
+
5
+ from ostk.physics import Environment
6
+ from ostk.physics.time import Instant, Interval
7
+ from ostk.physics.coordinate import Position
8
+ from ostk.physics.coordinate.spherical import LLA, AER
9
+
10
+ from ostk.astrodynamics import utilities
11
+ from ostk.astrodynamics import Trajectory
12
+ from ostk.astrodynamics.trajectory import State
13
+
14
+
15
+ class TestUtility:
16
+ def test_lla_from_state(
17
+ self,
18
+ state: State,
19
+ ):
20
+ lla: LLA = utilities.lla_from_state(state)
21
+
22
+ assert lla is not None
23
+ assert isinstance(lla, LLA)
24
+ assert lla.is_defined()
25
+
26
+ def test_lla_from_position(
27
+ self,
28
+ instant: Instant,
29
+ position: Position,
30
+ ):
31
+ lla: LLA = utilities.lla_from_position(position, instant)
32
+
33
+ assert lla is not None
34
+ assert isinstance(lla, LLA)
35
+ assert lla.is_defined()
36
+
37
+ def test_position_from_lla(
38
+ self,
39
+ lla: LLA,
40
+ ):
41
+ position: Position = utilities.position_from_lla(lla)
42
+
43
+ assert position is not None
44
+ assert isinstance(position, Position)
45
+ assert position.is_defined()
46
+
47
+ def test_compute_aer(
48
+ self,
49
+ instant: Instant,
50
+ position: Position,
51
+ environment: Environment,
52
+ ):
53
+ aer: AER = utilities.compute_aer(instant, position, position, environment)
54
+
55
+ assert aer is not None
56
+ assert isinstance(aer, AER)
57
+
58
+ def test_compute_time_lla_aer_coordinates(
59
+ self,
60
+ state: State,
61
+ position: Position,
62
+ environment: Environment,
63
+ ):
64
+ time_lla_aer: float[datetime, float, float, float, float, float, float] = (
65
+ utilities.compute_time_lla_aer_coordinates(state, position, environment)
66
+ )
67
+
68
+ assert time_lla_aer is not None
69
+ assert len(time_lla_aer) == 7
70
+ assert isinstance(time_lla_aer[0], datetime)
71
+ for i in range(1, 7):
72
+ assert isinstance(time_lla_aer[i], float)
73
+
74
+ def test_compute_trajectory_geometry(
75
+ self,
76
+ interval: Interval,
77
+ trajectory: Trajectory,
78
+ ):
79
+ output: list[LLA] = utilities.compute_trajectory_geometry(trajectory, interval)
80
+
81
+ assert output is not None
82
+ assert len(output) == 2
83
+ assert isinstance(output[0], LLA)
84
+
85
+ def test_compute_ground_track(
86
+ self,
87
+ interval: Interval,
88
+ trajectory: Trajectory,
89
+ ):
90
+ output: list[LLA] = utilities.compute_ground_track(trajectory, interval)
91
+
92
+ assert output is not None
93
+ assert len(output) == 2
94
+ assert isinstance(output[0], LLA)
95
+ assert output[0].get_altitude().in_meters() <= 15.0
96
+
97
+ def test_convert_state(self, state: State):
98
+ output: tuple[
99
+ str, float, float, float, float, float, float, float, float, float
100
+ ] = utilities.convert_state(state)
101
+
102
+ assert output is not None
103
+ assert len(output) == 11
104
+ assert isinstance(output[0], str)
105
+ for i in range(1, 11):
106
+ 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"))