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.
Files changed (120) hide show
  1. {satkit-0.3.0 → satkit-0.3.2}/Cargo.toml +9 -7
  2. {satkit-0.3.0/python/satkit.egg-info → satkit-0.3.2}/PKG-INFO +1 -1
  3. {satkit-0.3.0 → satkit-0.3.2}/pyproject.toml +1 -1
  4. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/__init__.pyi +6 -2
  5. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/satkit.pyi +207 -3
  6. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/satprop.pyi +3 -5
  7. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/utils.pyi +1 -1
  8. {satkit-0.3.0 → satkit-0.3.2/python/satkit.egg-info}/PKG-INFO +1 -1
  9. {satkit-0.3.0 → satkit-0.3.2}/python/test/orbitprop_gps_fit.py +33 -27
  10. {satkit-0.3.0 → satkit-0.3.2}/python/test/test.py +14 -8
  11. {satkit-0.3.0 → satkit-0.3.2}/src/astrotime.rs +5 -1
  12. {satkit-0.3.0 → satkit-0.3.2}/src/earthgravity.rs +99 -3
  13. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rk_adaptive.rs +19 -5
  14. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv87.rs +2 -2
  15. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv98.rs +2 -2
  16. {satkit-0.3.0 → satkit-0.3.2}/src/ode/types.rs +4 -2
  17. {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/propagator.rs +12 -5
  18. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/mod.rs +7 -11
  19. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pypropagate.rs +0 -1
  20. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pypropresult.rs +66 -0
  21. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pysgp4.rs +18 -12
  22. {satkit-0.3.0 → satkit-0.3.2}/LICENSE +0 -0
  23. {satkit-0.3.0 → satkit-0.3.2}/MANIFEST.in +0 -0
  24. {satkit-0.3.0 → satkit-0.3.2}/README.md +0 -0
  25. {satkit-0.3.0 → satkit-0.3.2}/python/docs/source/conf.py +0 -0
  26. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/__init__.py +0 -0
  27. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/density.pyi +0 -0
  28. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/frametransform.pyi +0 -0
  29. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/jplephem.pyi +0 -0
  30. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/moon.pyi +0 -0
  31. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/planets.pyi +0 -0
  32. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/py.typed +0 -0
  33. {satkit-0.3.0 → satkit-0.3.2}/python/satkit/sun.pyi +0 -0
  34. {satkit-0.3.0 → satkit-0.3.2}/python/satkit.egg-info/SOURCES.txt +0 -0
  35. {satkit-0.3.0 → satkit-0.3.2}/python/satkit.egg-info/dependency_links.txt +0 -0
  36. {satkit-0.3.0 → satkit-0.3.2}/python/satkit.egg-info/requires.txt +0 -0
  37. {satkit-0.3.0 → satkit-0.3.2}/python/satkit.egg-info/top_level.txt +0 -0
  38. {satkit-0.3.0 → satkit-0.3.2}/python/test/download_data.py +0 -0
  39. {satkit-0.3.0 → satkit-0.3.2}/python/test/download_from_json.py +0 -0
  40. {satkit-0.3.0 → satkit-0.3.2}/python/test/download_testvecs.py +0 -0
  41. {satkit-0.3.0 → satkit-0.3.2}/python/test/sp3file.py +0 -0
  42. {satkit-0.3.0 → satkit-0.3.2}/setup.cfg +0 -0
  43. {satkit-0.3.0 → satkit-0.3.2}/src/consts.rs +0 -0
  44. {satkit-0.3.0 → satkit-0.3.2}/src/duration.rs +0 -0
  45. {satkit-0.3.0 → satkit-0.3.2}/src/earth_orientation_params.rs +0 -0
  46. {satkit-0.3.0 → satkit-0.3.2}/src/frames.rs +0 -0
  47. {satkit-0.3.0 → satkit-0.3.2}/src/frametransform/ierstable.rs +0 -0
  48. {satkit-0.3.0 → satkit-0.3.2}/src/frametransform/mod.rs +0 -0
  49. {satkit-0.3.0 → satkit-0.3.2}/src/frametransform/qcirs2gcrs.rs +0 -0
  50. {satkit-0.3.0 → satkit-0.3.2}/src/itrfcoord.rs +0 -0
  51. {satkit-0.3.0 → satkit-0.3.2}/src/jplephem.rs +0 -0
  52. {satkit-0.3.0 → satkit-0.3.2}/src/kepler.rs +0 -0
  53. {satkit-0.3.0 → satkit-0.3.2}/src/lib.rs +0 -0
  54. {satkit-0.3.0 → satkit-0.3.2}/src/lpephem/mod.rs +0 -0
  55. {satkit-0.3.0 → satkit-0.3.2}/src/lpephem/moon.rs +0 -0
  56. {satkit-0.3.0 → satkit-0.3.2}/src/lpephem/planets.rs +0 -0
  57. {satkit-0.3.0 → satkit-0.3.2}/src/lpephem/sun.rs +0 -0
  58. {satkit-0.3.0 → satkit-0.3.2}/src/nrlmsise.rs +0 -0
  59. {satkit-0.3.0 → satkit-0.3.2}/src/ode/harmonic_oscillator.rs +0 -0
  60. {satkit-0.3.0 → satkit-0.3.2}/src/ode/mod.rs +0 -0
  61. {satkit-0.3.0 → satkit-0.3.2}/src/ode/nalgebra.rs +0 -0
  62. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rk_adaptive_settings.rs +0 -0
  63. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rk_explicit.rs +0 -0
  64. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkf45.rs +0 -0
  65. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkts54.rs +0 -0
  66. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv65.rs +0 -0
  67. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv65_table.rs +0 -0
  68. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv87_table.rs +0 -0
  69. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv98_nointerp.rs +0 -0
  70. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv98_nointerp_table.rs +0 -0
  71. {satkit-0.3.0 → satkit-0.3.2}/src/ode/rkv98_table.rs +0 -0
  72. {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/drag.rs +0 -0
  73. {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/mod.rs +0 -0
  74. {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/point_gravity.rs +0 -0
  75. {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/satproperties.rs +0 -0
  76. {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/satstate.rs +0 -0
  77. {satkit-0.3.0 → satkit-0.3.2}/src/orbitprop/settings.rs +0 -0
  78. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/mod_utils.rs +0 -0
  79. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyastrotime.rs +0 -0
  80. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyconsts.rs +0 -0
  81. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pydensity.rs +0 -0
  82. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyduration.rs +0 -0
  83. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyframes.rs +0 -0
  84. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyframetransform.rs +0 -0
  85. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pygravity.rs +0 -0
  86. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyitrfcoord.rs +0 -0
  87. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyjplephem.rs +0 -0
  88. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pykepler.rs +0 -0
  89. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pylpephem_moon.rs +0 -0
  90. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pylpephem_planets.rs +0 -0
  91. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pylpephem_sun.rs +0 -0
  92. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pynrlmsise.rs +0 -0
  93. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pypropsettings.rs +0 -0
  94. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyquaternion.rs +0 -0
  95. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pysatproperties.rs +0 -0
  96. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pysatstate.rs +0 -0
  97. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pysolarsystem.rs +0 -0
  98. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pytle.rs +0 -0
  99. {satkit-0.3.0 → satkit-0.3.2}/src/pybindings/pyutils.rs +0 -0
  100. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/dpper.rs +0 -0
  101. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/dscom.rs +0 -0
  102. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/dsinit.rs +0 -0
  103. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/dspace.rs +0 -0
  104. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/getgravconst.rs +0 -0
  105. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/initl.rs +0 -0
  106. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/mod.rs +0 -0
  107. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/satrec.rs +0 -0
  108. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/sgp4.rs +0 -0
  109. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/sgp4_lowlevel.rs +0 -0
  110. {satkit-0.3.0 → satkit-0.3.2}/src/sgp4/sgp4init.rs +0 -0
  111. {satkit-0.3.0 → satkit-0.3.2}/src/solarsystem.rs +0 -0
  112. {satkit-0.3.0 → satkit-0.3.2}/src/spaceweather.rs +0 -0
  113. {satkit-0.3.0 → satkit-0.3.2}/src/tle.rs +0 -0
  114. {satkit-0.3.0 → satkit-0.3.2}/src/types.rs +0 -0
  115. {satkit-0.3.0 → satkit-0.3.2}/src/utils/datadir.rs +0 -0
  116. {satkit-0.3.0 → satkit-0.3.2}/src/utils/download.rs +0 -0
  117. {satkit-0.3.0 → satkit-0.3.2}/src/utils/mod.rs +0 -0
  118. {satkit-0.3.0 → satkit-0.3.2}/src/utils/skerror.rs +0 -0
  119. {satkit-0.3.0 → satkit-0.3.2}/src/utils/test.rs +0 -0
  120. {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.0"
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.6"
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.9.1"
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.0.74", features = ["parallel"] }
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satkit
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Satellite Orbital Dynamics Toolkit
5
5
  Author-email: Steven Michael <ssmichael@gmail.com>
6
6
  Maintainer-email: Steven Michael <ssmichael@gmail.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "satkit"
7
- version = "0.3.0"
7
+ version = "0.3.2"
8
8
  dependencies = ["numpy>=1.20.0"]
9
9
  requires-python = ">= 3.8"
10
10
  authors = [{ name = "Steven Michael", email = "ssmichael@gmail.com" }]
@@ -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 Arguments:
1494
- propsettings: satkit.satprop.propsettings object describing settings to use in the propagation. If omitted, default is used
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 Arguments:
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
- If left out, drag and radiation pressure are neglected
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 Arguments:
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satkit
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Satellite Orbital Dynamics Toolkit
5
5
  Author-email: Steven Michael <ssmichael@gmail.com>
6
6
  Maintainer-email: Steven Michael <ssmichael@gmail.com>
@@ -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.01])
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((res["pos"] - pgcrf) ** 2, axis=1), axis=0)
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], dt=sk.duration(minutes=5),
104
- propsettings=settings, satproperties=satprops
105
+ stoptime=timearr[-1],
106
+ propsettings=settings, satproperties=satprops,
107
+ output_dense=True
105
108
  )
106
- perr = res['pos'] - pgcrf
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.satprop.propsettings()
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.satprop.satproperties_static()
603
- satprops.craoverm = 2.13018578e-2
604
- print(satprops)
605
- res = sk.satprop.propagate(
608
+ satprops = sk.satproperties_static()
609
+ satprops.craoverm = fitparam[3]
610
+
611
+ res = sk.propagate(
606
612
  pgcrf[0, :],
607
- np.array([2.47130555e03, 2.94682777e03, -5.34171918e02]),
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 < 10 meters over 1 day on
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]) < 10
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
- #[derive(PartialEq, PartialOrd, Copy, Clone, Debug)]
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