Orbital Motion Compatibility
The issue 1629 audit compares the orbital utilities, their three SWIG export
paths, module callers, and tests with the branch’s starting revision
3193231686. Numerical defect corrections remain enabled. Public types,
representations, signatures, and previously accepted domain behavior are
preserved as described below.
The existing methods and conventions remain supported without deprecation warnings or a removal schedule. Numerical improvements are available through the original method names. Optional checked calls and alternate encodings are additions; existing callers do not need to adopt them.
Preserved behavior
Python
rv2elemretains NumPyfloat64fieldsa,e,rmag,alpha,rPeriap, andrApoap. Expressions such asaxis_history - elements.acontinue to work when the history is a list.M2EandN2Hretain NumPy scalar results when either argument is a NumPy scalar, including their zero-anomaly shortcuts. Zero-dimensional mean arrays retain their container type without changing the caller’s input.Python’s default
rv2elemretains the planar parabolic representationa = -rPeriap, rApoap = -1. Optionally userv2elem(mu, r, v, canonical=True)for the C-compatiblea = rApoap = 0, rPeriap > 0representation accepted byelem2rv. Legacy output can still be passed toelem2rv_parab. That adapter always interpretse = 1, a < 0as a planar parabola with periapsis-a, even when auxiliary fields are omitted, unset, or zero. Python and SWIG element inputs remain unchanged on repeated calls.rv2elem_parabretains signed node, periapsis, and nonradial true-anomaly angles, its circular convention with periapsis at the current position, anda = rApoap = -rPeriapfor planar parabolas. The main Crv2elemretains its nonradial true-anomaly interval [0, 2*pi); the main Python function retains its signed hyperbolic anomaly interval.The Python
*_parabadapters retain inward motion for positivesin(E)on rectilinear ellipses. When explicitly converting those input elements for use withelem2rv, negate the radial eccentric anomaly. The canonical core uses outward-positive radial E. Rectilinear hyperbolas use the coreelem2rvwith outward-positive H; they are distinct from the adapter’s original negative-a planar parabolic encoding. Eccentricity one alone never selects a parabola: the angular momentum, energy, and documented auxiliary fields distinguish the cases.KeplerianOrbitretains its native member layout, including reserved legacy storage. Its public signatures and units are unchanged.
Planet selection
Ordinary C/C++ calls with three arguments, jPerturb(r, degree, acceleration),
now select Earth safely through the header adapter. Four-argument calls still compile
and run, and honor the selected planet. All three SWIG bindings retain both
call forms. Native source calls also accept C compound literals and C++ braced
initializers as vector arguments. Checked planet selection is available through:
jPerturbForPlanet(r, degree, acceleration, CELESTIAL_MARS);
The legacy four-argument native path retains Earth fallback for unknown body
identifiers and leaves the output unchanged for Sun/Pluto. The corresponding
Python utility retains its unknown-name Earth fallback, None for Sun/Pluto,
and floating degree cutoffs. Python callers can opt into checked
selection using orbitalMotion.jPerturb(r, degree, planet, strict=True).
Checked paths reject unknown bodies and return explicit zero vectors for
Sun/Pluto’s zero-zonal approximation. Saturn’s previously incorrect Earth
coefficients are corrected in all paths.
The historical variadic native symbol remains available for existing
explicit-planet function pointers and binary callers. Such pointers require
one trailing integer planet identifier. A raw three-argument call to that
variadic symbol already had undefined behavior because it read an absent
argument; it cannot be made safe by preserving that binary calling convention.
Use jPerturbEarth for a fixed three-argument pointer. The header dispatch
makes ordinary three-argument source calls safe when rebuilt.
Checked domains
C and Python now provide the additive entry points hillFrameChecked,
hill2rvChecked, rv2hillChecked, clMeanOscMapChecked, and
clElem2eqElemChecked. Supported inputs receive the improved calculations
through both old and checked names. Checked calls report domain failures as
NaN outputs with diagnostics in C, or ValueError in Python. The old names
retain historical rejected-domain formulas, sentinel outputs, and exceptions.
Neither form is deprecated; checked calls are optional.
Inclination validation is an intentional exception to this compatibility path: all element-input APIs require finite inclination in [0, pi], including both endpoints. Negative and wrapped inclinations are rejected immediately. The constellation example’s documented input remains radians; its main call and test now convert 56 degrees explicitly. Optical-navigation test fixtures likewise convert 10 degrees. Monte Carlo configurations use nonnegative radian inclination bounds; this intentionally changes their former invalid samples. A valid inclination can still coincide with a particular coordinate singularity: prograde equinoctial elements remain singular at the retrograde equator.
meanOEFeedback explicitly uses the checked conversions and stops rather
than publishing an invalid force after conversion failure. oeStateEphem
uses the fitted conic without snapping near-unit eccentricity to a parabola;
its positive-periapsis records cannot encode rectilinear states or parabolic
mean anomaly. These module messages and configuration field names are unchanged.
Corrections retained without compatibility fallbacks
The audit retains corrections to unconverged Kepler roots, singular orbit
geometry, near-parabolic and rectilinear Cartesian reconstruction, equatorial
and whole-revolution mean/osculating mapping, zonal coefficients, zero-speed
drag, characteristic energy, and eclipse disk overlap. Matching an incorrect
numerical answer is not a supported compatibility mode. KeplerianOrbit.c3
now returns -mu/a rather than its erroneous constant zero.
Explicit failure replaces undefined or unsupported calculations: nonphysical
conics, unrepresentable states, nonfinite Kepler inputs, nonpositive mass or
gravity parameters, and unsupported KeplerianOrbit conics. In
particular, the drag helper no longer reads outside a three-vector on invalid
position input. Callers supplying invalid inputs can observe different error
types or NaN diagnostics; they must not rely on the previous accidental
IndexError, uninitialized data, or unconverged output.
The removed AVS self-check names were test-harness selectors that executed no native test; the four real self-check entry points remain. Eclipse corrections and debris plotting compatibility preserve their callable interfaces. Forward-anomaly precision near the parabolic limit remains outside this change.
Regression coverage
Compatibility tests exercise NumPy scalar methods and original debris list arithmetic; default and canonical parabolic encodings; radial adapter velocity signs; input-storage invariance for Python and all SWIG element types; large wrapped anomalies against direct trigonometric references; signed and circular angle conventions; native/SWIG optional planet calls; legacy Sun/Pluto and unknown-body sentinels; fractional degree cutoffs; checked versus legacy domain failures; output aliasing; and accepted/rejected inclination boundaries. Compatibility tests reject deprecation warnings for the preserved APIs. Existing numerical, controller, ephemeris, and scenario tests remain part of validation. The optional Vizard-driven OpNav Monte Carlo example requires an external renderer and is not exercised by the normal suite; its inclination bounds were updated by inspection.