open-space-toolkit-astrodynamics 13.1.0__py313-none-manylinux2014_aarch64.whl → 15.0.0__py313-none-manylinux2014_aarch64.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 (60) hide show
  1. {open_space_toolkit_astrodynamics-13.1.0.dist-info → open_space_toolkit_astrodynamics-15.0.0.dist-info}/METADATA +4 -4
  2. {open_space_toolkit_astrodynamics-13.1.0.dist-info → open_space_toolkit_astrodynamics-15.0.0.dist-info}/RECORD +59 -28
  3. {open_space_toolkit_astrodynamics-13.1.0.dist-info → open_space_toolkit_astrodynamics-15.0.0.dist-info}/WHEEL +1 -1
  4. ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-313-aarch64-linux-gnu.so +0 -0
  5. ostk/astrodynamics/__init__.pyi +785 -0
  6. ostk/astrodynamics/access.pyi +588 -0
  7. ostk/astrodynamics/conjunction/__init__.pyi +3 -0
  8. ostk/astrodynamics/conjunction/message/__init__.pyi +3 -0
  9. ostk/astrodynamics/conjunction/message/ccsds.pyi +723 -0
  10. ostk/astrodynamics/converters.pyi +54 -0
  11. ostk/astrodynamics/data/__init__.pyi +3 -0
  12. ostk/astrodynamics/data/provider.pyi +22 -0
  13. ostk/astrodynamics/dynamics.pyi +329 -0
  14. ostk/astrodynamics/event_condition.pyi +580 -0
  15. ostk/astrodynamics/flight/__init__.pyi +547 -0
  16. ostk/astrodynamics/flight/profile/__init__.pyi +102 -0
  17. ostk/astrodynamics/flight/profile/model.pyi +176 -0
  18. ostk/astrodynamics/flight/system.pyi +277 -0
  19. ostk/astrodynamics/guidance_law.pyi +282 -0
  20. ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.15 +0 -0
  21. ostk/astrodynamics/pytrajectory/__init__.pyi +3 -0
  22. ostk/astrodynamics/pytrajectory/pystate.py +2 -4
  23. ostk/astrodynamics/pytrajectory/pystate.pyi +63 -0
  24. ostk/astrodynamics/solver.pyi +232 -0
  25. ostk/astrodynamics/test/access/test_generator.py +130 -59
  26. ostk/astrodynamics/test/access/test_visibility_criterion.py +198 -0
  27. ostk/astrodynamics/test/data/provider/test_off_nadir.py +58 -0
  28. ostk/astrodynamics/test/dynamics/test_dynamics.py +1 -1
  29. ostk/astrodynamics/test/flight/system/test_propulsion_system.py +2 -11
  30. ostk/astrodynamics/test/flight/system/test_satellite_system.py +6 -14
  31. ostk/astrodynamics/test/flight/test_maneuver.py +49 -64
  32. ostk/astrodynamics/test/flight/test_profile.py +4 -2
  33. ostk/astrodynamics/test/flight/test_system.py +5 -15
  34. ostk/astrodynamics/test/solvers/test_finite_difference_solver.py +31 -16
  35. ostk/astrodynamics/test/solvers/test_temporal_condition_solver.py +9 -1
  36. ostk/astrodynamics/test/test_display.py +11 -5
  37. ostk/astrodynamics/test/test_event_condition.py +4 -2
  38. ostk/astrodynamics/test/test_utilities.py +1 -1
  39. ostk/astrodynamics/test/test_viewer.py +70 -1
  40. ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_acceleration.py +136 -0
  41. ostk/astrodynamics/test/trajectory/state/test_coordinate_subset.py +9 -0
  42. ostk/astrodynamics/test/trajectory/state/test_numerical_solver.py +4 -2
  43. ostk/astrodynamics/test/trajectory/test_local_orbital_frame_factory.py +25 -15
  44. ostk/astrodynamics/test/trajectory/test_propagator.py +21 -27
  45. ostk/astrodynamics/test/trajectory/test_segment.py +0 -1
  46. ostk/astrodynamics/test/trajectory/test_state_builder.py +1 -0
  47. ostk/astrodynamics/trajectory/__init__.pyi +1800 -0
  48. ostk/astrodynamics/trajectory/orbit/__init__.pyi +361 -0
  49. ostk/astrodynamics/trajectory/orbit/message/__init__.pyi +3 -0
  50. ostk/astrodynamics/trajectory/orbit/message/spacex.pyi +273 -0
  51. ostk/astrodynamics/trajectory/orbit/model/__init__.pyi +517 -0
  52. ostk/astrodynamics/trajectory/orbit/model/brouwerLyddaneMean.pyi +127 -0
  53. ostk/astrodynamics/trajectory/orbit/model/kepler.pyi +581 -0
  54. ostk/astrodynamics/trajectory/orbit/model/sgp4.pyi +333 -0
  55. ostk/astrodynamics/trajectory/state/__init__.pyi +406 -0
  56. ostk/astrodynamics/trajectory/state/coordinate_subset.pyi +223 -0
  57. ostk/astrodynamics/viewer.py +32 -0
  58. ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.13 +0 -0
  59. {open_space_toolkit_astrodynamics-13.1.0.dist-info → open_space_toolkit_astrodynamics-15.0.0.dist-info}/top_level.txt +0 -0
  60. {open_space_toolkit_astrodynamics-13.1.0.dist-info → open_space_toolkit_astrodynamics-15.0.0.dist-info}/zip-safe +0 -0
@@ -12,24 +12,21 @@ from ostk.physics.coordinate import Frame
12
12
  from ostk.physics.unit import Mass
13
13
 
14
14
  from ostk.astrodynamics.flight import Maneuver
15
+ from ostk.astrodynamics.trajectory import State
15
16
  from ostk.astrodynamics.dynamics import Tabulated as TabulatedDynamics
16
17
  from ostk.astrodynamics.trajectory.state import CoordinateSubset
17
-
18
-
19
- from ..dynamics.test_tabulated import (
20
- instants as tabulated_instants,
21
- contribution_profile as tabulated_contribution_profile,
22
- coordinate_subsets as tabulated_coordinate_subsets,
23
- )
18
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianPosition
19
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianVelocity
20
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianAcceleration
24
21
 
25
22
 
26
23
  @pytest.fixture
27
24
  def instants() -> list[Instant]:
28
25
  return [
29
26
  Instant.J2000(),
30
- Instant.J2000() + Duration.seconds(1.0),
31
- Instant.J2000() + Duration.seconds(5.0),
32
- Instant.J2000() + Duration.seconds(7.0),
27
+ Instant.J2000() + Duration.seconds(30.0),
28
+ Instant.J2000() + Duration.seconds(35.0),
29
+ Instant.J2000() + Duration.seconds(37.0),
33
30
  ]
34
31
 
35
32
 
@@ -54,13 +51,43 @@ def mass_flow_rate_profile() -> list[float]:
54
51
 
55
52
 
56
53
  @pytest.fixture
57
- def maneuver(
54
+ def coordinate_subsets() -> list[CoordinateSubset]:
55
+ return [
56
+ CartesianPosition.default(),
57
+ CartesianVelocity.default(),
58
+ CartesianAcceleration.thrust_acceleration(),
59
+ CoordinateSubset.mass_flow_rate(),
60
+ ]
61
+
62
+
63
+ @pytest.fixture
64
+ def states(
58
65
  instants: list[Instant],
59
66
  acceleration_profile: list[np.ndarray],
60
- frame: Frame,
61
67
  mass_flow_rate_profile: list[float],
68
+ frame: Frame,
69
+ coordinate_subsets: list[CoordinateSubset],
70
+ ) -> list[State]:
71
+ states = []
72
+ for instant, acceleration, mass_flow_rate in zip(
73
+ instants, acceleration_profile, mass_flow_rate_profile
74
+ ):
75
+ states.append(
76
+ State(
77
+ instant,
78
+ [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, *acceleration, mass_flow_rate],
79
+ frame,
80
+ coordinate_subsets,
81
+ )
82
+ )
83
+ return states
84
+
85
+
86
+ @pytest.fixture
87
+ def maneuver(
88
+ states: list[State],
62
89
  ) -> Maneuver:
63
- return Maneuver(instants, acceleration_profile, frame, mass_flow_rate_profile)
90
+ return Maneuver(states)
64
91
 
65
92
 
66
93
  @pytest.fixture
@@ -97,35 +124,15 @@ class TestManeuver:
97
124
  def test_getters(
98
125
  self,
99
126
  maneuver: Maneuver,
100
- instants: list[Instant],
101
- acceleration_profile: list[np.ndarray],
102
- mass_flow_rate_profile: list[float],
127
+ states: list[State],
103
128
  ):
104
129
  assert maneuver.is_defined()
105
130
 
106
- assert maneuver.get_instants() == instants
131
+ assert maneuver.get_states() == states
107
132
 
108
- computed_acceleration_profile_default_frame = maneuver.get_acceleration_profile()
109
- for i in range(len(instants)):
110
- assert np.array_equal(
111
- computed_acceleration_profile_default_frame[i], acceleration_profile[i]
112
- )
113
-
114
- computed_acceleration_profile_non_default_frame = (
115
- maneuver.get_acceleration_profile(frame=Frame.ITRF())
133
+ assert maneuver.get_interval() == Interval.closed(
134
+ states[0].get_instant(), states[-1].get_instant()
116
135
  )
117
- for i in range(len(instants)):
118
- assert (
119
- np.array_equal(
120
- computed_acceleration_profile_non_default_frame[i],
121
- acceleration_profile[i],
122
- )
123
- == False
124
- )
125
-
126
- assert maneuver.get_mass_flow_rate_profile() == mass_flow_rate_profile
127
-
128
- assert maneuver.get_interval() == Interval.closed(instants[0], instants[-1])
129
136
 
130
137
  def test_calculators(
131
138
  self,
@@ -159,7 +166,9 @@ class TestManeuver:
159
166
  )
160
167
 
161
168
  assert tabulated_dynamics.is_defined()
162
- assert tabulated_dynamics.access_instants() == maneuver.get_instants()
169
+ assert tabulated_dynamics.access_instants() == [
170
+ state.get_instant() for state in maneuver.get_states()
171
+ ]
163
172
 
164
173
  contribution_profile: np.ndarray = (
165
174
  tabulated_dynamics.access_contribution_profile()
@@ -175,38 +184,14 @@ class TestManeuver:
175
184
 
176
185
  assert tabulated_dynamics.access_frame() == frame
177
186
 
178
- def test_from_tabulated_dynamics(
179
- self,
180
- tabulated_dynamics: TabulatedDynamics,
181
- ):
182
- maneuver = Maneuver.tabulated_dynamics(tabulated_dynamics)
183
-
184
- assert maneuver.is_defined()
185
- assert maneuver.get_instants() == tabulated_dynamics.access_instants()
186
- assert (
187
- len(maneuver.get_acceleration_profile())
188
- == tabulated_dynamics.access_contribution_profile().shape[0]
189
- )
190
- assert (
191
- len(maneuver.get_mass_flow_rate_profile())
192
- == tabulated_dynamics.access_contribution_profile().shape[0]
193
- )
194
-
195
187
  def test_from_constant_mass_flow_rate(
196
188
  self,
197
- instants: list[Instant],
198
- acceleration_profile: list[np.ndarray],
199
- frame: Frame,
189
+ states: list[State],
200
190
  ):
201
191
  mass_flow_rate: float = -1.0e-5
202
192
  maneuver = Maneuver.constant_mass_flow_rate_profile(
203
- instants=instants,
204
- acceleration_profile=acceleration_profile,
205
- frame=frame,
193
+ states=states,
206
194
  mass_flow_rate=mass_flow_rate,
207
195
  )
208
196
 
209
197
  assert maneuver.is_defined()
210
- assert maneuver.get_mass_flow_rate_profile() == [
211
- mass_flow_rate for _ in range(len(instants))
212
- ]
@@ -192,11 +192,13 @@ class TestProfile:
192
192
  assert isinstance(profile, Profile)
193
193
  assert profile.is_defined()
194
194
 
195
- def test_nadir_pointing(
195
+ def test_local_orbital_frame_pointing(
196
196
  self,
197
197
  orbit: Orbit,
198
198
  ):
199
- profile: Profile = Profile.nadir_pointing(orbit, Orbit.FrameType.VVLH)
199
+ profile: Profile = Profile.local_orbital_frame_pointing(
200
+ orbit, Orbit.FrameType.VVLH
201
+ )
200
202
 
201
203
  assert profile is not None
202
204
  assert isinstance(profile, Profile)
@@ -2,21 +2,11 @@
2
2
 
3
3
  import pytest
4
4
 
5
- import numpy as np
6
-
7
- import ostk.mathematics as mathematics
8
-
9
- import ostk.physics as physics
10
-
11
- import ostk.astrodynamics as astrodynamics
12
-
13
- Cuboid = mathematics.geometry.d3.object.Cuboid
14
- Composite = mathematics.geometry.d3.object.Composite
15
- Point = mathematics.geometry.d3.object.Point
16
-
17
- Mass = physics.unit.Mass
18
-
19
- System = astrodynamics.flight.System
5
+ from ostk.mathematics.geometry.d3.object import Cuboid
6
+ from ostk.mathematics.geometry.d3.object import Composite
7
+ from ostk.mathematics.geometry.d3.object import Point
8
+ from ostk.physics.unit import Mass
9
+ from ostk.astrodynamics.flight import System
20
10
 
21
11
 
22
12
  @pytest.fixture
@@ -1,5 +1,7 @@
1
1
  # Apache License 2.0
2
2
 
3
+ from typing import Callable
4
+
3
5
  import pytest
4
6
  import math
5
7
 
@@ -71,7 +73,7 @@ def instants(initial_instant: Instant) -> list[Instant]:
71
73
 
72
74
 
73
75
  @pytest.fixture
74
- def generate_states_coordinates() -> callable:
76
+ def generate_states_coordinates() -> Callable:
75
77
  def state_fn(state, instants) -> np.ndarray:
76
78
  x0: float = state.get_coordinates()[0]
77
79
  v0: float = state.get_coordinates()[1]
@@ -84,17 +86,17 @@ def generate_states_coordinates() -> callable:
84
86
  x: float = x0 * math.cos(omega * t) + v0 / omega * math.sin(omega * t)
85
87
  v: float = -x0 * omega * math.sin(omega * t) + v0 * math.cos(omega * t)
86
88
 
87
- coordinates: list[float] = [x, v]
89
+ coordinates: list[float] = list(np.array([x, v]).astype(float))
88
90
 
89
91
  states_coordinates.append(coordinates)
90
92
 
91
- return np.array(states_coordinates)
93
+ return np.array(states_coordinates).transpose()
92
94
 
93
95
  return state_fn
94
96
 
95
97
 
96
98
  @pytest.fixture
97
- def generate_state_coordinates() -> callable:
99
+ def generate_state_coordinates() -> Callable:
98
100
  def state_fn(state, instant) -> np.ndarray:
99
101
  x0: float = state.get_coordinates()[0]
100
102
  v0: float = state.get_coordinates()[1]
@@ -126,37 +128,37 @@ class TestFiniteDifferenceSolver:
126
128
  == "Forward"
127
129
  )
128
130
 
129
- def test_compute_jacobian_array(
131
+ def test_compute_state_transition_matrix_array(
130
132
  self,
131
133
  finite_difference_solver: FiniteDifferenceSolver,
132
134
  state: State,
133
135
  instants: list[Instant],
134
- generate_states_coordinates: callable,
136
+ generate_states_coordinates: Callable,
135
137
  ):
136
- stm = finite_difference_solver.compute_jacobian(
138
+ stms: list[np.ndarray] = finite_difference_solver.compute_state_transition_matrix(
137
139
  state=state,
138
140
  instants=instants,
139
141
  generate_states_coordinates=generate_states_coordinates,
140
- coordinates_dimension=2,
141
142
  )
142
- assert isinstance(stm, np.ndarray)
143
- assert stm.shape == (
144
- len(state.get_coordinates()) * len(instants),
143
+
144
+ assert len(stms) == len(instants)
145
+
146
+ assert stms[0].shape == (
147
+ len(state.get_coordinates()),
145
148
  len(state.get_coordinates()),
146
149
  )
147
150
 
148
- def test_compute_jacobian_single(
151
+ def test_compute_state_transition_matrix_single(
149
152
  self,
150
153
  finite_difference_solver: FiniteDifferenceSolver,
151
154
  state: State,
152
- generate_state_coordinates: callable,
155
+ generate_state_coordinates: Callable,
153
156
  instant: Instant,
154
157
  ):
155
- stm = finite_difference_solver.compute_jacobian(
158
+ stm: np.ndarray = finite_difference_solver.compute_state_transition_matrix(
156
159
  state=state,
157
160
  instant=instant,
158
161
  generate_state_coordinates=generate_state_coordinates,
159
- coordinates_dimension=2,
160
162
  )
161
163
  assert isinstance(stm, np.ndarray)
162
164
  assert stm.shape == (
@@ -168,7 +170,7 @@ class TestFiniteDifferenceSolver:
168
170
  self,
169
171
  finite_difference_solver: FiniteDifferenceSolver,
170
172
  state: State,
171
- generate_state_coordinates: callable,
173
+ generate_state_coordinates: Callable,
172
174
  ):
173
175
  gradient = finite_difference_solver.compute_gradient(
174
176
  state=state,
@@ -177,5 +179,18 @@ class TestFiniteDifferenceSolver:
177
179
  assert isinstance(gradient, np.ndarray)
178
180
  assert all(gradient - np.array([0.0, -1.0]) < 1e-6)
179
181
 
182
+ def test_compute_jacobian(
183
+ self,
184
+ finite_difference_solver: FiniteDifferenceSolver,
185
+ state: State,
186
+ generate_state_coordinates: Callable,
187
+ ):
188
+ gradient = finite_difference_solver.compute_jacobian(
189
+ state=state,
190
+ generate_state_coordinates=generate_state_coordinates,
191
+ )
192
+ assert isinstance(gradient, np.ndarray)
193
+ assert np.all(gradient - np.array([[0.0, 1.0], [-1.0, 0.0]]) < 1e-6)
194
+
180
195
  def test_default(self):
181
196
  assert isinstance(FiniteDifferenceSolver.default(), FiniteDifferenceSolver)
@@ -16,6 +16,8 @@ from ostk.astrodynamics.trajectory.orbit.model import Kepler
16
16
  from ostk.astrodynamics.trajectory.orbit.model.kepler import COE
17
17
  from ostk.astrodynamics.access import Generator
18
18
  from ostk.astrodynamics.solver import TemporalConditionSolver
19
+ from ostk.astrodynamics.access import AccessTarget
20
+ from ostk.astrodynamics.access import VisibilityCriterion
19
21
 
20
22
 
21
23
  @pytest.fixture
@@ -141,9 +143,15 @@ class TestTemporalConditionSolver:
141
143
  celestial_object=earth,
142
144
  )
143
145
 
146
+ visibility_criterion: VisibilityCriterion = (
147
+ VisibilityCriterion.from_line_of_sight(environment)
148
+ )
149
+
150
+ access_target = AccessTarget.from_trajectory(visibility_criterion, trajectory)
151
+
144
152
  solution: list[Interval] = temporal_condition_solver.solve(
145
153
  condition=generator.get_condition_function(
146
- from_trajectory=trajectory,
154
+ access_target=access_target,
147
155
  to_trajectory=trajectory,
148
156
  ),
149
157
  interval=interval,
@@ -15,12 +15,13 @@ from ostk.physics.time import Scale
15
15
  from ostk.physics.unit import Length
16
16
  from ostk.physics.unit import Angle
17
17
 
18
- from ostk.astrodynamics import Trajectory
19
18
  from ostk.astrodynamics import display
20
19
  from ostk.astrodynamics.access import Generator as AccessGenerator
21
20
  from ostk.astrodynamics.trajectory import Orbit
22
21
  from ostk.astrodynamics.trajectory.orbit.model import SGP4
23
22
  from ostk.astrodynamics.trajectory.orbit.model.sgp4 import TLE
23
+ from ostk.astrodynamics.access import AccessTarget
24
+ from ostk.astrodynamics.access import VisibilityCriterion
24
25
 
25
26
 
26
27
  class TestDisplay:
@@ -29,7 +30,7 @@ class TestDisplay:
29
30
  DateTime(2023, 1, 3, 0, 0, 0),
30
31
  Scale.UTC,
31
32
  )
32
- duration: Duration = Duration.hours(12.0)
33
+ duration: Duration = Duration.hours(1.0)
33
34
  step: Duration = Duration.seconds(10.0)
34
35
  tolerance: Duration = Duration.seconds(1.0)
35
36
 
@@ -52,7 +53,12 @@ class TestDisplay:
52
53
  environment: Environment = Environment.default()
53
54
  earth: Celestial = environment.access_celestial_object_with_name("Earth")
54
55
 
55
- ground_station_trajectory: Trajectory = Trajectory.position(
56
+ visibility_criterion: VisibilityCriterion = (
57
+ VisibilityCriterion.from_line_of_sight(environment)
58
+ )
59
+
60
+ access_target: AccessTarget = AccessTarget.from_position(
61
+ visibility_criterion,
56
62
  Position.meters(
57
63
  ground_station_lla.to_cartesian(
58
64
  earth.get_equatorial_radius(),
@@ -76,7 +82,7 @@ class TestDisplay:
76
82
 
77
83
  accesses_1 = generator.compute_accesses(
78
84
  interval=search_interval,
79
- from_trajectory=ground_station_trajectory,
85
+ access_target=access_target,
80
86
  to_trajectory=orbit_1,
81
87
  )
82
88
 
@@ -84,7 +90,7 @@ class TestDisplay:
84
90
 
85
91
  accesses_2 = generator.compute_accesses(
86
92
  interval=search_interval,
87
- from_trajectory=ground_station_trajectory,
93
+ access_target=access_target,
88
94
  to_trajectory=orbit_2,
89
95
  )
90
96
 
@@ -1,5 +1,7 @@
1
1
  # Apache License 2.0
2
2
 
3
+ from typing import Callable
4
+
3
5
  import pytest
4
6
 
5
7
  from ostk.physics.time import Instant
@@ -15,7 +17,7 @@ def name() -> str:
15
17
 
16
18
 
17
19
  @pytest.fixture
18
- def evaluator() -> callable:
20
+ def evaluator() -> Callable:
19
21
  return lambda state: 5.0
20
22
 
21
23
 
@@ -31,7 +33,7 @@ def target(target_value: float) -> EventCondition.Target:
31
33
 
32
34
  @pytest.fixture
33
35
  def event_condition(
34
- name: str, evaluator: callable, target: EventCondition.Target
36
+ name: str, evaluator: Callable, target: EventCondition.Target
35
37
  ) -> EventCondition:
36
38
  class MyEventCondition(EventCondition):
37
39
  def is_satisfied(
@@ -61,7 +61,7 @@ class TestUtility:
61
61
  position: Position,
62
62
  environment: Environment,
63
63
  ):
64
- time_lla_aer: float[datetime, float, float, float, float, float, float] = (
64
+ time_lla_aer: tuple[datetime, float, float, float, float, float, float] = (
65
65
  utilities.compute_time_lla_aer_coordinates(state, position, environment)
66
66
  )
67
67
 
@@ -38,7 +38,7 @@ def orbit(environment: Environment) -> Orbit:
38
38
 
39
39
  @pytest.fixture
40
40
  def profile(orbit: Orbit) -> Profile:
41
- return Profile.nadir_pointing(
41
+ return Profile.local_orbital_frame_pointing(
42
42
  orbit=orbit,
43
43
  orbital_frame_type=Orbit.FrameType.VVLH,
44
44
  )
@@ -127,3 +127,72 @@ class TestViewer:
127
127
  in rendered_html
128
128
  )
129
129
  assert rendered_html.endswith("</script>")
130
+
131
+ def test_add_target_with_label_success(
132
+ self,
133
+ viewer: Viewer,
134
+ ):
135
+ viewer.add_target(
136
+ position=Position.meters([1.0, 2.0, 3.0], Frame.ITRF()),
137
+ size=123,
138
+ color="red",
139
+ label="TEST",
140
+ )
141
+
142
+ rendered_html: str = viewer.render()
143
+
144
+ assert rendered_html.startswith('<meta charset="utf-8">')
145
+ assert "var widget = new Cesium.Viewer" in rendered_html
146
+ assert (
147
+ "widget.entities.add({position: Cesium.Cartesian3.fromDegrees(63.43494882292201, 18.22447811510915, -6376045.535225509), point: {pixelSize: 123.0, color: Cesium.Color.RED}});"
148
+ in rendered_html
149
+ )
150
+ assert (
151
+ 'widget.entities.add({position: Cesium.Cartesian3.fromDegrees(63.43494882292201, 18.22447811510915, -6376045.535225509), label: {text: "TEST", fillColor: Cesium.Color.RED, scale: 123.0}});'
152
+ in rendered_html
153
+ )
154
+ assert rendered_html.endswith("</script>")
155
+
156
+ def test_add_line_success(
157
+ self,
158
+ viewer: Viewer,
159
+ ):
160
+ viewer.add_line(
161
+ positions=[
162
+ Position.meters([1.0, 2.0, 3.0], Frame.ITRF()),
163
+ Position.meters([4.0, 5.0, 6.0], Frame.ITRF()),
164
+ ],
165
+ size=10.0,
166
+ color="red",
167
+ )
168
+
169
+ rendered_html: str = viewer.render()
170
+
171
+ assert rendered_html.startswith('<meta charset="utf-8">')
172
+ assert "var widget = new Cesium.Viewer" in rendered_html
173
+ assert (
174
+ "widget.entities.add({polyline: {positions: Cesium.Cartesian3.fromDegreesArrayHeights([63.43494882292201, 18.22447811510915, 10.0, 51.34019174590991, 10.165199393640696, 10.0]), width: 10.0, material: Cesium.Color.RED}});"
175
+ in rendered_html
176
+ )
177
+ assert rendered_html.endswith("</script>")
178
+
179
+ def test_add_label_success(
180
+ self,
181
+ viewer: Viewer,
182
+ ):
183
+ viewer.add_label(
184
+ position=Position.meters([6671000.0, 0.0, 0.0], Frame.ITRF()),
185
+ text="Hello, World!",
186
+ size=1.0,
187
+ color="red",
188
+ )
189
+
190
+ rendered_html: str = viewer.render()
191
+
192
+ assert rendered_html.startswith('<meta charset="utf-8">')
193
+ assert "var widget = new Cesium.Viewer" in rendered_html
194
+ assert (
195
+ 'widget.entities.add({position: Cesium.Cartesian3.fromDegrees(0.0, 0.0, 292863.0000000001), label: {text: "Hello, World!", fillColor: Cesium.Color.RED, scale: 1.0}});'
196
+ in rendered_html
197
+ )
198
+ assert rendered_html.endswith("</script>")
@@ -0,0 +1,136 @@
1
+ # Apache License 2.0
2
+
3
+ import pytest
4
+
5
+ from ostk.physics.time import Instant
6
+ from ostk.physics.coordinate import Frame
7
+
8
+ from ostk.astrodynamics.trajectory.state import CoordinateBroker, CoordinateSubset
9
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianAcceleration
10
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianPosition
11
+ from ostk.astrodynamics.trajectory.state.coordinate_subset import CartesianVelocity
12
+
13
+
14
+ @pytest.fixture
15
+ def name() -> str:
16
+ return "Cartesian Acceleration"
17
+
18
+
19
+ @pytest.fixture
20
+ def cartesian_position() -> CartesianPosition:
21
+ return CartesianPosition.default()
22
+
23
+
24
+ @pytest.fixture
25
+ def cartesian_velocity() -> CartesianVelocity:
26
+ return CartesianVelocity.default()
27
+
28
+
29
+ @pytest.fixture
30
+ def cartesian_acceleration() -> CartesianAcceleration:
31
+ return CartesianAcceleration.default()
32
+
33
+
34
+ @pytest.fixture
35
+ def coordinate_subsets(
36
+ cartesian_acceleration: CartesianAcceleration,
37
+ ) -> list[CoordinateSubset]:
38
+ return [cartesian_acceleration]
39
+
40
+
41
+ @pytest.fixture
42
+ def instant() -> Instant:
43
+ return Instant.J2000()
44
+
45
+
46
+ @pytest.fixture
47
+ def frame() -> Frame:
48
+ return Frame.GCRF()
49
+
50
+
51
+ @pytest.fixture
52
+ def coordinate_broker(
53
+ coordinate_subsets: list[CoordinateSubset],
54
+ ) -> CoordinateBroker:
55
+ return CoordinateBroker(coordinate_subsets)
56
+
57
+
58
+ @pytest.fixture
59
+ def coordinates() -> list[float]:
60
+ return [9.81, 0.0, 0.0]
61
+
62
+
63
+ @pytest.fixture
64
+ def another_coordinates() -> list[float]:
65
+ return [0.0, 9.81, 0.0]
66
+
67
+
68
+ class TestCartesianAcceleration:
69
+ def test_constructor(
70
+ self,
71
+ cartesian_position: CartesianPosition,
72
+ cartesian_velocity: CartesianVelocity,
73
+ name: str,
74
+ ):
75
+ assert (
76
+ CartesianAcceleration(cartesian_position, cartesian_velocity, name)
77
+ is not None
78
+ )
79
+
80
+ def test_add(
81
+ self,
82
+ cartesian_acceleration: CartesianAcceleration,
83
+ instant: Instant,
84
+ frame: Frame,
85
+ coordinates: list[float],
86
+ another_coordinates: list[float],
87
+ coordinate_broker: CoordinateBroker,
88
+ ):
89
+ assert all(
90
+ cartesian_acceleration.add(
91
+ instant, coordinates, another_coordinates, frame, coordinate_broker
92
+ )
93
+ == [9.81, 9.81, 0.0]
94
+ )
95
+
96
+ def test_subtract(
97
+ self,
98
+ cartesian_acceleration: CartesianAcceleration,
99
+ instant: Instant,
100
+ frame: Frame,
101
+ coordinates: list[float],
102
+ another_coordinates: list[float],
103
+ coordinate_broker: CoordinateBroker,
104
+ ):
105
+ assert all(
106
+ cartesian_acceleration.subtract(
107
+ instant, coordinates, another_coordinates, frame, coordinate_broker
108
+ )
109
+ == [9.81, -9.81, 0.0]
110
+ )
111
+
112
+ def test_in_frame(
113
+ self,
114
+ cartesian_acceleration: CartesianAcceleration,
115
+ instant: Instant,
116
+ frame: Frame,
117
+ coordinates: list[float],
118
+ coordinate_broker: CoordinateBroker,
119
+ ):
120
+ assert (
121
+ cartesian_acceleration.in_frame(
122
+ instant, coordinates, frame, frame, coordinate_broker
123
+ )
124
+ is not None
125
+ )
126
+
127
+ with pytest.raises(RuntimeError):
128
+ cartesian_acceleration.in_frame(
129
+ instant, coordinates, frame, Frame.ITRF(), coordinate_broker
130
+ )
131
+
132
+ def test_default(self):
133
+ assert CartesianAcceleration.default() is not None
134
+
135
+ def test_thrust_acceleration(self):
136
+ assert CartesianAcceleration.thrust_acceleration() is not None
@@ -44,3 +44,12 @@ class TestCoordinateSubset:
44
44
 
45
45
  def test_mass(self):
46
46
  assert CoordinateSubset.mass() is not None
47
+
48
+ def test_surface_area(self):
49
+ assert CoordinateSubset.surface_area() is not None
50
+
51
+ def test_drag_coefficient(self):
52
+ assert CoordinateSubset.drag_coefficient() is not None
53
+
54
+ def test_mass_flow_rate(self):
55
+ assert CoordinateSubset.mass_flow_rate() is not None