Skip to main content

Crate lambert_izzo

Crate lambert_izzo 

Source
Expand description

Izzo’s revisited Lambert solver — single + multi-revolution, short/long way.

Reference: D. Izzo, Revisiting Lambert’s problem, Celestial Mechanics & Dynamical Astronomy, 2014. arXiv:1403.2705. PDF in docs/izzo.pdf.

Inline Eq. N / Algorithm N references in the source point to that paper.

§Public API

Two entry points:

Both return LambertSolutions, which always carries the single-revolution trajectory, every reachable multi-rev pair, and the per-branch SolverDiagnostics (Householder iteration counts).

§Units

The crate is unit-agnostic at the type level — all quantities are plain f64 and [f64; 3]. The convention used throughout the docs and examples is SI for astrodynamics work:

QuantityUnit
Positionkm
Velocitykm/s
Time of flights
Gravitational parameterkm³/s²

Any consistent unit system works — pass r in meters and mu in m³/s² and you get velocities in m/s. The math is dimensionally homogeneous.

The algorithm is also frame-invariant under any inertial frame — pass r1 and r2 in the same inertial frame (ECI for Earth orbits, HCRS for solar transfers, etc.) and the returned velocities are in that same frame. The function signature is frame-agnostic; the calling code’s variable names carry the frame info.

Position and velocity vectors are plain [f64; 3] arrays; the crate has no hard math-library dependency. Both nalgebra::Vector3<f64> and glam::DVec3 already convert to/from [f64; 3] natively, so callers using either library can pass and receive vectors without an explicit interop layer.

// nalgebra:
let r1: [f64; 3] = nalgebra::Vector3::new(7000.0, 0.0, 0.0).into();
let v1: nalgebra::Vector3<f64> = solution.single.v1.into();

// glam:
let r2 = glam::DVec3::new(0.0, 7000.0, 0.0).to_array();
let v2 = glam::DVec3::from_array(solution.single.v2);

§Example

use lambert_izzo::{lambert, LambertError, LambertInput, RevolutionBudget, TransferWay};

// LEO → LEO 90° transfer at 7000 km altitude.
let mu = 398_600.4418;
let r = 7000.0_f64;
let input = LambertInput {
    r1: [r, 0.0, 0.0],
    r2: [0.0, r, 0.0],
    tof: core::f64::consts::PI / 2.0 * (r.powi(3) / mu).sqrt(),
    mu,
    way: TransferWay::Short,
    revolutions: RevolutionBudget::SingleOnly,
};

let solutions = lambert(&input)?;
assert!(solutions.multi.is_empty());
assert!(solutions.diagnostics.single.iters > 0);
let v1 = solutions.single.v1;

§Cargo features

Both features are off by default.

  • serde — derives Serialize + Deserialize on every public type, including LambertError. Stays no_std-compatible.
  • rayon — enables lambert_par for parallel batch evaluation. Pulls in std transitively and is not no_std-compatible.

Structs§

BoundedRevs
Validated revolution count for multi-rev Lambert solves.
LambertDiagnostics
Diagnostics structure mirroring LambertSolutions.
LambertInput
One Lambert call’s inputs.
LambertSolution
One Lambert transfer trajectory.
LambertSolutions
All Lambert trajectories for a given boundary problem and revolution budget.
MultiRevDiagnostics
Per-pair diagnostics for the multi-revolution solver branches.
MultiRevPair
One multi-revolution pair: long-period and short-period trajectories for a given revolution count.
MultiRevPairDiagnostics
Diagnostics for one multi-rev pair.
MultiRevSet
Multi-revolution Lambert solution pairs in ascending M order.
RevsOutOfRange
Construction-time validation error returned by BoundedRevs::try_new (and by extension crate::RevolutionBudget::try_up_to).
SolverDiagnostics
Diagnostic data for one converged Householder solve.

Enums§

LambertError
Failure modes of the Izzo Lambert solver.
NonFiniteParameter
Identifies which public input was rejected by the finiteness check.
Position
Identifies which of the two endpoint positions an error refers to.
RevolutionBudget
Maximum number of complete revolutions to consider beyond single-rev.
TransferWay
Direction around the transfer plane from r1 to r2.

Constants§

MAX_MULTI_REV_PAIRS
Hard upper bound on the number of multi-revolution pairs returned.

Functions§

lambert
Solve Lambert’s boundary-value problem using Izzo’s revisited algorithm.