Skip to main content

gooding_lambert/
lib.rs

1//! # gooding-lambert
2//!
3//! Gooding's method for solving Lambert's orbital boundary-value problem.
4//!
5//! Given two position vectors and a time of flight, computes the velocity
6//! vectors at each endpoint of the connecting Keplerian arc. Handles all
7//! conic sections (elliptic, parabolic, hyperbolic), all transfer angles,
8//! and multi-revolution solutions.
9//!
10//! ## Quick Start
11//!
12//! ```
13//! use gooding_lambert::{lambert, Direction};
14//!
15//! let mu = 398600.4418_f64; // Earth GM (km³/s²)
16//! let r1 = [6678.0, 0.0, 0.0]; // km
17//! let r2 = [0.0, 42164.0, 0.0]; // km (GEO)
18//! let tof = 5.0 * 3600.0; // seconds
19//!
20//! let sol = lambert(mu, r1, r2, tof, 0, Direction::Prograde).unwrap();
21//! let speed = (sol.v1[0].powi(2) + sol.v1[1].powi(2) + sol.v1[2].powi(2)).sqrt();
22//! assert!(speed > 5.0 && speed < 15.0); // km/s at LEO departure
23//! ```
24//!
25//! ## References
26//!
27//! Gooding, R. H. (1990). "A procedure for the solution of Lambert's orbital
28//! boundary-value problem." *Celestial Mechanics and Dynamical Astronomy*, 48(2), 145–165.
29
30mod gooding;
31
32pub use gooding::gooding_lambert;
33pub use gooding::lambert;
34
35/// Transfer direction for Lambert's problem.
36///
37/// Prograde means the transfer orbit has positive angular momentum aligned
38/// with `r1 × r2`. Retrograde uses the supplementary transfer angle
39/// (> 180°), with angular momentum aligned with `r2 × r1`.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum Direction {
42    /// Transfer angle ∈ (0°, 180°); angular momentum parallel to r1 × r2.
43    Prograde,
44    /// Transfer angle ∈ (180°, 360°); angular momentum parallel to r2 × r1.
45    Retrograde,
46}
47
48/// Velocity solution returned by [`lambert`].
49#[derive(Debug, Clone, PartialEq)]
50pub struct LambertSolution {
51    /// Velocity vector at the departure point (same units as position / time).
52    pub v1: [f64; 3],
53    /// Velocity vector at the arrival point (same units as position / time).
54    pub v2: [f64; 3],
55}
56
57/// Errors returned by [`lambert`].
58#[derive(Debug, Clone, PartialEq)]
59pub enum LambertError {
60    /// Transfer angle is exactly 180° — transfer plane undefined.
61    SingularTransfer,
62    /// No solution exists for the given revolution count and time of flight
63    /// (TOF is below the minimum time for the requested revolution count).
64    NoSolution,
65    /// Householder iteration failed to converge within the iteration limit.
66    ConvergenceFailed,
67    /// One or more inputs are invalid (zero radius, non-positive TOF, etc.).
68    InvalidInput(&'static str),
69}