Skip to main content
Glama

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
NameRequiredDescriptionDefault
state_vectorYes

Implementation Reference

  • 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,
        )
  • 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

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cheesejaguar/aerospace-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server