satkit 0.2.7__tar.gz → 0.2.9__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 (124) hide show
  1. {satkit-0.2.7 → satkit-0.2.9}/Cargo.toml +1 -1
  2. {satkit-0.2.7/python/satkit.egg-info → satkit-0.2.9}/PKG-INFO +3 -2
  3. {satkit-0.2.7 → satkit-0.2.9}/README.md +2 -1
  4. {satkit-0.2.7 → satkit-0.2.9}/pyproject.toml +1 -1
  5. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/__init__.pyi +3 -0
  6. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/jplephem.pyi +1 -1
  7. satkit-0.2.9/python/satkit/planets.pyi +28 -0
  8. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/satkit.pyi +98 -0
  9. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/satprop.pyi +6 -3
  10. {satkit-0.2.7 → satkit-0.2.9/python/satkit.egg-info}/PKG-INFO +3 -2
  11. {satkit-0.2.7 → satkit-0.2.9}/python/satkit.egg-info/SOURCES.txt +7 -1
  12. {satkit-0.2.7 → satkit-0.2.9}/python/test/orbitprop_gps_fit.py +46 -11
  13. {satkit-0.2.7 → satkit-0.2.9}/python/test/test.py +38 -0
  14. {satkit-0.2.7 → satkit-0.2.9}/src/astrotime.rs +4 -4
  15. satkit-0.2.9/src/frames.rs +52 -0
  16. {satkit-0.2.7 → satkit-0.2.9}/src/frametransform/mod.rs +1 -1
  17. {satkit-0.2.7 → satkit-0.2.9}/src/jplephem.rs +18 -18
  18. satkit-0.2.9/src/kepler.rs +312 -0
  19. {satkit-0.2.7 → satkit-0.2.9}/src/lib.rs +6 -0
  20. satkit-0.2.9/src/lpephem/mod.rs +9 -0
  21. satkit-0.2.9/src/lpephem/planets.rs +284 -0
  22. {satkit-0.2.7 → satkit-0.2.9}/src/nrlmsise.rs +5 -1
  23. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rk_adaptive.rs +1 -1
  24. {satkit-0.2.7 → satkit-0.2.9}/src/orbitprop/propagator.rs +4 -5
  25. {satkit-0.2.7 → satkit-0.2.9}/src/orbitprop/satstate.rs +12 -12
  26. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/mod.rs +20 -0
  27. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pyastrotime.rs +32 -7
  28. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pyduration.rs +21 -1
  29. satkit-0.2.9/src/pybindings/pyframes.rs +53 -0
  30. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pyitrfcoord.rs +34 -1
  31. satkit-0.2.9/src/pybindings/pykepler.rs +231 -0
  32. satkit-0.2.9/src/pybindings/pylpephem_planets.rs +21 -0
  33. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pyquaternion.rs +30 -2
  34. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pysatproperties.rs +27 -1
  35. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pysatstate.rs +39 -4
  36. satkit-0.2.9/src/pybindings/pysolarsystem.rs +66 -0
  37. satkit-0.2.9/src/pybindings/pytle.rs +242 -0
  38. satkit-0.2.9/src/solarsystem.rs +56 -0
  39. {satkit-0.2.7 → satkit-0.2.9}/src/spaceweather.rs +2 -2
  40. {satkit-0.2.7 → satkit-0.2.9}/src/tle.rs +1 -1
  41. satkit-0.2.7/python/satkit/py.typed +0 -0
  42. satkit-0.2.7/src/lpephem/mod.rs +0 -4
  43. satkit-0.2.7/src/pybindings/pysolarsystem.rs +0 -66
  44. satkit-0.2.7/src/pybindings/pytle.rs +0 -150
  45. satkit-0.2.7/src/solarsystem.rs +0 -37
  46. {satkit-0.2.7 → satkit-0.2.9}/LICENSE +0 -0
  47. {satkit-0.2.7 → satkit-0.2.9}/MANIFEST.in +0 -0
  48. {satkit-0.2.7 → satkit-0.2.9}/python/docs/source/conf.py +0 -0
  49. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/__init__.py +0 -0
  50. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/density.pyi +0 -0
  51. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/frametransform.pyi +0 -0
  52. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/moon.pyi +0 -0
  53. {satkit-0.2.7/python/satkit/astro-data → satkit-0.2.9/python/satkit}/py.typed +0 -0
  54. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/sun.pyi +0 -0
  55. {satkit-0.2.7 → satkit-0.2.9}/python/satkit/utils.pyi +0 -0
  56. {satkit-0.2.7 → satkit-0.2.9}/python/satkit.egg-info/dependency_links.txt +0 -0
  57. {satkit-0.2.7 → satkit-0.2.9}/python/satkit.egg-info/requires.txt +0 -0
  58. {satkit-0.2.7 → satkit-0.2.9}/python/satkit.egg-info/top_level.txt +0 -0
  59. {satkit-0.2.7 → satkit-0.2.9}/python/test/download_data.py +0 -0
  60. {satkit-0.2.7 → satkit-0.2.9}/python/test/download_from_json.py +0 -0
  61. {satkit-0.2.7 → satkit-0.2.9}/python/test/download_testvecs.py +0 -0
  62. {satkit-0.2.7 → satkit-0.2.9}/python/test/sp3file.py +0 -0
  63. {satkit-0.2.7 → satkit-0.2.9}/setup.cfg +0 -0
  64. {satkit-0.2.7 → satkit-0.2.9}/src/consts.rs +0 -0
  65. {satkit-0.2.7 → satkit-0.2.9}/src/duration.rs +0 -0
  66. {satkit-0.2.7 → satkit-0.2.9}/src/earth_orientation_params.rs +0 -0
  67. {satkit-0.2.7 → satkit-0.2.9}/src/earthgravity.rs +0 -0
  68. {satkit-0.2.7 → satkit-0.2.9}/src/frametransform/ierstable.rs +0 -0
  69. {satkit-0.2.7 → satkit-0.2.9}/src/frametransform/qcirs2gcrs.rs +0 -0
  70. {satkit-0.2.7 → satkit-0.2.9}/src/itrfcoord.rs +0 -0
  71. {satkit-0.2.7 → satkit-0.2.9}/src/lpephem/moon.rs +0 -0
  72. {satkit-0.2.7 → satkit-0.2.9}/src/lpephem/sun.rs +0 -0
  73. {satkit-0.2.7 → satkit-0.2.9}/src/ode/harmonic_oscillator.rs +0 -0
  74. {satkit-0.2.7 → satkit-0.2.9}/src/ode/mod.rs +0 -0
  75. {satkit-0.2.7 → satkit-0.2.9}/src/ode/nalgebra.rs +0 -0
  76. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rk_adaptive_settings.rs +0 -0
  77. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rk_explicit.rs +0 -0
  78. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkf45.rs +0 -0
  79. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkts54.rs +0 -0
  80. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkv65.rs +0 -0
  81. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkv65_table.rs +0 -0
  82. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkv87.rs +0 -0
  83. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkv87_table.rs +0 -0
  84. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkv98.rs +0 -0
  85. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkv98_nointerp.rs +0 -0
  86. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkv98_nointerp_table.rs +0 -0
  87. {satkit-0.2.7 → satkit-0.2.9}/src/ode/rkv98_table.rs +0 -0
  88. {satkit-0.2.7 → satkit-0.2.9}/src/ode/types.rs +0 -0
  89. {satkit-0.2.7 → satkit-0.2.9}/src/orbitprop/drag.rs +0 -0
  90. {satkit-0.2.7 → satkit-0.2.9}/src/orbitprop/mod.rs +0 -0
  91. {satkit-0.2.7 → satkit-0.2.9}/src/orbitprop/point_gravity.rs +0 -0
  92. {satkit-0.2.7 → satkit-0.2.9}/src/orbitprop/satproperties.rs +0 -0
  93. {satkit-0.2.7 → satkit-0.2.9}/src/orbitprop/settings.rs +0 -0
  94. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/mod_utils.rs +0 -0
  95. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pyconsts.rs +0 -0
  96. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pydensity.rs +0 -0
  97. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pyframetransform.rs +0 -0
  98. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pygravity.rs +0 -0
  99. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pyjplephem.rs +0 -0
  100. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pylpephem_moon.rs +0 -0
  101. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pylpephem_sun.rs +0 -0
  102. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pynrlmsise.rs +0 -0
  103. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pypropagate.rs +0 -0
  104. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pypropsettings.rs +0 -0
  105. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pysgp4.rs +0 -0
  106. {satkit-0.2.7 → satkit-0.2.9}/src/pybindings/pyutils.rs +0 -0
  107. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/dpper.rs +0 -0
  108. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/dscom.rs +0 -0
  109. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/dsinit.rs +0 -0
  110. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/dspace.rs +0 -0
  111. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/getgravconst.rs +0 -0
  112. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/initl.rs +0 -0
  113. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/mod.rs +0 -0
  114. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/satrec.rs +0 -0
  115. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/sgp4.rs +0 -0
  116. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/sgp4_lowlevel.rs +0 -0
  117. {satkit-0.2.7 → satkit-0.2.9}/src/sgp4/sgp4init.rs +0 -0
  118. {satkit-0.2.7 → satkit-0.2.9}/src/types.rs +0 -0
  119. {satkit-0.2.7 → satkit-0.2.9}/src/utils/datadir.rs +0 -0
  120. {satkit-0.2.7 → satkit-0.2.9}/src/utils/download.rs +0 -0
  121. {satkit-0.2.7 → satkit-0.2.9}/src/utils/mod.rs +0 -0
  122. {satkit-0.2.7 → satkit-0.2.9}/src/utils/skerror.rs +0 -0
  123. {satkit-0.2.7 → satkit-0.2.9}/src/utils/test.rs +0 -0
  124. {satkit-0.2.7 → satkit-0.2.9}/src/utils/update_data.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "satkit"
3
- version = "0.2.7"
3
+ version = "0.2.9"
4
4
  edition = "2021"
5
5
  description = "Satellite Toolkit"
6
6
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satkit
3
- Version: 0.2.7
3
+ Version: 0.2.9
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>
@@ -21,6 +21,7 @@ Requires-Dist: numpy>=1.20.0
21
21
 
22
22
  An accurate, high-performance satellite orbital kinematics toolkit, written in Rust with a sensible interface.
23
23
  <br/>
24
+ Also includes python bindings for *all* functions via via [pyo3](https://pyo3.rs/)
24
25
 
25
26
  ### Github
26
27
 
@@ -48,7 +49,7 @@ An accurate, high-performance satellite orbital kinematics toolkit, written in R
48
49
  - **Native Rust** bindings
49
50
  - **Python bindings** for compiled rust code ... speed of Rust with convenience of Python<br/>
50
51
  Install with `pip install satkit`<br/>
51
- PyPi includes binaries for windows, macos (Intel & arm), and linux
52
+ PyPi includes binary packages for windows, macos (Intel & ARM), and linux. Python documentation is at: <https://satellite-toolkit.readthedocs.io/latest/>
52
53
 
53
54
  ## Features
54
55
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  An accurate, high-performance satellite orbital kinematics toolkit, written in Rust with a sensible interface.
4
4
  <br/>
5
+ Also includes python bindings for *all* functions via via [pyo3](https://pyo3.rs/)
5
6
 
6
7
  ### Github
7
8
 
@@ -29,7 +30,7 @@ An accurate, high-performance satellite orbital kinematics toolkit, written in R
29
30
  - **Native Rust** bindings
30
31
  - **Python bindings** for compiled rust code ... speed of Rust with convenience of Python<br/>
31
32
  Install with `pip install satkit`<br/>
32
- PyPi includes binaries for windows, macos (Intel & arm), and linux
33
+ PyPi includes binary packages for windows, macos (Intel & ARM), and linux. Python documentation is at: <https://satellite-toolkit.readthedocs.io/latest/>
33
34
 
34
35
  ## Features
35
36
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "satkit"
7
- version = "0.2.7"
7
+ version = "0.2.9"
8
8
  dependencies = ["numpy>=1.20.0"]
9
9
  requires-python = ">= 3.8"
10
10
  authors = [{ name = "Steven Michael", email = "ssmichael@gmail.com" }]
@@ -8,6 +8,7 @@ from . import sun
8
8
  from . import satprop
9
9
  from . import density
10
10
  from . import utils
11
+ from . import planets
11
12
 
12
13
  __all__ = [
13
14
  "time",
@@ -21,12 +22,14 @@ __all__ = [
21
22
  "solarsystem",
22
23
  "TLE",
23
24
  "itrfcoord",
25
+ "kepler",
24
26
  "consts",
25
27
  "frametransform",
26
28
  "jplephem",
27
29
  "utils",
28
30
  "moon",
29
31
  "sun",
32
+ "planets",
30
33
  "satprop",
31
34
  "density",
32
35
  "utils"
@@ -1,7 +1,7 @@
1
1
  """
2
2
  High-precision JPL ephemerides for solar-system bodies
3
3
 
4
- For details, see:
4
+ For details, see: https://ssd.jpl.nasa.gov/
5
5
  """
6
6
 
7
7
  from __future__ import annotations
@@ -0,0 +1,28 @@
1
+ """
2
+ Low-precision planetary ephemerides from https://ssd.jpl.nasa.gov/?planet_pos
3
+ """
4
+
5
+ from __future__ import annotations
6
+ import typing
7
+ import numpy.typing as npt
8
+ import numpy as np
9
+
10
+ import satkit
11
+
12
+ def heliocentric_pos(body: satkit.solarsystem, tm: satkit.time|list[satkit.time]|npt.ArrayLike[satkit.time]) -> npt.ArrayLike[np.float64]:
13
+ """Return the position of the given body in the Heliocentric coordinate system (origin is the Sun)
14
+
15
+ Note: This function is only valid for the Sun and the 8 planets
16
+
17
+ Note: This is less accurate than using the jpl ephemeris, but involves fewer calculations
18
+
19
+ Note: See https://ssd.jpl.nasa.gov/?planet_pos for more information and accuracy details
20
+
21
+ Args:
22
+ body (satkit.solarsystem): Solar system body for which to return position
23
+ tm (satkit.time|numpy.ndarray|list): Time[s] at which to return position
24
+
25
+ Returns:
26
+ numpy.ndarray: 3-vector of Cartesian position in meters, with the origin at the Sun.
27
+ If input is list or numpy array of N times, then r will be Nx3 array
28
+ """
@@ -1050,6 +1050,104 @@ class quaternion:
1050
1050
  quaternion: Quaternion representing interpolation between self and other
1051
1051
  """
1052
1052
 
1053
+ class kepler:
1054
+ """ Represent Keplerian element sets and convert between cartesian
1055
+
1056
+
1057
+ Notes:
1058
+ * This class is used to represent Keplerian elements and convert between Cartesian coordinates
1059
+ * The class uses the semi-major axis (a), not the semiparameter
1060
+ * All angle units are radians
1061
+ * All length units are meters
1062
+ * All velocity units are meters / second
1063
+ """
1064
+
1065
+ def __init__(self, *args):
1066
+ """Create Keplerian element set object from input elements
1067
+
1068
+ # Args:
1069
+ a (float) : Semi-major axis, meters
1070
+ e (float) : Eccentricity, unitless
1071
+ i (float) : Inclination, radians
1072
+ raan (float) : Right ascension of ascending node, radians
1073
+ argp (float) : Argument of perigee, radians
1074
+ nu (float) : True anomaly, radians
1075
+
1076
+ # Keyword Args:
1077
+ true_anomaly (float) : True anomaly, radians
1078
+ mean_anomaly (float) : Mean anomaly, radians
1079
+ eccentric_anomaly (float) : Eccentric anomaly, radians
1080
+
1081
+ # Notes:
1082
+ * If "nu" is provided (6th argument), it will be used as the true anomaly
1083
+ * Anomaly may also be set via keyword arguments; if so, the there should only be
1084
+ 5 input arguments
1085
+
1086
+ # Returns:
1087
+ satkit.kepler: Keplerian element set object
1088
+ """
1089
+
1090
+ def to_pv(self) -> typing.Tuple[npt.ArrayLike[np.float64], npt.ArrayLike[np.float64]]:
1091
+ """Convert Keplerian element set to position and velocity vectors
1092
+
1093
+ Returns:
1094
+ tuple[npt.ArrayLike[np.float64], npt.ArrayLike[np.float64]]: Tuple with two elements representing the position and velocity vectors
1095
+ """
1096
+
1097
+ def propagate(self, dt: duration|float) -> kepler:
1098
+ """Propagate Keplerian element set by input duration
1099
+
1100
+ Args:
1101
+ dt (duration | float): Duration by which to propagate the Keplerian element set
1102
+ If float, value is seconds
1103
+
1104
+ Returns:
1105
+ satkit.kepler: Keplerian element set object after propagation
1106
+ """
1107
+
1108
+ @property
1109
+ def mean_motion(self) -> float:
1110
+ """Mean motion, radians / second
1111
+ """
1112
+
1113
+ @property
1114
+ def true_anomaly(self) -> float:
1115
+ """True anomaly, radians
1116
+ """
1117
+
1118
+ @property
1119
+ def eccentric_anomaly(self) -> float:
1120
+ """Eccentric anomaly, radians
1121
+ """
1122
+
1123
+ @property
1124
+ def mean_anomaly(self) -> float:
1125
+ """Mean anomaly, radians
1126
+ """
1127
+
1128
+ @property
1129
+ def mean_motion(self) -> float:
1130
+ """Mean motion, radians / second
1131
+ """
1132
+
1133
+ @property
1134
+ def period(self) -> float:
1135
+ """Orbital period, seconds
1136
+ """
1137
+
1138
+ def from_pv(
1139
+ pos: npt.ArrayLike[np.float64], vel: npt.ArrayLike[np.float64]
1140
+ ) -> kepler:
1141
+ """Create Keplerian element set from input position and velocity vectors
1142
+
1143
+ Args:
1144
+ pos (npt.ArrayLike[np.float64]): 3-element array representing position vector
1145
+ vel (npt.ArrayLike[np.float64]): 3-element array representing velocity vector
1146
+
1147
+ Returns:
1148
+ satkit.kepler: Keplerian element set object
1149
+ """
1150
+
1053
1151
  class itrfcoord:
1054
1152
  """ Representation of a coordinate in the International Terrestrial Reference Frame (ITRF)
1055
1153
 
@@ -113,7 +113,7 @@ class satstate:
113
113
  """
114
114
 
115
115
  @property
116
- def pos(self) -> npt.ArrayLike[np.float64]:
116
+ def pos_gcrf(self) -> npt.ArrayLike[np.float64]:
117
117
  """state position in meters in GCRF frame
118
118
 
119
119
  Returns:
@@ -121,7 +121,7 @@ class satstate:
121
121
  """
122
122
 
123
123
  @property
124
- def vel(self) -> npt.ArrayLike[np.float64]:
124
+ def vel_gcrf(self) -> npt.ArrayLike[np.float64]:
125
125
  """Return this state velocity in meters / second in GCRF
126
126
 
127
127
  Returns:
@@ -154,9 +154,12 @@ class satstate:
154
154
  satkit.time: Time instant of this state
155
155
  """
156
156
 
157
- def propagate(self, time: satkit.time, propsettings=None) -> satstate:
157
+ def propagate(self, time: satkit.time|satkit.duration, propsettings=None) -> satstate:
158
158
  """Propagate this state to a new time, specified by the "time" input, updating the position, the velocity, and the covariance if set
159
159
 
160
+ Args:
161
+ time (satkit.time|satkit.duration): Time or duration from current time to which to propagate the state
162
+
160
163
  Keyword Arguments:
161
164
  propsettings: satkit.satprop.propsettings object describing settings to use in the propagation. If omitted, default is used
162
165
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satkit
3
- Version: 0.2.7
3
+ Version: 0.2.9
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>
@@ -21,6 +21,7 @@ Requires-Dist: numpy>=1.20.0
21
21
 
22
22
  An accurate, high-performance satellite orbital kinematics toolkit, written in Rust with a sensible interface.
23
23
  <br/>
24
+ Also includes python bindings for *all* functions via via [pyo3](https://pyo3.rs/)
24
25
 
25
26
  ### Github
26
27
 
@@ -48,7 +49,7 @@ An accurate, high-performance satellite orbital kinematics toolkit, written in R
48
49
  - **Native Rust** bindings
49
50
  - **Python bindings** for compiled rust code ... speed of Rust with convenience of Python<br/>
50
51
  Install with `pip install satkit`<br/>
51
- PyPi includes binaries for windows, macos (Intel & arm), and linux
52
+ PyPi includes binary packages for windows, macos (Intel & ARM), and linux. Python documentation is at: <https://satellite-toolkit.readthedocs.io/latest/>
52
53
 
53
54
  ## Features
54
55
 
@@ -10,6 +10,7 @@ python/satkit/density.pyi
10
10
  python/satkit/frametransform.pyi
11
11
  python/satkit/jplephem.pyi
12
12
  python/satkit/moon.pyi
13
+ python/satkit/planets.pyi
13
14
  python/satkit/py.typed
14
15
  python/satkit/satkit.pyi
15
16
  python/satkit/satprop.pyi
@@ -20,7 +21,6 @@ python/satkit.egg-info/SOURCES.txt
20
21
  python/satkit.egg-info/dependency_links.txt
21
22
  python/satkit.egg-info/requires.txt
22
23
  python/satkit.egg-info/top_level.txt
23
- python/satkit/astro-data/py.typed
24
24
  python/test/download_data.py
25
25
  python/test/download_from_json.py
26
26
  python/test/download_testvecs.py
@@ -32,8 +32,10 @@ src/consts.rs
32
32
  src/duration.rs
33
33
  src/earth_orientation_params.rs
34
34
  src/earthgravity.rs
35
+ src/frames.rs
35
36
  src/itrfcoord.rs
36
37
  src/jplephem.rs
38
+ src/kepler.rs
37
39
  src/lib.rs
38
40
  src/nrlmsise.rs
39
41
  src/solarsystem.rs
@@ -45,6 +47,7 @@ src/frametransform/mod.rs
45
47
  src/frametransform/qcirs2gcrs.rs
46
48
  src/lpephem/mod.rs
47
49
  src/lpephem/moon.rs
50
+ src/lpephem/planets.rs
48
51
  src/lpephem/sun.rs
49
52
  src/ode/harmonic_oscillator.rs
50
53
  src/ode/mod.rs
@@ -76,11 +79,14 @@ src/pybindings/pyastrotime.rs
76
79
  src/pybindings/pyconsts.rs
77
80
  src/pybindings/pydensity.rs
78
81
  src/pybindings/pyduration.rs
82
+ src/pybindings/pyframes.rs
79
83
  src/pybindings/pyframetransform.rs
80
84
  src/pybindings/pygravity.rs
81
85
  src/pybindings/pyitrfcoord.rs
82
86
  src/pybindings/pyjplephem.rs
87
+ src/pybindings/pykepler.rs
83
88
  src/pybindings/pylpephem_moon.rs
89
+ src/pybindings/pylpephem_planets.rs
84
90
  src/pybindings/pylpephem_sun.rs
85
91
  src/pybindings/pynrlmsise.rs
86
92
  src/pybindings/pypropagate.rs
@@ -1,3 +1,4 @@
1
+ # %%
1
2
  """
2
3
  This function reads an SP3 file containing precise GPS locaions in the ITRF frame
3
4
 
@@ -24,16 +25,30 @@ import os
24
25
  basedir = os.getenv(
25
26
  "SATKIT_TESTVEC_ROOT", default="../.." + os.path.sep + "satkit-testvecs"
26
27
  )
27
- fname = (
28
- basedir
29
- + os.path.sep
30
- + "orbitprop"
31
- + os.path.sep
32
- + "ESA0OPSFIN_20233640000_01D_05M_ORB.SP3"
33
- )
34
28
 
35
- # Get positions and times from SP3 file
36
- [pitrf, timearr] = read_sp3file(fname)
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
+
49
+ print(pitrf.shape)
50
+ print(timearr.shape)
51
+ print(timearr[0], timearr[-1])
37
52
 
38
53
  # Rotate positions to the GCRF frame
39
54
  pgcrf = np.stack(
@@ -42,13 +57,12 @@ pgcrf = np.stack(
42
57
  ),
43
58
  axis=0,
44
59
  )
45
-
46
60
  # Crude estimation of initial velocity
47
61
  vgcrf = (pgcrf[1, :] - pgcrf[0, :]) / (timearr[1] - timearr[0]).seconds()
48
62
 
49
63
  # Initial state for non-linear least squares is initial velocity
50
64
  # and susceptibility to radiation pressuer : Cr A / m
51
- v0 = np.array([vgcrf[0], vgcrf[1], vgcrf[2], 1 * 10**2 / 5000])
65
+ v0 = np.array([vgcrf[0], vgcrf[1], vgcrf[2], 0.01])
52
66
 
53
67
 
54
68
  def minfunc(v):
@@ -68,6 +82,7 @@ def minfunc(v):
68
82
  propsettings=settings,
69
83
  satproperties=satprops,
70
84
  )
85
+
71
86
  return np.sum(np.sum((res["pos"] - pgcrf) ** 2, axis=1), axis=0)
72
87
 
73
88
 
@@ -75,3 +90,23 @@ def minfunc(v):
75
90
  # by tuning initial velocity and CrAoverM
76
91
  r = minimize(minfunc, v0, method="Nelder-Mead")
77
92
  print(r)
93
+
94
+ # %%
95
+ import plotly.graph_objects as go
96
+
97
+ settings = sk.satprop.propsettings()
98
+ settings.use_jplephem = False
99
+ satprops = sk.satprop.satproperties_static()
100
+ satprops.craoverm = r.x[3]
101
+ res = sk.satprop.propagate(
102
+ pgcrf[0,:], r.x[0:3], timearr[0],
103
+ stoptime=timearr[-1], dt=sk.duration(minutes=5),
104
+ propsettings=settings, satproperties=satprops
105
+ )
106
+ perr = res['pos'] - pgcrf
107
+ fig = go.Figure()
108
+ fig.add_trace(go.Scatter(x=[t.datetime() for t in timearr], y=perr[:,0], mode='lines', name='X'))
109
+ fig.add_trace(go.Scatter(x=[t.datetime() for t in timearr], y=perr[:,1], mode='lines', name='Y'))
110
+ fig.add_trace(go.Scatter(x=[t.datetime() for t in timearr], y=perr[:,2], mode='lines', name='Z'))
111
+
112
+ # %%
@@ -121,6 +121,44 @@ class TestTime:
121
121
  assert minute == 0
122
122
  assert sec == 0
123
123
 
124
+ class TestKepler:
125
+ def test_kepler_from_pv(self):
126
+ """
127
+ Test creation of Kepler elements from position and velocity
128
+ """
129
+
130
+ # Test case from Vallado, example 2-6
131
+ r = np.array([6524.834, 6862.875, 6448.296])*1.0e3
132
+ v = np.array([4.901327, 5.533756, -1.976341])*1.0e3
133
+ kep = sk.kepler.from_pv(r, v)
134
+ rad2deg = 180.0/m.pi
135
+ print(kep)
136
+ assert kep.a == pytest.approx(36127343, 1.0e-3)
137
+ assert kep.eccen == pytest.approx(0.83285, 1.0e-5)
138
+ assert kep.inclination*rad2deg == pytest.approx(87.87, 1.0e-3)
139
+ assert kep.raan*rad2deg == pytest.approx(227.89, 1.0e-3)
140
+ assert kep.w*rad2deg == pytest.approx(53.38, 1.0e-3)
141
+ assert kep.nu*rad2deg == pytest.approx(92.335, 1.0e-3)
142
+
143
+ def test_kepler_to_pv(self):
144
+ """
145
+ Test conversion of Kepler elements to position and velocity
146
+ """
147
+ p = 11067790
148
+ eccen = 0.83285
149
+ incl = 87.87*m.pi/180
150
+ raan = 227.89*m.pi/180
151
+ w = 53.38*m.pi/180
152
+ nu = 92.335*m.pi/180
153
+
154
+ a = p/(1-eccen**2)
155
+ kep = sk.kepler(a, eccen, incl, raan, w, nu)
156
+ pos, vel = kep.to_pv()
157
+ assert pos == pytest.approx(np.array([6525.368, 6861.532, 6449.119])*1.0e3, 1.0e-3)
158
+ assert vel == pytest.approx(np.array([4.902279, 5.533140, -1.975710])*1.0e3, 1.0e-3)
159
+
160
+
161
+
124
162
  class TestJPLEphem:
125
163
  def test_jplephem_testvecs(self):
126
164
  """
@@ -423,7 +423,7 @@ impl AstroTime {
423
423
  /// # Returns
424
424
  ///
425
425
  /// * AstroTime Object
426
- pub fn from_date(year: u32, month: u32, day: u32) -> AstroTime {
426
+ pub fn from_date(year: i32, month: u32, day: u32) -> AstroTime {
427
427
  AstroTime::from_mjd(date2mjd_utc(year, month, day) as f64, Scale::UTC)
428
428
  }
429
429
 
@@ -500,7 +500,7 @@ impl AstroTime {
500
500
  /// * AstroTime object
501
501
  #[inline]
502
502
  pub fn from_datetime(
503
- year: u32,
503
+ year: i32,
504
504
  month: u32,
505
505
  day: u32,
506
506
  hour: u32,
@@ -526,7 +526,7 @@ impl AstroTime {
526
526
  ///
527
527
  /// * AstroTime object
528
528
  pub fn from_datetime_with_scale(
529
- year: u32,
529
+ year: i32,
530
530
  month: u32,
531
531
  day: u32,
532
532
  hour: u32,
@@ -649,7 +649,7 @@ fn mjd_utc2date(mjd_utc: f64) -> (u32, u32, u32) {
649
649
  (year as u32, month as u32, day as u32)
650
650
  }
651
651
 
652
- fn date2mjd_utc(year: u32, month: u32, day: u32) -> i32 {
652
+ fn date2mjd_utc(year: i32, month: u32, day: u32) -> i32 {
653
653
  // Chapter 15 "Calendars" section 15.11.3 of the
654
654
  // Explanatory Suppliment to the Astronomical Almanac
655
655
  // Algorithm 3
@@ -0,0 +1,52 @@
1
+
2
+
3
+ #[derive(Clone, Debug)]
4
+ pub enum Frame {
5
+ /// International Terrestrial Reference Frame
6
+ ITRF,
7
+ /// Terrestrial Intermediate Reference System
8
+ TIRS,
9
+ /// Celestial Intermediate Reference System
10
+ CIRS,
11
+ /// Geocentric Celestial Reference Frame
12
+ GCRF,
13
+ /// True Equator Mean Equinox
14
+ TEME,
15
+ /// Earth Mean Equator 2000
16
+ EME2000,
17
+ /// International Celestial Reference Frame
18
+ ICRF,
19
+ /// Local Vertical Local Horizontal
20
+ LVLH,
21
+ }
22
+
23
+ impl std::fmt::Display for Frame {
24
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
25
+ match self {
26
+ Frame::ITRF => write!(f, "ITRF"),
27
+ Frame::TIRS => write!(f, "TIRS"),
28
+ Frame::CIRS => write!(f, "CIRS"),
29
+ Frame::GCRF => write!(f, "GCRF"),
30
+ Frame::TEME => write!(f, "TEME"),
31
+ Frame::EME2000 => write!(f, "EME2000"),
32
+ Frame::ICRF => write!(f, "ICRF"),
33
+ Frame::LVLH => write!(f, "LVLH"),
34
+ }
35
+ }
36
+ }
37
+
38
+ impl Frame {
39
+ pub fn from_str(s: &str) -> Result<Self, &'static str> {
40
+ match s {
41
+ "ITRF" => Ok(Frame::ITRF),
42
+ "TIRS" => Ok(Frame::TIRS),
43
+ "CIRS" => Ok(Frame::CIRS),
44
+ "GCRF" => Ok(Frame::GCRF),
45
+ "TEME" => Ok(Frame::TEME),
46
+ "EME2000" => Ok(Frame::EME2000),
47
+ "ICRF" => Ok(Frame::ICRF),
48
+ "LVLH" => Ok(Frame::LVLH),
49
+ _ => Err("Invalid frame"),
50
+ }
51
+ }
52
+ }
@@ -210,7 +210,7 @@ pub fn qgcrf2itrf_approx(tm: &AstroTime) -> Quat {
210
210
  // Neglecting polar motion
211
211
  let qitrf2tod_approx: Quat = qrot_zcoord(-gast(tm));
212
212
 
213
- qmod2gcrf(tm) * qtod2mod_approx(tm) * qitrf2tod_approx
213
+ (qmod2gcrf(tm) * qtod2mod_approx(tm) * qitrf2tod_approx).conjugate()
214
214
  }
215
215
 
216
216
  ///
@@ -38,17 +38,17 @@ impl TryFrom<i32> for SolarSystem {
38
38
  type Error = ();
39
39
  fn try_from(v: i32) -> Result<Self, Self::Error> {
40
40
  match v {
41
- x if x == SolarSystem::MERCURY as i32 => Ok(SolarSystem::MERCURY),
42
- x if x == SolarSystem::VENUS as i32 => Ok(SolarSystem::VENUS),
41
+ x if x == SolarSystem::Mercury as i32 => Ok(SolarSystem::Mercury),
42
+ x if x == SolarSystem::Venus as i32 => Ok(SolarSystem::Venus),
43
43
  x if x == SolarSystem::EMB as i32 => Ok(SolarSystem::EMB),
44
- x if x == SolarSystem::MARS as i32 => Ok(SolarSystem::MARS),
45
- x if x == SolarSystem::JUPITER as i32 => Ok(SolarSystem::JUPITER),
46
- x if x == SolarSystem::SATURN as i32 => Ok(SolarSystem::SATURN),
47
- x if x == SolarSystem::URANUS as i32 => Ok(SolarSystem::URANUS),
48
- x if x == SolarSystem::NEPTUNE as i32 => Ok(SolarSystem::NEPTUNE),
49
- x if x == SolarSystem::PLUTO as i32 => Ok(SolarSystem::PLUTO),
50
- x if x == SolarSystem::MOON as i32 => Ok(SolarSystem::MOON),
51
- x if x == SolarSystem::SUN as i32 => Ok(SolarSystem::SUN),
44
+ x if x == SolarSystem::Mars as i32 => Ok(SolarSystem::Mars),
45
+ x if x == SolarSystem::Jupiter as i32 => Ok(SolarSystem::Jupiter),
46
+ x if x == SolarSystem::Saturn as i32 => Ok(SolarSystem::Saturn),
47
+ x if x == SolarSystem::Uranus as i32 => Ok(SolarSystem::Uranus),
48
+ x if x == SolarSystem::Neptune as i32 => Ok(SolarSystem::Neptune),
49
+ x if x == SolarSystem::Pluto as i32 => Ok(SolarSystem::Pluto),
50
+ x if x == SolarSystem::Moon as i32 => Ok(SolarSystem::Moon),
51
+ x if x == SolarSystem::Sun as i32 => Ok(SolarSystem::Sun),
52
52
  _ => Err(()),
53
53
  }
54
54
  }
@@ -130,7 +130,7 @@ impl JPLEphem {
130
130
  /// let t = AstroTime::from_datetime(2021, 3, 1, 12, 0, 0.0);
131
131
  ///
132
132
  /// // Find geocentric moon position at this time in the GCRF frame
133
- /// let p = jplephem::geocentric_pos(SolarSystem::MOON, &t).unwrap();
133
+ /// let p = jplephem::geocentric_pos(SolarSystem::Moon, &t).unwrap();
134
134
  /// println!("p = {}", p);
135
135
  /// ```
136
136
  ///
@@ -453,11 +453,11 @@ impl JPLEphem {
453
453
  /// 3-vector of cartesian Geocentric position in meters
454
454
  ///
455
455
  fn geocentric_pos(&self, body: SolarSystem, tm: &AstroTime) -> SKResult<Vec3> {
456
- if body == SolarSystem::MOON {
456
+ if body == SolarSystem::Moon {
457
457
  return self.barycentric_pos(body, tm);
458
458
  } else {
459
459
  let emb: Vec3 = self.barycentric_pos(SolarSystem::EMB, tm)?;
460
- let moon: Vec3 = self.barycentric_pos(SolarSystem::MOON, tm)?;
460
+ let moon: Vec3 = self.barycentric_pos(SolarSystem::Moon, tm)?;
461
461
  let b: Vec3 = self.barycentric_pos(body, tm)?;
462
462
 
463
463
  // Compute the position of the body relative to the Earth-moon
@@ -483,11 +483,11 @@ impl JPLEphem {
483
483
  /// Note: velocity is relative to Earth
484
484
  ///
485
485
  fn geocentric_state(&self, body: SolarSystem, tm: &AstroTime) -> SKResult<(Vec3, Vec3)> {
486
- if body == SolarSystem::MOON {
486
+ if body == SolarSystem::Moon {
487
487
  return self.barycentric_state(body, tm);
488
488
  } else {
489
489
  let emb: (Vec3, Vec3) = self.barycentric_state(SolarSystem::EMB, tm)?;
490
- let moon: (Vec3, Vec3) = self.barycentric_state(SolarSystem::MOON, tm)?;
490
+ let moon: (Vec3, Vec3) = self.barycentric_state(SolarSystem::Moon, tm)?;
491
491
  let b: (Vec3, Vec3) = self.barycentric_state(body, tm)?;
492
492
 
493
493
  // Compute the position of the body relative to the Earth-moon
@@ -613,7 +613,7 @@ mod tests {
613
613
 
614
614
  let tm = AstroTime::from_jd(2451545.0, Scale::TT);
615
615
  //let tm = &AstroTime::from_jd(2451545.0, Scale::UTC);
616
- let (_, _): (Vec3, Vec3) = jpl.geocentric_state(SolarSystem::MOON, &tm).unwrap();
616
+ let (_, _): (Vec3, Vec3) = jpl.geocentric_state(SolarSystem::Moon, &tm).unwrap();
617
617
  println!("au = {:.20}", jpl._au);
618
618
  }
619
619
 
@@ -672,7 +672,7 @@ mod tests {
672
672
  let (_mpos, mvel): (Vec3, Vec3) = jplephem_singleton()
673
673
  .as_ref()
674
674
  .unwrap()
675
- .geocentric_state(SolarSystem::MOON, &tm)
675
+ .geocentric_state(SolarSystem::Moon, &tm)
676
676
  .unwrap();
677
677
  // Scale Earth velocity
678
678
  tvel = tvel - mvel / (1.0 + jplephem_singleton().as_ref().unwrap().emrat);
@@ -682,7 +682,7 @@ mod tests {
682
682
  let (_mpos, mvel): (Vec3, Vec3) = jplephem_singleton()
683
683
  .as_ref()
684
684
  .unwrap()
685
- .geocentric_state(SolarSystem::MOON, &tm)
685
+ .geocentric_state(SolarSystem::Moon, &tm)
686
686
  .unwrap();
687
687
  //Scale Earth velocity
688
688
  svel = svel - mvel / (1.0 + jplephem_singleton().as_ref().unwrap().emrat);