Source code for opengnc.disturbances.drag

"""
Lumped atmospheric drag model for spacecraft acceleration.
"""

from typing import Any

import numpy as np


[docs] class LumpedDrag: r""" Atmospheric Drag Model. Acceleration Equation: $\mathbf{a}_d = -\frac{1}{2} \rho v_{rel}^2 \frac{C_d A}{m} \hat{\mathbf{v}}_{rel}$ Parameters ---------- density_model : Any Atmospheric density provider. co_rotate : bool, optional Atmospheric co-rotation with planet. Default True. """ def __init__(self, density_model: Any, co_rotate: bool = True) -> None: """Initialize drag model with density source.""" self.density_model = density_model self.co_rotate = co_rotate
[docs] def get_acceleration( self, r_eci: np.ndarray, v_eci: np.ndarray, jd: float, mass: float, area: float, cd: float ) -> np.ndarray: r""" Calculate instantaneous drag acceleration vector. Formula: $\mathbf{a}_d = -\frac{1}{2} \rho v_{rel}^2 \frac{C_d A}{m} \hat{\mathbf{v}}_{rel}$ Parameters ---------- r_eci : np.ndarray ECI Position vector (m). v_eci : np.ndarray ECI Velocity vector (m/s). jd : float Julian Date. mass : float Total spacecraft mass (kg). area : float Effective cross-sectional area ($m^2$). cd : float Drag coefficient. Returns ------- np.ndarray Acceleration vector ($m/s^2$). """ r_val = np.asarray(r_eci) v_val = np.asarray(v_eci) rho = self.density_model.get_density(r_val, jd) if self.co_rotate: # Earth rotation vector approx (rad/s) w_earth = np.array([0, 0, 7.2921159e-5]) v_rel = v_val - np.cross(w_earth, r_val) else: v_rel = v_val v_rel_norm = np.linalg.norm(v_rel) if v_rel_norm < 1e-6: return np.zeros(3, dtype=float) # Acceleration calculation acc_mag = 0.5 * rho * v_rel_norm**2 * cd * (area / mass) return np.asarray(-acc_mag * (v_rel / v_rel_norm))