Lambert Solver — Izzo 2015 Algorithm
Background
Lambert’s problem: given two position vectors and a time of flight, find the orbit connecting them. Used for interplanetary transfer planning, departure window scanning, and trajectory optimization.
Previous Implementation (Curtis)
Universal-variable formulation from Curtis “Orbital Mechanics for Engineering Students”. Newton-Raphson with bisection safeguard. Single-revolution only (M=0).
Benchmark Results (#722)
10,000 random problems across interplanetary, lunar, and LEO scales:
| Metric | Curtis | Izzo (lamberthub) |
|---|---|---|
| Median time | 59 us | 30 us |
| P95 time | 92 us | 39 us |
| Failure rate | 2.86% | 0.00% |
| Multi-rev | No | Yes |
Solution agreement when both solve: max Dv diff = 0.000024 m/s, max direction diff = 0.000002 deg.
Izzo solves 286 problems Curtis fails on. Curtis never solves problems Izzo fails on.
Multi-Revolution
Izzo finds lower-Dv multi-rev transfers that Curtis cannot attempt:
- LEO to GEO (24h TOF): M=0 gives 10,436 m/s, M=2H gives 10,017 m/s (4% savings)
Decision
Adopt Izzo 2015 algorithm as a pure Python port (no lamberthub dependency).
Rationale:
- lamberthub pulls in numpy, numba, scipy, llvmlite (~100 MB) — too heavy for a game server
- The Izzo algorithm itself is ~250 lines of math that ports cleanly to pure Python
- Gives us: zero failures, 2x faster, multi-rev capability, no new dependencies
Algorithm
Based on Izzo’s “Revisiting Lambert’s Problem” (2015), inheriting from Lancaster-Blanchard universal formulation:
- Compute geometry: chord, semiperimeter, transfer angle parameter lambda
- Non-dimensionalize time of flight
- Compute initial guess for universal variable x (piecewise by T regime)
- Householder iteration (4th order) — converges in ~2-4 iterations
- Reconstruct velocity vectors from x, y via Lagrange coefficients
Multi-Revolution (M > 0)
For M > 0 revolutions:
- Compute minimum TOF via Halley iteration
- Two solutions exist (low-path and high-path)
- Initial guess differs from M=0 case
API
lambert_solve(r1_vec, r2_vec, tof, mu, prograde=True, M=0, low_path=True)
Returns (v1, v2) tuple of velocity vectors, or None if no solution.
Attribution
Algorithm: Izzo, D. (2015). “Revisiting Lambert’s problem.” Celestial Mechanics and Dynamical Astronomy, 121(1), 1-15.
Implementation ported from lamberthub/poliastro (GPL-3.0, Juan Luis Cano Rodriguez et al.), adapted to pure Python without numpy/numba dependencies.