Source code for opengnc.ssa.maneuver

"""
Debris Avoidance Maneuver Planning.
"""


import numpy as np
from typing import cast


[docs] def plan_avoidance_maneuver( r_sat: np.ndarray, v_sat: np.ndarray, r_debris: np.ndarray, v_debris: np.ndarray, safety_radius: float, t_encounter: float, ) -> tuple[np.ndarray, float]: """ Plan an impulsive Debris Avoidance Maneuver (DAM). Primarily calculates an along-track thrust to achieve a target miss distance at encounter via phasing. Parameters ---------- r_sat, v_sat : np.ndarray Spacecraft ECI state at planning epoch (m, m/s). r_debris, v_debris : np.ndarray Debris ECI state at planning epoch (m, m/s). safety_radius : float Desired minimum separation distance (m). t_encounter : float Time until predicted conjunction (s). Returns ------- Tuple[np.ndarray, float] - Delta-V vector in ECI (m/s). - Estimated miss distance after maneuver (m). """ rs, vs = np.asarray(r_sat), np.asarray(v_sat) rd, vd = np.asarray(r_debris), np.asarray(v_debris) v_mag = float(np.linalg.norm(vs)) if v_mag < 1e-6: raise ValueError("Velocity is too small.") # Unit along-track vector t_hat = vs / v_mag # Current predicted miss (Euclidean distance at encounter/epoch) r_rel = rs - rd d_curr = float(np.linalg.norm(r_rel)) if d_curr >= safety_radius: return np.zeros(3), float(d_curr) # Phasing approximation: d_r_track ~ 3 * dt * dv_t d_req = safety_radius - d_curr if t_encounter < 10.0: # Radial/Direct avoidance (Heuristic) dv_mag = d_req / t_encounter else: # Efficient along-track phasing dv_mag = d_req / (3.0 * t_encounter) dv_vec = cast(np.ndarray, t_hat * dv_mag) d_est = d_curr + np.abs(dv_mag) * (3.0 * t_encounter if t_encounter > 10.0 else t_encounter) return dv_vec, float(d_est)