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.
- {astrox_python-1.0.0 → astrox_python-1.1.0}/.gitignore +1 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/PKG-INFO +1 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/celestial.py +53 -4
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/orbits.py +38 -6
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/propagator.py +31 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/compute_lambert_transfer.md +10 -3
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/propagate_an_orbit.md +3 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/compute_lambert_transfer.md +11 -3
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/propagate_an_orbit.md +3 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/celestial/README.md +27 -9
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/orbits/README.md +18 -2
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/propagator/README.md +40 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/celestial/README.md +27 -9
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/orbits/README.md +18 -2
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/propagator/README.md +40 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/celestial.md +14 -8
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/orbits.md +5 -3
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/propagator.md +26 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/README.md +3 -1
- astrox_python-1.1.0/examples/01_propagation/two_body_rv.py +38 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/lambert_delta_v.py +14 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/11_celestial/celestial_queries.py +7 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/pyproject.toml +2 -2
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/celestial/test_celestial.py +124 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_conversions.py +95 -4
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_public_contract.py +1 -0
- astrox_python-1.1.0/tests/sdk/propagator/test_two_body_rv.py +138 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/celestial/test_lambert_transfer_lamberthub.py +144 -4
- astrox_python-1.1.0/tests/validation/cross_validation/celestial/test_mpc_target_elements.py +170 -0
- astrox_python-1.1.0/tests/validation/cross_validation/orbits/test_lambert_path_points.py +172 -0
- astrox_python-1.1.0/tests/validation/cross_validation/propagator/test_two_body_rv_brahe.py +228 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/celestial/celestial.snap.json +16 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/celestial/test_celestial.py +9 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/conversions.snap.json +28 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/test_conversions.py +16 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_two_body.py +22 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/two_body.snap.json +32 -1
- {astrox_python-1.0.0 → astrox_python-1.1.0}/uv.lock +34 -23
- {astrox_python-1.0.0 → astrox_python-1.1.0}/LICENSE +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/_http.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/access.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/astrogator/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/astrogator/_api.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/astrogator/_models.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/astrogator/_results.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/cat.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/catalog.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_axes.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_common.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_constraints.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_objects.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_positions.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_rotations.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_sensors.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/components/_vgt.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/conjunction.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/_core.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/_fom.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/coverage_time.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/number_of_assets.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/response_time.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/revisit_time.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/coverage/simple_coverage.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/exceptions.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/libration.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/lighting.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/rocket.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/astrox/terrain.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/CONTRIBUTING.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/automated-workflows.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/docs-principles.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/getting_started.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/build_an_hpop_configuration.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/compute_access_intervals.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/compute_lighting_conditions.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/convert_between_orbit_representations.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/generate_a_crtbp_periodic_orbit.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/run_an_astrogator_mcs.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/how_to/screen_close_approaches.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/getting_started.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/build_an_hpop_configuration.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/compute_access_intervals.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/compute_lighting_conditions.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/convert_between_orbit_representations.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/generate_a_crtbp_periodic_orbit.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/run_an_astrogator_mcs.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/how_to/screen_close_approaches.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/access/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/astrogator/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/cat/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/catalog/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/components/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/conjunction/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/coverage/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/libration/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/lighting/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/rocket/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/i18n/en/manual/terrain/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/access/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/astrogator/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/cat/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/catalog/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/components/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/conjunction/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/coverage/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/libration/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/lighting/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/rocket/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/manual/terrain/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/sdk-principles.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/test-principles.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/access.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/astrogator.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/cat.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/catalog.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/conjunction.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/coverage.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/libration.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/lighting.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/rocket.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/docs/validation/terrain.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/ballistic_apogee_alt.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/ballistic_delta_v.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/ballistic_min_ecc.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/ballistic_time_of_flight.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/batch_propagators.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/hpop.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/j2_classical.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/propagator_reference.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/sgp4_tle.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/simple_ascent.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/01_propagation/two_body_classical.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/conversions.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/orbit_system.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/02_orbits/wizards.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/03_lighting/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/03_lighting/lighting.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/chain.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/compute.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/constraints.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/custom_axes.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/04_access/sensor_pointing.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/05_rocket/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/05_rocket/landing_zone.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/compute.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/fom.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/grid_points.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/06_coverage/reports.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/07_astrogator/run_mcs.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/08_conjunction/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/08_conjunction/close_approaches.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/09_cat/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/09_cat/cat_workflows.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/10_catalog/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/10_catalog/catalog_queries.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/11_celestial/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/12_terrain/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/12_terrain/terrain_masks.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/13_libration/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/13_libration/libration_dynamics.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/examples/manifest.toml +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/conftest.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/access/helpers.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/access/test_chain.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/access/test_compute.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/access/test_values.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/astrogator/test_api.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/astrogator/test_models.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/astrogator/test_results.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/cat/test_cat.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/catalog/test_catalog.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/client/test_client.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/components/test_components.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/conjunction/test_conjunction.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/coverage/test_coverage.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/coverage/test_coverage_fom.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/helpers.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/libration/test_libration.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/lighting/test_lighting.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/helpers.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_keplerian.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_orbit_system.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_tle.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/orbits/test_wizards.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/helpers.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_ballistic.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_hpop.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_j2_two_body.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_multi.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/propagator/test_sgp4_simple_ascent.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/rocket/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/rocket/test_rocket.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/sdk/terrain/test_terrain.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_external/gmat/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_external/gmat/hpop_driver.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_external/gmat/test_hpop_driver.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/contracts.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/external_tools.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/gmat.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/orekit.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/test_contracts.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/test_external_tools.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/test_gmat.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/_support/test_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/README.md +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_aer.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_cases.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_constraints.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_exclusion.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_mixed_model.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/_orientation.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_axes_orientation_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_chain_sgp4_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_composite_czml_axes_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_constraints_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_exclusion_constraints_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_ground_sgp4_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_j2_two_body_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_sgp4_j2_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_site_hpop_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_site_j2_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_compute_site_two_body_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_sensor_pointing_geometry.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/access/test_vgt_orientation_resolution.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_branch_semantics.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_initial_state_conversions.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_maneuver_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_run_mcs_two_body_brahe.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_scalar_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_sequence_czml_brahe.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/astrogator/test_target_sequence_local.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/cat/test_cat_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/celestial/test_cb_axes_rotation_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/celestial/test_ephemeris_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/conjunction/test_close_approaches_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/_fom_helpers.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_exclusion_grid_constraints_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_at_time_boundaries_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_edge_cases_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_grid_options_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_interval_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_resource_options_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_response_shapes_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_fom_response_time_dynamic_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_grid_generation_local.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_grid_point_modifiers_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_resource_reports_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/coverage/test_sgp4_grid_membership_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/_support.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_cross_endpoint_consistency.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_crtbp_trajectory.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_e2m2e_qualification.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_fixed_x_correction.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_orekit_qualification.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_periodic_families.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/libration/test_positions_and_units.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/lighting/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/lighting/test_site_sun_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/lighting/test_spacecraft_solar_intensity_orekit.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/lighting/test_spacecraft_sun_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbit_system/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbit_system/_support.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbit_system/test_convert_czml_position.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbit_system/test_earth_moon_libration.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/test_kozai_izsak_mean_elements_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/test_lambert_lamberthub.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/test_walker_constellation_equations.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/orbits/test_wizards_local_derivation.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_ballistic_geodetic.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_hpop_gmat.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_j2_analytical.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_multi_sgp4_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_sgp4_skyfield.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_simple_ascent_geodetic.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/propagator/test_two_body_brahe.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/rocket/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/rocket/test_landing_zone_geographiclib.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/cross_validation/terrain/test_terrain_mask_invariants.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/access.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/test_access.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/test_chain_topology.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/test_compute_model_pairs.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/access/test_compute_options.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/astrogator/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/astrogator/run_mcs.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/astrogator/test_run_mcs.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/cat/cat.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/cat/test_cat.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/catalog/catalog.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/catalog/test_catalog.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/conjunction/close_approaches.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/conjunction/test_close_approaches.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/coverage/coverage.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/coverage/test_coverage.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/libration/libration.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/libration/test_libration.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/lighting/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/lighting/lighting.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/lighting/test_lighting.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/orbit_system.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/test_conversion_roundtrip.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/test_orbit_system.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/test_wizards.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/orbits/wizards.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/ballistic.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/hpop.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/j2.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/multi_j2.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/multi_sgp4.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/multi_two_body.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/sgp4.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/simple_ascent.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_ballistic.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_hpop.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_j2.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_multi_j2.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_multi_sgp4.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_multi_two_body.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_sgp4.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/propagator/test_simple_ascent.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/rocket/__init__.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/rocket/landing_zone.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/rocket/test_landing_zone.py +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/terrain/terrain.snap.json +0 -0
- {astrox_python-1.0.0 → astrox_python-1.1.0}/tests/validation/live_snapshot/terrain/test_terrain.py +0 -0
|
@@ -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,
|
|
100
|
-
payload: dict[str,
|
|
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,
|
|
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
|
-
|
|
527
|
-
|
|
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
|
-
|
|
542
|
-
|
|
543
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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`, `
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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`.
|