Transferencias Interplanetarias con Python

Jorge Martinez

Aerospace Engineer and Senior Software Developer

Whoami

Ingeniero aeroespacial interesado en la astrodinámica computacional. Actualmente trabajo como ingeniero senior de I+D en ANSYS, Inc.

En mi tiempo libre colaboro en proyectos de código abierto en el ámbito científico.


GitHub Web
jorgepiloto https://jorgemartinez.space

Misiones a Marte 2020 – 2021

¿Por qué todas las misiones se lanzan y llegan a Marte al mismo tiempo?

Misión Lanzamiento Llegada
Hope (UAE) 19 Julio 2020 9 Febrero 2021
Tianwen-1 23 Julio 2020 10 Febrero 2021
Perseverance 30 Julio 2020 18 Febrero 2021

Fundamentos del viaje interplanetario

Primero, debemos resolver las siguientes preguntas:

  • ¿Cómo se mueven los cuerpos en el espacio exterior?
  • ¿Es posible navegar en el espacio exterior?
  • ¿Es posible hacerlo de forma óptima?

Modelo matemático real


El Sistema Solar es complejo de modelar:


  • Plentas, lunas, asteroides, cometas, polvo…
  • Perturbaciones gravitacionales
  • Perturbaciones no-gravitacionales

Modelo matemático simplificado





El problema de los dos cuerpos se utiliza para describir el movimiento de dos cuerpos que interactúan entre sí. Asume que:

  • Uno de los cuerpos es mucho más masivo que el otro
  • Ambos cuerpos son esféricos y homogéneos
  • La única fuerza que actúa entre ellos es la gravedad
  • No hay perturbaciones (atmosféricas, gravitacionales, etc.)
  • No hay fuerzas externas actuando sobre ellos

¿Dónde obtener datos sobre los planetas?

El JPL de la NASA mantiene un conjunto de efemérides de alta precisión. Las efemérides son tablas o modelos que proporcionan las posiciones y velocidades de los cuerpos celestes a lo largo del tiempo.

  • Elaboradas a partir de observaciones astronómicas y datos de misiones espaciales

Kernels de SPICE

Existen varios tipos de kernels:

  • LSK: datos de tiempo
  • SPK: efemérides de cuerpos celestes
  • PCK: datos físicos de cuerpos celestes

Ejemplo: obtener la posición de la Tierra respecto al Sol

import spiceypy as spice

spice.furnsh("latest_leapseconds.tls")
spice.furnsh("de430.bsp")

utc_time = "2025-09-26 00:00:00"
et = spice.str2et(utc_time)

state, light_time = spice.spkezr("EARTH", et, "J2000", "LT+S", "SUN")
position, velocity = state[:3], state[3:]

print(f"Epoch (UTC): {utc_time}")
print(f"Position: {position} [km]")
print(f"Velocity: {velocity} [km]")
print(f"Light time: {light_time:.6f} [s]")

spice.kclear()

Resultado:

Epoch (UTC): 2025-09-26 00:00:00
Position: [1.49823038e+08 6.74792631e+06 2.92466037e+06] [km]
Velocity: [-1.9519849  27.20267832 11.79246548] [km]
Light time: 500.357603 [s]

Órbitas

Los objetos en el espacio están sujetos a la fuerza de gravedad. Esto hace que sigan trayectorias cónicas conocidas como órbitas.

  • La forma y orientación están definidas por la posición y velocidad
  • La ubicación dentro de la órbita está definida por la época

Hay diferentes elementos para definir una órbita:

  • Cartesiano: rx, ry, rz, vx, vy, vz
  • Kepler: a, e, i, RAAN, W, w, nu
  • Equinoccio: p, f, g, h, k, L
  • Equinoccio modificado: p, f, g, h, k, L
  • Delaunay: L, G, H, l, g, h

Tipos de órbitas por geometría

Las órbitas pueden clasificarse según su geometría:

Geometría Trayectoria Excentricidad (e)
Órbita circular Círculo perfecto e = 0
Órbita elíptica Elipse 0 < e < 1
Órbita parabólica Parábola abierta e = 1
Órbita hiperbólica Hipérbola abierta e > 1

Maniobras impulsivas

Son maniobras que cambian instantáneamente la velocidad de una nave espacial. Esto inserta a la nave espacial en una nueva órbita.

  • Transferencia de Hohmann (la órbita objetivo debe ser coplanar)
  • Transferencia bi-elliptica (la órbita objetivo debe ser coplanar)
  • Transferencia de Lambert

Maniobras impulsivas

Dado que las maniobras impulsivas introducen un \(\Delta v\), es posible calcular el gasto de combustible asociado a la maniobra aplicando la ecuación de Tsiolkovsky.

\[ \Delta v = v_e \ln \left( \frac{m_0}{m_f} \right) \]

Es común utilizar la energía específica como una métrica para comparar el gasto de combustible entre diferentes maniobras.

\[ C_3 = v_\infty^2 \]

El problema de Lambert

Debemos resolver el problema de Lambert para encontrar la órbita entre dos puntos en el espacio.


Conocido:

  • Parámetro gravitacional
  • Posición en el origen
  • Posición en el destino
  • Tiempo de vuelo

Calculamos:

  • Velocidad en el origen
  • Velocidad en el destino

Resolviendo el problema con Python

Resolviendo el problema con lamberthub

Lamberthub es una librería que contiene un conjunto de algoritmos para resolver el problema de Lambert.

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
)

Las velocidades de lanzamiento y llegada se usan para calcular los impulsos de la de la maniobra.

Ejemplo: viaje de la Tierra a Marte

from lamberthub import izzo2015 as lambert
import spiceypy as spice

MU_SUN = 1.32712440018e11  # Gravitational parameter of the Sun in [km^3/s^2]


norm = lambda vector: sum(x**2 for x in vector) ** 0.5
furnsh_kernels = lambda *kernels: list(map(spice.furnsh, kernels))

def get_state_for_body_at_epoch(body, et):
    state, light_time = spice.spkezr(body, et, "J2000", "LT+S", "SSB")
    return state[:3], state[3:], light_time


furnsh_kernels("de430.bsp", "latest_leapseconds.tls", "pck00011.tpc")

departure_time, arrival_time = spice.str2et("2025-01-01 00:00:00"), spice.str2et("2025-03-01 00:00:00")
tof = arrival_time - departure_time

earth_pos, earth_vel, _ = get_state_for_body_at_epoch("EARTH_BARYCENTER", departure_time)
mars_pos, mars_vel, _ = get_state_for_body_at_epoch("MARS_BARYCENTER", arrival_time)

v1, v2 = lambert(MU_SUN, earth_pos, mars_pos, tof)

delta_v1, delta_v2 = abs(norm(v1) - norm(earth_vel)), abs(norm(mars_vel) - norm(v2))

print(f"Delta-v departure: {delta_v1:.2f} [km/s]")
print(f"Delta-v arrival: {delta_v2:.2f} [km/s]")
Delta-v departure: 6.76 [km/s]
Delta-v arrival: 3.02 [km/s]

Resolviendo para varias fechas

¿Y si resolvemos el problema para diferentes combinaciones de fechas de salida y llegada?


Fecha de salida Fecha de llegada Delta-v salida [km/s] Delta-v llegada [km/s]
2025-01-01 2025-04-01 3.11 2.80
2025-01-01 2025-05-01 2.09 4.67
2025-01-01 2025-06-01 1.87 5.07

Es difícil identificar la mejor combinación de fechas a simple vista. Vamos a usar un mapa de contornos para visualizar los resultados.

Porkchop plots

Mapa de contornos que muestra la energía necesaria para viajar entre dos órbitas en función de las fechas de salida y llegada.

Porkchop plots


Forma rápida de visualizar el espacio de soluciones:


  • A más energía, más combustible
  • A más combustible, menos carga útil
  • Se buscan trayectorias de baja energía
  • También pueden buscarse tiempos de llegada rápidos

Optimización de trayectorias

En misiones complejas, optimizar la trayectoria puede ser complicado. La imagen muestra la trayectoria de la sonda Cassini a Saturno.

Optimización de trayectorias

Existen diversas herramientas para optimizar trayectorias:

Categoría Ventajas Desventajas Uso típico
Evolutivos Buena exploración global, multiobjetivo Lentitud, alto cómputo Flybys múltiples
Metaheurísticas Simples, fáciles de aplicar Precisión limitada Exploración inicial
Control Óptimo Alta precisión, refinamiento Difíciles, condiciones frágiles Ajuste final

Normalmente, los algoritmos se programan en un leguaje compilado y se exponen a través de bindings a Python.