Orbital Maneuvers ================= Finite burns integrate with the same Cowell force model as coast arcs (see :doc:`architecture`). For ephemeris span, drag, and related assumptions, see :doc:`limitations`. ASTRA-Core provides a physically rigorous engine for simulating finite burns and Collision Avoidance Maneuvers (CAMs). Mass Depletion (7-DOF) ---------------------- Unlike basic 6-DOF propagators (which solve :math:`[x, y, z, v_x, v_y, v_z]`), the ASTRA-powered integration arc solves a **7-DOF** state vector that strongly couples the vehicle's mass :math:`[\ldots, m]`. During a thrusting arc, mass is continuously depleted according to the Tsiolkovsky equation: .. math:: \dot{m} = \frac{-F}{I_{sp} \cdot g_0} where :math:`F` is thrust in Newtons, :math:`I_{sp}` is specific impulse in seconds, and :math:`g_0 = 9.80665` m/s². Burn Sequencing --------------- Before integrating, the propagator calls ``validate_burn_sequence`` to enforce: - :math:`t_{start} < t_{end}` for each burn. - No overlapping burns in the sequence. - :math:`F > 0`, :math:`I_{sp} > 0`, :math:`m > 0`. A ``ManeuverError`` is raised immediately on violation—burns are never silently truncated or ignored. Attitude Steering ----------------- Thrust direction is dynamically re-computed at **every integration substep**. ASTRA supports two frames: - **VNB (Velocity-Normal-Binormal):** :math:`\hat{V} = \vec{v}/|\vec{v}|`, :math:`\hat{N} = (\vec{r} \times \vec{v})/|\vec{r} \times \vec{v}|`, :math:`\hat{B} = \hat{V} \times \hat{N}`. Pure prograde burns use ``direction_vnb = (1, 0, 0)``. - **RTN (Radial-Transverse-Normal):** :math:`\hat{R} = \vec{r}/|\vec{r}|`, :math:`\hat{N} = (\vec{r} \times \vec{v})/|\vec{r} \times \vec{v}|`, :math:`\hat{T} = \hat{N} \times \hat{R}`. Segmented Orchestration ----------------------- The propagator slices the time span at engine ignition and cutoff boundaries before calling ``scipy.integrate.solve_ivp``. This prevents the integrator from stepping across a discontinuous force model — the transition from 6-DOF coast to 7-DOF thrust is handled by chaining separate ``solve_ivp`` calls, not by a mid-step event function. Powered arcs use tighter tolerances (``rtol = atol = 1e-12``) than coast arcs (``rtol = atol = 1e-8``) to maintain accuracy during rapid thrust. Simulation Workflow ------------------- .. code-block:: python from astra import ( propagate_cowell, NumericalState, DragConfig, FiniteBurn, ManeuverFrame, validate_burn_sequence, ) import numpy as np # Define initial state (LEO circular orbit) state = NumericalState( t_jd=2460000.5, position_km=np.array([7000.0, 0.0, 0.0]), velocity_km_s=np.array([0.0, 7.546, 0.0]), mass_kg=500.0, ) drag = DragConfig( cd=2.2, area_m2=10.0, mass_kg=500.0, srp_conical_shadow=True, # high-fidelity penumbra ) # 500 N thruster, Isp = 310 s, prograde burn for 120 s burn = FiniteBurn( t_start_s=0.0, t_end_s=120.0, thrust_N=500.0, isp_s=310.0, direction_vnb=(1.0, 0.0, 0.0), # pure prograde frame=ManeuverFrame.VNB, ) validate_burn_sequence([burn]) # raises ManeuverError on invalid sequence trajectory = propagate_cowell( state, duration_s=600.0, dt_out=10.0, drag_config=drag, burns=[burn], ) final = trajectory[-1] print(f"Final mass: {final.mass_kg:.2f} kg") print(f"ΔV achieved: {np.linalg.norm(final.velocity_km_s - state.velocity_km_s) * 1000:.1f} m/s") Next steps ---------- * Review :doc:`limitations` for Numba IEEE-754 notes on powered-arc tolerances. * Use ``astra.warmup()`` before the first ``propagate_cowell`` call in production workers to eliminate JIT compilation latency.