satkit 0.2.9__tar.gz → 0.3.0__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 (122) hide show
  1. {satkit-0.2.9 → satkit-0.3.0}/Cargo.toml +6 -6
  2. {satkit-0.2.9/python/satkit.egg-info → satkit-0.3.0}/PKG-INFO +1 -1
  3. {satkit-0.2.9 → satkit-0.3.0}/pyproject.toml +1 -1
  4. {satkit-0.2.9 → satkit-0.3.0}/python/docs/source/conf.py +4 -4
  5. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/__init__.pyi +2 -1
  6. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/density.pyi +15 -28
  7. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/satkit.pyi +110 -20
  8. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/satprop.pyi +41 -118
  9. {satkit-0.2.9 → satkit-0.3.0/python/satkit.egg-info}/PKG-INFO +1 -1
  10. {satkit-0.2.9 → satkit-0.3.0}/python/satkit.egg-info/SOURCES.txt +1 -0
  11. {satkit-0.2.9 → satkit-0.3.0}/python/test/test.py +7 -5
  12. {satkit-0.2.9 → satkit-0.3.0}/src/astrotime.rs +2 -2
  13. {satkit-0.2.9 → satkit-0.3.0}/src/duration.rs +2 -1
  14. {satkit-0.2.9 → satkit-0.3.0}/src/earthgravity.rs +7 -8
  15. {satkit-0.2.9 → satkit-0.3.0}/src/lib.rs +4 -3
  16. {satkit-0.2.9 → satkit-0.3.0}/src/ode/mod.rs +4 -0
  17. {satkit-0.2.9 → satkit-0.3.0}/src/ode/nalgebra.rs +0 -5
  18. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rk_adaptive.rs +38 -97
  19. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rk_explicit.rs +1 -0
  20. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkts54.rs +29 -18
  21. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkv65.rs +27 -18
  22. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkv87.rs +28 -18
  23. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkv98.rs +13 -26
  24. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkv98_nointerp.rs +2 -11
  25. {satkit-0.2.9 → satkit-0.3.0}/src/ode/types.rs +1 -13
  26. {satkit-0.2.9 → satkit-0.3.0}/src/orbitprop/propagator.rs +101 -46
  27. {satkit-0.2.9 → satkit-0.3.0}/src/orbitprop/satstate.rs +5 -5
  28. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/mod.rs +5 -6
  29. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyastrotime.rs +107 -81
  30. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyitrfcoord.rs +41 -42
  31. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pykepler.rs +3 -3
  32. satkit-0.3.0/src/pybindings/pypropagate.rs +181 -0
  33. satkit-0.3.0/src/pybindings/pypropresult.rs +217 -0
  34. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pysatstate.rs +94 -26
  35. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyutils.rs +35 -4
  36. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/sgp4.rs +7 -7
  37. satkit-0.3.0/src/types.rs +9 -0
  38. satkit-0.2.9/src/pybindings/pypropagate.rs +0 -298
  39. satkit-0.2.9/src/types.rs +0 -2
  40. {satkit-0.2.9 → satkit-0.3.0}/LICENSE +0 -0
  41. {satkit-0.2.9 → satkit-0.3.0}/MANIFEST.in +0 -0
  42. {satkit-0.2.9 → satkit-0.3.0}/README.md +0 -0
  43. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/__init__.py +0 -0
  44. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/frametransform.pyi +0 -0
  45. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/jplephem.pyi +0 -0
  46. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/moon.pyi +0 -0
  47. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/planets.pyi +0 -0
  48. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/py.typed +0 -0
  49. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/sun.pyi +0 -0
  50. {satkit-0.2.9 → satkit-0.3.0}/python/satkit/utils.pyi +0 -0
  51. {satkit-0.2.9 → satkit-0.3.0}/python/satkit.egg-info/dependency_links.txt +0 -0
  52. {satkit-0.2.9 → satkit-0.3.0}/python/satkit.egg-info/requires.txt +0 -0
  53. {satkit-0.2.9 → satkit-0.3.0}/python/satkit.egg-info/top_level.txt +0 -0
  54. {satkit-0.2.9 → satkit-0.3.0}/python/test/download_data.py +0 -0
  55. {satkit-0.2.9 → satkit-0.3.0}/python/test/download_from_json.py +0 -0
  56. {satkit-0.2.9 → satkit-0.3.0}/python/test/download_testvecs.py +0 -0
  57. {satkit-0.2.9 → satkit-0.3.0}/python/test/orbitprop_gps_fit.py +0 -0
  58. {satkit-0.2.9 → satkit-0.3.0}/python/test/sp3file.py +0 -0
  59. {satkit-0.2.9 → satkit-0.3.0}/setup.cfg +0 -0
  60. {satkit-0.2.9 → satkit-0.3.0}/src/consts.rs +0 -0
  61. {satkit-0.2.9 → satkit-0.3.0}/src/earth_orientation_params.rs +0 -0
  62. {satkit-0.2.9 → satkit-0.3.0}/src/frames.rs +0 -0
  63. {satkit-0.2.9 → satkit-0.3.0}/src/frametransform/ierstable.rs +0 -0
  64. {satkit-0.2.9 → satkit-0.3.0}/src/frametransform/mod.rs +0 -0
  65. {satkit-0.2.9 → satkit-0.3.0}/src/frametransform/qcirs2gcrs.rs +0 -0
  66. {satkit-0.2.9 → satkit-0.3.0}/src/itrfcoord.rs +0 -0
  67. {satkit-0.2.9 → satkit-0.3.0}/src/jplephem.rs +0 -0
  68. {satkit-0.2.9 → satkit-0.3.0}/src/kepler.rs +0 -0
  69. {satkit-0.2.9 → satkit-0.3.0}/src/lpephem/mod.rs +0 -0
  70. {satkit-0.2.9 → satkit-0.3.0}/src/lpephem/moon.rs +0 -0
  71. {satkit-0.2.9 → satkit-0.3.0}/src/lpephem/planets.rs +0 -0
  72. {satkit-0.2.9 → satkit-0.3.0}/src/lpephem/sun.rs +0 -0
  73. {satkit-0.2.9 → satkit-0.3.0}/src/nrlmsise.rs +0 -0
  74. {satkit-0.2.9 → satkit-0.3.0}/src/ode/harmonic_oscillator.rs +0 -0
  75. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rk_adaptive_settings.rs +0 -0
  76. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkf45.rs +0 -0
  77. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkv65_table.rs +0 -0
  78. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkv87_table.rs +0 -0
  79. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkv98_nointerp_table.rs +0 -0
  80. {satkit-0.2.9 → satkit-0.3.0}/src/ode/rkv98_table.rs +0 -0
  81. {satkit-0.2.9 → satkit-0.3.0}/src/orbitprop/drag.rs +0 -0
  82. {satkit-0.2.9 → satkit-0.3.0}/src/orbitprop/mod.rs +0 -0
  83. {satkit-0.2.9 → satkit-0.3.0}/src/orbitprop/point_gravity.rs +0 -0
  84. {satkit-0.2.9 → satkit-0.3.0}/src/orbitprop/satproperties.rs +0 -0
  85. {satkit-0.2.9 → satkit-0.3.0}/src/orbitprop/settings.rs +0 -0
  86. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/mod_utils.rs +0 -0
  87. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyconsts.rs +0 -0
  88. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pydensity.rs +0 -0
  89. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyduration.rs +0 -0
  90. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyframes.rs +0 -0
  91. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyframetransform.rs +0 -0
  92. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pygravity.rs +0 -0
  93. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyjplephem.rs +0 -0
  94. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pylpephem_moon.rs +0 -0
  95. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pylpephem_planets.rs +0 -0
  96. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pylpephem_sun.rs +0 -0
  97. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pynrlmsise.rs +0 -0
  98. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pypropsettings.rs +0 -0
  99. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pyquaternion.rs +0 -0
  100. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pysatproperties.rs +0 -0
  101. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pysgp4.rs +0 -0
  102. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pysolarsystem.rs +0 -0
  103. {satkit-0.2.9 → satkit-0.3.0}/src/pybindings/pytle.rs +0 -0
  104. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/dpper.rs +0 -0
  105. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/dscom.rs +0 -0
  106. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/dsinit.rs +0 -0
  107. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/dspace.rs +0 -0
  108. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/getgravconst.rs +0 -0
  109. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/initl.rs +0 -0
  110. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/mod.rs +0 -0
  111. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/satrec.rs +0 -0
  112. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/sgp4_lowlevel.rs +0 -0
  113. {satkit-0.2.9 → satkit-0.3.0}/src/sgp4/sgp4init.rs +0 -0
  114. {satkit-0.2.9 → satkit-0.3.0}/src/solarsystem.rs +0 -0
  115. {satkit-0.2.9 → satkit-0.3.0}/src/spaceweather.rs +0 -0
  116. {satkit-0.2.9 → satkit-0.3.0}/src/tle.rs +0 -0
  117. {satkit-0.2.9 → satkit-0.3.0}/src/utils/datadir.rs +0 -0
  118. {satkit-0.2.9 → satkit-0.3.0}/src/utils/download.rs +0 -0
  119. {satkit-0.2.9 → satkit-0.3.0}/src/utils/mod.rs +0 -0
  120. {satkit-0.2.9 → satkit-0.3.0}/src/utils/skerror.rs +0 -0
  121. {satkit-0.2.9 → satkit-0.3.0}/src/utils/test.rs +0 -0
  122. {satkit-0.2.9 → satkit-0.3.0}/src/utils/update_data.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "satkit"
3
- version = "0.2.9"
3
+ version = "0.3.0"
4
4
  edition = "2021"
5
5
  description = "Satellite Toolkit"
6
6
  readme = "README.md"
@@ -20,25 +20,25 @@ name = "satkit"
20
20
 
21
21
 
22
22
  [dependencies]
23
- nalgebra = "0.32.3"
23
+ nalgebra = "0.33.0"
24
24
  ndarray = "0.15.6"
25
25
  libc = "0.2"
26
26
  chrono = "0.4.19"
27
27
  cty = "0.2.2"
28
28
  num-traits = "0.2"
29
29
  thiserror = "1.0"
30
- simba = "0.8"
30
+ simba = "0.9"
31
31
  once_cell = "1.6.0"
32
32
  numpy = { version = "0.21.0", optional = true }
33
- pyo3 = { version = "0.21.0", features = ["extension-module"], optional = true }
33
+ pyo3 = { version = "0.21", features = ["extension-module"], optional = true }
34
34
  ureq = "2.9.1"
35
35
  json = "0.12.4"
36
36
  process_path = "0.1.4"
37
37
 
38
38
  [build-dependencies]
39
39
  cc = { version = "1.0.74", features = ["parallel"] }
40
- chrono = "0.4.19"
41
- pyo3-build-config = { version = "0.21.0", optional = true }
40
+ chrono = "0.4.38"
41
+ pyo3-build-config = { version = "0.21", optional = true }
42
42
 
43
43
  [dev-dependencies]
44
44
  rand = "0.8.5"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satkit
3
- Version: 0.2.9
3
+ Version: 0.3.0
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.2.9"
7
+ version = "0.3.0"
8
8
  dependencies = ["numpy>=1.20.0"]
9
9
  requires-python = ">= 3.8"
10
10
  authors = [{ name = "Steven Michael", email = "ssmichael@gmail.com" }]
@@ -77,8 +77,8 @@ github_project_url = "https://github.com/ssmichael1/satkit"
77
77
  ##version = "%i.%i" % version_ns["version_info"][:2]
78
78
  # The full version, including alpha/beta/rc tags.
79
79
  ##release = version_ns["__version__"]
80
- version = "0.2.7"
81
- release = "0.2.7"
80
+ version = "0.2.9"
81
+ release = "0.2.9"
82
82
 
83
83
  # The language for content autogenerated by Sphinx. Refer to documentation
84
84
  # for a list of supported languages.
@@ -162,7 +162,7 @@ html_theme = "sphinx_rtd_theme"
162
162
  # NOTE: Sphinx's 'make html' builder will throw a warning about an unfound
163
163
  # _static directory. Do not remove or comment out html_static_path
164
164
  # since it is needed to properly generate _static in the build directory
165
- html_static_path = ["source/_static"]
165
+ html_static_path = ["_static"]
166
166
 
167
167
  # Add any extra paths that contain custom files (such as robots.txt or
168
168
  # .htaccess) here, relative to this directory. These files are copied
@@ -324,5 +324,5 @@ intersphinx_mapping = {
324
324
  spelling_lang = "en_US"
325
325
  spelling_word_list_filename = "spelling_wordlist.txt"
326
326
 
327
- primary_domain = "python"
327
+ # primary_domain = "python"
328
328
  highlight_language = "python"
@@ -31,6 +31,7 @@ __all__ = [
31
31
  "sun",
32
32
  "planets",
33
33
  "satprop",
34
+ "satstate",
34
35
  "density",
35
- "utils"
36
+ "utils",
36
37
  ]
@@ -22,22 +22,16 @@ def nrlmsise(itrf: satkit.itrfcoord, time: satkit.time | None) -> typing.Tuple[f
22
22
  or for more detail:
23
23
  https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2002JA009430
24
24
 
25
- Inputs:
25
+ Args:
26
26
 
27
- itrf: satkit.itrfcoord representing position at which to
28
- compute density & temperature
29
-
30
- time: Optional instant at which to compute density & temperature.
27
+ itrf (satkit.itrfcoord): position at which to compute density & temperature
28
+ time (satkit.time|numpy.ndarray|list): Optional instant(s) at which to compute density & temperature.
31
29
  "Space weather" data at this time will be used in model
32
30
  computation. Note: at satellite altitudes, density can
33
31
  change by > 10 X depending on solar cycle
34
32
 
35
- Outputs:
36
-
37
- rho: Atmosphere mass density in kg / m^3
38
-
39
- T: Atmosphere temperature in Kelvin
40
-
33
+ Returns:
34
+ tuple: (rho, T) where rho is mass density in kg/m^3 and T is temperature in Kelvin
41
35
  """
42
36
 
43
37
  @typing.overload
@@ -53,22 +47,15 @@ def nrlmsise(altitude_meters: float,
53
47
  or for more detail:
54
48
  https://agupubs.onlinelibrary.wiley.com/doi/full/10.1029/2002JA009430
55
49
 
56
- Inputs:
57
-
58
- altitude_meters: Altitude in meters
59
-
60
- latitude_rad: Latitude in radians
61
-
62
- longitude_rad: Longitude in radians
50
+ Args:
51
+ altitude_meters (float): Altitude in meters
52
+ latitude_rad (float, optional): Latitude in radians. Default is 0.
53
+ longitude_rad (float, optional): Longitude in radians. Default is 0.
54
+ time (satkit.time|numpy.ndarray|list, optional): Optional instant(s) at which to compute density & temperature.
55
+ "Space weather" data at this time will be used in model
56
+ computation. Note: at satellite altitudes, density can
57
+ change by > 10 X depending on solar cycle
63
58
 
64
- time: Optional instant at which to compute density & temperature.
65
- "Space weather" data at this time will be used in model
66
- computation. Note: at satellite altitudes, density can
67
- change by > 10 X depending on solar cycle
68
- Outputs:
69
-
70
- rho: Atmosphere mass density in kg / m^3
71
-
72
- T: Atmosphere temperature in Kelvin
73
-
59
+ Returns:
60
+ tuple: (rho, T) where rho is mass density in kg/m^3 and T is temperature in Kelvin
74
61
  """
@@ -454,15 +454,17 @@ class time:
454
454
 
455
455
  Notes:
456
456
  * If no arguments are passed in, the created object represents the current time
457
-
457
+ * If year is passed in, month and day must also be passed in
458
+ * If hour is passed in, minute and second must also be passed in
459
+
458
460
  Args:
459
- year (int): Gregorian year (e.g., 2024) (optional)
460
- month (int): Gregorian month (1 = January, 2 = February, ...) (optional)
461
- day (int): Day of month, beginning with 1 (optional)
462
- hour (int): Hour of day, in range [0,23] (optional), default is 0
463
- min (int): Minute of hour, in range [0,59] (optional), default is 0
464
- sec (float): floating point second of minute, in range [0,60) (optional), defialt is 0
465
- scale (satkit.timescale): Time scale (optional), default is satkit.timescale.UTC
461
+ year (int, optional): Gregorian year (e.g., 2024)
462
+ month (int, optional): Gregorian month (1 = January, 2 = February, ...)
463
+ day (int, optional): Day of month, beginning with 1
464
+ hour (int, optional): Hour of day, in range [0,23] (optional), default is 0
465
+ min (int, optional): Minute of hour, in range [0,59], default is 0
466
+ sec (float, optional): floating point second of minute, in range [0,60), default is 0
467
+ scale (satkit.timescale, optional): Time scale , default is satkit.timescale.UTC
466
468
 
467
469
  Returns:
468
470
  satkit.time: Time object representing input date and time, or if no arguments, the current date and time
@@ -488,13 +490,13 @@ class time:
488
490
  * If no arguments are passed in, the created object represents the current time
489
491
 
490
492
  Args:
491
- year (int): Gregorian year (e.g., 2024) (optional)
492
- month (int): Gregorian month (1 = January, 2 = February, ...) (optional)
493
- day (int): Day of month, beginning with 1 (optional)
494
- hour (int): Hour of day, in range [0,23] (optional), default is 0
495
- min (int): Minute of hour, in range [0,59] (optional), default is 0
496
- sec (float): floating point second of minute, in range [0,60) (optional), defialt is 0
497
- scale (satkit.timescale): Time scale (optional), default is satkit.timescale.UTC
493
+ year (int, optional): Gregorian year (e.g., 2024)
494
+ month (int, optional): Gregorian month (1 = January, 2 = February, ...)
495
+ day (int, optional): Day of month, beginning with 1
496
+ hour (int, optional): Hour of day, in range [0,23] (optional), default is 0
497
+ min (int, optional): Minute of hour, in range [0,59], default is 0
498
+ sec (float, optional): floating point second of minute, in range [0,60), default is 0
499
+ scale (satkit.timescale, optional): Time scale , default is satkit.timescale.UTC
498
500
 
499
501
  Returns:
500
502
  satkit.time: Time object representing input date and time, or if no arguments, the current date and time
@@ -541,6 +543,17 @@ class time:
541
543
  satkit.time: Time object representing input Julian date and time scale
542
544
  """
543
545
 
546
+ @staticmethod
547
+ def from_unixtime(ut: float) -> time:
548
+ """Return a time object representing input unixtime
549
+
550
+ Args:
551
+ ut (float): unixtime, UTC seconds since Jan 1, 1970 00:00:00
552
+
553
+ Returns:
554
+ satkit.time: Time object representing input unixtime
555
+ """
556
+
544
557
  @staticmethod
545
558
  def from_mjd(mjd: float, scale: timescale = timescale.UTC) -> time:
546
559
  """Return a time object representing input modified Julian date and time scale
@@ -1125,11 +1138,6 @@ class kepler:
1125
1138
  """Mean anomaly, radians
1126
1139
  """
1127
1140
 
1128
- @property
1129
- def mean_motion(self) -> float:
1130
- """Mean motion, radians / second
1131
- """
1132
-
1133
1141
  @property
1134
1142
  def period(self) -> float:
1135
1143
  """Orbital period, seconds
@@ -1406,3 +1414,85 @@ class consts:
1406
1414
  def jgm3_j2() -> float:
1407
1415
  """ "J2" gravity due oblateness of Earth from JGM3 gravity model, unitless
1408
1416
  """
1417
+ class satstate:
1418
+ """
1419
+ A convenience class representing a satellite position and velocity, and
1420
+ optionally 6x6 position/velocity covariance at a particular instant in time
1421
+
1422
+ This class can be used to propagate the position, velocity, and optional
1423
+ covariance to different points in time.
1424
+ """
1425
+
1426
+ def __init__(
1427
+ self,
1428
+ time: time,
1429
+ pos: npt.ArrayLike[np.float64],
1430
+ vel: npt.ArrayLike[np.float64],
1431
+ cov: npt.ArrayLike[np.float64] | None = None,
1432
+ ):
1433
+ """Create a new satellite state
1434
+
1435
+ Args:
1436
+ time (satkit.time): Time instant of this state
1437
+ pos (npt.ArrayLike[np.float64]): Position in meters in GCRF frame
1438
+ vel (npt.ArrayLike[np.float64]): Velocity in meters / second in GCRF frame
1439
+ cov (npt.ArrayLike[np.float64]|None, optional): Covariance in GCRF frame. Defaults to None. If input, should be a 6x6 numpy array
1440
+
1441
+ Returns:
1442
+ satstate: New satellite state object
1443
+ """
1444
+
1445
+ @property
1446
+ def pos_gcrf(self) -> npt.ArrayLike[np.float64]:
1447
+ """state position in meters in GCRF frame
1448
+
1449
+ Returns:
1450
+ npt.ArrayLike[np.float64]: 3-element numpy array representing position in meters in GCRF frame
1451
+ """
1452
+
1453
+ @property
1454
+ def vel_gcrf(self) -> npt.ArrayLike[np.float64]:
1455
+ """Return this state velocity in meters / second in GCRF
1456
+
1457
+ Returns:
1458
+ npt.ArrayLike[np.float64]: 3-element numpy array representing velocity in meters / second in GCRF frame
1459
+ """
1460
+
1461
+ @property
1462
+ def qgcrf2lvlh(self) -> quaternion:
1463
+ """ Quaternion that rotates from the GCRF to the LVLH frame for the current state
1464
+
1465
+ Returns:
1466
+ satkit.quaternion: Quaternion that rotates from the GCRF to the LVLH frame for the current state
1467
+ """
1468
+
1469
+
1470
+ @property
1471
+ def cov(self) -> npt.ArrayLike[np.float64] | None:
1472
+ """6x6 state covariance matrix in GCRF frame
1473
+
1474
+ Returns:
1475
+ npt.ArrayLike[np.float64] | None: 6x6 numpy array representing state covariance in GCRF frame or None if not set
1476
+ """
1477
+
1478
+
1479
+ @property
1480
+ def time(self) -> time:
1481
+ """Return time of this satellite state
1482
+
1483
+ Returns:
1484
+ satkit.time: Time instant of this state
1485
+ """
1486
+
1487
+ def propagate(self, time: time | duration, propsettings=None) -> satstate:
1488
+ """Propagate this state to a new time, specified by the "time" input, updating the position, the velocity, and the covariance if set
1489
+
1490
+ Args:
1491
+ time (satkit.time|satkit.duration): Time or duration from current time to which to propagate the state
1492
+
1493
+ Keyword Arguments:
1494
+ propsettings: satkit.satprop.propsettings object describing settings to use in the propagation. If omitted, default is used
1495
+
1496
+ Returns:
1497
+ satstate: New satellite state object representing the state at the new time
1498
+ """
@@ -38,134 +38,65 @@ import numpy as np
38
38
  import satkit
39
39
  import datetime
40
40
 
41
- class PropStats(typing.TypedDict):
42
- """PropStats is a dictionary containing statistics for the propagation.
43
- """
44
-
45
- num_eval: int
46
- """int: Number of function evaluations of the force model computed during propagation function call
47
- """
41
+ class propstats:
42
+ @property
43
+ def num_eval() -> int:
44
+ """Number of function evaluations"""
48
45
 
49
- accepted_steps: int
50
- """int: Accepted steps in the adaptive Runga-Kutta solver
51
- """
52
-
53
- rejected_steps: int
54
- """int: Rejected steps in the adaptive Runga-Kutta solver
55
- """
46
+ @property
47
+ def num_accept() -> int:
48
+ """Number of accepted steps in adaptive RK integrator"""
56
49
 
57
- class PropResult(typing.TypedDict):
58
- """
59
- PropResult is a dictionary containing the results of a high-precision orbit propagation that is returned by the "propagate" function
60
- """
50
+ @property
51
+ def num_reject() -> int:
52
+ """Number of rejected steps in adaptive RK integrator"""
61
53
 
62
- time: npt.ArrayLike[satkit.time]
63
- """npt.ArrayLike[satkit.time]: List of satkit.time objects at which time is computed
64
- """
54
+ class propresult:
55
+ """Results of a satellite propagation
65
56
 
66
- pos: npt.ArrayLike[np.float64]
67
- """npt.ArrayLike[float]: GCRF position in meters at output times. Output is Nx3 numpy matrix, where N is the number of times
68
- """
69
-
70
- vel: npt.ArrayLike[np.float64]
71
- """npt.ArrayLike[float]: GCRF velocity in meters per second at output times. Output is Nx3 numpy matrix, where N is the number of times
72
- """
73
-
74
- Phi: typing.NotRequired[npt.ArrayLike[np.float64]]
75
- """6x6 State transition matrix corresponding to each time. Output is Nx6x6 numpy matrix, where N is the lenght of the output "time" list. Not included if output_phi kwarg is set to false (the default)
76
- """
77
-
78
- stats: PropStats
79
- """
80
- (PropStats): Python dictionary with statistics for the propagation. This includes:
81
-
82
- * num_eval: Number of function evaluations of the force model required to get solution with desired accuracy
83
- * accepted_steps: Accepted steps in the adpative Runga-Kutta solver
84
- * rejected_steps: Rejected steps in the adaptive Runga-Kutta solver
85
- """
86
-
87
- class satstate:
88
- """
89
- A convenience class representing a satellite position and velocity, and
90
- optionally 6x6 position/velocity covariance at a particular instant in time
91
-
92
- This class can be used to propagate the position, velocity, and optional
93
- covariance to different points in time.
57
+ This class lets the user access results of the satellite propagation
94
58
  """
95
59
 
96
- def __init__(
97
- self,
98
- time: satkit.time,
99
- pos: npt.ArrayLike[np.float64],
100
- vel: npt.ArrayLike[np.float64],
101
- cov: npt.ArrayLike[np.float64] | None = None,
102
- ):
103
- """Create a new satellite state
104
-
105
- Args:
106
- time (satkit.time): Time instant of this state
107
- pos (npt.ArrayLike[np.float64]): Position in meters in GCRF frame
108
- vel (npt.ArrayLike[np.float64]): Velocity in meters / second in GCRF frame
109
- cov (npt.ArrayLike[np.float64]|None, optional): Covariance in GCRF frame. Defaults to None. If input, should be a 6x6 numpy array
110
-
111
- Returns:
112
- satstate: New satellite state object
113
- """
114
-
115
60
  @property
116
- def pos_gcrf(self) -> npt.ArrayLike[np.float64]:
117
- """state position in meters in GCRF frame
118
-
119
- Returns:
120
- npt.ArrayLike[np.float64]: 3-element numpy array representing position in meters in GCRF frame
121
- """
61
+ def pos() -> npt.ArrayLike[float]:
62
+ """GCRF position of satellite, meters"""
122
63
 
123
64
  @property
124
- def vel_gcrf(self) -> npt.ArrayLike[np.float64]:
125
- """Return this state velocity in meters / second in GCRF
126
-
127
- Returns:
128
- npt.ArrayLike[np.float64]: 3-element numpy array representing velocity in meters / second in GCRF frame
129
- """
65
+ def vel() -> npt.ArrayLike[float]:
66
+ """GCRF velocity of satellite, meters/second"""
130
67
 
131
68
  @property
132
- def qgcrf2lvlh(self) -> satkit.quaternion:
133
- """ Quaternion that rotates from the GCRF to the LVLH frame for the current state
134
-
135
- Returns:
136
- satkit.quaternion: Quaternion that rotates from the GCRF to the LVLH frame for the current state
137
- """
138
-
69
+ def state() -> npt.ArrayLike[float]:
70
+ """6-element state (pos + vel) of satellite in meters & meters/second"""
139
71
 
140
72
  @property
141
- def cov(self) -> npt.ArrayLike[np.float64] | None:
142
- """6x6 state covariance matrix in GCRF frame
143
-
144
- Returns:
145
- npt.ArrayLike[np.float64] | None: 6x6 numpy array representing state covariance in GCRF frame or None if not set
146
- """
73
+ def time() -> satkit.time:
74
+ """Time at which state is valid"""
147
75
 
76
+ @property
77
+ def stats() -> propstats:
78
+ """Statistics of propagation"""
148
79
 
149
80
  @property
150
- def time(self) -> satkit.time:
151
- """Return time of this satellite state
152
-
153
- Returns:
154
- satkit.time: Time instant of this state
155
- """
81
+ def phi() -> npt.ArrayLike[np.float64]|None:
82
+ """6x6 State transition matrix
83
+ or None if not computed
84
+ """
156
85
 
157
- def propagate(self, time: satkit.time|satkit.duration, propsettings=None) -> satstate:
158
- """Propagate this state to a new time, specified by the "time" input, updating the position, the velocity, and the covariance if set
86
+ def interp(time: satkit.time, output_phi: bool=False) -> npt.ArrayLike[np.float64]|typing.Tuple[npt.ArrayLike[np.float64], npt.ArrayLike[np.float64]]:
87
+ """Interpolate state at given time
159
88
 
160
89
  Args:
161
- time (satkit.time|satkit.duration): Time or duration from current time to which to propagate the state
90
+ time (satkit.time): Time at which to interpolate state
162
91
 
163
92
  Keyword Arguments:
164
- propsettings: satkit.satprop.propsettings object describing settings to use in the propagation. If omitted, default is used
93
+ output_phi (bool): Output 6x6 state transition matrix at the interpolated time
165
94
 
166
95
  Returns:
167
- satstate: New satellite state object representing the state at the new time
96
+ 6-element vector representing state at given time
97
+ if output_phi, also output 6x6 state transition matrix at given time
168
98
  """
99
+
169
100
 
170
101
  class satproperties_static:
171
102
  """Satellite properties relevant for drag and radiation pressure
@@ -274,7 +205,7 @@ def propagate(
274
205
  vel: npt.ArrayLike[float],
275
206
  start: satkit.time,
276
207
  **kwargs,
277
- ) -> PropResult:
208
+ ) -> propresult:
278
209
  """High-precision orbit propagator
279
210
 
280
211
  Notes:
@@ -302,21 +233,13 @@ def propagate(
302
233
  duration_secs (float): duration in seconds from "tm" for at which new position and velocity will be computed.
303
234
  duration_days (float): duration in days from "tm" at which new position and velocity will be computed.
304
235
  duration (satkit.duration): duration from "tm" at which new position & velocity will be computed.
305
- dt_secs (float): Interval in seconds between "starttime" and "stoptime" at which solution will also be computed
306
- dt_days (float): Interval in days between "starttime" and "stoptime" at which solution will also be computed
307
- dt (satkit.duration): Interval over which new position & velocity will be computed
308
236
  output_phi (bool): Output 6x6 state transition matrix between "starttime" and "stoptime" (and at intervals, if specified)
309
237
  propsettings (propsettings): "propsettings" object with input settings for the propagation. if left out, default will be used.
310
- satproperties (satproperties_static): "SatPropertiesStatic" object with drag and radiation pressure succeptibility of satellite. If left out, drag and radiation pressure are neglected
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
311
242
 
312
243
  Returns:
313
- (PropResult): Python dictionary with the following elements:
314
- * "time": list of satkit.time objects at which solution is computed
315
- * "pos": GCRF position in meters at "time". Output is a Nx3 numpy matrix, where N is the length of the output "time" list
316
- * "vel": GCRF velocity in meters / second at "time". Output is a Nx3 numpy matrix, where N is the length of the output "time" list
317
- * "Phi": 6x6 State transition matrix corresponding to each time. Output is Nx6x6 numpy matrix, where N is the lenght of the output "time" list. Not included if output_phi kwarg is set to false (the default)
318
- * "stats": Python dictionary with statistics for the propagation. This includes:
319
- * "num_eval": Number of function evaluations of the force model required to get solution with desired accuracy
320
- * "accepted_steps": Accepted steps in the adpative Runga-Kutta solver
321
- * "rejected_steps": Rejected steps in the adaptive Runga-Kutta solver
244
+ (propresult): Propagation result object holding state outputs, statistics, and dense output if requested
322
245
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: satkit
3
- Version: 0.2.9
3
+ Version: 0.3.0
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>
@@ -90,6 +90,7 @@ src/pybindings/pylpephem_planets.rs
90
90
  src/pybindings/pylpephem_sun.rs
91
91
  src/pybindings/pynrlmsise.rs
92
92
  src/pybindings/pypropagate.rs
93
+ src/pybindings/pypropresult.rs
93
94
  src/pybindings/pypropsettings.rs
94
95
  src/pybindings/pyquaternion.rs
95
96
  src/pybindings/pysatproperties.rs
@@ -607,16 +607,18 @@ class TestHighPrecisionPropagation:
607
607
  np.array([2.47130555e03, 2.94682777e03, -5.34171918e02]),
608
608
  timearr[0],
609
609
  stoptime=timearr[-1],
610
- dt=sk.duration.from_minutes(5),
611
610
  propsettings=settings,
612
611
  satproperties=satprops,
612
+ output_dense=True,
613
613
  )
614
+ print(res)
614
615
 
615
616
  # See if propagator is accurate to < 10 meters over 1 day on
616
617
  # each Cartesian axis
617
- for iv in range(pgcrf.shape[0]):
618
+ for iv in range(pgcrf.shape[0]-5):
619
+ state = res.interp(timearr[iv])
618
620
  for ix in range(0, 3):
619
- assert m.fabs(res["pos"][iv, ix] - pgcrf[iv, ix]) < 10
621
+ assert m.fabs(state[ix] - pgcrf[iv, ix]) < 10
620
622
 
621
623
  class TestSatState:
622
624
  def test_lvlh(self):
@@ -624,8 +626,8 @@ class TestSatState:
624
626
  Test rotations of satellite state into the LVLH frame
625
627
  """
626
628
  time = sk.time(2015, 3, 20, 0, 0, 0)
627
- satstate = sk.satprop.satstate(time,
628
- np.array([sk.consts.geo_r, 0, 0]),
629
+ satstate = sk.satstate(time,
630
+ np.array([sk.consts.geo_r, 0, 0]),
629
631
  np.array([0, m.sqrt(sk.consts.mu_earth/sk.consts.geo_r), 0]))
630
632
  state2 = satstate.propagate(time + sk.duration.from_hours(3.5))
631
633
  h =np.cross(state2.pos, state2.vel)
@@ -37,7 +37,7 @@
37
37
  //!
38
38
  #[derive(PartialEq, PartialOrd, Copy, Clone, Debug)]
39
39
  pub struct AstroTime {
40
- mjd_tai: f64,
40
+ pub(crate) mjd_tai: f64,
41
41
  }
42
42
 
43
43
  use crate::utils::{download_if_not_exist, skerror, SKResult};
@@ -92,7 +92,7 @@ const DELTAAT_OLD: [[f64; 4]; 15] = [
92
92
  /// Time Scales
93
93
  ///
94
94
  /// # Enum Values:
95
- ///
95
+ ///
96
96
  /// * `UTC` - Univeral Time Coordiante
97
97
  /// * `TT` - Terrestrial Time
98
98
  /// * `UT1` - UT1
@@ -66,6 +66,7 @@ impl Duration {
66
66
  }
67
67
  }
68
68
 
69
+ /// String representation of duration
69
70
  pub fn to_string(&self) -> String {
70
71
  let mut secs = self.seconds();
71
72
  let mut sign = String::from("");
@@ -77,7 +78,7 @@ impl Duration {
77
78
  // e.g. if seconds = 59.999..., rather than round up and
78
79
  // display "seconds" in second field, show 0 and increment
79
80
  // minutes...
80
- if secs % 60.0 > 59.9995 {
81
+ if secs % 60.0 > 59.9995 {
81
82
  secs = secs + 5.0e-4;
82
83
  }
83
84