Functions: Transfers
Functions for computing interplanetary transfer orbits using the Lambert problem solver. Given a departure body, arrival body, departure time, and arrival time, the solver finds the transfer orbit that connects the two positions.
lambert_transfer
Section titled “lambert_transfer”Solves the Lambert problem for a transfer between two planets and returns the full solution record. The solver computes heliocentric positions of both bodies at the departure and arrival times using VSOP87, then finds the conic section connecting them.
Signature
Section titled “Signature”lambert_transfer( dep_body int4, arr_body int4, dep_time timestamptz, arr_time timestamptz) → RECORD( c3_departure float8, c3_arrival float8, v_inf_departure float8, v_inf_arrival float8, tof_days float8, transfer_sma float8)Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
dep_body | int4 | Departure planet body ID (1-8). See Body ID Reference. |
arr_body | int4 | Arrival planet body ID (1-8) |
dep_time | timestamptz | Departure epoch |
arr_time | timestamptz | Arrival epoch. Must be after dep_time. |
Returns
Section titled “Returns”A record with the following fields:
| Field | Type | Unit | Description |
|---|---|---|---|
c3_departure | float8 | km^2/s^2 | Departure characteristic energy. The square of the hyperbolic excess velocity at the departure planet. A smaller C3 requires less launch energy. |
c3_arrival | float8 | km^2/s^2 | Arrival characteristic energy. The energy that must be shed for orbit insertion at the arrival planet. |
v_inf_departure | float8 | km/s | Hyperbolic excess velocity at departure (= sqrt(C3)). |
v_inf_arrival | float8 | km/s | Hyperbolic excess velocity at arrival. |
tof_days | float8 | days | Time of flight from departure to arrival. |
transfer_sma | float8 | AU | Semi-major axis of the transfer orbit. Negative for hyperbolic transfers. |
Example
Section titled “Example”-- Earth to Mars transfer for a 2028 opportunitySELECT round(c3_departure::numeric, 2) AS c3_depart, round(c3_arrival::numeric, 2) AS c3_arrive, round(v_inf_departure::numeric, 3) AS v_inf_dep, round(v_inf_arrival::numeric, 3) AS v_inf_arr, round(tof_days::numeric, 1) AS flight_days, round(transfer_sma::numeric, 4) AS sma_auFROM lambert_transfer(3, 4, '2028-10-01'::timestamptz, '2029-06-15'::timestamptz);-- Pork chop plot: scan departure and arrival dates for Earth-Mars-- 150 departure dates x 150 arrival dates = 22,500 solutionsSELECT dep, arr, round(c3_departure::numeric, 2) AS c3FROM generate_series('2028-08-01'::timestamptz, '2029-01-28'::timestamptz, interval '1 day') AS depCROSS JOIN generate_series('2029-03-01'::timestamptz, '2029-07-28'::timestamptz, interval '1 day') AS arr,LATERAL lambert_transfer(3, 4, dep, arr) AS ltWHERE c3_departure IS NOT NULL AND c3_departure < 50ORDER BY c3_departure;-- Compare transfer windows for all outer planets from EarthSELECT arr_body, CASE arr_body WHEN 5 THEN 'Jupiter' WHEN 6 THEN 'Saturn' WHEN 7 THEN 'Uranus' WHEN 8 THEN 'Neptune' END AS target, round(c3_departure::numeric, 2) AS c3, round(tof_days::numeric, 0) AS flight_daysFROM unnest(ARRAY[5,6,7,8]) AS arr_body, lambert_transfer(3, arr_body, '2030-01-01'::timestamptz, '2030-01-01'::timestamptz + interval '2 years') AS lt;lambert_c3
Section titled “lambert_c3”A convenience function that solves the Lambert problem and returns only the departure C3 value. Returns NULL on solver failure (e.g., degenerate geometry, transfer angle near 0 or 180 degrees). This is the function to use for generating pork chop plots where only departure energy matters.
Signature
Section titled “Signature”lambert_c3(dep_body int4, arr_body int4, dep_time timestamptz, arr_time timestamptz) → float8Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
dep_body | int4 | Departure planet body ID (1-8) |
arr_body | int4 | Arrival planet body ID (1-8) |
dep_time | timestamptz | Departure epoch |
arr_time | timestamptz | Arrival epoch |
Returns
Section titled “Returns”Departure C3 in km^2/s^2, or NULL if the solver fails.
Example
Section titled “Example”-- Quick C3 check for a specific transferSELECT round(lambert_c3(3, 4, '2028-10-15'::timestamptz, '2029-05-01'::timestamptz)::numeric, 2) AS c3_km2s2;-- Dense pork chop plot using the scalar function-- Faster than lambert_transfer when you only need C3SELECT dep, arr, round(lambert_c3(3, 4, dep, arr)::numeric, 2) AS c3FROM generate_series('2028-08-01'::timestamptz, '2029-01-28'::timestamptz, interval '1 day') AS depCROSS JOIN generate_series('2029-03-01'::timestamptz, '2029-07-28'::timestamptz, interval '1 day') AS arrWHERE lambert_c3(3, 4, dep, arr) IS NOT NULL AND lambert_c3(3, 4, dep, arr) < 30;