Skip to main content
Glama

propagate_orbit_j2

Calculate orbital trajectories with J2 gravitational perturbations using numerical integration for aerospace analysis and flight planning.

Instructions

Propagate orbit with J2 perturbations using numerical integration.

Args: initial_state: Initial orbital state (elements or state vector) propagation_time_s: Propagation time in seconds time_step_s: Integration time step in seconds

Returns: JSON string with propagated state

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
initial_stateYes
propagation_time_sYes
time_step_sNo

Implementation Reference

  • MCP tool handler: wrapper function that imports and calls the core propagation logic from integrations, serializes result to JSON.
    def propagate_orbit_j2(
        initial_state: dict, propagation_time_s: float, time_step_s: float = 60.0
    ) -> str:
        """Propagate orbit with J2 perturbations using numerical integration.
    
        Args:
            initial_state: Initial orbital state (elements or state vector)
            propagation_time_s: Propagation time in seconds
            time_step_s: Integration time step in seconds
    
        Returns:
            JSON string with propagated state
        """
        try:
            from ..integrations.orbits import propagate_orbit_j2 as _propagate
    
            result = _propagate(initial_state, propagation_time_s, time_step_s)
    
            return json.dumps(result, indent=2)
    
        except ImportError:
            return "Orbit propagation not available - install orbital packages"
        except Exception as e:
            logger.error(f"Orbit propagation error: {str(e)}", exc_info=True)
            return f"Orbit propagation error: {str(e)}"
  • Core implementation: performs Runge-Kutta 4th order numerical integration of orbit propagation including J2 oblateness perturbation.
    def propagate_orbit_j2(
        initial_state: StateVector, time_span_s: float, time_step_s: float = 60.0
    ) -> list[StateVector]:
        """
        Propagate orbit with J2 perturbations using numerical integration.
    
        Args:
            initial_state: Initial state vector
            time_span_s: Propagation time span (seconds)
            time_step_s: Integration time step (seconds)
    
        Returns:
            List of state vectors over time
        """
    
        def acceleration_j2(r_vec: list[float]) -> list[float]:
            """Calculate acceleration including J2 perturbations."""
            r = vector_magnitude(r_vec)
    
            # Central body acceleration
            a_central = [-MU_EARTH * r_vec[i] / r**3 for i in range(3)]
    
            # J2 perturbation
            factor = 1.5 * J2_EARTH * MU_EARTH * R_EARTH**2 / r**5
            z2_r2 = (r_vec[2] / r) ** 2
    
            a_j2 = [
                factor * r_vec[0] * (1 - 5 * z2_r2),
                factor * r_vec[1] * (1 - 5 * z2_r2),
                factor * r_vec[2] * (3 - 5 * z2_r2),
            ]
    
            return [a_central[i] + a_j2[i] for i in range(3)]
    
        # Initialize
        states = [initial_state]
        r = initial_state.position_m.copy()
        v = initial_state.velocity_ms.copy()
    
        # Parse initial epoch
        try:
            epoch = datetime.fromisoformat(initial_state.epoch_utc.replace("Z", "+00:00"))
        except (ValueError, TypeError):
            epoch = datetime.now(UTC)
    
        # Numerical integration (RK4)
        t = 0.0
        while t < time_span_s:
            dt = min(time_step_s, time_span_s - t)
    
            # RK4 integration
            k1_r = v
            k1_v = acceleration_j2(r)
    
            r2 = [r[i] + 0.5 * dt * k1_r[i] for i in range(3)]
            v2 = [v[i] + 0.5 * dt * k1_v[i] for i in range(3)]
            k2_r = v2
            k2_v = acceleration_j2(r2)
    
            r3 = [r[i] + 0.5 * dt * k2_r[i] for i in range(3)]
            v3 = [v[i] + 0.5 * dt * k2_v[i] for i in range(3)]
            k3_r = v3
            k3_v = acceleration_j2(r3)
    
            r4 = [r[i] + dt * k3_r[i] for i in range(3)]
            v4 = [v[i] + dt * k3_v[i] for i in range(3)]
            k4_r = v4
            k4_v = acceleration_j2(r4)
    
            # Update state
            r = [
                r[i] + dt / 6 * (k1_r[i] + 2 * k2_r[i] + 2 * k3_r[i] + k4_r[i])
                for i in range(3)
            ]
            v = [
                v[i] + dt / 6 * (k1_v[i] + 2 * k2_v[i] + 2 * k3_v[i] + k4_v[i])
                for i in range(3)
            ]
    
            t += dt
    
            # Create new state
            new_epoch = epoch.replace(microsecond=0) + type(epoch - epoch)(seconds=int(t))
    
            states.append(
                StateVector(
                    position_m=r.copy(),
                    velocity_ms=v.copy(),
                    epoch_utc=new_epoch.isoformat(),
                    frame=initial_state.frame,
                )
            )
    
        return states
  • Registers the propagate_orbit_j2 tool with the FastMCP server.
    mcp.tool(propagate_orbit_j2)
  • Tool schema definition including parameters, description, and usage example for LLM agent integration.
    name="propagate_orbit_j2",
    description="Propagate satellite orbit with J2 perturbations",
    parameters={
        "initial_state": "dict - Initial orbital elements or state vector",
        "time_span_s": "float - Propagation time span in seconds",
        "time_step_s": "float - Time step for propagation in seconds (default 300)",
    },
    examples=[
        'propagate_orbit_j2({"semi_major_axis_m": 6793000, "eccentricity": 0.001, "inclination_deg": 51.6, "raan_deg": 0.0, "arg_periapsis_deg": 0.0, "true_anomaly_deg": 0.0, "epoch_utc": "2024-01-01T12:00:00"}, 86400, 600)'
    ],
  • Imports the propagate_orbit_j2 function from tools.orbits for registration in FastMCP server.
    from .tools.orbits import (
        calculate_ground_track,
        elements_to_state_vector,
        hohmann_transfer,
        orbital_rendezvous_planning,
        propagate_orbit_j2,
        state_vector_to_elements,
    )

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