satkit 0.3.0__tar.gz → 0.3.2__tar.gz
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.
- {satkit-0.3.0 → satkit-0.3.2}/Cargo.toml +9 -7
- {satkit-0.3.0/python/satkit.egg-info → satkit-0.3.2}/PKG-INFO +1 -1
- {satkit-0.3.0 → satkit-0.3.2}/pyproject.toml +1 -1
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/__init__.pyi +6 -2
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/satkit.pyi +207 -3
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/satprop.pyi +3 -5
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/utils.pyi +1 -1
- {satkit-0.3.0 → satkit-0.3.2/python/satkit.egg-info}/PKG-INFO +1 -1
- {satkit-0.3.0 → satkit-0.3.2}/python/test/orbitprop_gps_fit.py +33 -27
- {satkit-0.3.0 → satkit-0.3.2}/python/test/test.py +14 -8
- {satkit-0.3.0 → satkit-0.3.2}/src/astrotime.rs +5 -1
- {satkit-0.3.0 → satkit-0.3.2}/src/earthgravity.rs +99 -3
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rk_adaptive.rs +19 -5
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv87.rs +2 -2
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv98.rs +2 -2
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/types.rs +4 -2
- {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/propagator.rs +12 -5
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/mod.rs +7 -11
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pypropagate.rs +0 -1
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pypropresult.rs +66 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pysgp4.rs +18 -12
- {satkit-0.3.0 → satkit-0.3.2}/LICENSE +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/MANIFEST.in +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/README.md +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/docs/source/conf.py +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/__init__.py +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/density.pyi +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/frametransform.pyi +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/jplephem.pyi +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/moon.pyi +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/planets.pyi +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/py.typed +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit/sun.pyi +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit.egg-info/SOURCES.txt +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit.egg-info/dependency_links.txt +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit.egg-info/requires.txt +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/satkit.egg-info/top_level.txt +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/test/download_data.py +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/test/download_from_json.py +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/test/download_testvecs.py +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/python/test/sp3file.py +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/setup.cfg +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/consts.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/duration.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/earth_orientation_params.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/frames.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/frametransform/ierstable.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/frametransform/mod.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/frametransform/qcirs2gcrs.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/itrfcoord.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/jplephem.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/kepler.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/lib.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/lpephem/mod.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/lpephem/moon.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/lpephem/planets.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/lpephem/sun.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/nrlmsise.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/harmonic_oscillator.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/mod.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/nalgebra.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rk_adaptive_settings.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rk_explicit.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkf45.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkts54.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv65.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv65_table.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv87_table.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv98_nointerp.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv98_nointerp_table.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv98_table.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/drag.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/mod.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/point_gravity.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/satproperties.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/satstate.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/settings.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/mod_utils.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyastrotime.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyconsts.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pydensity.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyduration.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyframes.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyframetransform.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pygravity.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyitrfcoord.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyjplephem.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pykepler.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pylpephem_moon.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pylpephem_planets.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pylpephem_sun.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pynrlmsise.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pypropsettings.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyquaternion.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pysatproperties.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pysatstate.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pysolarsystem.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pytle.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyutils.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/dpper.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/dscom.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/dsinit.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/dspace.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/getgravconst.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/initl.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/mod.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/satrec.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/sgp4.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/sgp4_lowlevel.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/sgp4init.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/solarsystem.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/spaceweather.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/tle.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/types.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/utils/datadir.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/utils/download.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/utils/mod.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/utils/skerror.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/utils/test.rs +0 -0
- {satkit-0.3.0 → satkit-0.3.2}/src/utils/update_data.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "satkit"
|
|
3
|
-
version = "0.3.
|
|
3
|
+
version = "0.3.2"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
description = "Satellite Toolkit"
|
|
6
6
|
readme = "README.md"
|
|
@@ -20,23 +20,25 @@ name = "satkit"
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
[dependencies]
|
|
23
|
-
nalgebra = "0.33.0"
|
|
24
|
-
ndarray = "0.15.
|
|
25
|
-
libc = "0.2"
|
|
23
|
+
nalgebra = { version = "0.33.0", features = ["serde-serialize"] }
|
|
24
|
+
ndarray = "0.15.4"
|
|
25
|
+
libc = "0.2.158"
|
|
26
26
|
chrono = "0.4.19"
|
|
27
27
|
cty = "0.2.2"
|
|
28
28
|
num-traits = "0.2"
|
|
29
|
-
thiserror = "1.0"
|
|
29
|
+
thiserror = "1.0.63"
|
|
30
30
|
simba = "0.9"
|
|
31
31
|
once_cell = "1.6.0"
|
|
32
32
|
numpy = { version = "0.21.0", optional = true }
|
|
33
33
|
pyo3 = { version = "0.21", features = ["extension-module"], optional = true }
|
|
34
|
-
ureq = "2.
|
|
34
|
+
ureq = "2.10.1"
|
|
35
35
|
json = "0.12.4"
|
|
36
36
|
process_path = "0.1.4"
|
|
37
|
+
serde = { version = "1.0.130", features = ["derive"] }
|
|
38
|
+
serde-pickle = "1.1.1"
|
|
37
39
|
|
|
38
40
|
[build-dependencies]
|
|
39
|
-
cc = { version = "1.
|
|
41
|
+
cc = { version = "1.1.15", features = ["parallel"] }
|
|
40
42
|
chrono = "0.4.38"
|
|
41
43
|
pyo3-build-config = { version = "0.21", optional = true }
|
|
42
44
|
|
|
@@ -5,7 +5,6 @@ from . import jplephem
|
|
|
5
5
|
from . import frametransform
|
|
6
6
|
from . import moon
|
|
7
7
|
from . import sun
|
|
8
|
-
from . import satprop
|
|
9
8
|
from . import density
|
|
10
9
|
from . import utils
|
|
11
10
|
from . import planets
|
|
@@ -30,8 +29,13 @@ __all__ = [
|
|
|
30
29
|
"moon",
|
|
31
30
|
"sun",
|
|
32
31
|
"planets",
|
|
33
|
-
"satprop",
|
|
34
32
|
"satstate",
|
|
35
33
|
"density",
|
|
36
34
|
"utils",
|
|
35
|
+
"propagate",
|
|
36
|
+
"propsettings",
|
|
37
|
+
"satproperties_static",
|
|
38
|
+
"propresult",
|
|
39
|
+
"propstats",
|
|
40
|
+
"satstate",
|
|
37
41
|
]
|
|
@@ -1490,9 +1490,213 @@ class satstate:
|
|
|
1490
1490
|
Args:
|
|
1491
1491
|
time (satkit.time|satkit.duration): Time or duration from current time to which to propagate the state
|
|
1492
1492
|
|
|
1493
|
-
Keyword
|
|
1494
|
-
propsettings: satkit.
|
|
1493
|
+
Keyword Args:
|
|
1494
|
+
propsettings: satkit.propsettings object describing settings to use in the propagation. If omitted, default is used
|
|
1495
1495
|
|
|
1496
1496
|
Returns:
|
|
1497
1497
|
satstate: New satellite state object representing the state at the new time
|
|
1498
|
-
"""
|
|
1498
|
+
"""
|
|
1499
|
+
|
|
1500
|
+
class propstats:
|
|
1501
|
+
@property
|
|
1502
|
+
def num_eval() -> int:
|
|
1503
|
+
"""Number of function evaluations"""
|
|
1504
|
+
|
|
1505
|
+
@property
|
|
1506
|
+
def num_accept() -> int:
|
|
1507
|
+
"""Number of accepted steps in adaptive RK integrator"""
|
|
1508
|
+
|
|
1509
|
+
@property
|
|
1510
|
+
def num_reject() -> int:
|
|
1511
|
+
"""Number of rejected steps in adaptive RK integrator"""
|
|
1512
|
+
|
|
1513
|
+
class propresult:
|
|
1514
|
+
"""Results of a satellite propagation
|
|
1515
|
+
|
|
1516
|
+
This class lets the user access results of the satellite propagation
|
|
1517
|
+
"""
|
|
1518
|
+
|
|
1519
|
+
@property
|
|
1520
|
+
def pos() -> npt.ArrayLike[float]:
|
|
1521
|
+
"""GCRF position of satellite, meters"""
|
|
1522
|
+
|
|
1523
|
+
@property
|
|
1524
|
+
def vel() -> npt.ArrayLike[float]:
|
|
1525
|
+
"""GCRF velocity of satellite, meters/second"""
|
|
1526
|
+
|
|
1527
|
+
@property
|
|
1528
|
+
def state() -> npt.ArrayLike[float]:
|
|
1529
|
+
"""6-element state (pos + vel) of satellite in meters & meters/second"""
|
|
1530
|
+
|
|
1531
|
+
@property
|
|
1532
|
+
def time() -> satkit.time:
|
|
1533
|
+
"""Time at which state is valid"""
|
|
1534
|
+
|
|
1535
|
+
@property
|
|
1536
|
+
def stats() -> propstats:
|
|
1537
|
+
"""Statistics of propagation"""
|
|
1538
|
+
|
|
1539
|
+
@property
|
|
1540
|
+
def phi() -> npt.ArrayLike[np.float64]|None:
|
|
1541
|
+
"""6x6 State transition matrix
|
|
1542
|
+
or None if not computed
|
|
1543
|
+
"""
|
|
1544
|
+
|
|
1545
|
+
def interp(time: satkit.time, output_phi: bool=False) -> npt.ArrayLike[np.float64]|typing.Tuple[npt.ArrayLike[np.float64], npt.ArrayLike[np.float64]]:
|
|
1546
|
+
"""Interpolate state at given time
|
|
1547
|
+
|
|
1548
|
+
Args:
|
|
1549
|
+
time (satkit.time): Time at which to interpolate state
|
|
1550
|
+
|
|
1551
|
+
Keyword Arguments:
|
|
1552
|
+
output_phi (bool): Output 6x6 state transition matrix at the interpolated time
|
|
1553
|
+
|
|
1554
|
+
Returns:
|
|
1555
|
+
6-element vector representing state at given time
|
|
1556
|
+
if output_phi, also output 6x6 state transition matrix at given time
|
|
1557
|
+
"""
|
|
1558
|
+
|
|
1559
|
+
|
|
1560
|
+
class satproperties_static:
|
|
1561
|
+
"""Satellite properties relevant for drag and radiation pressure
|
|
1562
|
+
|
|
1563
|
+
This class lets the satellite radiation pressure and drag
|
|
1564
|
+
paramters be set to static values for duration of propagation
|
|
1565
|
+
"""
|
|
1566
|
+
|
|
1567
|
+
def __init__(self, *args, **kwargs):
|
|
1568
|
+
"""Create a satproperties_static object with given craoverm and cdaoverm in m^2/kg
|
|
1569
|
+
|
|
1570
|
+
Args:
|
|
1571
|
+
cdaroverm (float): Coefficient of drag times area over mass in m^2/kg
|
|
1572
|
+
craoverm (float): Coefficient of radiation pressure times area over mass in m^2/kg
|
|
1573
|
+
|
|
1574
|
+
Keyword Arguments:
|
|
1575
|
+
craoverm (float): Coefficient of radiation pressure times area over mass in m^2/kg
|
|
1576
|
+
cdaoverm (float): Coefficient of drag times area over mass in m^2/kg
|
|
1577
|
+
|
|
1578
|
+
|
|
1579
|
+
Notes:
|
|
1580
|
+
The two arguments can be passed as positional arguments or as keyword arguments
|
|
1581
|
+
|
|
1582
|
+
Example:
|
|
1583
|
+
|
|
1584
|
+
>>> properties = satproperties_static(craoverm = 0.5, cdaoverm = 0.4)
|
|
1585
|
+
|
|
1586
|
+
or with same output
|
|
1587
|
+
|
|
1588
|
+
>>> properties = satproperties_static(0.5, 0.4)
|
|
1589
|
+
|
|
1590
|
+
"""
|
|
1591
|
+
|
|
1592
|
+
@property
|
|
1593
|
+
def cdaoverm() -> float:
|
|
1594
|
+
"""Coeffecient of drag times area over mass. Units are m^2/kg
|
|
1595
|
+
"""
|
|
1596
|
+
|
|
1597
|
+
@property
|
|
1598
|
+
def craoverm() -> float:
|
|
1599
|
+
"""Coefficient of radiation pressure times area over mass. Units are m^2/kg
|
|
1600
|
+
"""
|
|
1601
|
+
|
|
1602
|
+
|
|
1603
|
+
class propsettings:
|
|
1604
|
+
"""This class contains settings used in the high-precision orbit propgator part of the "satkit" python toolbox
|
|
1605
|
+
"""
|
|
1606
|
+
|
|
1607
|
+
def __init__(self):
|
|
1608
|
+
""" Create default propsetting object
|
|
1609
|
+
|
|
1610
|
+
Notes:
|
|
1611
|
+
* Default settings:
|
|
1612
|
+
* abs_error: 1e-8
|
|
1613
|
+
* rel_error: 1e-8
|
|
1614
|
+
* gravity_order: 4
|
|
1615
|
+
* use_spaceweather: True
|
|
1616
|
+
* use_jplephem: True
|
|
1617
|
+
|
|
1618
|
+
|
|
1619
|
+
Returns:
|
|
1620
|
+
propsettings: New propsettings object with default settings
|
|
1621
|
+
"""
|
|
1622
|
+
|
|
1623
|
+
@property
|
|
1624
|
+
def abs_error() -> float:
|
|
1625
|
+
"""Maxmum absolute value of error for any element in propagated state following ODE integration
|
|
1626
|
+
|
|
1627
|
+
Default: 1e-8
|
|
1628
|
+
"""
|
|
1629
|
+
|
|
1630
|
+
@property
|
|
1631
|
+
def rel_error() -> float:
|
|
1632
|
+
"""Maximum relative error of any element in propagated state following ODE integration
|
|
1633
|
+
|
|
1634
|
+
Default: 1e-8
|
|
1635
|
+
"""
|
|
1636
|
+
|
|
1637
|
+
@property
|
|
1638
|
+
def gravity_order() -> int:
|
|
1639
|
+
"""Earth gravity order to use in ODE integration
|
|
1640
|
+
|
|
1641
|
+
Default: 4
|
|
1642
|
+
"""
|
|
1643
|
+
|
|
1644
|
+
@property
|
|
1645
|
+
def use_spaceweather() -> bool:
|
|
1646
|
+
"""Use space weather data when computing atmospheric density for drag forces
|
|
1647
|
+
|
|
1648
|
+
Default: true
|
|
1649
|
+
|
|
1650
|
+
Notes:
|
|
1651
|
+
* Space weather data can have a large effect on the density of the atmosphere
|
|
1652
|
+
* This can be important for accurate drag force calculations
|
|
1653
|
+
* Space weather data is updated every 3 hours. Most-recent data can be downloaded with ``satkit.utils.update_datafiles()``
|
|
1654
|
+
|
|
1655
|
+
"""
|
|
1656
|
+
|
|
1657
|
+
@property
|
|
1658
|
+
def use_jplephem() -> bool:
|
|
1659
|
+
"""Use high-precision but computationally expensive JPL ephemerides for sun and mun when computing their gravitational force
|
|
1660
|
+
"""
|
|
1661
|
+
|
|
1662
|
+
def propagate(
|
|
1663
|
+
pos: npt.ArrayLike[float],
|
|
1664
|
+
vel: npt.ArrayLike[float],
|
|
1665
|
+
start: time,
|
|
1666
|
+
**kwargs,
|
|
1667
|
+
) -> propresult:
|
|
1668
|
+
"""High-precision orbit propagator
|
|
1669
|
+
|
|
1670
|
+
Notes:
|
|
1671
|
+
* Propagator uses advanced Runga-Kutta integrators and includes the following forces:
|
|
1672
|
+
* Earth gravity with higher-order zonal terms
|
|
1673
|
+
* Sun, Moon gravity
|
|
1674
|
+
* Radiation pressure
|
|
1675
|
+
* Atmospheric drag: NRL-MISE 2000 density model, with option to include space weather effects (can be large)
|
|
1676
|
+
* Stop time must be set by keyword argument, either explicitely or by duration
|
|
1677
|
+
* Solid Earth tides are not (yet) included in the model
|
|
1678
|
+
|
|
1679
|
+
|
|
1680
|
+
Propagate statellite ephemeris (position, velocity in gcrs & time) to new time
|
|
1681
|
+
and output new position and velocity via Runge-Kutta integration.
|
|
1682
|
+
|
|
1683
|
+
Inputs and outputs are all in the Geocentric Celestial Reference Frame (GCRF)
|
|
1684
|
+
|
|
1685
|
+
Args:
|
|
1686
|
+
pos (npt.ArrayLike[float]): 3-element numpy array representing satellite GCRF position in meters
|
|
1687
|
+
vel (npt.ArrayLike[float]): 3-element numpy array representing satellite GCRF velocity in m/s
|
|
1688
|
+
tm (satkit.time): satkit.time object representing instant at which satellite is at "pos" & "vel"
|
|
1689
|
+
|
|
1690
|
+
Keyword Args:
|
|
1691
|
+
stop_time (satkit.time): satkit.time object representing instant at which new position and velocity will be computed
|
|
1692
|
+
duration_secs (float): duration in seconds from "tm" for at which new position and velocity will be computed.
|
|
1693
|
+
duration_days (float): duration in days from "tm" at which new position and velocity will be computed.
|
|
1694
|
+
duration (satkit.duration): duration from "tm" at which new position & velocity will be computed.
|
|
1695
|
+
output_phi (bool): Output 6x6 state transition matrix between "starttime" and "stoptime" (and at intervals, if specified)
|
|
1696
|
+
propsettings (propsettings): "propsettings" object with input settings for the propagation. if left out, default will be used.
|
|
1697
|
+
satproperties (satproperties_static): "SatPropertiesStatic" object with drag and radiation pressure succeptibility of satellite. If left out, drag and radiation pressure are neglected
|
|
1698
|
+
output_dense: boolean indicting whether or not dense output should be recorded. Default is false. If true, this will allow for calling the "interp" function to query states at arbitrary times between the start time and the stop time
|
|
1699
|
+
|
|
1700
|
+
Returns:
|
|
1701
|
+
(propresult): Propagation result object holding state outputs, statistics, and dense output if requested
|
|
1702
|
+
"""
|
|
@@ -228,17 +228,15 @@ def propagate(
|
|
|
228
228
|
vel (npt.ArrayLike[float]): 3-element numpy array representing satellite GCRF velocity in m/s
|
|
229
229
|
tm (satkit.time): satkit.time object representing instant at which satellite is at "pos" & "vel"
|
|
230
230
|
|
|
231
|
-
Keyword
|
|
231
|
+
Keyword Args:
|
|
232
232
|
stop_time (satkit.time): satkit.time object representing instant at which new position and velocity will be computed
|
|
233
233
|
duration_secs (float): duration in seconds from "tm" for at which new position and velocity will be computed.
|
|
234
234
|
duration_days (float): duration in days from "tm" at which new position and velocity will be computed.
|
|
235
235
|
duration (satkit.duration): duration from "tm" at which new position & velocity will be computed.
|
|
236
236
|
output_phi (bool): Output 6x6 state transition matrix between "starttime" and "stoptime" (and at intervals, if specified)
|
|
237
237
|
propsettings (propsettings): "propsettings" object with input settings for the propagation. if left out, default will be used.
|
|
238
|
-
satproperties (satproperties_static): "SatPropertiesStatic" object with drag and radiation pressure succeptibility of satellite.
|
|
239
|
-
|
|
240
|
-
output_dense: boolean indicting whether or not dense output should be recorded. Default is false. If true, this will allow for calling the "interp" function
|
|
241
|
-
to query states at arbitrary times between the start time and the stop time
|
|
238
|
+
satproperties (satproperties_static): "SatPropertiesStatic" object with drag and radiation pressure succeptibility of satellite. If left out, drag and radiation pressure are neglected
|
|
239
|
+
output_dense: boolean indicting whether or not dense output should be recorded. Default is false. If true, this will allow for calling the "interp" function to query states at arbitrary times between the start time and the stop time
|
|
242
240
|
|
|
243
241
|
Returns:
|
|
244
242
|
(propresult): Propagation result object holding state outputs, statistics, and dense output if requested
|
|
@@ -12,7 +12,7 @@ import satkit
|
|
|
12
12
|
def update_datafiles(**kwargs):
|
|
13
13
|
"""Download & store data files needed for "satkit" computations
|
|
14
14
|
|
|
15
|
-
Keyword
|
|
15
|
+
Keyword Args:
|
|
16
16
|
|
|
17
17
|
overwrite (bool): Download and overwrite files if they already exist
|
|
18
18
|
dir(string): Target directory for files. Uses existing data directory if not specified. (see "datadir" function)
|
|
@@ -25,26 +25,20 @@ import os
|
|
|
25
25
|
basedir = os.getenv(
|
|
26
26
|
"SATKIT_TESTVEC_ROOT", default="../.." + os.path.sep + "satkit-testvecs"
|
|
27
27
|
)
|
|
28
|
+
fname = (
|
|
29
|
+
basedir + os.path.sep + "orbitprop" + os.path.sep
|
|
30
|
+
+ "ESA0OPSFIN_20233640000_01D_05M_ORB.SP3"
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
[pitrf, timearr] = read_sp3file(fname)
|
|
34
|
+
pgcrf = np.stack(
|
|
35
|
+
np.fromiter(
|
|
36
|
+
(q * p for q, p in zip(sk.frametransform.qitrf2gcrf(timearr), pitrf)),
|
|
37
|
+
list,
|
|
38
|
+
),
|
|
39
|
+
axis=0,
|
|
40
|
+
)
|
|
28
41
|
|
|
29
|
-
sp3names = ['mid22630.sp3', 'mid22631.sp3', 'mid22632.sp3',
|
|
30
|
-
'mid22633.sp3', 'mid22634.sp3', 'mid22635.sp3',
|
|
31
|
-
'mid22636.sp3']
|
|
32
|
-
|
|
33
|
-
sp3names = ['mid22630.sp3', 'mid22631.sp3', 'mid22632.sp3']
|
|
34
|
-
pitrf = np.zeros((0,3), np.float64)
|
|
35
|
-
timearr = np.array([])
|
|
36
|
-
|
|
37
|
-
for sp3name in sp3names:
|
|
38
|
-
fname = (
|
|
39
|
-
basedir
|
|
40
|
-
+ os.path.sep
|
|
41
|
-
+ "orbitprop"
|
|
42
|
-
+ os.path.sep
|
|
43
|
-
+ sp3name
|
|
44
|
-
)
|
|
45
|
-
[pitrf1, timearray1] = read_sp3file(fname)
|
|
46
|
-
pitrf = np.append(pitrf, pitrf1, axis=0)
|
|
47
|
-
timearr = np.append(timearr, timearray1)
|
|
48
42
|
|
|
49
43
|
print(pitrf.shape)
|
|
50
44
|
print(timearr.shape)
|
|
@@ -62,14 +56,15 @@ vgcrf = (pgcrf[1, :] - pgcrf[0, :]) / (timearr[1] - timearr[0]).seconds()
|
|
|
62
56
|
|
|
63
57
|
# Initial state for non-linear least squares is initial velocity
|
|
64
58
|
# and susceptibility to radiation pressuer : Cr A / m
|
|
65
|
-
v0 = np.array([vgcrf[0], vgcrf[1], vgcrf[2], 0.
|
|
66
|
-
|
|
59
|
+
#v0 = np.array([vgcrf[0], vgcrf[1], vgcrf[2], 0.02])
|
|
60
|
+
v0 = np.array([2.47130555e03, 2.94682777e03, -5.34171918e02, 2.13018578e-02])
|
|
67
61
|
|
|
68
62
|
def minfunc(v):
|
|
69
63
|
tstart = timearr[0]
|
|
70
64
|
tend = timearr[-1]
|
|
71
65
|
settings = sk.satprop.propsettings()
|
|
72
66
|
settings.use_jplephem = False
|
|
67
|
+
settings.gravity_order = 10
|
|
73
68
|
satprops = sk.satprop.satproperties_static()
|
|
74
69
|
satprops.craoverm = v[3]
|
|
75
70
|
|
|
@@ -78,12 +73,15 @@ def minfunc(v):
|
|
|
78
73
|
v[0:3],
|
|
79
74
|
tstart,
|
|
80
75
|
stoptime=tend,
|
|
81
|
-
dt=sk.duration.from_minutes(5),
|
|
82
76
|
propsettings=settings,
|
|
83
|
-
satproperties=satprops,
|
|
77
|
+
satproperties=satprops,
|
|
78
|
+
output_dense=True,
|
|
84
79
|
)
|
|
80
|
+
pest = np.zeros((len(timearr), 3))
|
|
81
|
+
for i in range(len(timearr)):
|
|
82
|
+
pest[i, :] = res.interp(timearr[i])[0:3]
|
|
85
83
|
|
|
86
|
-
return np.sum(np.sum((
|
|
84
|
+
return np.sum(np.sum((pest - pgcrf) ** 2, axis=1), axis=0)
|
|
87
85
|
|
|
88
86
|
|
|
89
87
|
# Minimize difference between true satellite state and propagated state
|
|
@@ -91,6 +89,10 @@ def minfunc(v):
|
|
|
91
89
|
r = minimize(minfunc, v0, method="Nelder-Mead")
|
|
92
90
|
print(r)
|
|
93
91
|
|
|
92
|
+
# %%
|
|
93
|
+
print(v0)
|
|
94
|
+
print(r.x)
|
|
95
|
+
|
|
94
96
|
# %%
|
|
95
97
|
import plotly.graph_objects as go
|
|
96
98
|
|
|
@@ -100,11 +102,15 @@ satprops = sk.satprop.satproperties_static()
|
|
|
100
102
|
satprops.craoverm = r.x[3]
|
|
101
103
|
res = sk.satprop.propagate(
|
|
102
104
|
pgcrf[0,:], r.x[0:3], timearr[0],
|
|
103
|
-
stoptime=timearr[-1],
|
|
104
|
-
propsettings=settings, satproperties=satprops
|
|
105
|
+
stoptime=timearr[-1],
|
|
106
|
+
propsettings=settings, satproperties=satprops,
|
|
107
|
+
output_dense=True
|
|
105
108
|
)
|
|
106
|
-
perr =
|
|
109
|
+
perr = np.zeros((len(timearr), 3))
|
|
110
|
+
for i in range(len(timearr)):
|
|
111
|
+
perr[i,:] = res.interp(timearr[i])[0:3] - pgcrf[i,:]
|
|
107
112
|
fig = go.Figure()
|
|
113
|
+
|
|
108
114
|
fig.add_trace(go.Scatter(x=[t.datetime() for t in timearr], y=perr[:,0], mode='lines', name='X'))
|
|
109
115
|
fig.add_trace(go.Scatter(x=[t.datetime() for t in timearr], y=perr[:,1], mode='lines', name='Y'))
|
|
110
116
|
fig.add_trace(go.Scatter(x=[t.datetime() for t in timearr], y=perr[:,2], mode='lines', name='Z'))
|
|
@@ -595,16 +595,22 @@ class TestHighPrecisionPropagation:
|
|
|
595
595
|
),
|
|
596
596
|
axis=0,
|
|
597
597
|
)
|
|
598
|
-
settings = sk.
|
|
598
|
+
settings = sk.propsettings()
|
|
599
599
|
settings.use_jplephem = False
|
|
600
600
|
|
|
601
|
+
# Determined by orbitprop_gps_fit.py
|
|
602
|
+
fitparam = np.array(
|
|
603
|
+
[ 2.47130562e+03, 2.94682753e+03, -5.34172176e+02, 2.32565692e-02]
|
|
604
|
+
)
|
|
605
|
+
|
|
606
|
+
|
|
601
607
|
# Values for craoverm and velocity come from orbitprop_gps_fit.py
|
|
602
|
-
satprops = sk.
|
|
603
|
-
satprops.craoverm =
|
|
604
|
-
|
|
605
|
-
res = sk.
|
|
608
|
+
satprops = sk.satproperties_static()
|
|
609
|
+
satprops.craoverm = fitparam[3]
|
|
610
|
+
|
|
611
|
+
res = sk.propagate(
|
|
606
612
|
pgcrf[0, :],
|
|
607
|
-
|
|
613
|
+
fitparam[0:3],
|
|
608
614
|
timearr[0],
|
|
609
615
|
stoptime=timearr[-1],
|
|
610
616
|
propsettings=settings,
|
|
@@ -613,12 +619,12 @@ class TestHighPrecisionPropagation:
|
|
|
613
619
|
)
|
|
614
620
|
print(res)
|
|
615
621
|
|
|
616
|
-
# See if propagator is accurate to <
|
|
622
|
+
# See if propagator is accurate to < 8 meters over 1 day on
|
|
617
623
|
# each Cartesian axis
|
|
618
624
|
for iv in range(pgcrf.shape[0]-5):
|
|
619
625
|
state = res.interp(timearr[iv])
|
|
620
626
|
for ix in range(0, 3):
|
|
621
|
-
assert m.fabs(state[ix] - pgcrf[iv, ix]) <
|
|
627
|
+
assert m.fabs(state[ix] - pgcrf[iv, ix]) < 8
|
|
622
628
|
|
|
623
629
|
class TestSatState:
|
|
624
630
|
def test_lvlh(self):
|
|
@@ -35,7 +35,11 @@
|
|
|
35
35
|
//!
|
|
36
36
|
//! For a good description, see [here](https://www.stjarnhimlen.se/comp/time.html)
|
|
37
37
|
//!
|
|
38
|
-
|
|
38
|
+
//!
|
|
39
|
+
|
|
40
|
+
use serde::{Deserialize, Serialize};
|
|
41
|
+
|
|
42
|
+
#[derive(PartialEq, PartialOrd, Copy, Clone, Debug, Serialize, Deserialize)]
|
|
39
43
|
pub struct AstroTime {
|
|
40
44
|
pub(crate) mjd_tai: f64,
|
|
41
45
|
}
|
|
@@ -159,7 +159,7 @@ type Mat3 = na::Matrix3<f64>;
|
|
|
159
159
|
/// * `pos` - Position as ITRF coordinate (satkit.itrfcoord) or numpy
|
|
160
160
|
/// 3-vector representing ITRF position in meters
|
|
161
161
|
///
|
|
162
|
-
/// * `order` - Order of the gravity model
|
|
162
|
+
/// * `order` - Order of the gravity model, up to 40
|
|
163
163
|
///
|
|
164
164
|
/// # References
|
|
165
165
|
///
|
|
@@ -199,8 +199,56 @@ impl Gravity {
|
|
|
199
199
|
self.accel_t::<14, 18>(pos)
|
|
200
200
|
} else if order == 15 {
|
|
201
201
|
self.accel_t::<15, 19>(pos)
|
|
202
|
-
} else {
|
|
202
|
+
} else if order == 16 {
|
|
203
203
|
self.accel_t::<16, 20>(pos)
|
|
204
|
+
} else if order == 17 {
|
|
205
|
+
self.accel_t::<17, 21>(pos)
|
|
206
|
+
} else if order == 18 {
|
|
207
|
+
self.accel_t::<18, 22>(pos)
|
|
208
|
+
} else if order == 19 {
|
|
209
|
+
self.accel_t::<19, 23>(pos)
|
|
210
|
+
} else if order == 20 {
|
|
211
|
+
self.accel_t::<20, 24>(pos)
|
|
212
|
+
} else if order == 21 {
|
|
213
|
+
self.accel_t::<21, 25>(pos)
|
|
214
|
+
} else if order == 22 {
|
|
215
|
+
self.accel_t::<22, 26>(pos)
|
|
216
|
+
} else if order == 23 {
|
|
217
|
+
self.accel_t::<23, 27>(pos)
|
|
218
|
+
} else if order == 24 {
|
|
219
|
+
self.accel_t::<24, 28>(pos)
|
|
220
|
+
} else if order == 25 {
|
|
221
|
+
self.accel_t::<25, 29>(pos)
|
|
222
|
+
} else if order == 26 {
|
|
223
|
+
self.accel_t::<26, 30>(pos)
|
|
224
|
+
} else if order == 27 {
|
|
225
|
+
self.accel_t::<27, 31>(pos)
|
|
226
|
+
} else if order == 28 {
|
|
227
|
+
self.accel_t::<28, 32>(pos)
|
|
228
|
+
} else if order == 29 {
|
|
229
|
+
self.accel_t::<29, 33>(pos)
|
|
230
|
+
} else if order == 30 {
|
|
231
|
+
self.accel_t::<30, 34>(pos)
|
|
232
|
+
} else if order == 31 {
|
|
233
|
+
self.accel_t::<31, 35>(pos)
|
|
234
|
+
} else if order == 32 {
|
|
235
|
+
self.accel_t::<32, 36>(pos)
|
|
236
|
+
} else if order == 33 {
|
|
237
|
+
self.accel_t::<33, 37>(pos)
|
|
238
|
+
} else if order == 34 {
|
|
239
|
+
self.accel_t::<34, 38>(pos)
|
|
240
|
+
} else if order == 35 {
|
|
241
|
+
self.accel_t::<35, 39>(pos)
|
|
242
|
+
} else if order == 36 {
|
|
243
|
+
self.accel_t::<36, 40>(pos)
|
|
244
|
+
} else if order == 37 {
|
|
245
|
+
self.accel_t::<37, 41>(pos)
|
|
246
|
+
} else if order == 37 {
|
|
247
|
+
self.accel_t::<38, 42>(pos)
|
|
248
|
+
} else if order == 39 {
|
|
249
|
+
self.accel_t::<39, 43>(pos)
|
|
250
|
+
} else {
|
|
251
|
+
self.accel_t::<40, 44>(pos)
|
|
204
252
|
}
|
|
205
253
|
}
|
|
206
254
|
|
|
@@ -235,8 +283,56 @@ impl Gravity {
|
|
|
235
283
|
self.accel_and_partials_t::<14, 18>(pos)
|
|
236
284
|
} else if order == 15 {
|
|
237
285
|
self.accel_and_partials_t::<15, 19>(pos)
|
|
238
|
-
} else {
|
|
286
|
+
} else if order == 16 {
|
|
239
287
|
self.accel_and_partials_t::<16, 20>(pos)
|
|
288
|
+
} else if order == 17 {
|
|
289
|
+
self.accel_and_partials_t::<17, 21>(pos)
|
|
290
|
+
} else if order == 18 {
|
|
291
|
+
self.accel_and_partials_t::<18, 22>(pos)
|
|
292
|
+
} else if order == 19 {
|
|
293
|
+
self.accel_and_partials_t::<19, 23>(pos)
|
|
294
|
+
} else if order == 20 {
|
|
295
|
+
self.accel_and_partials_t::<20, 24>(pos)
|
|
296
|
+
} else if order == 21 {
|
|
297
|
+
self.accel_and_partials_t::<21, 25>(pos)
|
|
298
|
+
} else if order == 22 {
|
|
299
|
+
self.accel_and_partials_t::<22, 26>(pos)
|
|
300
|
+
} else if order == 23 {
|
|
301
|
+
self.accel_and_partials_t::<23, 27>(pos)
|
|
302
|
+
} else if order == 24 {
|
|
303
|
+
self.accel_and_partials_t::<24, 28>(pos)
|
|
304
|
+
} else if order == 25 {
|
|
305
|
+
self.accel_and_partials_t::<25, 29>(pos)
|
|
306
|
+
} else if order == 26 {
|
|
307
|
+
self.accel_and_partials_t::<26, 30>(pos)
|
|
308
|
+
} else if order == 27 {
|
|
309
|
+
self.accel_and_partials_t::<27, 31>(pos)
|
|
310
|
+
} else if order == 28 {
|
|
311
|
+
self.accel_and_partials_t::<28, 32>(pos)
|
|
312
|
+
} else if order == 29 {
|
|
313
|
+
self.accel_and_partials_t::<29, 33>(pos)
|
|
314
|
+
} else if order == 30 {
|
|
315
|
+
self.accel_and_partials_t::<30, 34>(pos)
|
|
316
|
+
} else if order == 31 {
|
|
317
|
+
self.accel_and_partials_t::<31, 35>(pos)
|
|
318
|
+
} else if order == 32 {
|
|
319
|
+
self.accel_and_partials_t::<32, 36>(pos)
|
|
320
|
+
} else if order == 33 {
|
|
321
|
+
self.accel_and_partials_t::<33, 37>(pos)
|
|
322
|
+
} else if order == 34 {
|
|
323
|
+
self.accel_and_partials_t::<34, 38>(pos)
|
|
324
|
+
} else if order == 35 {
|
|
325
|
+
self.accel_and_partials_t::<35, 39>(pos)
|
|
326
|
+
} else if order == 36 {
|
|
327
|
+
self.accel_and_partials_t::<36, 40>(pos)
|
|
328
|
+
} else if order == 37 {
|
|
329
|
+
self.accel_and_partials_t::<37, 15>(pos)
|
|
330
|
+
} else if order == 38 {
|
|
331
|
+
self.accel_and_partials_t::<38, 16>(pos)
|
|
332
|
+
} else if order == 39 {
|
|
333
|
+
self.accel_and_partials_t::<39, 17>(pos)
|
|
334
|
+
} else {
|
|
335
|
+
self.accel_and_partials_t::<40, 20>(pos)
|
|
240
336
|
}
|
|
241
337
|
}
|
|
242
338
|
|