Source code for opengnc.guidance.porkchop

"""
Porkchop plot grid generation for interplanetary transfers.
"""

from collections.abc import Callable

import numpy as np

from ..guidance.rendezvous import solve_lambert


[docs] def generate_porkchop_grid( departure_dates: np.ndarray | list[float], arrival_dates: np.ndarray | list[float], r_dep_func: Callable[[float], np.ndarray], v_dep_func: Callable[[float], np.ndarray], r_arr_func: Callable[[float], np.ndarray], v_arr_func: Callable[[float], np.ndarray], mu: float = 398600.4418, ) -> dict[str, np.ndarray | list[float]]: """ Generate a grid of C3 and V-infinity values for interplanetary transfers. Computes a 'porkchop' plot grid by solving Lambert's problem for every combination of departure and arrival dates. Parameters ---------- departure_dates : array-like List or array of departure times (e.g., seconds from J2000). arrival_dates : array-like List or array of arrival times (e.g., seconds from J2000). r_dep_func : Callable Function returning the planet's position vector [3] at departure time t. v_dep_func : Callable Function returning the planet's velocity vector [3] at departure time t. r_arr_func : Callable Function returning the destination's position vector [3] at arrival time t. v_arr_func : Callable Function returning the destination's velocity vector [3] at arrival time t. mu : float, optional Gravitational parameter of the central body. Default is Earth. Returns ------- Dict Dictionary containing: - 'departure_dates': Copy of departure axes. - 'arrival_dates': Copy of arrival axes. - 'c3': (N_arr, N_dep) grid of Launch C3 values ($km^2/s^2$). - 'v_inf_arr': (N_arr, N_dep) grid of Arrival V-infinity ($km/s$). - 'tof': (N_arr, N_dep) grid of Time-of-flight (s). """ n_dep = len(departure_dates) n_arr = len(arrival_dates) c3_grid = np.full((n_arr, n_dep), np.nan) v_inf_arr_grid = np.full((n_arr, n_dep), np.nan) tof_grid = np.full((n_arr, n_dep), np.nan) for i, t_dep in enumerate(departure_dates): r_dep = r_dep_func(t_dep) v_dep_planet = v_dep_func(t_dep) for j, t_arr in enumerate(arrival_dates): dt = float(t_arr - t_dep) if dt <= 0: continue r_arr = r_arr_func(t_arr) v_arr_planet = v_arr_func(t_arr) try: # Solve Lambert problem v_dep_sc, v_arr_sc = solve_lambert(r_dep, r_arr, dt, mu=mu) # V_infinity at departure v_inf_dep = v_dep_sc - v_dep_planet c3_val = np.dot(v_inf_dep, v_inf_dep) # V_infinity at arrival v_inf_arr_val = np.linalg.norm(v_arr_sc - v_arr_planet) c3_grid[j, i] = c3_val v_inf_arr_grid[j, i] = v_inf_arr_val tof_grid[j, i] = dt except Exception: continue return { "departure_dates": departure_dates, "arrival_dates": arrival_dates, "c3": c3_grid, "v_inf_arr": v_inf_arr_grid, "tof": tof_grid, }