state_vector_to_elements
Convert position and velocity state vectors into classical orbital elements for aerospace analysis and flight planning calculations.
Instructions
Convert state vector to classical orbital elements.
Args: state_vector: Dict with position_m and velocity_ms arrays
Returns: JSON string with orbital elements
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| state_vector | Yes |
Implementation Reference
- aerospace_mcp/tools/orbits.py:54-91 (handler)MCP tool handler function that takes a state vector dictionary, converts it to OrbitElements using the helper, and returns formatted JSON string.def state_vector_to_elements(state_vector: dict) -> str: """Convert state vector to classical orbital elements. Args: state_vector: Dict with position_m and velocity_ms arrays Returns: JSON string with orbital elements """ try: from ..integrations.orbits import ( StateVector, ) from ..integrations.orbits import ( state_vector_to_elements as _state_to_elements, ) state = StateVector(**state_vector) result = _state_to_elements(state) return json.dumps( { "semi_major_axis_m": result.semi_major_axis_m, "eccentricity": result.eccentricity, "inclination_deg": result.inclination_deg, "raan_deg": result.raan_deg, "arg_perigee_deg": result.arg_perigee_deg, "true_anomaly_deg": result.true_anomaly_deg, "epoch_utc": result.epoch_utc, }, indent=2, ) except ImportError: return "Orbital mechanics not available - install orbital packages" except Exception as e: logger.error(f"State vector to elements error: {str(e)}", exc_info=True) return f"State vector to elements error: {str(e)}"
- Core orbital mechanics helper function that implements the conversion from state vector (position and velocity) to classical orbital elements using vector calculations and two-body formulas.def state_vector_to_elements(state: StateVector) -> OrbitElements: """ Convert state vector to orbital elements using manual calculations. Args: state: State vector in J2000 frame Returns: Classical orbital elements """ r_vec = state.position_m v_vec = state.velocity_ms # Position and velocity magnitudes r = vector_magnitude(r_vec) v = vector_magnitude(v_vec) # Specific angular momentum h_vec = vector_cross(r_vec, v_vec) h = vector_magnitude(h_vec) # Semi-major axis energy = v**2 / 2 - MU_EARTH / r a = -MU_EARTH / (2 * energy) # Eccentricity vector v_cross_h = vector_cross(v_vec, h_vec) e_vec = [v_cross_h[i] / MU_EARTH - r_vec[i] / r for i in range(3)] e = vector_magnitude(e_vec) # Inclination i = math.acos(h_vec[2] / h) # Node vector k_vec = [0, 0, 1] n_vec = vector_cross(k_vec, h_vec) n = vector_magnitude(n_vec) # RAAN if n > 1e-10: raan = math.acos(n_vec[0] / n) if n_vec[1] < 0: raan = 2 * math.pi - raan else: raan = 0.0 # Argument of periapsis if n > 1e-10 and e > 1e-10: cos_arg_pe = vector_dot(n_vec, e_vec) / (n * e) cos_arg_pe = max(-1, min(1, cos_arg_pe)) # Clamp to [-1, 1] arg_pe = math.acos(cos_arg_pe) if e_vec[2] < 0: arg_pe = 2 * math.pi - arg_pe else: arg_pe = 0.0 # True anomaly if e > 1e-10: cos_nu = vector_dot(e_vec, r_vec) / (e * r) cos_nu = max(-1, min(1, cos_nu)) # Clamp to [-1, 1] nu = math.acos(cos_nu) if vector_dot(r_vec, v_vec) < 0: nu = 2 * math.pi - nu else: # For circular orbits, use longitude of ascending node if n > 1e-10: cos_nu = vector_dot(n_vec, r_vec) / (n * r) cos_nu = max(-1, min(1, cos_nu)) nu = math.acos(cos_nu) if r_vec[2] < 0: nu = 2 * math.pi - nu else: nu = math.atan2(r_vec[1], r_vec[0]) if nu < 0: nu += 2 * math.pi return OrbitElements( semi_major_axis_m=a, eccentricity=e, inclination_deg=rad_to_deg(i), raan_deg=rad_to_deg(raan), arg_periapsis_deg=rad_to_deg(arg_pe), true_anomaly_deg=rad_to_deg(nu), epoch_utc=state.epoch_utc, )
- aerospace_mcp/fastmcp_server.py:116-121 (registration)Registers the state_vector_to_elements tool (imported from tools.orbits) with the FastMCP server instance.mcp.tool(elements_to_state_vector) mcp.tool(state_vector_to_elements) mcp.tool(propagate_orbit_j2) mcp.tool(calculate_ground_track) mcp.tool(hohmann_transfer) mcp.tool(orbital_rendezvous_planning)
- Dataclass defining the input StateVector type used by the tool (position_m, velocity_ms, epoch_utc, frame).class StateVector: """Position and velocity state vector.""" position_m: list[float] # Position vector [x, y, z] in meters velocity_ms: list[float] # Velocity vector [vx, vy, vz] in m/s epoch_utc: str # Epoch in UTC ISO format frame: str = "J2000" # Reference frame
- Dataclass defining the output OrbitElements type returned by the conversion (semi_major_axis_m, eccentricity, etc.).class OrbitElements: """Classical orbital elements.""" semi_major_axis_m: float # Semi-major axis (m) eccentricity: float # Eccentricity (dimensionless) inclination_deg: float # Inclination (degrees) raan_deg: float # Right ascension of ascending node (degrees) arg_periapsis_deg: float # Argument of periapsis (degrees) true_anomaly_deg: float # True anomaly (degrees) epoch_utc: str # Epoch in UTC ISO format