Add Universal Variable Lambert solver for computing transfer orbits between any two planets. Enables pork chop plot generation as SQL: SELECT dep_date, arr_date, lambert_c3(3, 4, dep_date, arr_date) FROM generate_series(...) dep CROSS JOIN generate_series(...) arr; New functions: - lambert_transfer(dep_body, arr_body, dep_time, arr_time) → RECORD Returns C3 departure/arrival (km^2/s^2), v_infinity (km/s), time of flight (days), and transfer orbit SMA (AU). - lambert_c3(dep_body, arr_body, dep_time, arr_time) → float8 Convenience: departure C3 only, NULL on solver failure. The solver uses Stumpff functions for unified elliptic/parabolic/hyperbolic handling, with Newton-Raphson iteration and bisection fallback. Each solve is sub-millisecond; PARALLEL SAFE for batch computation. All 11 regression tests pass.
189 lines
9.4 KiB
SQL
189 lines
9.4 KiB
SQL
-- pg_orbit 0.1.0 -> 0.2.0 migration
|
|
--
|
|
-- Phase 1: Stars, comets, and Keplerian propagation.
|
|
-- Adds heliocentric type, star observation, and two-body propagation.
|
|
|
|
|
|
-- ============================================================
|
|
-- Heliocentric type: ecliptic J2000 position in AU
|
|
-- ============================================================
|
|
|
|
CREATE TYPE heliocentric;
|
|
|
|
CREATE FUNCTION heliocentric_in(cstring) RETURNS heliocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
CREATE FUNCTION heliocentric_out(heliocentric) RETURNS cstring
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
CREATE FUNCTION heliocentric_recv(internal) RETURNS heliocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
CREATE FUNCTION heliocentric_send(heliocentric) RETURNS bytea
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
|
|
CREATE TYPE heliocentric (
|
|
INPUT = heliocentric_in,
|
|
OUTPUT = heliocentric_out,
|
|
RECEIVE = heliocentric_recv,
|
|
SEND = heliocentric_send,
|
|
INTERNALLENGTH = 24,
|
|
ALIGNMENT = double,
|
|
STORAGE = plain
|
|
);
|
|
|
|
COMMENT ON TYPE heliocentric IS 'Heliocentric position in ecliptic J2000 frame (x, y, z in AU)';
|
|
|
|
CREATE FUNCTION helio_x(heliocentric) RETURNS float8
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION helio_x(heliocentric) IS 'X component in AU (ecliptic J2000, vernal equinox direction)';
|
|
|
|
CREATE FUNCTION helio_y(heliocentric) RETURNS float8
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION helio_y(heliocentric) IS 'Y component in AU (ecliptic J2000)';
|
|
|
|
CREATE FUNCTION helio_z(heliocentric) RETURNS float8
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION helio_z(heliocentric) IS 'Z component in AU (ecliptic J2000, north ecliptic pole)';
|
|
|
|
CREATE FUNCTION helio_distance(heliocentric) RETURNS float8
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION helio_distance(heliocentric) IS 'Heliocentric distance in AU';
|
|
|
|
|
|
-- ============================================================
|
|
-- Star observation functions
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION star_observe(float8, float8, observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION star_observe(float8, float8, observer, timestamptz) IS
|
|
'Observe a star from (ra_hours J2000, dec_degrees J2000, observer, time). Returns topocentric az/el. Range is 0 (infinite distance).';
|
|
|
|
CREATE FUNCTION star_observe_safe(float8, float8, observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE PARALLEL SAFE;
|
|
COMMENT ON FUNCTION star_observe_safe(float8, float8, observer, timestamptz) IS
|
|
'Like star_observe but returns NULL on invalid inputs. For batch queries over star catalogs.';
|
|
|
|
|
|
-- ============================================================
|
|
-- Keplerian propagation functions
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION kepler_propagate(
|
|
q_au float8, eccentricity float8,
|
|
inclination_deg float8, arg_perihelion_deg float8,
|
|
long_asc_node_deg float8, perihelion_jd float8,
|
|
t timestamptz
|
|
) RETURNS heliocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION kepler_propagate(float8, float8, float8, float8, float8, float8, timestamptz) IS
|
|
'Two-body Keplerian propagation from classical orbital elements. Returns heliocentric ecliptic J2000 position in AU. Handles elliptic, parabolic, and hyperbolic orbits.';
|
|
|
|
|
|
-- ============================================================
|
|
-- Comet observation
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION comet_observe(
|
|
q_au float8, eccentricity float8,
|
|
inclination_deg float8, arg_perihelion_deg float8,
|
|
long_asc_node_deg float8, perihelion_jd float8,
|
|
earth_x_au float8, earth_y_au float8, earth_z_au float8,
|
|
obs observer, t timestamptz
|
|
) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION comet_observe(float8, float8, float8, float8, float8, float8, float8, float8, float8, observer, timestamptz) IS
|
|
'Observe a comet/asteroid from orbital elements. Requires Earth heliocentric ecliptic J2000 position (AU). Returns topocentric az/el with geocentric range in km.';
|
|
|
|
|
|
-- ============================================================
|
|
-- Phase 2: VSOP87 planets, ELP82B Moon, Sun observation
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION planet_heliocentric(int4, timestamptz) RETURNS heliocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION planet_heliocentric(int4, timestamptz) IS
|
|
'VSOP87 heliocentric ecliptic J2000 position (AU). Body IDs: 0=Sun, 1=Mercury, ..., 8=Neptune.';
|
|
|
|
CREATE FUNCTION planet_observe(int4, observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION planet_observe(int4, observer, timestamptz) IS
|
|
'Observe a planet from (body_id 1-8, observer, time). Returns topocentric az/el with geocentric range in km.';
|
|
|
|
CREATE FUNCTION sun_observe(observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION sun_observe(observer, timestamptz) IS
|
|
'Observe the Sun from (observer, time). Returns topocentric az/el with geocentric range in km.';
|
|
|
|
CREATE FUNCTION moon_observe(observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION moon_observe(observer, timestamptz) IS
|
|
'Observe the Moon via ELP2000-82B from (observer, time). Returns topocentric az/el with geocentric range in km.';
|
|
|
|
|
|
-- ============================================================
|
|
-- Phase 3: Planetary moon observation
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION galilean_observe(int4, observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION galilean_observe(int4, observer, timestamptz) IS
|
|
'Observe a Galilean moon of Jupiter via L1.2 theory. Body IDs: 0=Io, 1=Europa, 2=Ganymede, 3=Callisto.';
|
|
|
|
CREATE FUNCTION saturn_moon_observe(int4, observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION saturn_moon_observe(int4, observer, timestamptz) IS
|
|
'Observe a Saturn moon via TASS 1.7. Body IDs: 0=Mimas, 1=Enceladus, 2=Tethys, 3=Dione, 4=Rhea, 5=Titan, 6=Iapetus, 7=Hyperion.';
|
|
|
|
CREATE FUNCTION uranus_moon_observe(int4, observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION uranus_moon_observe(int4, observer, timestamptz) IS
|
|
'Observe a Uranus moon via GUST86. Body IDs: 0=Miranda, 1=Ariel, 2=Umbriel, 3=Titania, 4=Oberon.';
|
|
|
|
CREATE FUNCTION mars_moon_observe(int4, observer, timestamptz) RETURNS topocentric
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION mars_moon_observe(int4, observer, timestamptz) IS
|
|
'Observe a Mars moon via MarsSat. Body IDs: 0=Phobos, 1=Deimos.';
|
|
|
|
|
|
-- ============================================================
|
|
-- Phase 3: Jupiter decametric radio burst prediction
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION io_phase_angle(timestamptz) RETURNS float8
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION io_phase_angle(timestamptz) IS
|
|
'Io orbital phase angle in degrees [0,360). 0=superior conjunction (behind Jupiter). Standard Radio JOVE convention.';
|
|
|
|
CREATE FUNCTION jupiter_cml(observer, timestamptz) RETURNS float8
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION jupiter_cml(observer, timestamptz) IS
|
|
'Jupiter Central Meridian Longitude, System III (1965.0), in degrees [0,360). Light-time corrected.';
|
|
|
|
CREATE FUNCTION jupiter_burst_probability(float8, float8) RETURNS float8
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION jupiter_burst_probability(float8, float8) IS
|
|
'Estimated Jupiter decametric burst probability (0-1) from (io_phase_deg, cml_deg). Based on Carr et al. (1983) source regions A, B, C, D.';
|
|
|
|
|
|
-- ============================================================
|
|
-- Phase 4: Interplanetary transfer orbits (Lambert solver)
|
|
-- ============================================================
|
|
|
|
CREATE FUNCTION lambert_transfer(
|
|
dep_body_id int4, arr_body_id int4,
|
|
dep_time timestamptz, arr_time timestamptz,
|
|
OUT c3_departure float8, OUT c3_arrival float8,
|
|
OUT v_inf_departure float8, OUT v_inf_arrival float8,
|
|
OUT tof_days float8, OUT transfer_sma float8
|
|
) RETURNS RECORD
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION lambert_transfer(int4, int4, timestamptz, timestamptz) IS
|
|
'Solve Lambert transfer between two planets. Returns C3 (km^2/s^2), v_infinity (km/s), TOF (days), SMA (AU). Body IDs 1-8.';
|
|
|
|
CREATE FUNCTION lambert_c3(int4, int4, timestamptz, timestamptz) RETURNS float8
|
|
AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
|
|
COMMENT ON FUNCTION lambert_c3(int4, int4, timestamptz, timestamptz) IS
|
|
'Departure C3 (km^2/s^2) for a Lambert transfer. Returns NULL if solver fails. For pork chop plots.';
|