open-space-toolkit-astrodynamics 12.0.1__py310-none-manylinux2014_x86_64.whl → 12.2.0__py310-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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: open-space-toolkit-astrodynamics
3
- Version: 12.0.1
3
+ Version: 12.2.0
4
4
  Summary: Orbit, attitude, access.
5
5
  Author: Open Space Collective
6
6
  Author-email: contact@open-space-collective.org
@@ -11,10 +11,10 @@ Classifier: Programming Language :: Python :: 3
11
11
  Classifier: License :: OSI Approved :: Apache Software License
12
12
  Classifier: Operating System :: POSIX :: Linux
13
13
  Description-Content-Type: text/markdown
14
- Requires-Dist: open-space-toolkit-core ~=4.0
14
+ Requires-Dist: open-space-toolkit-core ~=4.1
15
15
  Requires-Dist: open-space-toolkit-io ~=4.0
16
- Requires-Dist: open-space-toolkit-mathematics ~=4.0
17
- Requires-Dist: open-space-toolkit-physics ~=9.0
16
+ Requires-Dist: open-space-toolkit-mathematics ~=4.2
17
+ Requires-Dist: open-space-toolkit-physics ~=10.1
18
18
 
19
19
  # Open Space Toolkit ▸ Astrodynamics
20
20
 
@@ -1,16 +1,16 @@
1
1
  ostk/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
2
- ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-310-x86_64-linux-gnu.so,sha256=BfVGsn5nhBe4kRaRSNV8kNAYj_bA2CDdHhTPox0pCPI,2422720
2
+ ostk/astrodynamics/OpenSpaceToolkitAstrodynamicsPy.cpython-310-x86_64-linux-gnu.so,sha256=bhOEl5LpzdX_dSO1iBYhvGu_-RoWb5OXaxRtWRKhiFc,2447328
3
3
  ostk/astrodynamics/__init__.py,sha256=3gWyqFIbhAfcdeMhmfBPQPlPQTmaOzm-6flkJe745Zk,251
4
4
  ostk/astrodynamics/converters.py,sha256=Ld-DLTaqg7pBkIJAcYeoaA-sDOQbR_uksRR-lg9dfXo,3278
5
5
  ostk/astrodynamics/dataframe.py,sha256=njimcfT2cvnSOp9eBR1Ej-LuYpXbVieAVEBk2tYW4Vg,18761
6
6
  ostk/astrodynamics/display.py,sha256=KiEGsjNftQfoUe-HfZeYpQQQ4TkaEnxtEl6p5_LX5f0,6303
7
- ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.12,sha256=gie8faYXnNGJladdNg6RIYnSuZ7HRQ0175QZNZxihCs,84588664
7
+ ostk/astrodynamics/libopen-space-toolkit-astrodynamics.so.12,sha256=jIwo6Hr9NJHfof3i6Or_ZYBhR3Zej8sqy6uQOHMAhR4,87107488
8
8
  ostk/astrodynamics/utilities.py,sha256=f0ySFhD6X9jhAZW1hLnbLVEOuy3QgVq2C6k4m8MFGYA,6963
9
9
  ostk/astrodynamics/viewer.py,sha256=8UxqsvU5wui7gPUwxXaKcIB-509NJiih9Df3mQgXyXY,11776
10
10
  ostk/astrodynamics/pytrajectory/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
11
- ostk/astrodynamics/pytrajectory/pystate.py,sha256=qtGofajIODveyy_g_lEeBqJQ1GddqmzRBVNCExF8pdk,5734
11
+ ostk/astrodynamics/pytrajectory/pystate.py,sha256=IoR4AIqZe7KuvxrNbnpPtQLC-bY1RPxUlSB8TbfmANg,6681
12
12
  ostk/astrodynamics/test/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
13
- ostk/astrodynamics/test/conftest.py,sha256=fsdUQnLxyfvBzfaSCkgipkPIhkPHchQqbeAro1pF648,2717
13
+ ostk/astrodynamics/test/conftest.py,sha256=stmQOt7UXjBlXKJzNN6RkS2miv1xXSOX-YNpFhaHTqI,2771
14
14
  ostk/astrodynamics/test/test_access.py,sha256=MCBsUPtuVm7NgHZR0z0DpWnPZ_qBu4aRhLI2PnRNUYs,3940
15
15
  ostk/astrodynamics/test/test_converters.py,sha256=mFpDD0YM8o356lj91GGIwYdMk2ut6xZFV3uYcgZepMY,8744
16
16
  ostk/astrodynamics/test/test_dataframe.py,sha256=IJMOODzTVYtiPxekmltH6lOMArPXbHwSEAl-jg0Ab2g,28414
@@ -18,7 +18,7 @@ ostk/astrodynamics/test/test_display.py,sha256=Ykvw2rUWWw8jsX0Suy11X27bHjwm_ira_
18
18
  ostk/astrodynamics/test/test_event_condition.py,sha256=mhMTH7wAoYFWRYt_8l2d1vjNPrFhVjMAEET4INLCVXY,1472
19
19
  ostk/astrodynamics/test/test_import.py,sha256=py_hALBR0IYuUzv9dfgQZzrrLHJIpnyKvt3Oi1XBqCg,1251
20
20
  ostk/astrodynamics/test/test_root_solver.py,sha256=hQ8O6g-WP49gZH_H3Rdufv0F0gQorpzJyIcjBGGUQ34,1831
21
- ostk/astrodynamics/test/test_trajectory.py,sha256=WC9X-O_prHeVLIZlmmYzgkskrs5ZwvmOfhz8yth2lgI,1345
21
+ ostk/astrodynamics/test/test_trajectory.py,sha256=0sgGPkMFy-u-33z6SF-sTvaBb_NU7OvaeMTVF6wevfY,3148
22
22
  ostk/astrodynamics/test/test_utilities.py,sha256=xmRt-5z9-FFYTMQxBpjGrcKP39trbOiH-NLxGcTWOJE,3048
23
23
  ostk/astrodynamics/test/test_viewer.py,sha256=rbVAiclzBZ1bS4Zdh4xUNJ-STCN4G0O7Gr8suSPJrSc,3986
24
24
  ostk/astrodynamics/test/access/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
@@ -45,7 +45,7 @@ ostk/astrodynamics/test/event_condition/test_logical_condition.py,sha256=09h5TYW
45
45
  ostk/astrodynamics/test/event_condition/test_real_condition.py,sha256=tle6HVzMFMIIkfRY7CuaA0mPtw3riJBG_JQkc1L0dpk,1374
46
46
  ostk/astrodynamics/test/flight/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
47
47
  ostk/astrodynamics/test/flight/test_maneuver.py,sha256=6LhnNhaiwId-IveUraHnhx8dYxeOgzntP_WPtv9GFjQ,6197
48
- ostk/astrodynamics/test/flight/test_profile.py,sha256=ZuK2FWWnFzvnJsMgZYeQyG6G0yolUihL4TjGt0BMrZI,7518
48
+ ostk/astrodynamics/test/flight/test_profile.py,sha256=-MI7mtkvJdq7eFr6terpD-2na306VRzYBTJ36qigjB4,7518
49
49
  ostk/astrodynamics/test/flight/test_system.py,sha256=MVaE7lJYisH4vmJPD-G-Hw4wNj-Xe8yMksgu8IXCLvg,1322
50
50
  ostk/astrodynamics/test/flight/system/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
51
51
  ostk/astrodynamics/test/flight/system/test_propulsion_system.py,sha256=jLUC74YjIQz7APr-kQcdYRYiKm8lfequjosptG29kmI,1964
@@ -64,7 +64,7 @@ ostk/astrodynamics/test/trajectory/test_orbit.py,sha256=iKVgScEo1osMIXjON4ToURCg
64
64
  ostk/astrodynamics/test/trajectory/test_propagator.py,sha256=dG31S5FY0NjJ5bnisqJ_HdL7amj_AZAWWLiOmdHfJAc,14233
65
65
  ostk/astrodynamics/test/trajectory/test_segment.py,sha256=ACVMYvjlTyCQHZ2-hFEurK08-LQxt6VlcGTMOrgDHaE,9333
66
66
  ostk/astrodynamics/test/trajectory/test_sequence.py,sha256=gswWqEBTYvbi5TQjF0DNPkAj5COo9Nb9IK7TdwJ_5C0,12882
67
- ostk/astrodynamics/test/trajectory/test_state.py,sha256=IRtdEyiYHCdBXSRmNEKZy355s7i8STYddOzQAMXh5EY,10805
67
+ ostk/astrodynamics/test/trajectory/test_state.py,sha256=rgJ4lHgp71axKdvdGSkk0sQbQ9i00gBi8ewLxXCojmo,13316
68
68
  ostk/astrodynamics/test/trajectory/test_state_builder.py,sha256=PSlXtmGURCrlf0w50tn3dEBRo6p0x4NmIF9gJsNOR3k,4782
69
69
  ostk/astrodynamics/test/trajectory/orbit/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
70
70
  ostk/astrodynamics/test/trajectory/orbit/test_model.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
@@ -83,7 +83,7 @@ ostk/astrodynamics/test/trajectory/orbit/models/kepler/__init__.py,sha256=epnVn2
83
83
  ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean.py,sha256=NvtwHJzZvfp8LZGcRhWU1kJ_rdLCim8GBXUbzMrPjjc,1542
84
84
  ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_long.py,sha256=c-8M4py0LEDHoRuc-ukmUyGYN7PcSDWFKY2Bh1KFNRk,2468
85
85
  ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_brouwer_lyddane_mean_short.py,sha256=rLA6Ud41SFZSWZiOzGFU1FBPlzv6-c6eP8Ly-bqsFKo,2485
86
- ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py,sha256=H42bc4SkXl7tvEMDwAdPImiJpFPBRjSD_Npsmxq4xaY,4778
86
+ ostk/astrodynamics/test/trajectory/orbit/models/kepler/test_coe.py,sha256=inXqK6zD3VgxvBZg-bh3AzLTh6q12hxJ8iiAyIodYMs,5319
87
87
  ostk/astrodynamics/test/trajectory/orbit/models/sgp4/__init__.py,sha256=epnVn2PwdQkUDZ1msqBRO5nEZIOUBIq-IfK3IlNPijE,21
88
88
  ostk/astrodynamics/test/trajectory/orbit/models/sgp4/test_tle.py,sha256=jkyRr5NJQMaSpI3ey7cKcH0E-BlalaUlf_mZPYTSow8,11482
89
89
  ostk/astrodynamics/test/trajectory/state/test_coordinate_broker.py,sha256=ho5FBfB3IvIjfQl7EYoIN1KBuH9lu76IiNMuweq8cqg,2844
@@ -93,8 +93,8 @@ ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_angular_velocity
93
93
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_attitude_quaternion.py,sha256=UEu9ApzQLmT87eeISw6_gcHTlX-4b2scIvHz-uE1p_c,393
94
94
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_position.py,sha256=XvHdk1KjacTwtkgx2jUAc9I9N3nvjPDv03FAanpv8jQ,2702
95
95
  ostk/astrodynamics/test/trajectory/state/coordinate_subset/test_cartesian_velocity.py,sha256=-kd5TZO5TICihbkqDTew2i_tDpggdpe3Yf23046FATM,3057
96
- open_space_toolkit_astrodynamics-12.0.1.dist-info/METADATA,sha256=Uz-7aAVpAbeRD9LZcYvamuARdgSEJa9ZbMi3GzE7Gjk,1916
97
- open_space_toolkit_astrodynamics-12.0.1.dist-info/WHEEL,sha256=EfzGwk6HazeuFg6dmyxdAa9hqpFBtmJ_haGsqhCVSCQ,110
98
- open_space_toolkit_astrodynamics-12.0.1.dist-info/top_level.txt,sha256=zOR18699uDYnafgarhL8WU_LmTZY_5NVqutv-flp_x4,5
99
- open_space_toolkit_astrodynamics-12.0.1.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
100
- open_space_toolkit_astrodynamics-12.0.1.dist-info/RECORD,,
96
+ open_space_toolkit_astrodynamics-12.2.0.dist-info/METADATA,sha256=ucBrKvH3LneOcECxN2_fL-UgEpSRSXsYkC0N4H_vxew,1917
97
+ open_space_toolkit_astrodynamics-12.2.0.dist-info/WHEEL,sha256=EfzGwk6HazeuFg6dmyxdAa9hqpFBtmJ_haGsqhCVSCQ,110
98
+ open_space_toolkit_astrodynamics-12.2.0.dist-info/top_level.txt,sha256=zOR18699uDYnafgarhL8WU_LmTZY_5NVqutv-flp_x4,5
99
+ open_space_toolkit_astrodynamics-12.2.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
100
+ open_space_toolkit_astrodynamics-12.2.0.dist-info/RECORD,,
@@ -54,13 +54,16 @@ def from_dict(data: dict) -> State:
54
54
  - 'vy'/'vy_eci'/'vy_ecef': The y-coordinate of the velocity.
55
55
  - 'vz'/'vz_eci'/'vz_ecef': The z-coordinate of the velocity.
56
56
  - 'frame': The frame of the state. Required if 'rx', 'ry', 'rz', 'vx', 'vy', 'vz' are provided.
57
- - 'q_B_ECI_x': The x-coordinate of the quaternion.
58
- - 'q_B_ECI_y': The y-coordinate of the quaternion.
59
- - 'q_B_ECI_z': The z-coordinate of the quaternion.
60
- - 'q_B_ECI_s': The s-coordinate of the quaternion.
61
- - 'w_B_ECI_in_B_x': The x-coordinate of the angular velocity.
62
- - 'w_B_ECI_in_B_y': The y-coordinate of the angular velocity.
63
- - 'w_B_ECI_in_B_z': The z-coordinate of the angular velocity.
57
+ - 'q_B_ECI_x': The x-coordinate of the quaternion. Optional.
58
+ - 'q_B_ECI_y': The y-coordinate of the quaternion. Optional.
59
+ - 'q_B_ECI_z': The z-coordinate of the quaternion. Optional.
60
+ - 'q_B_ECI_s': The s-coordinate of the quaternion. Optional.
61
+ - 'w_B_ECI_in_B_x': The x-coordinate of the angular velocity. Optional.
62
+ - 'w_B_ECI_in_B_y': The y-coordinate of the angular velocity. Optional.
63
+ - 'w_B_ECI_in_B_z': The z-coordinate of the angular velocity. Optional.
64
+ - 'drag_coefficient'/'cd': The drag coefficient. Optional.
65
+ - 'cross_sectional_area'/'surface_area': The cross-sectional area. Optional.
66
+ - 'mass': The mass. Optional.
64
67
 
65
68
 
66
69
  Args:
@@ -184,6 +187,27 @@ def from_dict(data: dict) -> State:
184
187
  ],
185
188
  )
186
189
 
190
+ if "drag_coefficient" in data or "cd" in data:
191
+ coordinate_subsets.append(CoordinateSubset.drag_coefficient())
192
+ coordinates = np.append(
193
+ coordinates,
194
+ data.get("drag_coefficient", data.get("cd")),
195
+ )
196
+
197
+ if "cross_sectional_area" in data or "surface_area" in data:
198
+ coordinate_subsets.append(CoordinateSubset.surface_area())
199
+ coordinates = np.append(
200
+ coordinates,
201
+ data.get("cross_sectional_area", data.get("surface_area")),
202
+ )
203
+
204
+ if "mass" in data:
205
+ coordinate_subsets.append(CoordinateSubset.mass())
206
+ coordinates = np.append(
207
+ coordinates,
208
+ data["mass"],
209
+ )
210
+
187
211
  return State(
188
212
  instant=instant,
189
213
  coordinates=coordinates,
@@ -115,5 +115,5 @@ def aer(azimuth: Angle, elevation: Angle, range: Length) -> LLA:
115
115
 
116
116
 
117
117
  @pytest.fixture
118
- def trajectory(position: Position) -> Trajectory:
119
- return Trajectory.position(position)
118
+ def trajectory(position: Position, instant_1: Instant) -> Trajectory:
119
+ return Trajectory.position(position.in_frame(Frame.ITRF(), instant_1))
@@ -172,7 +172,7 @@ class TestProfile:
172
172
  quaternion: Quaternion = Quaternion([0.0, 0.0, 0.0, 1.0], Quaternion.Format.XYZS)
173
173
 
174
174
  trajectory: Trajectory = Trajectory.position(
175
- Position.meters((0.0, 0.0, 0.0), Frame.GCRF())
175
+ Position.meters((0.0, 0.0, 0.0), Frame.ITRF())
176
176
  )
177
177
 
178
178
  profile: Profile = Profile.inertial_pointing(trajectory, quaternion)
@@ -1,40 +1,118 @@
1
1
  # Apache License 2.0
2
2
 
3
- import ostk.mathematics as mathematics
4
-
5
- import ostk.physics as physics
6
-
7
- import ostk.astrodynamics as astrodynamics
8
-
9
- RealInterval = mathematics.object.RealInterval
10
- Quaternion = mathematics.geometry.d3.transformation.rotation.Quaternion
11
- Length = physics.unit.Length
12
- Angle = physics.unit.Angle
13
- DateTime = physics.time.DateTime
14
- Scale = physics.time.Scale
15
- Duration = physics.time.Duration
16
- Instant = physics.time.Instant
17
- Transform = physics.coordinate.Transform
18
- Frame = physics.coordinate.Frame
19
- Axes = physics.coordinate.Axes
20
- DynamicProvider = physics.coordinate.frame.provider.Dynamic
21
- Environment = physics.Environment
22
- Earth = physics.environment.object.celestial.Earth
23
- Trajectory = astrodynamics.Trajectory
24
- Profile = astrodynamics.flight.Profile
25
- SatelliteSystem = astrodynamics.flight.system.SatelliteSystem
26
- Orbit = astrodynamics.trajectory.Orbit
27
- State = astrodynamics.trajectory.State
28
- Pass = astrodynamics.trajectory.orbit.Pass
29
- Kepler = astrodynamics.trajectory.orbit.model.Kepler
30
- COE = astrodynamics.trajectory.orbit.model.kepler.COE
31
- SGP4 = astrodynamics.trajectory.orbit.model.sgp4
32
- Access = astrodynamics.Access
33
-
34
-
35
- def test_trajectory_undefined():
36
- trajectory: Trajectory = Trajectory.undefined()
37
-
38
- assert trajectory is not None
39
- assert isinstance(trajectory, Trajectory)
40
- assert trajectory.is_defined() is False
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
@@ -4,7 +4,9 @@ import pytest
4
4
 
5
5
  from ostk.physics.unit import Length
6
6
  from ostk.physics.unit import Angle
7
+ from ostk.physics.time import Instant
7
8
  from ostk.physics.environment.gravitational import Earth
9
+ from ostk.physics.environment.object.celestial import Sun
8
10
 
9
11
  from ostk.astrodynamics.trajectory.orbit.model.kepler import COE
10
12
 
@@ -140,6 +142,17 @@ class TestCOE:
140
142
  )
141
143
  assert COE.compute_radial_distance(7000.0e3, 0.0, 0.0) is not None
142
144
 
145
+ assert COE.compute_ltan(Angle.degrees(270.0), Instant.J2000()) is not None
146
+ assert (
147
+ COE.compute_ltan(Angle.degrees(270.0), Instant.J2000(), Sun.default())
148
+ is not None
149
+ )
150
+ assert COE.compute_mean_ltan(Angle.degrees(270.0), Instant.J2000()) is not None
151
+ assert (
152
+ COE.compute_mean_ltan(Angle.degrees(270.0), Instant.J2000(), Sun.default())
153
+ is not None
154
+ )
155
+
143
156
  def test_from_SI_vector(
144
157
  self,
145
158
  coe: COE,
@@ -195,6 +195,7 @@ class TestState:
195
195
  assert state is not None
196
196
  assert isinstance(state, State)
197
197
  assert state.get_frame() == Frame.GCRF()
198
+ assert state.get_size() == 6
198
199
 
199
200
  def test_from_dict_with_ecef_coordinates(self):
200
201
  data = {
@@ -212,6 +213,7 @@ class TestState:
212
213
  assert state is not None
213
214
  assert isinstance(state, State)
214
215
  assert state.get_frame() == Frame.ITRF()
216
+ assert state.get_size() == 6
215
217
 
216
218
  def test_from_dict_with_generic_coordinates(self):
217
219
  data = {
@@ -230,6 +232,7 @@ class TestState:
230
232
  assert state is not None
231
233
  assert isinstance(state, State)
232
234
  assert state.get_frame() == Frame.GCRF()
235
+ assert state.get_size() == 6
233
236
 
234
237
  with pytest.raises(
235
238
  ValueError, match="Frame must be provided for generic columns."
@@ -294,6 +297,7 @@ class TestState:
294
297
  assert state is not None
295
298
  assert isinstance(state, State)
296
299
  assert state.get_frame() == Frame.GCRF()
300
+ assert state.get_size() == 10
297
301
 
298
302
  def test_from_dict_with_angular_velocity(self):
299
303
  data = {
@@ -313,7 +317,95 @@ class TestState:
313
317
 
314
318
  assert state is not None
315
319
  assert isinstance(state, State)
316
- assert state.get_frame() == Frame.GCRF()
320
+ assert state.get_size() == 9
321
+
322
+ def test_from_dict_with_drag_coefficient(self):
323
+ data = {
324
+ "timestamp": datetime.now(timezone.utc).isoformat(),
325
+ "rx_eci": 7000.0,
326
+ "ry_eci": 0.0,
327
+ "rz_eci": 0.0,
328
+ "vx_eci": 0.0,
329
+ "vy_eci": 7.5,
330
+ "vz_eci": 0.0,
331
+ "drag_coefficient": 2.2,
332
+ }
333
+
334
+ state: State = State.from_dict(data)
335
+
336
+ assert state is not None
337
+ assert isinstance(state, State)
338
+ assert state.get_size() == 7
339
+
340
+ data = {
341
+ "timestamp": datetime.now(timezone.utc).isoformat(),
342
+ "rx_eci": 7000.0,
343
+ "ry_eci": 0.0,
344
+ "rz_eci": 0.0,
345
+ "vx_eci": 0.0,
346
+ "vy_eci": 7.5,
347
+ "vz_eci": 0.0,
348
+ "cd": 2.2,
349
+ }
350
+
351
+ state: State = State.from_dict(data)
352
+
353
+ assert state is not None
354
+ assert isinstance(state, State)
355
+ assert state.get_size() == 7
356
+
357
+ def test_from_dict_with_surface_area(self):
358
+ data = {
359
+ "timestamp": datetime.now(timezone.utc).isoformat(),
360
+ "rx_eci": 7000.0,
361
+ "ry_eci": 0.0,
362
+ "rz_eci": 0.0,
363
+ "vx_eci": 0.0,
364
+ "vy_eci": 7.5,
365
+ "vz_eci": 0.0,
366
+ "surface_area": 2.2,
367
+ }
368
+
369
+ state: State = State.from_dict(data)
370
+
371
+ assert state is not None
372
+ assert isinstance(state, State)
373
+ assert state.get_size() == 7
374
+
375
+ data = {
376
+ "timestamp": datetime.now(timezone.utc).isoformat(),
377
+ "rx_eci": 7000.0,
378
+ "ry_eci": 0.0,
379
+ "rz_eci": 0.0,
380
+ "vx_eci": 0.0,
381
+ "vy_eci": 7.5,
382
+ "vz_eci": 0.0,
383
+ "cross_sectional_area": 2.2,
384
+ }
385
+
386
+ state: State = State.from_dict(data)
387
+
388
+ assert state is not None
389
+ assert isinstance(state, State)
390
+ assert state.get_size() == 7
391
+
392
+ def test_from_dict_with_mass(self):
393
+ data = {
394
+ "timestamp": datetime.now(timezone.utc).isoformat(),
395
+ "rx_eci": 7000.0,
396
+ "ry_eci": 0.0,
397
+ "rz_eci": 0.0,
398
+ "vx_eci": 0.0,
399
+ "vy_eci": 7.5,
400
+ "vz_eci": 0.0,
401
+ "mass": 2.2,
402
+ }
403
+
404
+ state: State = State.from_dict(data)
405
+
406
+ assert state is not None
407
+ assert isinstance(state, State)
408
+ assert state.get_size() == 7
317
409
 
318
410
  def test_comparators(self, state: State):
319
411
  assert (state == state) is True