# lamberthub: a hub of Lambert's problem solvers
<img align="left" width=350px src="https://github.com/jorgepiloto/lamberthub/raw/main/doc/source/_static/lamberts_problem_geometry.png"/>
A Python library designed to provide solutions to Lambert's problem, a
classical problem in astrodynamics that involves determining the orbit of a
spacecraft given two points in space and the time of flight between them. The
problem is essential for trajectory planning, particularly for interplanetary
missions.
This library implements multiple algorithms, each named after its author and
publication year, for solving different variations of Lambert's problem. These
algorithms can handle different types of orbits, including multi-revolution
paths and direct transfers.
<br>
<!-- vale off -->
[![Python](https://img.shields.io/pypi/pyversions/lamberthub?logo=pypi)](https://pypi.org/project/lamberthub/)
[![PyPI](https://img.shields.io/pypi/v/lamberthub.svg?logo=python&logoColor=white)](https://pypi.org/project/lamberthub/)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![CI](https://github.com/jorgepiloto/lamberthub/actions/workflows/ci_cd.yml/badge.svg?branch=main)](https://github.com/jorgepiloto/lamberthub/actions/workflows/ci_cd.yml)
[![Coverage](https://codecov.io/gh/jorgepiloto/lamberthub/branch/main/graph/badge.svg?token=3BY2J5AB8D)](https://codecov.io/gh/jorgepiloto/lamberthub)
[![DOI](https://zenodo.org/badge/364482782.svg)](https://zenodo.org/badge/latestdoi/364482782)
<!-- vale on -->
## Installation
Multiple installation methods are supported:
| **Logo** | **Platform** | **Command** |
|:-----------------------------------------------------------------:|:------------:|:---------------------------------------------------------------------------------:|
| ![PyPI logo](https://simpleicons.org/icons/pypi.svg) | PyPI | ``python -m pip install lamberthub`` |
| ![GitHub logo](https://simpleicons.org/icons/github.svg) | GitHub | ``python -m pip install https://github.com/jorgepiloto/lamberthub/archive/main.zip`` |
## Available solvers
<!-- vale off -->
| Algorithm | Reference |
|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| `gauss1809` | C. F. Gauss, *Theoria motus corporum coelestium in sectionibus conicis solem ambientium*. 1809. |
| `battin1984` | R. H. Battin and R. M. Vaughan, “An elegant lambert algorithm,” *Journal of Guidance, Control, and Dynamics*, vol. 7, no. 6, pp. 662–670, 1984. |
| `gooding1990` | R. Gooding, “A procedure for the solution of lambert’s orbital boundary-value problem,” *Celestial Mechanics and Dynamical Astronomy*, vol. 48, no. 2, pp. 145–165, 1990. |
| `avanzini2008`| G. Avanzini, “A simple lambert algorithm,” *Journal of Guidance, Control, and Dynamics*, vol. 31, no. 6, pp. 1587–1594, 2008. |
| `arora2013` | N. Arora and R. P. Russell, “A fast and robust multiple revolution lambert algorithm using a cosine transformation,” Paper AAS, vol. 13, p. 728, 2013. |
| `vallado2013` | D. A. Vallado, *Fundamentals of astrodynamics and applications*. Springer Science & Business Media, 2013, vol. 12. |
| `izzo2015` | D. Izzo, “Revisiting lambert’s problem,” *Celestial Mechanics and Dynamical Astronomy*, vol. 121, no. 1, pp. 1–15, 2015. |
<!-- vale on -->
## Using a solver
Any Lambert's problem algorithm implemented in `lamberthub` is a Python function
which accepts the following parameters:
```python
from lamberthub import authorYYYY
v1, v2 = authorYYYY(
mu, r1, r2, tof, M=0, prograde=True, low_path=True, # Type of solution
maxiter=35, atol=1e-5, rtol=1e-7, full_output=False # Iteration config
)
```
where `author` is the name of the author which developed the solver and `YYYY`
the year of publication. Any of the solvers hosted by the `ALL_SOLVERS` list.
### Parameters
| Parameters | Type | Description |
|---------------|-----------|-------------|
| `mu` | `float` | The gravitational parameter, that is, the mass of the attracting body times the gravitational constant. |
| `r1` | `np.array`| Initial position vector. |
| `r2` | `np.array`| Final position vector. |
| `tof` | `float` | Time of flight between initial and final vectors. |
| `M` | `int` | The number of revolutions. If zero (default), direct transfer is assumed. |
| `prograde` | `bool` | Controls the inclination of the final orbit. If `True`, inclination between 0 and 90 degrees. If `False`, inclination between 90 and 180 degrees. |
| `low_path` | `bool` | Selects the type of path when more than two solutions are available. No specific advantage unless there are mission constraints. |
| `maxiter` | `int` | Maximum number of iterations allowed when computing the solution. |
| `atol` | `float` | Absolute tolerance for the iterative method. |
| `rtol` | `float` | Relative tolerance for the iterative method. |
| `full_output` | `bool` | If `True`, returns additional information such as the number of iterations. |
### Returns
| Returns | Type | Description |
|---------------|------------|-------------|
| `v1` | `np.array` | Initial velocity vector. |
| `v2` | `np.array` | Final velocity vector. |
| `numiter` | `int` | Number of iterations (only if `full_output` is `True`). |
| `tpi` | `float` | Time per iteration (only if `full_output` is `True`). |
## Examples
### Example: solving for a direct and prograde transfer orbit
**Problem statement**
Suppose you want to solve for the orbit of an interplanetary vehicle (that is
Sun is the main attractor) form which you know that the initial and final
positions are given by:
```math
\vec{r_1} = \begin{bmatrix} 0.159321004 \\ 0.579266185 \\ 0.052359607 \end{bmatrix} \text{ [AU]} \quad \quad
\vec{r_2} = \begin{bmatrix} 0.057594337 \\ 0.605750797 \\ 0.068345246 \end{bmatrix} \text{ [AU]} \quad \quad
```
<br>
The time of flight is $\Delta t = 0.010794065$ years. The orbit is
prograde and direct, thus $M=0$. Remember that when $M=0$, there is only one
possible solution, so the `low_path` flag does not play any role in this
problem.
**Solution**
For this problem, `gooding1990` is used. Any other solver would work too. Next,
the parameters of the problem are instantiated. Finally, the initial and final
velocity vectors are computed.
```python
from lamberthub import gooding1990
import numpy as np
mu_sun = 39.47692641
r1 = np.array([0.159321004, 0.579266185, 0.052359607])
r2 = np.array([0.057594337, 0.605750797, 0.068345246])
tof = 0.010794065
v1, v2 = gooding1990(mu_sun, r1, r2, tof, M=0, prograde=True)
print(f"Initial velocity: {v1} [AU / years]")
print(f"Final velocity: {v2} [AU / years]")
```
**Result**
```console
Initial velocity: [-9.303608 3.01862016 1.53636008] [AU / years]
Final velocity: [-9.511186 1.88884006 1.42137810] [AU / years]
```
Directly taken from *An Introduction to the Mathematics and Methods of
Astrodynamics, revised edition, by R.H. Battin, problem 7-12*.
Raw data
{
"_id": null,
"home_page": null,
"name": "lamberthub",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "Jorge Mart\u00ednez Garrido <contact@jorgemartinez.space>",
"keywords": "aerospace, astrodynamics, orbital-mechanics, kepler, lambert, orbit-determination",
"author": null,
"author_email": "Jorge Mart\u00ednez Garrido <contact@jorgemartinez.space>",
"download_url": "https://files.pythonhosted.org/packages/11/53/92f74e57f1d375e04e4dd67a245079c09fc3bb0b81c992bedfc34a31e6b9/lamberthub-1.0.0.tar.gz",
"platform": null,
"description": "# lamberthub: a hub of Lambert's problem solvers\n\n<img align=\"left\" width=350px src=\"https://github.com/jorgepiloto/lamberthub/raw/main/doc/source/_static/lamberts_problem_geometry.png\"/>\n\nA Python library designed to provide solutions to Lambert's problem, a\nclassical problem in astrodynamics that involves determining the orbit of a\nspacecraft given two points in space and the time of flight between them. The\nproblem is essential for trajectory planning, particularly for interplanetary\nmissions.\n\nThis library implements multiple algorithms, each named after its author and\npublication year, for solving different variations of Lambert's problem. These\nalgorithms can handle different types of orbits, including multi-revolution\npaths and direct transfers.\n\n<br>\n\n<!-- vale off -->\n[![Python](https://img.shields.io/pypi/pyversions/lamberthub?logo=pypi)](https://pypi.org/project/lamberthub/)\n[![PyPI](https://img.shields.io/pypi/v/lamberthub.svg?logo=python&logoColor=white)](https://pypi.org/project/lamberthub/)\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n[![CI](https://github.com/jorgepiloto/lamberthub/actions/workflows/ci_cd.yml/badge.svg?branch=main)](https://github.com/jorgepiloto/lamberthub/actions/workflows/ci_cd.yml)\n[![Coverage](https://codecov.io/gh/jorgepiloto/lamberthub/branch/main/graph/badge.svg?token=3BY2J5AB8D)](https://codecov.io/gh/jorgepiloto/lamberthub)\n[![DOI](https://zenodo.org/badge/364482782.svg)](https://zenodo.org/badge/latestdoi/364482782)\n<!-- vale on -->\n\n## Installation\n\nMultiple installation methods are supported:\n\n| **Logo** | **Platform** | **Command** |\n|:-----------------------------------------------------------------:|:------------:|:---------------------------------------------------------------------------------:|\n| ![PyPI logo](https://simpleicons.org/icons/pypi.svg) | PyPI | ``python -m pip install lamberthub`` |\n| ![GitHub logo](https://simpleicons.org/icons/github.svg) | GitHub | ``python -m pip install https://github.com/jorgepiloto/lamberthub/archive/main.zip`` |\n\n## Available solvers\n\n<!-- vale off -->\n\n| Algorithm | Reference |\n|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `gauss1809` | C. F. Gauss, *Theoria motus corporum coelestium in sectionibus conicis solem ambientium*. 1809. |\n| `battin1984` | R. H. Battin and R. M. Vaughan, \u201cAn elegant lambert algorithm,\u201d *Journal of Guidance, Control, and Dynamics*, vol. 7, no. 6, pp. 662\u2013670, 1984. |\n| `gooding1990` | R. Gooding, \u201cA procedure for the solution of lambert\u2019s orbital boundary-value problem,\u201d *Celestial Mechanics and Dynamical Astronomy*, vol. 48, no. 2, pp. 145\u2013165, 1990. |\n| `avanzini2008`| G. Avanzini, \u201cA simple lambert algorithm,\u201d *Journal of Guidance, Control, and Dynamics*, vol. 31, no. 6, pp. 1587\u20131594, 2008. |\n| `arora2013` | N. Arora and R. P. Russell, \u201cA fast and robust multiple revolution lambert algorithm using a cosine transformation,\u201d Paper AAS, vol. 13, p. 728, 2013. |\n| `vallado2013` | D. A. Vallado, *Fundamentals of astrodynamics and applications*. Springer Science & Business Media, 2013, vol. 12. |\n| `izzo2015` | D. Izzo, \u201cRevisiting lambert\u2019s problem,\u201d *Celestial Mechanics and Dynamical Astronomy*, vol. 121, no. 1, pp. 1\u201315, 2015. |\n\n<!-- vale on -->\n\n## Using a solver\n\nAny Lambert's problem algorithm implemented in `lamberthub` is a Python function\nwhich accepts the following parameters:\n\n```python\nfrom lamberthub import authorYYYY\n\n\nv1, v2 = authorYYYY(\n mu, r1, r2, tof, M=0, prograde=True, low_path=True, # Type of solution\n maxiter=35, atol=1e-5, rtol=1e-7, full_output=False # Iteration config\n)\n```\n\nwhere `author` is the name of the author which developed the solver and `YYYY`\nthe year of publication. Any of the solvers hosted by the `ALL_SOLVERS` list.\n\n### Parameters\n\n| Parameters | Type | Description |\n|---------------|-----------|-------------|\n| `mu` | `float` | The gravitational parameter, that is, the mass of the attracting body times the gravitational constant. |\n| `r1` | `np.array`| Initial position vector. |\n| `r2` | `np.array`| Final position vector. |\n| `tof` | `float` | Time of flight between initial and final vectors. |\n| `M` | `int` | The number of revolutions. If zero (default), direct transfer is assumed. |\n| `prograde` | `bool` | Controls the inclination of the final orbit. If `True`, inclination between 0 and 90 degrees. If `False`, inclination between 90 and 180 degrees. |\n| `low_path` | `bool` | Selects the type of path when more than two solutions are available. No specific advantage unless there are mission constraints. |\n| `maxiter` | `int` | Maximum number of iterations allowed when computing the solution. |\n| `atol` | `float` | Absolute tolerance for the iterative method. |\n| `rtol` | `float` | Relative tolerance for the iterative method. |\n| `full_output` | `bool` | If `True`, returns additional information such as the number of iterations. |\n\n### Returns\n\n| Returns | Type | Description |\n|---------------|------------|-------------|\n| `v1` | `np.array` | Initial velocity vector. |\n| `v2` | `np.array` | Final velocity vector. |\n| `numiter` | `int` | Number of iterations (only if `full_output` is `True`). |\n| `tpi` | `float` | Time per iteration (only if `full_output` is `True`). |\n\n## Examples\n\n### Example: solving for a direct and prograde transfer orbit\n\n**Problem statement**\n\nSuppose you want to solve for the orbit of an interplanetary vehicle (that is\nSun is the main attractor) form which you know that the initial and final\npositions are given by:\n\n```math\n\\vec{r_1} = \\begin{bmatrix} 0.159321004 \\\\ 0.579266185 \\\\ 0.052359607 \\end{bmatrix} \\text{ [AU]} \\quad \\quad\n\\vec{r_2} = \\begin{bmatrix} 0.057594337 \\\\ 0.605750797 \\\\ 0.068345246 \\end{bmatrix} \\text{ [AU]} \\quad \\quad\n```\n\n<br>\n\nThe time of flight is $\\Delta t = 0.010794065$ years. The orbit is\nprograde and direct, thus $M=0$. Remember that when $M=0$, there is only one\npossible solution, so the `low_path` flag does not play any role in this\nproblem.\n\n**Solution**\n\nFor this problem, `gooding1990` is used. Any other solver would work too. Next,\nthe parameters of the problem are instantiated. Finally, the initial and final\nvelocity vectors are computed.\n\n```python\nfrom lamberthub import gooding1990\nimport numpy as np\n\n\nmu_sun = 39.47692641\nr1 = np.array([0.159321004, 0.579266185, 0.052359607])\nr2 = np.array([0.057594337, 0.605750797, 0.068345246])\ntof = 0.010794065\n\nv1, v2 = gooding1990(mu_sun, r1, r2, tof, M=0, prograde=True)\nprint(f\"Initial velocity: {v1} [AU / years]\")\nprint(f\"Final velocity: {v2} [AU / years]\")\n```\n\n**Result**\n\n```console\nInitial velocity: [-9.303608 3.01862016 1.53636008] [AU / years]\nFinal velocity: [-9.511186 1.88884006 1.42137810] [AU / years]\n```\n\nDirectly taken from *An Introduction to the Mathematics and Methods of\nAstrodynamics, revised edition, by R.H. Battin, problem 7-12*.\n\n\n",
"bugtrack_url": null,
"license": null,
"summary": "A collection of Lambert's problem solvers.",
"version": "1.0.0",
"project_urls": {
"Documentation": "https://github.com/jorgepiloto/lamberthub/blob/main/README.md",
"Homepage": "https://github.com/jorgepiloto/lamberthub",
"Issues": "https://github.com/jorgepiloto/lamberthub/issues",
"Releases": "https://github.com/jorgepiloto/lamberthub/releases",
"Source": "https://github.com/jorgepiloto/lamberthub"
},
"split_keywords": [
"aerospace",
" astrodynamics",
" orbital-mechanics",
" kepler",
" lambert",
" orbit-determination"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9cc151bdff9d1f2dbfbf9e772f20ac415f8d2040fd0c7c991bbb46c37ef2f05d",
"md5": "3095c2b668e68d729fd213d831c96786",
"sha256": "3a1f7ebadad9e325a8e06ae3da4680b716aeeb51c765debd9491267356c92ef4"
},
"downloads": -1,
"filename": "lamberthub-1.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3095c2b668e68d729fd213d831c96786",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 56447,
"upload_time": "2024-09-16T10:35:04",
"upload_time_iso_8601": "2024-09-16T10:35:04.725061Z",
"url": "https://files.pythonhosted.org/packages/9c/c1/51bdff9d1f2dbfbf9e772f20ac415f8d2040fd0c7c991bbb46c37ef2f05d/lamberthub-1.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "115392f74e57f1d375e04e4dd67a245079c09fc3bb0b81c992bedfc34a31e6b9",
"md5": "1629809de7758a70b7f8f26a34563adf",
"sha256": "cde13891f118dc51895d1a0c13cb9ae3c060d526429a789594427585bf431c91"
},
"downloads": -1,
"filename": "lamberthub-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "1629809de7758a70b7f8f26a34563adf",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 47712,
"upload_time": "2024-09-16T10:35:05",
"upload_time_iso_8601": "2024-09-16T10:35:05.876151Z",
"url": "https://files.pythonhosted.org/packages/11/53/92f74e57f1d375e04e4dd67a245079c09fc3bb0b81c992bedfc34a31e6b9/lamberthub-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-16 10:35:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jorgepiloto",
"github_project": "lamberthub",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "lamberthub"
}