astrox-python 1.0.0__tar.gz → 1.1.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 (352) hide show
  1. {astrox_python-1.0.0 → astrox_python-1.1.0}/.gitignore +1 -0
  2. {astrox_python-1.0.0 → astrox_python-1.1.0}/PKG-INFO +1 -1
  3. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/celestial.py +53 -4
  4. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/orbits.py +38 -6
  5. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/propagator.py +31 -0
  6. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/compute_lambert_transfer.md +10 -3
  7. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/propagate_an_orbit.md +3 -1
  8. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/compute_lambert_transfer.md +11 -3
  9. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/propagate_an_orbit.md +3 -1
  10. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/celestial/README.md +27 -9
  11. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/orbits/README.md +18 -2
  12. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/propagator/README.md +40 -1
  13. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/celestial/README.md +27 -9
  14. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/orbits/README.md +18 -2
  15. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/propagator/README.md +40 -1
  16. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/celestial.md +14 -8
  17. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/orbits.md +5 -3
  18. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/propagator.md +26 -0
  19. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/README.md +3 -1
  20. astrox_python-1.1.0/examples/01_propagation/two_body_rv.py +38 -0
  21. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/lambert_delta_v.py +14 -0
  22. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/11_celestial/celestial_queries.py +7 -1
  23. {astrox_python-1.0.0 → astrox_python-1.1.0}/pyproject.toml +2 -2
  24. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/celestial/test_celestial.py +124 -0
  25. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_conversions.py +95 -4
  26. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_public_contract.py +1 -0
  27. astrox_python-1.1.0/tests/sdk/propagator/test_two_body_rv.py +138 -0
  28. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/celestial/test_lambert_transfer_lamberthub.py +144 -4
  29. astrox_python-1.1.0/tests/validation/cross_validation/celestial/test_mpc_target_elements.py +170 -0
  30. astrox_python-1.1.0/tests/validation/cross_validation/orbits/test_lambert_path_points.py +172 -0
  31. astrox_python-1.1.0/tests/validation/cross_validation/propagator/test_two_body_rv_brahe.py +228 -0
  32. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/celestial/celestial.snap.json +16 -1
  33. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/celestial/test_celestial.py +9 -1
  34. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/conversions.snap.json +28 -1
  35. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/test_conversions.py +16 -0
  36. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_two_body.py +22 -1
  37. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/two_body.snap.json +32 -1
  38. {astrox_python-1.0.0 → astrox_python-1.1.0}/uv.lock +34 -23
  39. {astrox_python-1.0.0 → astrox_python-1.1.0}/LICENSE +0 -0
  40. {astrox_python-1.0.0 → astrox_python-1.1.0}/README.md +0 -0
  41. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/__init__.py +0 -0
  42. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/_http.py +0 -0
  43. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/access.py +0 -0
  44. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/astrogator/__init__.py +0 -0
  45. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/astrogator/_api.py +0 -0
  46. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/astrogator/_models.py +0 -0
  47. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/astrogator/_results.py +0 -0
  48. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/cat.py +0 -0
  49. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/catalog.py +0 -0
  50. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/__init__.py +0 -0
  51. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_axes.py +0 -0
  52. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_common.py +0 -0
  53. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_constraints.py +0 -0
  54. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_objects.py +0 -0
  55. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_positions.py +0 -0
  56. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_rotations.py +0 -0
  57. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_sensors.py +0 -0
  58. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_vgt.py +0 -0
  59. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/conjunction.py +0 -0
  60. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/__init__.py +0 -0
  61. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/_core.py +0 -0
  62. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/_fom.py +0 -0
  63. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/coverage_time.py +0 -0
  64. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/number_of_assets.py +0 -0
  65. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/response_time.py +0 -0
  66. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/revisit_time.py +0 -0
  67. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/simple_coverage.py +0 -0
  68. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/exceptions.py +0 -0
  69. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/libration.py +0 -0
  70. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/lighting.py +0 -0
  71. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/rocket.py +0 -0
  72. {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/terrain.py +0 -0
  73. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/CONTRIBUTING.md +0 -0
  74. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/README.md +0 -0
  75. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/automated-workflows.md +0 -0
  76. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/docs-principles.md +0 -0
  77. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/getting_started.md +0 -0
  78. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/README.md +0 -0
  79. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/build_an_hpop_configuration.md +0 -0
  80. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/compute_access_intervals.md +0 -0
  81. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/compute_lighting_conditions.md +0 -0
  82. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/convert_between_orbit_representations.md +0 -0
  83. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/generate_a_crtbp_periodic_orbit.md +0 -0
  84. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/run_an_astrogator_mcs.md +0 -0
  85. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/screen_close_approaches.md +0 -0
  86. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/README.md +0 -0
  87. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/getting_started.md +0 -0
  88. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/README.md +0 -0
  89. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/build_an_hpop_configuration.md +0 -0
  90. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/compute_access_intervals.md +0 -0
  91. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/compute_lighting_conditions.md +0 -0
  92. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/convert_between_orbit_representations.md +0 -0
  93. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/generate_a_crtbp_periodic_orbit.md +0 -0
  94. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/run_an_astrogator_mcs.md +0 -0
  95. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/screen_close_approaches.md +0 -0
  96. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/README.md +0 -0
  97. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/access/README.md +0 -0
  98. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/astrogator/README.md +0 -0
  99. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/cat/README.md +0 -0
  100. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/catalog/README.md +0 -0
  101. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/components/README.md +0 -0
  102. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/conjunction/README.md +0 -0
  103. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/coverage/README.md +0 -0
  104. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/libration/README.md +0 -0
  105. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/lighting/README.md +0 -0
  106. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/rocket/README.md +0 -0
  107. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/terrain/README.md +0 -0
  108. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/README.md +0 -0
  109. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/access/README.md +0 -0
  110. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/astrogator/README.md +0 -0
  111. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/cat/README.md +0 -0
  112. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/catalog/README.md +0 -0
  113. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/components/README.md +0 -0
  114. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/conjunction/README.md +0 -0
  115. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/coverage/README.md +0 -0
  116. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/libration/README.md +0 -0
  117. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/lighting/README.md +0 -0
  118. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/rocket/README.md +0 -0
  119. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/terrain/README.md +0 -0
  120. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/sdk-principles.md +0 -0
  121. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/test-principles.md +0 -0
  122. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/README.md +0 -0
  123. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/access.md +0 -0
  124. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/astrogator.md +0 -0
  125. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/cat.md +0 -0
  126. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/catalog.md +0 -0
  127. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/conjunction.md +0 -0
  128. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/coverage.md +0 -0
  129. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/libration.md +0 -0
  130. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/lighting.md +0 -0
  131. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/rocket.md +0 -0
  132. {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/terrain.md +0 -0
  133. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/ballistic_apogee_alt.py +0 -0
  134. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/ballistic_delta_v.py +0 -0
  135. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/ballistic_min_ecc.py +0 -0
  136. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/ballistic_time_of_flight.py +0 -0
  137. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/batch_propagators.py +0 -0
  138. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/hpop.py +0 -0
  139. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/j2_classical.py +0 -0
  140. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/propagator_reference.py +0 -0
  141. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/sgp4_tle.py +0 -0
  142. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/simple_ascent.py +0 -0
  143. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/two_body_classical.py +0 -0
  144. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/README.md +0 -0
  145. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/conversions.py +0 -0
  146. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/orbit_system.py +0 -0
  147. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/wizards.py +0 -0
  148. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/03_lighting/README.md +0 -0
  149. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/03_lighting/lighting.py +0 -0
  150. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/README.md +0 -0
  151. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/chain.py +0 -0
  152. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/compute.py +0 -0
  153. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/constraints.py +0 -0
  154. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/custom_axes.py +0 -0
  155. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/sensor_pointing.py +0 -0
  156. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/05_rocket/README.md +0 -0
  157. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/05_rocket/landing_zone.py +0 -0
  158. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/README.md +0 -0
  159. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/compute.py +0 -0
  160. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/fom.py +0 -0
  161. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/grid_points.py +0 -0
  162. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/reports.py +0 -0
  163. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/07_astrogator/run_mcs.py +0 -0
  164. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/08_conjunction/README.md +0 -0
  165. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/08_conjunction/close_approaches.py +0 -0
  166. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/09_cat/README.md +0 -0
  167. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/09_cat/cat_workflows.py +0 -0
  168. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/10_catalog/README.md +0 -0
  169. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/10_catalog/catalog_queries.py +0 -0
  170. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/11_celestial/README.md +0 -0
  171. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/12_terrain/README.md +0 -0
  172. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/12_terrain/terrain_masks.py +0 -0
  173. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/13_libration/README.md +0 -0
  174. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/13_libration/libration_dynamics.py +0 -0
  175. {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/manifest.toml +0 -0
  176. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/README.md +0 -0
  177. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/conftest.py +0 -0
  178. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/access/helpers.py +0 -0
  179. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/access/test_chain.py +0 -0
  180. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/access/test_compute.py +0 -0
  181. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/access/test_values.py +0 -0
  182. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/astrogator/test_api.py +0 -0
  183. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/astrogator/test_models.py +0 -0
  184. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/astrogator/test_results.py +0 -0
  185. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/cat/test_cat.py +0 -0
  186. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/catalog/test_catalog.py +0 -0
  187. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/client/test_client.py +0 -0
  188. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/components/test_components.py +0 -0
  189. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/conjunction/test_conjunction.py +0 -0
  190. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/coverage/test_coverage.py +0 -0
  191. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/coverage/test_coverage_fom.py +0 -0
  192. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/helpers.py +0 -0
  193. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/libration/test_libration.py +0 -0
  194. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/lighting/test_lighting.py +0 -0
  195. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/helpers.py +0 -0
  196. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_keplerian.py +0 -0
  197. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_orbit_system.py +0 -0
  198. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_tle.py +0 -0
  199. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_wizards.py +0 -0
  200. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/helpers.py +0 -0
  201. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_ballistic.py +0 -0
  202. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_hpop.py +0 -0
  203. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_j2_two_body.py +0 -0
  204. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_multi.py +0 -0
  205. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_sgp4_simple_ascent.py +0 -0
  206. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/rocket/__init__.py +0 -0
  207. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/rocket/test_rocket.py +0 -0
  208. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/terrain/test_terrain.py +0 -0
  209. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/README.md +0 -0
  210. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_external/gmat/README.md +0 -0
  211. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_external/gmat/hpop_driver.py +0 -0
  212. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_external/gmat/test_hpop_driver.py +0 -0
  213. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/__init__.py +0 -0
  214. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/contracts.py +0 -0
  215. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/external_tools.py +0 -0
  216. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/gmat.py +0 -0
  217. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/orekit.py +0 -0
  218. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/skyfield.py +0 -0
  219. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/test_contracts.py +0 -0
  220. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/test_external_tools.py +0 -0
  221. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/test_gmat.py +0 -0
  222. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/test_skyfield.py +0 -0
  223. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/__init__.py +0 -0
  224. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/README.md +0 -0
  225. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/__init__.py +0 -0
  226. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_aer.py +0 -0
  227. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_cases.py +0 -0
  228. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_constraints.py +0 -0
  229. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_exclusion.py +0 -0
  230. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_geometry.py +0 -0
  231. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_mixed_model.py +0 -0
  232. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_orientation.py +0 -0
  233. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_axes_orientation_geometry.py +0 -0
  234. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_chain_sgp4_skyfield.py +0 -0
  235. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_composite_czml_axes_geometry.py +0 -0
  236. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_constraints_skyfield.py +0 -0
  237. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_exclusion_constraints_invariants.py +0 -0
  238. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_ground_sgp4_skyfield.py +0 -0
  239. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_j2_two_body_geometry.py +0 -0
  240. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_sgp4_j2_geometry.py +0 -0
  241. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_site_hpop_geometry.py +0 -0
  242. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_site_j2_geometry.py +0 -0
  243. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_site_two_body_geometry.py +0 -0
  244. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_sensor_pointing_geometry.py +0 -0
  245. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_vgt_orientation_resolution.py +0 -0
  246. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/__init__.py +0 -0
  247. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_branch_semantics.py +0 -0
  248. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_initial_state_conversions.py +0 -0
  249. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_maneuver_invariants.py +0 -0
  250. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_run_mcs_two_body_brahe.py +0 -0
  251. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_scalar_invariants.py +0 -0
  252. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_sequence_czml_brahe.py +0 -0
  253. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_target_sequence_local.py +0 -0
  254. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/cat/test_cat_skyfield.py +0 -0
  255. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/celestial/test_cb_axes_rotation_invariants.py +0 -0
  256. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/celestial/test_ephemeris_skyfield.py +0 -0
  257. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/conjunction/test_close_approaches_skyfield.py +0 -0
  258. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/_fom_helpers.py +0 -0
  259. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_exclusion_grid_constraints_skyfield.py +0 -0
  260. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_at_time_boundaries_invariants.py +0 -0
  261. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_edge_cases_invariants.py +0 -0
  262. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_grid_options_invariants.py +0 -0
  263. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_interval_invariants.py +0 -0
  264. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_resource_options_invariants.py +0 -0
  265. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_response_shapes_invariants.py +0 -0
  266. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_response_time_dynamic_invariants.py +0 -0
  267. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_grid_generation_local.py +0 -0
  268. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_grid_point_modifiers_invariants.py +0 -0
  269. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_resource_reports_invariants.py +0 -0
  270. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_sgp4_grid_membership_skyfield.py +0 -0
  271. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/_support.py +0 -0
  272. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_cross_endpoint_consistency.py +0 -0
  273. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_crtbp_trajectory.py +0 -0
  274. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_e2m2e_qualification.py +0 -0
  275. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_fixed_x_correction.py +0 -0
  276. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_orekit_qualification.py +0 -0
  277. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_periodic_families.py +0 -0
  278. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_positions_and_units.py +0 -0
  279. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/lighting/__init__.py +0 -0
  280. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/lighting/test_site_sun_skyfield.py +0 -0
  281. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/lighting/test_spacecraft_solar_intensity_orekit.py +0 -0
  282. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/lighting/test_spacecraft_sun_skyfield.py +0 -0
  283. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbit_system/__init__.py +0 -0
  284. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbit_system/_support.py +0 -0
  285. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbit_system/test_convert_czml_position.py +0 -0
  286. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbit_system/test_earth_moon_libration.py +0 -0
  287. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/__init__.py +0 -0
  288. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/test_kozai_izsak_mean_elements_invariants.py +0 -0
  289. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/test_lambert_lamberthub.py +0 -0
  290. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/test_walker_constellation_equations.py +0 -0
  291. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/test_wizards_local_derivation.py +0 -0
  292. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_ballistic_geodetic.py +0 -0
  293. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_hpop_gmat.py +0 -0
  294. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_j2_analytical.py +0 -0
  295. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_multi_sgp4_skyfield.py +0 -0
  296. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_sgp4_skyfield.py +0 -0
  297. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_simple_ascent_geodetic.py +0 -0
  298. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_two_body_brahe.py +0 -0
  299. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/rocket/__init__.py +0 -0
  300. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/rocket/test_landing_zone_geographiclib.py +0 -0
  301. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/terrain/test_terrain_mask_invariants.py +0 -0
  302. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/__init__.py +0 -0
  303. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/__init__.py +0 -0
  304. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/access.snap.json +0 -0
  305. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/test_access.py +0 -0
  306. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/test_chain_topology.py +0 -0
  307. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/test_compute_model_pairs.py +0 -0
  308. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/test_compute_options.py +0 -0
  309. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/astrogator/__init__.py +0 -0
  310. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/astrogator/run_mcs.snap.json +0 -0
  311. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/astrogator/test_run_mcs.py +0 -0
  312. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/cat/cat.snap.json +0 -0
  313. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/cat/test_cat.py +0 -0
  314. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/catalog/catalog.snap.json +0 -0
  315. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/catalog/test_catalog.py +0 -0
  316. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/conjunction/close_approaches.snap.json +0 -0
  317. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/conjunction/test_close_approaches.py +0 -0
  318. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/coverage/coverage.snap.json +0 -0
  319. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/coverage/test_coverage.py +0 -0
  320. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/libration/libration.snap.json +0 -0
  321. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/libration/test_libration.py +0 -0
  322. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/lighting/__init__.py +0 -0
  323. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/lighting/lighting.snap.json +0 -0
  324. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/lighting/test_lighting.py +0 -0
  325. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/__init__.py +0 -0
  326. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/orbit_system.snap.json +0 -0
  327. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/test_conversion_roundtrip.py +0 -0
  328. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/test_orbit_system.py +0 -0
  329. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/test_wizards.py +0 -0
  330. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/wizards.snap.json +0 -0
  331. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/__init__.py +0 -0
  332. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/ballistic.snap.json +0 -0
  333. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/hpop.snap.json +0 -0
  334. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/j2.snap.json +0 -0
  335. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/multi_j2.snap.json +0 -0
  336. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/multi_sgp4.snap.json +0 -0
  337. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/multi_two_body.snap.json +0 -0
  338. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/sgp4.snap.json +0 -0
  339. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/simple_ascent.snap.json +0 -0
  340. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_ballistic.py +0 -0
  341. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_hpop.py +0 -0
  342. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_j2.py +0 -0
  343. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_multi_j2.py +0 -0
  344. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_multi_sgp4.py +0 -0
  345. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_multi_two_body.py +0 -0
  346. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_sgp4.py +0 -0
  347. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_simple_ascent.py +0 -0
  348. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/rocket/__init__.py +0 -0
  349. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/rocket/landing_zone.snap.json +0 -0
  350. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/rocket/test_landing_zone.py +0 -0
  351. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/terrain/terrain.snap.json +0 -0
  352. {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/terrain/test_terrain.py +0 -0
@@ -14,6 +14,7 @@ wheels/
14
14
  # Internal & intermediate docs
15
15
  *.md
16
16
  !README.md
17
+ !AGENTS.md
17
18
  !docs/**/*.md
18
19
  docs/MAINTAINER_QUESTIONS.md
19
20
  !openapi/**/*.md
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: astrox-python
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Summary: Python SDK for the ASTROX Web API.
5
5
  Project-URL: Homepage, https://github.com/Mtrya/astrox-python
6
6
  Project-URL: Repository, https://github.com/Mtrya/astrox-python.git
@@ -74,6 +74,9 @@ class MpcOrbitalElements:
74
74
  raan_deg: float | None = None
75
75
  argument_of_periapsis_deg: float | None = None
76
76
  mean_anomaly_deg: float | None = None
77
+ reference_frame: str | None = None
78
+ """Heliocentric mean-ecliptic variant: ``MeanEclpJ2000`` (JPL) or
79
+ ``EclpJ2000ICRF`` (MPC, server default)."""
77
80
 
78
81
  def __post_init__(self) -> None:
79
82
  for field_name in (
@@ -95,9 +98,14 @@ class MpcOrbitalElements:
95
98
  parameter=field_name,
96
99
  ),
97
100
  )
101
+ object.__setattr__(
102
+ self,
103
+ "reference_frame",
104
+ _optional_string(self.reference_frame, parameter="reference_frame"),
105
+ )
98
106
 
99
- def to_wire(self) -> dict[str, float]:
100
- payload: dict[str, float] = {}
107
+ def to_wire(self) -> dict[str, Any]:
108
+ payload: dict[str, Any] = {}
101
109
  _include_if_supplied(payload, "EpochMjdTdt", self.epoch_mjd_tdt)
102
110
  _include_if_supplied(payload, "PeriTimeMjdTdt", self.periapsis_time_mjd_tdt)
103
111
  _include_if_supplied(payload, "Q", self.periapsis_distance_au)
@@ -111,6 +119,7 @@ class MpcOrbitalElements:
111
119
  self.argument_of_periapsis_deg,
112
120
  )
113
121
  _include_if_supplied(payload, "MeanAnomaly", self.mean_anomaly_deg)
122
+ _include_if_supplied(payload, "ReferenceFrame", self.reference_frame)
114
123
  return payload
115
124
 
116
125
 
@@ -125,6 +134,7 @@ def mpc_orbital_elements(
125
134
  raan_deg: float | None = None,
126
135
  argument_of_periapsis_deg: float | None = None,
127
136
  mean_anomaly_deg: float | None = None,
137
+ reference_frame: str | None = None,
128
138
  ) -> MpcOrbitalElements:
129
139
  """Build an MPC orbital-element fragment without adding physics policy."""
130
140
  return MpcOrbitalElements(
@@ -137,6 +147,7 @@ def mpc_orbital_elements(
137
147
  raan_deg=raan_deg,
138
148
  argument_of_periapsis_deg=argument_of_periapsis_deg,
139
149
  mean_anomaly_deg=mean_anomaly_deg,
150
+ reference_frame=reference_frame,
140
151
  )
141
152
 
142
153
 
@@ -153,7 +164,7 @@ def _elements_to_wire(
153
164
  value: MpcOrbitalElements | None,
154
165
  *,
155
166
  parameter: str,
156
- ) -> dict[str, float] | None:
167
+ ) -> dict[str, Any] | None:
157
168
  if value is None:
158
169
  return None
159
170
  if not isinstance(value, MpcOrbitalElements):
@@ -175,6 +186,9 @@ def lambert_transfer_window(
175
186
  arrival_step_days: float | None = None,
176
187
  departure_elements: MpcOrbitalElements | None = None,
177
188
  arrival_elements: MpcOrbitalElements | None = None,
189
+ max_departure_delta_v_m_s: int | None = None,
190
+ max_arrival_delta_v_m_s: int | None = None,
191
+ max_time_of_flight_days: int | None = None,
178
192
  ) -> dict[str, Any]:
179
193
  """Return a Lambert transfer-window scan from ASTROX.
180
194
 
@@ -236,6 +250,30 @@ def lambert_transfer_window(
236
250
  "ArrivalElements",
237
251
  _elements_to_wire(arrival_elements, parameter="arrival_elements"),
238
252
  )
253
+ _include_if_supplied(
254
+ payload,
255
+ "MaxDepartureDV",
256
+ _optional_integer(
257
+ max_departure_delta_v_m_s,
258
+ parameter="max_departure_delta_v_m_s",
259
+ ),
260
+ )
261
+ _include_if_supplied(
262
+ payload,
263
+ "MaxArrivalDV",
264
+ _optional_integer(
265
+ max_arrival_delta_v_m_s,
266
+ parameter="max_arrival_delta_v_m_s",
267
+ ),
268
+ )
269
+ _include_if_supplied(
270
+ payload,
271
+ "MaxTofDays",
272
+ _optional_integer(
273
+ max_time_of_flight_days,
274
+ parameter="max_time_of_flight_days",
275
+ ),
276
+ )
239
277
  return _without_status_fields(
240
278
  raw.post("/celestial/transfer", json=payload),
241
279
  endpoint="/celestial/transfer",
@@ -331,8 +369,14 @@ def mpc_ephemeris(
331
369
  observer_frame: str | None = None,
332
370
  start: str | None = None,
333
371
  stop: str | None = None,
372
+ target_elements: MpcOrbitalElements | None = None,
334
373
  ) -> dict[str, Any]:
335
- """Return ASTROX minor-planet ephemeris output from its MPC-backed route."""
374
+ """Return ASTROX minor-planet ephemeris output from its MPC-backed route.
375
+
376
+ When ``target_elements`` is supplied, the server integrates those MPC
377
+ orbital elements directly instead of resolving ``target_name`` through the
378
+ MPC network query.
379
+ """
336
380
  payload: dict[str, Any] = {
337
381
  "TargetName": _string(target_name, parameter="target_name"),
338
382
  }
@@ -351,6 +395,11 @@ def mpc_ephemeris(
351
395
  "Stop",
352
396
  _optional_string(stop, parameter="stop"),
353
397
  )
398
+ _include_if_supplied(
399
+ payload,
400
+ "TargetElements",
401
+ _elements_to_wire(target_elements, parameter="target_elements"),
402
+ )
354
403
  return _without_status_fields(
355
404
  raw.post("/celestial/mpc", json=payload),
356
405
  endpoint="/celestial/mpc",
@@ -11,6 +11,7 @@ from astrox._http import raw
11
11
  __all__ = [
12
12
  "CartesianState",
13
13
  "KeplerianElements",
14
+ "LambertResult",
14
15
  "MeanKeplerianElements",
15
16
  "Tle",
16
17
  "cartesian_state",
@@ -517,14 +518,37 @@ def geo_ym_lambert_delta_v(
517
518
  )
518
519
 
519
520
 
521
+ @dataclass(frozen=True, kw_only=True)
522
+ class LambertResult:
523
+ """Single-case Lambert solution with the sampled transfer positions."""
524
+
525
+ departure_delta_v_m_s: tuple[float, float, float]
526
+ arrival_delta_v_m_s: tuple[float, float, float]
527
+ positions: tuple[float, ...]
528
+ """Flat ``(x, y, z, ...)`` transfer position sequence in meters.
529
+
530
+ The server samples ``path_point_count`` points including the departure and
531
+ arrival positions, so the sequence length is ``path_point_count * 3``.
532
+ """
533
+
534
+
520
535
  def lambert_delta_v(
521
536
  *,
522
537
  departure_state: CartesianState,
523
538
  arrival_state: CartesianState,
524
539
  time_of_flight_s: float,
525
540
  gravitational_parameter_m3_s2: float | None = None,
526
- ) -> tuple[tuple[float, float, float], tuple[float, float, float]]:
527
- """Return single-revolution Lambert delta-v between two Cartesian states."""
541
+ get_path_points: bool = False,
542
+ path_point_count: int | None = None,
543
+ ) -> tuple[tuple[float, float, float], tuple[float, float, float]] | LambertResult:
544
+ """Return single-revolution Lambert delta-v between two Cartesian states.
545
+
546
+ By default returns ``(departure_delta_v_m_s, arrival_delta_v_m_s)``. When
547
+ ``get_path_points`` is true, the server also samples the transfer orbit and
548
+ the return is a :class:`LambertResult` carrying the delta-v pair plus the
549
+ flat position sequence; ``path_point_count`` sets the sample count
550
+ (server default 100, including both endpoints).
551
+ """
528
552
  if not isinstance(departure_state, CartesianState):
529
553
  raise TypeError("departure_state must be a CartesianState instance")
530
554
  if not isinstance(arrival_state, CartesianState):
@@ -536,12 +560,20 @@ def lambert_delta_v(
536
560
  "TOF": [time_of_flight_s],
537
561
  }
538
562
  _include_if_supplied(payload, "Gm", gravitational_parameter_m3_s2)
563
+ if get_path_points:
564
+ payload["GetPathPoints"] = True
565
+ _include_if_supplied(payload, "NumberOfPathPoints", path_point_count)
539
566
 
540
567
  result = raw.post("/orbit/lambert", json=payload)
541
- return (
542
- (result["DV1"][0], result["DV1"][1], result["DV1"][2]),
543
- (result["DV2"][0], result["DV2"][1], result["DV2"][2]),
544
- )
568
+ departure_delta_v = (result["DV1"][0], result["DV1"][1], result["DV1"][2])
569
+ arrival_delta_v = (result["DV2"][0], result["DV2"][1], result["DV2"][2])
570
+ if get_path_points:
571
+ return LambertResult(
572
+ departure_delta_v_m_s=departure_delta_v,
573
+ arrival_delta_v_m_s=arrival_delta_v,
574
+ positions=tuple(result["Positions"]),
575
+ )
576
+ return departure_delta_v, arrival_delta_v
545
577
 
546
578
 
547
579
  def convert_czml_position(
@@ -42,6 +42,7 @@ __all__ = [
42
42
  "sgp4",
43
43
  "simple_ascent",
44
44
  "two_body",
45
+ "two_body_rv",
45
46
  ]
46
47
 
47
48
 
@@ -672,6 +673,36 @@ def two_body(
672
673
  return _success_path(result)
673
674
 
674
675
 
676
+ def two_body_rv(
677
+ *,
678
+ state: CartesianState,
679
+ time_of_flight_s: float,
680
+ gravitational_parameter_m3_s2: float | None = None,
681
+ step_s: float | None = None,
682
+ ) -> tuple[float, ...]:
683
+ """Propagate a Cartesian state with two-body dynamics and return the sampled ephemeris.
684
+
685
+ Returns the flat ``[t, x, y, z, vx, vy, vz, ...]`` sequence, where ``t`` is
686
+ seconds relative to the initial epoch, positions are in meters, and
687
+ velocities are in m/s. The sequence includes the start and stop samples;
688
+ intermediate samples follow ``step_s`` (server default 60 s).
689
+ """
690
+ if not isinstance(state, CartesianState):
691
+ raise TypeError("state must be a CartesianState instance")
692
+
693
+ payload: dict[str, Any] = {
694
+ "RV0": state.to_wire(),
695
+ "TimeOfFlight": time_of_flight_s,
696
+ }
697
+ if gravitational_parameter_m3_s2 is not None:
698
+ payload["Gm"] = gravitational_parameter_m3_s2
699
+ if step_s is not None:
700
+ payload["Step"] = step_s
701
+
702
+ result = raw.post("/Propagator/TwoBodyRV", json=payload)
703
+ return tuple(result["Positions"])
704
+
705
+
675
706
  def j2(
676
707
  *,
677
708
  start: str,
@@ -23,6 +23,9 @@ transfer = celestial.lambert_transfer_window(
23
23
  min_time_of_flight_days=10,
24
24
  departure_step_days=2.0,
25
25
  arrival_step_days=1.0,
26
+ # 该窗口出发双曲超速约 15 km/s,超出服务端 MaxDepartureDV 缺省值
27
+ # (10000 m/s),需要显式放宽上限才能保留结果
28
+ max_departure_delta_v_m_s=20000,
26
29
  )
27
30
 
28
31
  results = transfer["TransferResults"]
@@ -32,7 +35,8 @@ for result in results:
32
35
  print(
33
36
  f"出发 {result['DepartureTime']} → 到达 {result['ArrivalTime']}: "
34
37
  f"|DeltaV1|={result['DV1_Mag']:.1f} m/s, "
35
- f"|DeltaV2|={result['DV2_Mag']:.1f} m/s"
38
+ f"|DeltaV2|={result['DV2_Mag']:.1f} m/s, "
39
+ f"TOF={result['TimeOfFlightDays']:.0f} d"
36
40
  )
37
41
  ```
38
42
 
@@ -47,14 +51,17 @@ python compute_lambert_transfer.py
47
51
  1. **选出发与到达天体**:`departure_body`/`arrival_body` 接受服务端支持的天体名称(如 `Earth`、`Mars`、`Ceres`)以及 MPC 编号或名称(如 `2015 XF261`)。小行星省略对应的 `*_elements` 参数时,服务端通过网络查询 MPC 根数。
48
52
  2. **定两个时间窗口**:`departure_start`/`departure_stop` 与 `arrival_start`/`arrival_stop` 各定义一个 UTC 时间窗口,SDK 分别组合为 `DepartureInterval`/`ArrivalInterval` 的 `"开始/结束"` 字符串。`departure_step_days` 与 `arrival_step_days`(单位 d)控制窗口内的采样步长,结果个数约等于两个窗口采样点数的乘积;示例中的 2 个出发日 × 3 个到达日产生 6 条结果。`min_time_of_flight_days`(单位 d,整数)过滤掉转移时间太短的组合,服务端缺省 10。
49
53
  3. **选输出参考系**:`sun_frame` 服务端缺省 `MeanEclpJ2000`;`ICRF` 分支的转移速度已与独立零圈顺行 Lambert 解一致,端点位置方向也已识别为 ICRF 轴方向,而 `MeanEclpJ2000` 与 ICRF 的精确关系尚未独立确认,需要参考系明确的数值时建议显式传 `sun_frame="ICRF"`。
54
+ 4. **按需调整过滤上限**:2026-08-20 起服务端按 `max_departure_delta_v_m_s`/`max_arrival_delta_v_m_s`(缺省各 10000 m/s,分别对应出发/到达双曲超速大小)与 `max_time_of_flight_days`(缺省 500 d)过滤算例,全部超界时返回空列表;扫描大 ΔV 或超长转移窗口时需显式放宽,示例中的 Earth→Mars 窗口就属于这种情况。
50
55
 
51
56
  ## 读懂结果
52
57
 
53
58
  每个结果对象包含:
54
59
 
55
60
  - `DepartureTime`/`ArrivalTime`:出发/到达时刻(UTC 字符串)。
56
- - `DeltaV1`/`DeltaV2`:出发/到达速度增量向量(m/s);`DV1_Mag`/`DV2_Mag` 是它们的欧几里得范数(m/s)。`DeltaV` 相对端点天体速度的物理含义尚未独立确认,需要严格物理解释时请先核对。
61
+ - `DeltaV1`/`DeltaV2`:出发/到达速度增量向量(出发/到达双曲超速矢量,m/s);`DV1_Mag`/`DV2_Mag` 是它们的欧几里得范数(m/s)。`DeltaV` 相对端点天体速度的物理含义尚未独立确认,需要严格物理解释时请先核对。
57
62
  - `RV1`/`RV2`:出发/到达时的日心位置速度 `[x, y, z, vx, vy, vz]`(位置 m、速度 m/s);ICRF 分支下转移速度与独立 Lambert 解一致,端点位置方向与 ICRF 轴方向一致。
63
+ - `TimeOfFlightDays`:飞行时间(d),已验证为到达与出发时刻的精确天数差。
64
+ - `ArrivalLightAngle`:到达时刻太阳光照角(deg),已验证为 `DeltaV2` 与 `RV2` 位置矢量的夹角。
58
65
 
59
66
  ## 小行星与显式 MPC 根数
60
67
 
@@ -84,7 +91,7 @@ transfer = celestial.lambert_transfer_window(
84
91
  )
85
92
  ```
86
93
 
87
- 注意:显式 MPC 根数的独立开普勒递推尚未验证,元素系、参考系与时间约定未确认;这个分支可调用、响应结构已由 live 快照记录,但数值语义请自行核对。
94
+ 注意:显式 MPC 根数在转移路由中的独立开普勒递推尚未验证,元素系与时间约定未确认(`reference_frame` 选项不改变该路由的到达状态);这个分支可调用、响应结构已由 live 快照记录,但数值语义请自行核对。`mpc_ephemeris` 的 `target_elements` 分支已验证(见天体手册)。
88
95
 
89
96
  ## 了解更多
90
97
 
@@ -6,9 +6,10 @@
6
6
 
7
7
  1. **输入决定传播器**:
8
8
  - 有开普勒根数 → 用 `propagator.j2` 或 `propagator.two_body`。
9
+ - 有笛卡尔位置速度状态 → 用 `propagator.two_body_rv`(纯二体,返回扁平星历序列,不返回 `(period_s, position)`)。
9
10
  - 有两行根数(TLE) → 用 `propagator.sgp4`。
10
11
  - 有力模型配置 → 用 `propagator.hpop`。
11
- 2. **读取采样**:所有单轨传播函数都返回 `(period_s, position)`,其中 `position.cartesian_velocity` 是 CZML 风格的扁平序列 `[t, x, y, z, vx, vy, vz, ...]`。
12
+ 2. **读取采样**:除 `two_body_rv` 外,所有单轨传播函数都返回 `(period_s, position)`,其中 `position.cartesian_velocity` 是 CZML 风格的扁平序列 `[t, x, y, z, vx, vy, vz, ...]`。
12
13
 
13
14
  ## 完整示例
14
15
 
@@ -139,6 +140,7 @@ HPOP 传播
139
140
  | --- | --- | --- |
140
141
  | 开普勒根数 | `propagator.j2` | 考虑 J2 摄动,适合大多数低轨任务。 |
141
142
  | 开普勒根数,纯二体 | `propagator.two_body` | 只考虑中心天体引力,计算最快。 |
143
+ | 笛卡尔位置速度状态 | `propagator.two_body_rv` | 定步长数值二体积分,返回扁平星历序列 `[t, x, y, z, vx, vy, vz, ...]`。 |
142
144
  | 两行根数(TLE) | `propagator.sgp4` | 直接从 TLE 传播,无需手动构造根数。 |
143
145
  | 需要配置力模型 | `propagator.hpop` | 支持重力场、大气、太阳辐射压、第三方天体摄动等配置。 |
144
146
 
@@ -23,6 +23,10 @@ transfer = celestial.lambert_transfer_window(
23
23
  min_time_of_flight_days=10,
24
24
  departure_step_days=2.0,
25
25
  arrival_step_days=1.0,
26
+ # this window's departure hyperbolic excess speed is about 15 km/s, above
27
+ # the server MaxDepartureDV default (10000 m/s); widen the bound explicitly
28
+ # to keep the results
29
+ max_departure_delta_v_m_s=20000,
26
30
  )
27
31
 
28
32
  results = transfer["TransferResults"]
@@ -32,7 +36,8 @@ for result in results:
32
36
  print(
33
37
  f"Departure {result['DepartureTime']} → arrival {result['ArrivalTime']}: "
34
38
  f"|DeltaV1|={result['DV1_Mag']:.1f} m/s, "
35
- f"|DeltaV2|={result['DV2_Mag']:.1f} m/s"
39
+ f"|DeltaV2|={result['DV2_Mag']:.1f} m/s, "
40
+ f"TOF={result['TimeOfFlightDays']:.0f} d"
36
41
  )
37
42
  ```
38
43
 
@@ -47,14 +52,17 @@ python compute_lambert_transfer.py
47
52
  1. **Choose the departure and arrival bodies**: `departure_body`/`arrival_body` accept server-supported body names (e.g. `Earth`, `Mars`, `Ceres`) and MPC numbers or names (e.g. `2015 XF261`). When the matching `*_elements` argument is omitted for an asteroid, the server queries the MPC elements over the network.
48
53
  2. **Set the two time windows**: `departure_start`/`departure_stop` and `arrival_start`/`arrival_stop` each define a UTC time window, which the SDK combines into the `"start/stop"` string of `DepartureInterval`/`ArrivalInterval` respectively. `departure_step_days` and `arrival_step_days` (unit d) control the sample step within each window; the number of results is roughly the product of the two windows' sample counts — the 2 departure days × 3 arrival days in the example produce 6 results. `min_time_of_flight_days` (unit d, integer) filters out combinations whose transfer time is too short; the server default is 10.
49
54
  3. **Choose the output reference frame**: the server default for `sun_frame` is `MeanEclpJ2000`; the transfer velocities of the `ICRF` branch agree with an independent zero-revolution prograde Lambert solution, and the endpoint position directions have also been identified as ICRF axes, while the exact relationship between `MeanEclpJ2000` and ICRF is not yet independently confirmed, so pass `sun_frame="ICRF"` explicitly when you need numbers with an identified frame.
55
+ 4. **Adjust the filter bounds as needed**: since 2026-08-20 the server filters cases by `max_departure_delta_v_m_s`/`max_arrival_delta_v_m_s` (defaults 10000 m/s each, the departure/arrival hyperbolic excess speed magnitudes) and `max_time_of_flight_days` (default 500 d), returning an empty list when everything is out of bounds; widen the bounds explicitly when scanning large-ΔV or very long transfer windows — the Earth→Mars window in the example is such a case.
50
56
 
51
57
  ## Reading the results
52
58
 
53
59
  Each result object contains:
54
60
 
55
61
  - `DepartureTime`/`ArrivalTime`: departure/arrival times (UTC strings).
56
- - `DeltaV1`/`DeltaV2`: departure/arrival velocity-increment vectors (m/s); `DV1_Mag`/`DV2_Mag` are their Euclidean norms (m/s). The physical meaning of `DeltaV` relative to the endpoint bodies' velocities is not yet independently confirmed, so verify it yourself when you need a strict physical interpretation.
62
+ - `DeltaV1`/`DeltaV2`: departure/arrival velocity-increment vectors (departure/arrival hyperbolic excess velocity vectors, m/s); `DV1_Mag`/`DV2_Mag` are their Euclidean norms (m/s). The physical meaning of `DeltaV` relative to the endpoint bodies' velocities is not yet independently confirmed, so verify it yourself when you need a strict physical interpretation.
57
63
  - `RV1`/`RV2`: heliocentric position and velocity at departure/arrival `[x, y, z, vx, vy, vz]` (positions m, velocities m/s); under the ICRF branch the transfer velocities agree with the independent Lambert solution, and the endpoint position directions match the ICRF axes.
64
+ - `TimeOfFlightDays`: time of flight (d), verified to be the exact day difference between the arrival and departure times.
65
+ - `ArrivalLightAngle`: Sun lighting angle at arrival (deg), verified to be the angle between `DeltaV2` and the `RV2` position vector.
58
66
 
59
67
  ## Asteroids and explicit MPC elements
60
68
 
@@ -84,7 +92,7 @@ transfer = celestial.lambert_transfer_window(
84
92
  )
85
93
  ```
86
94
 
87
- Note: independent Kepler propagation of explicit MPC elements is not yet verified, and the element system, reference frame, and time convention are unconfirmed; this branch is callable and its response structure is recorded by live snapshots, but verify the numeric semantics yourself.
95
+ Note: independent Kepler propagation of explicit MPC elements in the transfer route is not yet verified, and the element system and time convention are unconfirmed (the `reference_frame` option does not change the arrival states of that route); this branch is callable and its response structure is recorded by live snapshots, but verify the numeric semantics yourself. The `target_elements` branch of `mpc_ephemeris` is verified (see the celestial manual).
88
96
 
89
97
  ## Learn more
90
98
 
@@ -6,9 +6,10 @@ This page solves a specific task: choose the right propagator from the orbit des
6
6
 
7
7
  1. **Input determines the propagator**:
8
8
  - You have Keplerian elements → use `propagator.j2` or `propagator.two_body`.
9
+ - You have a Cartesian position/velocity state → use `propagator.two_body_rv` (pure two-body; returns a flat ephemeris sequence, not `(period_s, position)`).
9
10
  - You have a two-line element set (TLE) → use `propagator.sgp4`.
10
11
  - You have a force model config → use `propagator.hpop`.
11
- 2. **Reading the samples**: all single-orbit propagation functions return `(period_s, position)`, where `position.cartesian_velocity` is a CZML-style flat sequence `[t, x, y, z, vx, vy, vz, ...]`.
12
+ 2. **Reading the samples**: except for `two_body_rv`, all single-orbit propagation functions return `(period_s, position)`, where `position.cartesian_velocity` is a CZML-style flat sequence `[t, x, y, z, vx, vy, vz, ...]`.
12
13
 
13
14
  ## Complete example
14
15
 
@@ -139,6 +140,7 @@ Every 7 numbers in `cartesian_velocity` form one frame: time offset (seconds), p
139
140
  | --- | --- | --- |
140
141
  | Keplerian elements | `propagator.j2` | Includes J2 perturbation; suitable for most LEO missions. |
141
142
  | Keplerian elements, pure two-body | `propagator.two_body` | Only central-body gravity; fastest computation. |
143
+ | Cartesian position/velocity state | `propagator.two_body_rv` | Fixed-step numerical two-body integration; returns a flat ephemeris sequence `[t, x, y, z, vx, vy, vz, ...]`. |
142
144
  | Two-line element set (TLE) | `propagator.sgp4` | Propagates directly from TLE; no need to build elements manually. |
143
145
  | Need to configure a force model | `propagator.hpop` | Supports gravity field, atmosphere, solar radiation pressure, third-body perturbations, and more. |
144
146
 
@@ -113,19 +113,23 @@ celestial.mpc_ephemeris(
113
113
  observer_frame: str | None = None,
114
114
  start: str | None = None,
115
115
  stop: str | None = None,
116
+ target_elements: MpcOrbitalElements | None = None,
116
117
  ) -> dict[str, Any]
117
118
  ```
118
119
 
119
- Queries an MPC minor-planet ephemeris by asteroid name or number and returns a raw JSON response dictionary.
120
+ Queries an MPC minor-planet ephemeris by asteroid name or number and returns a raw JSON response dictionary. When `target_elements` is provided, the server integrates the given MPC orbital elements directly instead of querying MPC over the network.
120
121
 
121
122
  | Parameter | Wire parameter | Description |
122
123
  | --- | --- | --- |
123
124
  | `target_name` | `TargetName` | Asteroid name or number, e.g. `Ceres`, `99942` |
124
- | `observer_frame` | `ObserverFrame` | Heliocentric frame, server options `FIXED`, `INERTIAL`, `MeanEclpJ2000`, `J2000`, default `MeanEclpJ2000` |
125
+ | `observer_frame` | `ObserverFrame` | Heliocentric frame, server options `FIXED`, `INERTIAL`, `J2000`, `ICRF`, `MeanEclpJ2000`, `EclpJ2000ICRF`, default `MeanEclpJ2000` |
125
126
  | `start` | `Start` | Start time (UTC); defaults to the orbital epoch and cannot be earlier than the orbital epoch (server rule) |
126
127
  | `stop` | `Stop` | Stop time (UTC); defaults to 1 year after `Start` |
128
+ | `target_elements` | `TargetElements` | Explicit MPC orbital elements (built with `mpc_orbital_elements`); when omitted, the server queries MPC over the network |
127
129
 
128
- This route fetches orbital elements from the external MPC data source (element epoch in MJD TDT), which the server propagates heliocentrically with a fixed 1-day step, and outputs a heliocentric CZML Position structure. The response contains `OrbitElements` (orbital elements with keys `EpochMjdTdt`, `PeriTimeMjdTdt`, `Q`, `SemimajorAxis`, `Eccentricity`, `Inclination`, `Raan`, `ArgOfPeriapsis`, `MeanAnomaly`) and `Position` (CZML structure, same as `ephemeris`). The orbital-element values come from external MPC data, are owned by that external data source, and may change with MPC updates. When `start`/`stop` are omitted, the server uses the orbital-epoch default window (`start` is the orbital epoch and `stop` is one year after it); an explicit fixed window depends on the orbital epoch at query time, and once the external MPC orbital epoch updates, a previously fixed window may fall before the new epoch and be rejected by the server, so prefer omitting the window parameters or following the current epoch.
130
+ This route fetches orbital elements from the external MPC data source (element epoch in MJD TDT), which the server propagates heliocentrically with a fixed 3-day step, and outputs a heliocentric CZML Position structure. The response contains `OrbitElements` (orbital elements with keys `EpochMjdTdt`, `PeriTimeMjdTdt`, `Q`, `SemimajorAxis`, `Eccentricity`, `Inclination`, `Raan`, `ArgOfPeriapsis`, `MeanAnomaly`, `ReferenceFrame`) and `Position` (CZML structure, same as `ephemeris`). The orbital-element values come from external MPC data, are owned by that external data source, and may change with MPC updates. When `start`/`stop` are omitted, the server uses the orbital-epoch default window (`start` is the orbital epoch and `stop` is one year after it); an explicit fixed window depends on the orbital epoch at query time, and once the external MPC orbital epoch updates, a previously fixed window may fall before the new epoch and be rejected by the server, so prefer omitting the window parameters or following the current epoch.
131
+
132
+ Verified (endpoint-internal invariant): passing the `OrbitElements` returned by a name query back as `target_elements` reproduces the name-query ephemeris exactly; the `reference_frame` values `EclpJ2000ICRF` (MPC convention, server default) and `MeanEclpJ2000` (JPL convention) are two distinguishable branches. See the [celestial validation page](../../../../validation/celestial.md) for the evidence.
129
133
 
130
134
  ```python
131
135
  mpc = celestial.mpc_ephemeris(target_name="Ceres")
@@ -149,6 +153,7 @@ celestial.mpc_orbital_elements(
149
153
  raan_deg: float | None = None,
150
154
  argument_of_periapsis_deg: float | None = None,
151
155
  mean_anomaly_deg: float | None = None,
156
+ reference_frame: str | None = None,
152
157
  ) -> MpcOrbitalElements
153
158
  ```
154
159
 
@@ -165,6 +170,7 @@ Builds a heliocentric MPC orbital-element fragment. When either the departure or
165
170
  | `raan_deg` | `Raan` | deg |
166
171
  | `argument_of_periapsis_deg` | `ArgOfPeriapsis` | deg |
167
172
  | `mean_anomaly_deg` | `MeanAnomaly` | deg |
173
+ | `reference_frame` | `ReferenceFrame` | Heliocentric ecliptic frame variant: `MeanEclpJ2000` (JPL) or `EclpJ2000ICRF` (MPC, server default) |
168
174
 
169
175
  ```python
170
176
  from astrox import celestial
@@ -184,7 +190,7 @@ elements = celestial.mpc_orbital_elements(
184
190
  print(elements.to_wire())
185
191
  ```
186
192
 
187
- `to_wire()` returns the ASTROX `MpcOrbElements` request fragment; the example above prints `{'EpochMjdTdt': 61000.0, 'PeriTimeMjdTdt': 60900.0, 'Q': 0.6740515, 'SemimajorAxis': 0.9898367, 'Eccentricity': 0.3190276, 'Inclination': 0.79379, 'Raan': 209.81829, 'ArgOfPeriapsis': 100.88187, 'MeanAnomaly': 120.0}`. When passed to `lambert_transfer_window`, the server propagates heliocentrically directly with these elements and no longer queries MPC over the network. The independent Kepler propagation of explicit elements is unverified: the element system, reference frame, and time convention are not confirmed, so verify their meaning yourself before use.
193
+ `to_wire()` returns the ASTROX `MpcOrbElements` request fragment; the example above prints `{'EpochMjdTdt': 61000.0, 'PeriTimeMjdTdt': 60900.0, 'Q': 0.6740515, 'SemimajorAxis': 0.9898367, 'Eccentricity': 0.3190276, 'Inclination': 0.79379, 'Raan': 209.81829, 'ArgOfPeriapsis': 100.88187, 'MeanAnomaly': 120.0}`. When passed to `lambert_transfer_window`, the server propagates heliocentrically directly with these elements and no longer queries MPC over the network. The independent Kepler propagation of explicit elements in that route is unverified: the element system and time convention are not confirmed (the `reference_frame` option does not change the arrival states of that route); the `target_elements` branch of `mpc_ephemeris` is verified (see above), so verify the meaning yourself before use.
188
194
 
189
195
  ## Lambert transfer windows
190
196
 
@@ -205,10 +211,13 @@ celestial.lambert_transfer_window(
205
211
  arrival_step_days: float | None = None,
206
212
  departure_elements: MpcOrbitalElements | None = None,
207
213
  arrival_elements: MpcOrbitalElements | None = None,
214
+ max_departure_delta_v_m_s: int | None = None,
215
+ max_arrival_delta_v_m_s: int | None = None,
216
+ max_time_of_flight_days: int | None = None,
208
217
  ) -> dict[str, Any]
209
218
  ```
210
219
 
211
- Samples over the departure time window and the arrival time window, computes Lambert transfers between bodies, and returns a raw JSON response dictionary. It is not the single-case `orbits.lambert_delta_v` interface: that function takes two `CartesianState` values and a `time_of_flight_s`, calls `/orbit/lambert`, and returns the two triples `(DV1, DV2)`; this function scans the whole grid of departure/arrival time pairs and returns a `TransferResults` list.
220
+ Samples over the departure time window and the arrival time window, computes Lambert transfers between bodies, and returns a raw JSON response dictionary. It is not the single-case `orbits.lambert_delta_v` interface: that function takes two `CartesianState` values and a `time_of_flight_s`, calls `/orbit/lambert`, and by default returns the two triples `(DV1, DV2)`; this function scans the whole grid of departure/arrival time pairs and returns a `TransferResults` list.
212
221
 
213
222
  | Parameter | Wire parameter | Description |
214
223
  | --- | --- | --- |
@@ -224,6 +233,9 @@ Samples over the departure time window and the arrival time window, computes Lam
224
233
  | `arrival_step_days` | `ArrivalStepDay` | Arrival time sample step, in d; server default 1 |
225
234
  | `departure_elements` | `DepartureElements` | MPC orbital elements of the departure asteroid (built with `mpc_orbital_elements`); when omitted, the server queries MPC over the network |
226
235
  | `arrival_elements` | `ArrivalElements` | MPC orbital elements of the arrival asteroid; when omitted, the server queries MPC over the network |
236
+ | `max_departure_delta_v_m_s` | `MaxDepartureDV` | Maximum departure velocity increment (departure hyperbolic excess speed magnitude), in m/s, integer; server default 10000, cases above it are filtered out |
237
+ | `max_arrival_delta_v_m_s` | `MaxArrivalDV` | Maximum arrival velocity increment (arrival hyperbolic excess speed magnitude), in m/s, integer; server default 10000, cases above it are filtered out |
238
+ | `max_time_of_flight_days` | `MaxTofDays` | Maximum transfer time, in d, integer; server default 500, cases above it are filtered out |
227
239
 
228
240
  `departure_body`, `arrival_body`, and the four time strings are the required request fields of this function; `DepartureInterval`/`ArrivalInterval` is a single `"start/stop"` string, e.g. `"2028-06-01T00:00:00Z/2028-06-03T00:00:00Z"`. Other optional parameters that are not supplied are not sent to ASTROX, and the server retains its default values.
229
241
 
@@ -241,6 +253,9 @@ transfer = celestial.lambert_transfer_window(
241
253
  min_time_of_flight_days=10,
242
254
  departure_step_days=2.0,
243
255
  arrival_step_days=1.0,
256
+ # this window's departure hyperbolic excess speed is about 15 km/s, above
257
+ # the server MaxDepartureDV default (10000 m/s); widen the bound explicitly
258
+ max_departure_delta_v_m_s=20000,
244
259
  )
245
260
 
246
261
  results = transfer["TransferResults"]
@@ -248,20 +263,23 @@ first = results[0]
248
263
  print(f"{len(results)} transfer results")
249
264
  print(
250
265
  f"First: {first['DepartureTime']} → {first['ArrivalTime']}, "
251
- f"|DeltaV1|={first['DV1_Mag']:.1f} m/s, |DeltaV2|={first['DV2_Mag']:.1f} m/s"
266
+ f"|DeltaV1|={first['DV1_Mag']:.1f} m/s, |DeltaV2|={first['DV2_Mag']:.1f} m/s, "
267
+ f"TOF={first['TimeOfFlightDays']:.0f} d"
252
268
  )
253
269
  ```
254
270
 
255
- The response contains `TransferResults` (an array of transfer results; each element corresponds to one sampled departure/arrival time pair, and the number of results is determined jointly by the two time windows and the sample steps). Each result has the following keys:
271
+ The response contains `TransferResults` (an array of transfer results; each element corresponds to one sampled departure/arrival time pair, and the number of results is determined jointly by the two time windows and the sample steps, and is also affected by `min_time_of_flight_days` and the `max_departure_delta_v_m_s`/`max_arrival_delta_v_m_s`/`max_time_of_flight_days` filter bounds — when every case is out of bounds the list is empty). Each result has the following keys:
256
272
 
257
273
  | Key | Type | Unit / description |
258
274
  | --- | --- | --- |
259
275
  | `DepartureTime` / `ArrivalTime` | string | Departure/arrival time (UTC string) |
260
- | `DeltaV1` / `DeltaV2` | number[3] | Departure/arrival velocity-increment vector, m/s |
276
+ | `DeltaV1` / `DeltaV2` | number[3] | Departure/arrival velocity-increment vector (departure/arrival hyperbolic excess velocity vector), m/s |
261
277
  | `DV1_Mag` / `DV2_Mag` | number | Departure/arrival velocity-increment magnitude, m/s; verified to be the Euclidean norm of the corresponding `DeltaV` vector |
262
278
  | `RV1` / `RV2` | number[6] | Position and velocity at departure/arrival (heliocentric) `[x, y, z, vx, vy, vz]`, positions m, velocities m/s |
279
+ | `TimeOfFlightDays` | number | Time of flight, in d; verified to be the exact day difference between `ArrivalTime` and `DepartureTime` |
280
+ | `ArrivalLightAngle` | number | Sun lighting angle at arrival, in deg; verified to be the angle between `DeltaV2` and the `RV2` position vector |
263
281
 
264
- Verified (supported by independent cross-validation): with `sun_frame="ICRF"`, the transfer velocities in `RV1`/`RV2` follow the zero-revolution prograde Lambert relationship, and the endpoint position directions use the ICRF axes. Unresolved: the exact coordinate relationship between `MeanEclpJ2000` and ICRF, the physical meaning of `DeltaV` relative to the endpoint-body velocities, and independent Kepler propagation of explicit MPC elements. These branches currently have only request-construction and response-structure evidence, so verify their meaning yourself before use.
282
+ Verified (supported by independent cross-validation): with `sun_frame="ICRF"`, the transfer velocities in `RV1`/`RV2` follow the zero-revolution prograde Lambert relationship, and the endpoint position directions use the ICRF axes; `max_departure_delta_v_m_s`/`max_arrival_delta_v_m_s`/`max_time_of_flight_days` filter the sampled grid by the `DV1_Mag`/`DV2_Mag`/time-of-flight upper bounds respectively. Note that since 2026-08-20 the server defaults (10000 m/s each for departure/arrival, 500 d) filter out cases beyond the defaults, so scans over large-ΔV windows need explicitly widened bounds. Unresolved: the exact coordinate relationship between `MeanEclpJ2000` and ICRF, the physical meaning of `DeltaV` relative to the endpoint-body velocities, and independent Kepler propagation of explicit MPC elements (the `reference_frame` option does not change the arrival states of that route; the element convention is still unconfirmed). These branches currently have only request-construction and response-structure evidence, so verify their meaning yourself before use.
265
283
 
266
284
  ## Convention notes
267
285
 
@@ -346,10 +346,12 @@ orbits.lambert_delta_v(
346
346
  arrival_state: CartesianState,
347
347
  time_of_flight_s: float,
348
348
  gravitational_parameter_m3_s2: float | None = None,
349
- ) -> tuple[tuple[float, float, float], tuple[float, float, float]]
349
+ get_path_points: bool = False,
350
+ path_point_count: int | None = None,
351
+ ) -> tuple[tuple[float, float, float], tuple[float, float, float]] | LambertResult
350
352
  ```
351
353
 
352
- Solves a single-revolution Lambert transfer between two Cartesian states, returning `(departure_delta_v_m_s, arrival_delta_v_m_s)`. Each delta-v is an `(x, y, z)` tuple in m/s.
354
+ Solves a single-revolution Lambert transfer between two Cartesian states. By default it returns `(departure_delta_v_m_s, arrival_delta_v_m_s)`; each delta-v is an `(x, y, z)` tuple in m/s. With `get_path_points=True` it returns `orbits.LambertResult`, which additionally carries `positions`: transfer-trajectory position samples as a flat `(x, y, z, ...)` sequence in m, including both endpoints, with `path_point_count` points (server default 100).
353
355
 
354
356
  | Parameter | Unit | Description |
355
357
  | --- | --- | --- |
@@ -357,6 +359,8 @@ Solves a single-revolution Lambert transfer between two Cartesian states, return
357
359
  | `arrival_state` | — | Cartesian state at arrival |
358
360
  | `time_of_flight_s` | s | Time of flight |
359
361
  | `gravitational_parameter_m3_s2` | m³/s² | Gravitational parameter |
362
+ | `get_path_points` | — | Whether to return transfer-trajectory position samples; single-case requests only |
363
+ | `path_point_count` | — | Number of position samples (including both endpoints); server default 100, only sent when `get_path_points=True` |
360
364
 
361
365
  ```python
362
366
  departure_delta_v_m_s, arrival_delta_v_m_s = orbits.lambert_delta_v(
@@ -365,8 +369,20 @@ departure_delta_v_m_s, arrival_delta_v_m_s = orbits.lambert_delta_v(
365
369
  time_of_flight_s=817.4257,
366
370
  gravitational_parameter_m3_s2=398600441500000.0,
367
371
  )
372
+
373
+ result = orbits.lambert_delta_v(
374
+ departure_state=departure_state,
375
+ arrival_state=arrival_state,
376
+ time_of_flight_s=817.4257,
377
+ gravitational_parameter_m3_s2=398600441500000.0,
378
+ get_path_points=True,
379
+ path_point_count=5,
380
+ )
381
+ print(result.positions) # flat (x, y, z, ...) sequence of 5 samples
368
382
  ```
369
383
 
384
+ The position samples are cross-validated: the first and last samples reproduce the position triples of the input `RV1`/`RV2`, and intermediate samples lie on the two-body transfer trajectory started from the departure state plus the returned delta-v (consistent with independent Brahe propagation). See the [orbits validation page](../../../../validation/orbits.md) for the evidence.
385
+
370
386
  ### `orbits.geo_ym_lambert_delta_v`
371
387
 
372
388
  ```python
@@ -27,7 +27,7 @@ For details on orbit constructors, see the [orbits manual](../orbits/README.md).
27
27
 
28
28
  ## Return Values
29
29
 
30
- Single-orbit propagation functions return a `(period_s, position)` tuple:
30
+ Except for `propagator.two_body_rv`, single-orbit propagation functions return a `(period_s, position)` tuple (`two_body_rv` returns a flat ephemeris sequence; see its section below):
31
31
 
32
32
  - `period_s`: `float`, the orbital period returned by ASTROX, in seconds.
33
33
  - `position`: `propagator.PropagatorPosition` frozen dataclass with the following fields:
@@ -126,6 +126,45 @@ period_s, position = propagator.two_body(
126
126
 
127
127
  A complete runnable example is available at `examples/01_propagation/two_body_classical.py`.
128
128
 
129
+ ### `propagator.two_body_rv`
130
+
131
+ ```python
132
+ propagator.two_body_rv(
133
+ *,
134
+ state: CartesianState,
135
+ time_of_flight_s: float,
136
+ gravitational_parameter_m3_s2: float | None = None,
137
+ step_s: float | None = None,
138
+ ) -> tuple[float, ...]
139
+ ```
140
+
141
+ Propagates directly from an initial position/velocity state using the two-body model (`/Propagator/TwoBodyRV`, simplified RV integrator), returning a flat ephemeris sequence `[t, x, y, z, vx, vy, vz, ...]`: `t` is seconds relative to the initial epoch, positions are in m and velocities in m/s. The sequence includes the start and end samples, with intermediate samples spaced by `step_s`.
142
+
143
+ | Parameter | Wire parameter | Unit | Description |
144
+ | --- | --- | --- | --- |
145
+ | `state` | `RV0` | m, m/s | Initial Cartesian state (built with `orbits.cartesian_state`) |
146
+ | `time_of_flight_s` | `TimeOfFlight` | s | Time of flight |
147
+ | `gravitational_parameter_m3_s2` | `Gm` | m³/s² | Central-body gravitational constant; server default 3.986004415E14 (Earth) |
148
+ | `step_s` | `Step` | s | Output step; server default 60 |
149
+
150
+ This route is a fixed-step numerical two-body integrator, unlike the analytic Kepler route of `propagator.two_body`: cross-validation against independent Brahe two-body propagation shows its residual oscillates with orbital phase, peaking at about 4e-4 m and 5.4e-7 m/s over a 10-minute arc, without secular growth. See the [propagator validation page](../../../../validation/propagator.md) for the evidence.
151
+
152
+ ```python
153
+ state = orbits.cartesian_state(
154
+ x_m=7000000.0, y_m=0.0, z_m=0.0,
155
+ vx_m_s=0.0, vy_m_s=7546.053290114564, vz_m_s=0.0,
156
+ )
157
+
158
+ positions = propagator.two_body_rv(
159
+ state=state,
160
+ time_of_flight_s=3600.0,
161
+ step_s=600.0,
162
+ gravitational_parameter_m3_s2=398600441500000.0,
163
+ )
164
+ ```
165
+
166
+ A complete runnable example is available at `examples/01_propagation/two_body_rv.py`.
167
+
129
168
  ## Batch Propagation
130
169
 
131
170
  Batch propagation brings multiple states or TLEs to a common target epoch `epoch`.