keplemon 0.1.9__cp313-cp313-win_amd64.whl → 2.0.2__cp313-cp313-win_amd64.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.
- keplemon/__init__.py +28 -10
- keplemon/__init__.pyi +24 -0
- keplemon/_keplemon.cp313-win_amd64.pyd +0 -0
- keplemon/bodies.pyi +190 -19
- keplemon/catalogs.pyi +6 -5
- keplemon/elements.py +16 -0
- keplemon/elements.pyi +161 -5
- keplemon/estimation.pyi +7 -4
- keplemon/events.py +12 -1
- keplemon/events.pyi +77 -3
- keplemon/exceptions.py +5 -0
- keplemon/propagation.py +3 -1
- keplemon/propagation.pyi +8 -0
- keplemon/saal/__init__.py +10 -0
- keplemon/saal/__init__.pyi +562 -0
- keplemon/saal/astro_func_interface.py +71 -0
- keplemon/saal/astro_func_interface.pyi +251 -0
- keplemon/saal/sat_state_interface.py +5 -0
- keplemon/saal/sat_state_interface.pyi +9 -0
- keplemon/saal/sgp4_prop_interface.py +7 -0
- keplemon/saal/sgp4_prop_interface.pyi +9 -0
- keplemon/saal/time_func_interface.py +17 -0
- keplemon/saal/time_func_interface.pyi +70 -0
- keplemon/time.py +25 -9
- keplemon/time.pyi +25 -1
- keplemon-2.0.2.dist-info/METADATA +21 -0
- {keplemon-0.1.9.dist-info → keplemon-2.0.2.dist-info}/RECORD +30 -21
- {keplemon-0.1.9.dist-info → keplemon-2.0.2.dist-info}/WHEEL +1 -1
- keplemon/saal.py +0 -15
- keplemon/saal.pyi +0 -8
- keplemon-0.1.9.dist-info/METADATA +0 -101
- /keplemon/{SGP4_Open_License.txt → assets/SGP4_Open_License.txt} +0 -0
- {keplemon-0.1.9.dist-info → keplemon-2.0.2.dist-info}/entry_points.txt +0 -0
keplemon/__init__.py
CHANGED
|
@@ -1,17 +1,35 @@
|
|
|
1
|
-
from keplemon._keplemon.
|
|
2
|
-
from keplemon._keplemon import
|
|
1
|
+
from keplemon._keplemon.saal.time_func_interface import load_time_constants # type: ignore
|
|
2
|
+
from keplemon._keplemon import ( # type: ignore
|
|
3
|
+
get_thread_count,
|
|
4
|
+
set_thread_count,
|
|
5
|
+
set_license_file_path,
|
|
6
|
+
get_license_file_path,
|
|
7
|
+
set_jpl_ephemeris_file_path,
|
|
8
|
+
)
|
|
3
9
|
from pathlib import Path
|
|
4
|
-
from shutil import copyfile
|
|
5
10
|
|
|
6
|
-
current_dir = Path(__file__).parent
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
PACKAGE_DIRECTORY = Path(__file__).parent
|
|
13
|
+
ASSETS_DIRECTORY = PACKAGE_DIRECTORY / "assets"
|
|
14
|
+
|
|
15
|
+
# Set the license file directory to the package directory
|
|
16
|
+
set_license_file_path(ASSETS_DIRECTORY.as_posix())
|
|
12
17
|
|
|
13
18
|
# Load the time constants from the assets directory
|
|
14
|
-
TIME_CONSTANTS_PATH =
|
|
19
|
+
TIME_CONSTANTS_PATH = ASSETS_DIRECTORY / "time_constants.dat"
|
|
15
20
|
load_time_constants(TIME_CONSTANTS_PATH.as_posix())
|
|
16
21
|
|
|
17
|
-
|
|
22
|
+
# Load the JPL path
|
|
23
|
+
JPL_EPHEMERIS_PATH = ASSETS_DIRECTORY / "JPLcon_1950_2050.405"
|
|
24
|
+
set_jpl_ephemeris_file_path(JPL_EPHEMERIS_PATH.as_posix())
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"get_thread_count",
|
|
28
|
+
"set_thread_count",
|
|
29
|
+
"TIME_CONSTANTS_PATH",
|
|
30
|
+
"JPL_EPHEMERIS_PATH",
|
|
31
|
+
"set_license_file_path",
|
|
32
|
+
"PACKAGE_DIRECTORY",
|
|
33
|
+
"ASSETS_DIRECTORY",
|
|
34
|
+
"get_license_file_path",
|
|
35
|
+
]
|
keplemon/__init__.pyi
CHANGED
|
@@ -28,3 +28,27 @@ Path to the default time constants file required by the SAAL binaries
|
|
|
28
28
|
!!! warning
|
|
29
29
|
This path should never be modified and is only exposed to allow inspection of current data.
|
|
30
30
|
"""
|
|
31
|
+
|
|
32
|
+
#: Path to the parent directory of the package
|
|
33
|
+
PACKAGE_DIRECTORY: Path
|
|
34
|
+
"""Path to the parent directory of the package"""
|
|
35
|
+
|
|
36
|
+
#: Path to the assets directory containing supporting data files for the package
|
|
37
|
+
ASSETS_DIRECTORY: Path
|
|
38
|
+
"""Path to the assets directory containing supporting data files for the package"""
|
|
39
|
+
|
|
40
|
+
def set_license_file_path(path: str) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Set the path to the license file required by the SAAL binaries
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
path: Path to the SGP4 license file
|
|
46
|
+
"""
|
|
47
|
+
...
|
|
48
|
+
|
|
49
|
+
def get_license_file_path() -> str:
|
|
50
|
+
"""
|
|
51
|
+
Returns:
|
|
52
|
+
Path to the SGP4 license file
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
Binary file
|
keplemon/bodies.pyi
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
# flake8: noqa
|
|
2
|
-
from keplemon.elements import
|
|
2
|
+
from keplemon.elements import (
|
|
3
|
+
TLE,
|
|
4
|
+
CartesianState,
|
|
5
|
+
Ephemeris,
|
|
6
|
+
KeplerianState,
|
|
7
|
+
GeodeticPosition,
|
|
8
|
+
OrbitPlotData,
|
|
9
|
+
TopocentricElements,
|
|
10
|
+
RelativeState,
|
|
11
|
+
BoreToBodyAngles,
|
|
12
|
+
)
|
|
3
13
|
from keplemon.catalogs import TLECatalog
|
|
4
14
|
from keplemon.time import Epoch, TimeSpan
|
|
5
|
-
from keplemon.events import CloseApproach, CloseApproachReport
|
|
15
|
+
from keplemon.events import CloseApproach, CloseApproachReport, HorizonAccessReport, FieldOfViewReport
|
|
16
|
+
from keplemon.propagation import ForceProperties
|
|
17
|
+
from keplemon.enums import ReferenceFrame
|
|
6
18
|
|
|
7
19
|
class Earth:
|
|
8
20
|
@staticmethod
|
|
@@ -17,16 +29,27 @@ class Earth:
|
|
|
17
29
|
def get_kem() -> float: ...
|
|
18
30
|
|
|
19
31
|
class Satellite:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
|
|
33
|
+
id: str
|
|
34
|
+
"""Unique identifier for the satellite."""
|
|
35
|
+
|
|
36
|
+
norad_id: int
|
|
37
|
+
"""Number corresponding to the satellite's NORAD catalog ID.
|
|
26
38
|
"""
|
|
39
|
+
|
|
40
|
+
force_properties: ForceProperties
|
|
41
|
+
"""Force properties of the satellite used for propagation"""
|
|
42
|
+
|
|
27
43
|
name: str | None
|
|
28
44
|
"""Human-readable name of the satellite"""
|
|
29
45
|
|
|
46
|
+
keplerian_state: KeplerianState | None
|
|
47
|
+
"""Keplerian state of the satellite at the epoch of the TLE, if available"""
|
|
48
|
+
|
|
49
|
+
geodetic_position: GeodeticPosition | None
|
|
50
|
+
"""Geodetic position of the satellite at the epoch of the TLE, if available"""
|
|
51
|
+
|
|
52
|
+
def __init__(self) -> None: ...
|
|
30
53
|
@classmethod
|
|
31
54
|
def from_tle(cls, tle: TLE) -> Satellite:
|
|
32
55
|
"""
|
|
@@ -59,11 +82,52 @@ class Satellite:
|
|
|
59
82
|
"""
|
|
60
83
|
...
|
|
61
84
|
|
|
85
|
+
def get_relative_state_at_epoch(self, other: Satellite, epoch: Epoch) -> RelativeState | None:
|
|
86
|
+
"""
|
|
87
|
+
Calculate the relative state between this satellite and another satellite at a given epoch.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
other: Secondary satellite to calculate the relative state against
|
|
91
|
+
epoch: UTC epoch at which the relative state will be calculated
|
|
92
|
+
"""
|
|
93
|
+
...
|
|
94
|
+
|
|
95
|
+
def get_body_angles_at_epoch(self, other: Satellite, epoch: Epoch) -> BoreToBodyAngles | None:
|
|
96
|
+
"""
|
|
97
|
+
Calculate the bore-to-body angles between this satellite and another satellite at a given epoch.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
other: Secondary satellite to calculate the bore-to-body angles against
|
|
101
|
+
epoch: UTC epoch at which the bore-to-body angles will be calculated
|
|
102
|
+
"""
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
def get_plot_data(self, start: Epoch, end: Epoch, step: TimeSpan) -> OrbitPlotData | None: ...
|
|
106
|
+
def get_observatory_access_report(
|
|
107
|
+
self,
|
|
108
|
+
observatories: list[Observatory],
|
|
109
|
+
start: Epoch,
|
|
110
|
+
end: Epoch,
|
|
111
|
+
min_el: float,
|
|
112
|
+
min_duration: TimeSpan,
|
|
113
|
+
) -> HorizonAccessReport | None:
|
|
114
|
+
"""
|
|
115
|
+
Calculate horizon access from multiple observatories to this satellite.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
observatories: List of observatories to check for horizon access
|
|
119
|
+
start: UTC epoch of the start of the report
|
|
120
|
+
end: UTC epoch of the end of the report
|
|
121
|
+
min_el: Minimum elevation angle in **_degrees_**
|
|
122
|
+
min_duration: Minimum duration of access
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Horizon access report containing accesses from all observatories to the satellite,
|
|
126
|
+
or None if the satellite ephemeris cannot be generated
|
|
127
|
+
"""
|
|
128
|
+
...
|
|
129
|
+
|
|
62
130
|
class Constellation:
|
|
63
|
-
"""
|
|
64
|
-
Args:
|
|
65
|
-
name: Identifier of the constellation
|
|
66
|
-
"""
|
|
67
131
|
|
|
68
132
|
count: int
|
|
69
133
|
"""Number of satellites in the constellation"""
|
|
@@ -71,7 +135,8 @@ class Constellation:
|
|
|
71
135
|
name: str | None
|
|
72
136
|
"""Human-readable name of the constellation"""
|
|
73
137
|
|
|
74
|
-
def __init__(self
|
|
138
|
+
def __init__(self) -> None: ...
|
|
139
|
+
def get_plot_data(self, start: Epoch, end: Epoch, step: TimeSpan) -> dict[str, OrbitPlotData]: ...
|
|
75
140
|
@classmethod
|
|
76
141
|
def from_tle_catalog(cls, tle_catalog: TLECatalog) -> Constellation:
|
|
77
142
|
"""
|
|
@@ -97,7 +162,7 @@ class Constellation:
|
|
|
97
162
|
start: Epoch,
|
|
98
163
|
end: Epoch,
|
|
99
164
|
step: TimeSpan,
|
|
100
|
-
) -> dict[
|
|
165
|
+
) -> dict[str, Ephemeris]:
|
|
101
166
|
"""
|
|
102
167
|
Args:
|
|
103
168
|
start: UTC epoch of the start of the ephemeris
|
|
@@ -152,7 +217,30 @@ class Constellation:
|
|
|
152
217
|
"""
|
|
153
218
|
...
|
|
154
219
|
|
|
155
|
-
def __getitem__(self, satellite_id:
|
|
220
|
+
def __getitem__(self, satellite_id: str) -> Satellite: ...
|
|
221
|
+
def __setitem__(self, satellite_id: str, sat: Satellite) -> None: ...
|
|
222
|
+
def get_horizon_access_report(
|
|
223
|
+
self,
|
|
224
|
+
site: Observatory,
|
|
225
|
+
start: Epoch,
|
|
226
|
+
end: Epoch,
|
|
227
|
+
min_el: float,
|
|
228
|
+
min_duration: TimeSpan,
|
|
229
|
+
) -> HorizonAccessReport:
|
|
230
|
+
"""
|
|
231
|
+
Calculate horizon access to a given observatory.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
site: Observatory to check for horizon access
|
|
235
|
+
start: UTC epoch of the start of the report
|
|
236
|
+
end: UTC epoch of the end of the report
|
|
237
|
+
min_el: Minimum elevation angle in **_degrees_**
|
|
238
|
+
min_duration: Minimum duration of access
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
Horizon access report for the constellation from the observatory
|
|
242
|
+
"""
|
|
243
|
+
...
|
|
156
244
|
|
|
157
245
|
class Sensor:
|
|
158
246
|
"""
|
|
@@ -161,7 +249,9 @@ class Sensor:
|
|
|
161
249
|
angular_noise: Angular noise in **_degrees_**
|
|
162
250
|
"""
|
|
163
251
|
|
|
164
|
-
|
|
252
|
+
id: str
|
|
253
|
+
"""Unique identifier for the sensor."""
|
|
254
|
+
name: str | None
|
|
165
255
|
angular_noise: float
|
|
166
256
|
range_noise: float | None
|
|
167
257
|
"""Range noise in **_kilometers_**"""
|
|
@@ -171,18 +261,19 @@ class Sensor:
|
|
|
171
261
|
|
|
172
262
|
angular_rate_noise: float | None
|
|
173
263
|
"""Angular rate noise in **_degrees per second_**"""
|
|
174
|
-
def __init__(self,
|
|
264
|
+
def __init__(self, angular_noise: float) -> None: ...
|
|
175
265
|
|
|
176
266
|
class Observatory:
|
|
177
267
|
"""
|
|
178
268
|
Args:
|
|
179
|
-
name: Identifier of the observatory
|
|
180
269
|
latitude: Latitude in **_degrees_**
|
|
181
270
|
longitude: Longitude in **_degrees_**
|
|
182
271
|
altitude: Altitude in **_kilometers_**
|
|
183
272
|
"""
|
|
184
273
|
|
|
185
274
|
name: str
|
|
275
|
+
id: str
|
|
276
|
+
"""Unique identifier for the observatory."""
|
|
186
277
|
latitude: float
|
|
187
278
|
longitude: float
|
|
188
279
|
altitude: float
|
|
@@ -190,7 +281,6 @@ class Observatory:
|
|
|
190
281
|
"""List of sensors at the observatory"""
|
|
191
282
|
def __init__(
|
|
192
283
|
self,
|
|
193
|
-
name: str,
|
|
194
284
|
latitude: float,
|
|
195
285
|
longitude: float,
|
|
196
286
|
altitude: float,
|
|
@@ -204,3 +294,84 @@ class Observatory:
|
|
|
204
294
|
TEME Cartesian state of the observatory in **_kilometers_** and **_kilometers per second_**
|
|
205
295
|
"""
|
|
206
296
|
...
|
|
297
|
+
|
|
298
|
+
@classmethod
|
|
299
|
+
def from_cartesian_state(cls, state: CartesianState) -> Observatory:
|
|
300
|
+
"""
|
|
301
|
+
Create an observatory from a Cartesian state.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
state: Cartesian state of the observatory
|
|
305
|
+
|
|
306
|
+
"""
|
|
307
|
+
...
|
|
308
|
+
|
|
309
|
+
def get_theta(self, epoch: Epoch) -> float:
|
|
310
|
+
"""
|
|
311
|
+
Calculate the Greenwich angle plus the observatory longitude at a given epoch.
|
|
312
|
+
|
|
313
|
+
Args:
|
|
314
|
+
epoch: UTC epoch for the calculation
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Greenwich angle plus the observatory longitude in **_radians_**
|
|
318
|
+
"""
|
|
319
|
+
...
|
|
320
|
+
|
|
321
|
+
def get_horizon_access_report(
|
|
322
|
+
self,
|
|
323
|
+
satellite: Satellite,
|
|
324
|
+
start: Epoch,
|
|
325
|
+
end: Epoch,
|
|
326
|
+
min_el: float,
|
|
327
|
+
min_duration: TimeSpan,
|
|
328
|
+
) -> HorizonAccessReport:
|
|
329
|
+
"""
|
|
330
|
+
Calculate horizon access for a satellite from the observatory.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
satellite: Satellite to check for horizon access
|
|
334
|
+
start: UTC epoch of the start of the report
|
|
335
|
+
end: UTC epoch of the end of the report
|
|
336
|
+
min_el: Minimum elevation angle in **_degrees_**
|
|
337
|
+
min_duration: Minimum duration of access in **_seconds_**
|
|
338
|
+
|
|
339
|
+
Returns:
|
|
340
|
+
Horizon access report for the satellite from the observatory
|
|
341
|
+
"""
|
|
342
|
+
...
|
|
343
|
+
|
|
344
|
+
def get_field_of_view_report(
|
|
345
|
+
self,
|
|
346
|
+
epoch: Epoch,
|
|
347
|
+
sensor_direction: TopocentricElements,
|
|
348
|
+
angular_threshold: float,
|
|
349
|
+
sats: Constellation,
|
|
350
|
+
reference_frame: ReferenceFrame,
|
|
351
|
+
) -> FieldOfViewReport:
|
|
352
|
+
"""
|
|
353
|
+
Calculate satellites in the field of view from a given time and direction.
|
|
354
|
+
|
|
355
|
+
Args:
|
|
356
|
+
epoch: UTC epoch of the report
|
|
357
|
+
sensor_direction: Topocentric direction the sensor is pointing
|
|
358
|
+
angular_threshold: Angular threshold in **_degrees_**
|
|
359
|
+
sats: Constellation of satellites to check for being in the field of view
|
|
360
|
+
reference_frame: Reference frame of the output direction elements
|
|
361
|
+
"""
|
|
362
|
+
...
|
|
363
|
+
|
|
364
|
+
def get_topocentric_to_satellite(
|
|
365
|
+
self,
|
|
366
|
+
epoch: Epoch,
|
|
367
|
+
sat: Satellite,
|
|
368
|
+
reference_frame: ReferenceFrame,
|
|
369
|
+
) -> TopocentricElements:
|
|
370
|
+
"""
|
|
371
|
+
Get the topocentric elements of a satellite as seen from the observatory.
|
|
372
|
+
Args:
|
|
373
|
+
epoch: UTC epoch of the observation
|
|
374
|
+
sat: Satellite to observe
|
|
375
|
+
reference_frame: Reference frame of the output direction elements
|
|
376
|
+
"""
|
|
377
|
+
...
|
keplemon/catalogs.pyi
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# flake8: noqa
|
|
2
|
-
from keplemon.elements import TLE
|
|
2
|
+
from keplemon.elements import TLE, OrbitPlotData
|
|
3
3
|
|
|
4
4
|
class TLECatalog:
|
|
5
5
|
count: int
|
|
@@ -8,9 +8,10 @@ class TLECatalog:
|
|
|
8
8
|
@classmethod
|
|
9
9
|
def from_tle_file(cls, filename: str) -> TLECatalog: ...
|
|
10
10
|
def add(self, tle: TLE) -> None: ...
|
|
11
|
-
def get(self, satellite_id:
|
|
12
|
-
def remove(self, satellite_id:
|
|
13
|
-
def keys(self) -> list[
|
|
11
|
+
def get(self, satellite_id: str) -> TLE: ...
|
|
12
|
+
def remove(self, satellite_id: str) -> None: ...
|
|
13
|
+
def keys(self) -> list[str]: ...
|
|
14
14
|
def get_count(self) -> int: ...
|
|
15
15
|
def clear(self) -> None: ...
|
|
16
|
-
def __getitem__(self, satellite_id:
|
|
16
|
+
def __getitem__(self, satellite_id: str) -> TLE: ...
|
|
17
|
+
def get_plot_data(self) -> OrbitPlotData: ...
|
keplemon/elements.py
CHANGED
|
@@ -7,6 +7,14 @@ from keplemon._keplemon.elements import ( # type: ignore
|
|
|
7
7
|
Ephemeris,
|
|
8
8
|
SphericalVector,
|
|
9
9
|
TopocentricElements,
|
|
10
|
+
HorizonState,
|
|
11
|
+
HorizonElements,
|
|
12
|
+
GeodeticPosition,
|
|
13
|
+
OrbitPlotData,
|
|
14
|
+
OrbitPlotState,
|
|
15
|
+
RelativeState,
|
|
16
|
+
BoreToBodyAngles,
|
|
17
|
+
TopocentricState,
|
|
10
18
|
)
|
|
11
19
|
|
|
12
20
|
__all__ = [
|
|
@@ -18,4 +26,12 @@ __all__ = [
|
|
|
18
26
|
"Ephemeris",
|
|
19
27
|
"SphericalVector",
|
|
20
28
|
"TopocentricElements",
|
|
29
|
+
"HorizonState",
|
|
30
|
+
"HorizonElements",
|
|
31
|
+
"GeodeticPosition",
|
|
32
|
+
"OrbitPlotData",
|
|
33
|
+
"OrbitPlotState",
|
|
34
|
+
"RelativeState",
|
|
35
|
+
"BoreToBodyAngles",
|
|
36
|
+
"TopocentricState",
|
|
21
37
|
]
|
keplemon/elements.pyi
CHANGED
|
@@ -2,8 +2,112 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
from keplemon.time import Epoch
|
|
4
4
|
from keplemon.enums import Classification, KeplerianType, ReferenceFrame
|
|
5
|
-
from keplemon.propagation import ForceProperties
|
|
6
5
|
from keplemon.events import CloseApproach
|
|
6
|
+
from keplemon.bodies import Observatory
|
|
7
|
+
|
|
8
|
+
class RelativeState:
|
|
9
|
+
epoch: Epoch
|
|
10
|
+
position: CartesianVector
|
|
11
|
+
velocity: CartesianVector
|
|
12
|
+
origin_satellite_id: str
|
|
13
|
+
secondary_satellite_id: str
|
|
14
|
+
|
|
15
|
+
class BoreToBodyAngles:
|
|
16
|
+
earth_angle: float
|
|
17
|
+
sun_angle: float
|
|
18
|
+
moon_angle: float
|
|
19
|
+
|
|
20
|
+
class OrbitPlotData:
|
|
21
|
+
satellite_id: str
|
|
22
|
+
epochs: list[str]
|
|
23
|
+
semi_major_axes: list[float]
|
|
24
|
+
eccentricities: list[float]
|
|
25
|
+
inclinations: list[float]
|
|
26
|
+
raans: list[float]
|
|
27
|
+
radii: list[float]
|
|
28
|
+
apogee_radii: list[float]
|
|
29
|
+
perigee_radii: list[float]
|
|
30
|
+
latitudes: list[float]
|
|
31
|
+
longitudes: list[float]
|
|
32
|
+
altitudes: list[float]
|
|
33
|
+
|
|
34
|
+
class GeodeticPosition:
|
|
35
|
+
"""
|
|
36
|
+
Args:
|
|
37
|
+
latitude: Latitude in **_degrees_**
|
|
38
|
+
longitude: Longitude in **_degrees_**
|
|
39
|
+
altitude: Altitude in **_kilometers_**
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
latitude: float
|
|
43
|
+
"""Latitude in **_degrees_**"""
|
|
44
|
+
|
|
45
|
+
longitude: float
|
|
46
|
+
"""Longitude in **_degrees_**"""
|
|
47
|
+
|
|
48
|
+
altitude: float
|
|
49
|
+
"""Altitude in **_kilometers_**"""
|
|
50
|
+
|
|
51
|
+
def __init__(self, latitude: float, longitude: float, altitude: float) -> None: ...
|
|
52
|
+
|
|
53
|
+
class HorizonElements:
|
|
54
|
+
"""
|
|
55
|
+
Args:
|
|
56
|
+
range: Range in **_kilometers_**
|
|
57
|
+
az: Azimuth in **_degrees_**
|
|
58
|
+
el: Elevation in **_degrees_**
|
|
59
|
+
range_rate: Range rate in **_kilometers per second_**
|
|
60
|
+
az_rate: Azimuth rate in **_degrees per second_**
|
|
61
|
+
el_rate: Elevation rate in **_degrees per second_**
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
range: float | None
|
|
65
|
+
azimuth: float
|
|
66
|
+
elevation: float
|
|
67
|
+
range_rate: float | None
|
|
68
|
+
azimuth_rate: float | None
|
|
69
|
+
elevation_rate: float | None
|
|
70
|
+
|
|
71
|
+
def __init__(
|
|
72
|
+
self,
|
|
73
|
+
azimuth: float,
|
|
74
|
+
elevation: float,
|
|
75
|
+
) -> None: ...
|
|
76
|
+
|
|
77
|
+
class HorizonState:
|
|
78
|
+
"""
|
|
79
|
+
Args:
|
|
80
|
+
epoch: UTC epoch of the state
|
|
81
|
+
elements: HorizonElements of the state
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
epoch: Epoch
|
|
85
|
+
"""UTC epoch of the state"""
|
|
86
|
+
|
|
87
|
+
elements: HorizonElements
|
|
88
|
+
"""Horizon elements of the state"""
|
|
89
|
+
|
|
90
|
+
range: float | None
|
|
91
|
+
"""Range in **_kilometers_**"""
|
|
92
|
+
|
|
93
|
+
azimuth: float
|
|
94
|
+
"""Azimuth in **_degrees_**"""
|
|
95
|
+
|
|
96
|
+
elevation: float
|
|
97
|
+
"""Elevation in **_degrees_**"""
|
|
98
|
+
|
|
99
|
+
range_rate: float | None
|
|
100
|
+
"""Range rate in **_kilometers per second_**"""
|
|
101
|
+
|
|
102
|
+
azimuth_rate: float | None
|
|
103
|
+
"""Azimuth rate in **_degrees per second_**"""
|
|
104
|
+
|
|
105
|
+
elevation_rate: float | None
|
|
106
|
+
"""Elevation rate in **_degrees per second_**"""
|
|
107
|
+
|
|
108
|
+
def __init__(self, epoch: Epoch, elements: HorizonElements) -> None: ...
|
|
109
|
+
@classmethod
|
|
110
|
+
def from_topocentric_state(cls, state: TopocentricState, observer: Observatory) -> HorizonState: ...
|
|
7
111
|
|
|
8
112
|
class KeplerianElements:
|
|
9
113
|
"""
|
|
@@ -34,7 +138,11 @@ class KeplerianElements:
|
|
|
34
138
|
) -> None: ...
|
|
35
139
|
|
|
36
140
|
class TLE:
|
|
37
|
-
|
|
141
|
+
|
|
142
|
+
norad_id: int
|
|
143
|
+
"""NORAD catalog ID of the satellite"""
|
|
144
|
+
|
|
145
|
+
satellite_id: str
|
|
38
146
|
""""""
|
|
39
147
|
|
|
40
148
|
name: str
|
|
@@ -88,6 +196,13 @@ class TLE:
|
|
|
88
196
|
cartesian_state: CartesianState
|
|
89
197
|
"""TEME cartesian state of the TLE at epoch"""
|
|
90
198
|
|
|
199
|
+
semi_major_axis: float
|
|
200
|
+
"""Average distance from the central body in **_kilometers_**
|
|
201
|
+
|
|
202
|
+
!!! note
|
|
203
|
+
This is always calculated using Brouwer mean motion and will differ slightly from Kozai-computed SMA.
|
|
204
|
+
"""
|
|
205
|
+
|
|
91
206
|
@classmethod
|
|
92
207
|
def from_lines(cls, line_1: str, line_2: str, line_3: str | None = None) -> TLE:
|
|
93
208
|
"""
|
|
@@ -284,8 +399,8 @@ class Ephemeris:
|
|
|
284
399
|
class TopocentricElements:
|
|
285
400
|
"""
|
|
286
401
|
Args:
|
|
287
|
-
|
|
288
|
-
|
|
402
|
+
right_ascension: TEME right ascension in **_degrees_**
|
|
403
|
+
declination: TEME declination in **_degrees_**
|
|
289
404
|
"""
|
|
290
405
|
|
|
291
406
|
range: float | None
|
|
@@ -302,7 +417,7 @@ class TopocentricElements:
|
|
|
302
417
|
declination_rate: float | None
|
|
303
418
|
"""Declination rate in **_degrees per second**"""
|
|
304
419
|
|
|
305
|
-
def __init__(self,
|
|
420
|
+
def __init__(self, right_ascension: float, declination: float) -> None: ...
|
|
306
421
|
@classmethod
|
|
307
422
|
def from_j2000(cls, epoch: Epoch, ra: float, dec: float) -> TopocentricElements:
|
|
308
423
|
"""
|
|
@@ -312,3 +427,44 @@ class TopocentricElements:
|
|
|
312
427
|
dec: J2000 declination in **_degrees_**
|
|
313
428
|
"""
|
|
314
429
|
...
|
|
430
|
+
|
|
431
|
+
class TopocentricState:
|
|
432
|
+
"""
|
|
433
|
+
Args:
|
|
434
|
+
epoch: UTC epoch of the state
|
|
435
|
+
elements: TopocentricElements of the state
|
|
436
|
+
"""
|
|
437
|
+
|
|
438
|
+
epoch: Epoch
|
|
439
|
+
"""UTC epoch of the state"""
|
|
440
|
+
|
|
441
|
+
elements: TopocentricElements
|
|
442
|
+
"""Topocentric elements of the state"""
|
|
443
|
+
|
|
444
|
+
range: float | None
|
|
445
|
+
"""Range in **_kilometers_**"""
|
|
446
|
+
|
|
447
|
+
right_ascension: float
|
|
448
|
+
"""TEME right ascension in **_degrees_**"""
|
|
449
|
+
|
|
450
|
+
declination: float
|
|
451
|
+
"""TEME declination in **_degrees_**"""
|
|
452
|
+
|
|
453
|
+
range_rate: float | None
|
|
454
|
+
"""Range rate in **_kilometers per second_**"""
|
|
455
|
+
|
|
456
|
+
right_ascension_rate: float | None
|
|
457
|
+
"""Right ascension rate in **_degrees per second**"""
|
|
458
|
+
|
|
459
|
+
declination_rate: float | None
|
|
460
|
+
"""Declination rate in **_degrees per second**"""
|
|
461
|
+
|
|
462
|
+
def __init__(self, epoch: Epoch, elements: TopocentricElements) -> None: ...
|
|
463
|
+
@classmethod
|
|
464
|
+
def from_horizon_state(cls, horizon_state: HorizonState, observer: Observatory) -> TopocentricState:
|
|
465
|
+
"""
|
|
466
|
+
Args:
|
|
467
|
+
horizon_state: HorizonState of the target
|
|
468
|
+
observer: Position of the observer
|
|
469
|
+
"""
|
|
470
|
+
...
|
keplemon/estimation.pyi
CHANGED
|
@@ -13,10 +13,13 @@ class Observation:
|
|
|
13
13
|
Args:
|
|
14
14
|
sensor: Sensor that made the observation
|
|
15
15
|
epoch: Time of the observation
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
observed_teme_topocentric: Topocentric elements of the satellite at the time of observation
|
|
17
|
+
observer_teme_position: Position of the observer in TEME coordinates
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
|
+
id: str
|
|
21
|
+
"""Unique identifier for the observation"""
|
|
22
|
+
|
|
20
23
|
sensor: Sensor
|
|
21
24
|
"""Sensor which produced the observation"""
|
|
22
25
|
|
|
@@ -48,8 +51,8 @@ class Observation:
|
|
|
48
51
|
self,
|
|
49
52
|
sensor: Sensor,
|
|
50
53
|
epoch: Epoch,
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
observed_teme_topocentric: TopocentricElements,
|
|
55
|
+
observer_teme_position: CartesianVector,
|
|
53
56
|
) -> None: ...
|
|
54
57
|
def get_residual(self, sat: Satellite) -> ObservationResidual | None:
|
|
55
58
|
"""
|
keplemon/events.py
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
from keplemon._keplemon.events import ( # type: ignore
|
|
2
2
|
CloseApproach,
|
|
3
3
|
CloseApproachReport,
|
|
4
|
+
HorizonAccess,
|
|
5
|
+
HorizonAccessReport,
|
|
6
|
+
FieldOfViewCandidate,
|
|
7
|
+
FieldOfViewReport,
|
|
4
8
|
)
|
|
5
9
|
|
|
6
|
-
__all__ = [
|
|
10
|
+
__all__ = [
|
|
11
|
+
"CloseApproach",
|
|
12
|
+
"CloseApproachReport",
|
|
13
|
+
"HorizonAccess",
|
|
14
|
+
"HorizonAccessReport",
|
|
15
|
+
"FieldOfViewCandidate",
|
|
16
|
+
"FieldOfViewReport",
|
|
17
|
+
]
|