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::lambert;
33
34/// Transfer direction for Lambert's problem.
35///
36/// Prograde means the transfer orbit has positive angular momentum aligned
37/// with `r1 × r2`. Retrograde uses the supplementary transfer angle
38/// (> 180°), with angular momentum aligned with `r2 × r1`.
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub enum Direction {
41 /// Transfer angle ∈ (0°, 180°); angular momentum parallel to r1 × r2.
42 Prograde,
43 /// Transfer angle ∈ (180°, 360°); angular momentum parallel to r2 × r1.
44 Retrograde,
45}
46
47/// Velocity solution returned by [`lambert`].
48#[derive(Debug, Clone, PartialEq)]
49pub struct LambertSolution {
50 /// Velocity vector at the departure point (same units as position / time).
51 pub v1: [f64; 3],
52 /// Velocity vector at the arrival point (same units as position / time).
53 pub v2: [f64; 3],
54}
55
56/// Errors returned by [`lambert`].
57#[derive(Debug, Clone, PartialEq)]
58pub enum LambertError {
59 /// Transfer angle is exactly 180° — transfer plane undefined.
60 SingularTransfer,
61 /// No solution exists for the given revolution count and time of flight
62 /// (TOF is below the minimum time for the requested revolution count).
63 NoSolution,
64 /// Householder iteration failed to converge within the iteration limit.
65 ConvergenceFailed,
66 /// One or more inputs are invalid (zero radius, non-positive TOF, etc.).
67 InvalidInput(&'static str),
68}