Skip to main content
Glama

landing_performance

Calculate landing distance for aircraft using weight, altitude, temperature, wind, runway slope, and condition. Obtain V-speeds, air distance, ground roll, and factored distances.

Instructions

Calculate landing distance for given conditions.

Args: weight_kg: Landing weight in kg pressure_altitude_ft: Airport pressure altitude in feet temperature_c: Outside air temperature in Celsius wind_kts: Headwind (+) or tailwind (-) in knots runway_slope_pct: Runway slope in percent (+ uphill) runway_condition: "dry", "wet", or "contaminated" cl_max_landing: Maximum lift coefficient in landing config wing_area_m2: Wing reference area in m² vref_factor: Approach speed factor (typically 1.3) approach_angle_deg: Approach angle in degrees

Returns: Formatted string with landing performance calculations including V-speeds, air distance from 50 ft, ground roll, and factored distances.

Raises: No exceptions are raised directly; errors are returned as formatted strings.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
weight_kgYes
pressure_altitude_ftYes
temperature_cYes
wind_ktsNo
runway_slope_pctNo
runway_conditionNodry
cl_max_landingNo
wing_area_m2No
vref_factorNo
approach_angle_degNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The main handler function that calculates landing performance. Computes V-speeds (VS0, VREF, VAPP, VTD), air distance from 50ft, ground roll distance, total distance, and factored distance with regulatory safety factors. Takes weight, pressure altitude, temperature, wind, runway slope/condition, and aircraft config parameters. Uses ISA atmosphere model, braking friction coefficients per runway condition (dry=0.4, wet=0.2, contaminated=0.1), and applies regulatory factors (CS 25.125: wet=1.43, contaminated=1.92). Returns a formatted string with results and embedded JSON.
    def landing_performance(
        weight_kg: float,
        pressure_altitude_ft: float,
        temperature_c: float,
        wind_kts: float = 0,
        runway_slope_pct: float = 0,
        runway_condition: Literal["dry", "wet", "contaminated"] = "dry",
        cl_max_landing: float = 2.2,
        wing_area_m2: float = 100,
        vref_factor: float = 1.3,
        approach_angle_deg: float = 3.0,
    ) -> str:
        """Calculate landing distance for given conditions.
    
        Args:
            weight_kg: Landing weight in kg
            pressure_altitude_ft: Airport pressure altitude in feet
            temperature_c: Outside air temperature in Celsius
            wind_kts: Headwind (+) or tailwind (-) in knots
            runway_slope_pct: Runway slope in percent (+ uphill)
            runway_condition: "dry", "wet", or "contaminated"
            cl_max_landing: Maximum lift coefficient in landing config
            wing_area_m2: Wing reference area in m²
            vref_factor: Approach speed factor (typically 1.3)
            approach_angle_deg: Approach angle in degrees
    
        Returns:
            Formatted string with landing performance calculations including V-speeds,
            air distance from 50 ft, ground roll, and factored distances.
    
        Raises:
            No exceptions are raised directly; errors are returned as formatted strings.
        """
        try:
            # Get atmospheric conditions
            altitude_m = pressure_altitude_ft * 0.3048
            isa = _get_isa_conditions(altitude_m)
            temp_k = temperature_c + 273.15
            rho = isa["pressure_pa"] / (R_AIR * temp_k)
    
            # Weight in Newtons
            W = weight_kg * G0
    
            # Calculate V-speeds
            ms_to_kts = 1.943844
    
            # VS0 (stall speed in landing config)
            vs0 = math.sqrt((2 * W) / (rho * wing_area_m2 * cl_max_landing))
            vs0_kts = vs0 * ms_to_kts
    
            # VREF (approach reference speed)
            vref_kts = vs0_kts * vref_factor
            _vref_ms = vref_kts / ms_to_kts  # noqa: F841
    
            # VAPP (approach speed with wind additive)
            wind_additive = max(0, -wind_kts * 0.5) + 5  # Add for gusts
            vapp_kts = vref_kts + wind_additive
    
            # VTD (touchdown speed) - typically VREF - 5-10 kts
            vtd_kts = vref_kts - 5
            vtd_ms = vtd_kts / ms_to_kts
    
            # Wind effect
            wind_ms = wind_kts * 0.5144
    
            # Air distance (from 50ft to touchdown)
            # Using approach angle
            approach_rad = math.radians(approach_angle_deg)
            air_distance_m = 50 * 0.3048 / math.tan(approach_rad)
    
            # Ground roll calculation after touchdown.
            # Braking friction coefficient (mu) varies significantly with runway condition.
            mu_braking = {"dry": 0.4, "wet": 0.2, "contaminated": 0.1}[runway_condition]
    
            # Average deceleration: a = mu*g - g*sin(slope)
            # Positive slope (uphill) aids deceleration; negative (downhill) opposes it.
            g = G0
            decel = mu_braking * g - g * math.sin(math.atan(runway_slope_pct / 100))
    
            # Ground speed at touchdown
            v_ground = vtd_ms - wind_ms
    
            # Ground roll distance
            if decel > 0:
                ground_roll_m = v_ground**2 / (2 * decel)
            else:
                ground_roll_m = v_ground * 10  # Default if can't calculate
    
            # Total landing distance
            total_distance_m = air_distance_m + ground_roll_m
    
            # Apply regulatory safety factors for landing distance.
            # Wet runway factor 1.43 (per CS 25.125); contaminated factor 1.92 approximate.
            condition_factors = {"dry": 1.0, "wet": 1.43, "contaminated": 1.92}
            factored_distance_m = total_distance_m * condition_factors[runway_condition]
    
            # Convert to feet
            air_distance_ft = air_distance_m * 3.281
            ground_roll_ft = ground_roll_m * 3.281
            total_distance_ft = total_distance_m * 3.281
            factored_distance_ft = factored_distance_m * 3.281
    
            result = {
                "input": {
                    "weight_kg": weight_kg,
                    "pressure_altitude_ft": pressure_altitude_ft,
                    "temperature_c": temperature_c,
                    "wind_kts": wind_kts,
                    "runway_slope_pct": runway_slope_pct,
                    "runway_condition": runway_condition,
                },
                "v_speeds_kts": {
                    "VS0": round(vs0_kts, 1),
                    "VREF": round(vref_kts, 1),
                    "VAPP": round(vapp_kts, 1),
                    "VTD": round(vtd_kts, 1),
                },
                "distances_m": {
                    "air_distance": round(air_distance_m, 0),
                    "ground_roll": round(ground_roll_m, 0),
                    "total_distance": round(total_distance_m, 0),
                    "factored_distance": round(factored_distance_m, 0),
                },
                "distances_ft": {
                    "air_distance": round(air_distance_ft, 0),
                    "ground_roll": round(ground_roll_ft, 0),
                    "total_distance": round(total_distance_ft, 0),
                    "factored_distance": round(factored_distance_ft, 0),
                },
                "performance": {
                    "braking_coefficient": mu_braking,
                    "condition_factor": condition_factors[runway_condition],
                },
            }
    
            output = f"""
    LANDING PERFORMANCE
    ===================
    Conditions:
      Weight: {weight_kg:,.0f} kg
      Pressure Altitude: {pressure_altitude_ft:,.0f} ft
      Temperature: {temperature_c:.1f}°C
      Wind: {wind_kts:+.0f} kts {"(headwind)" if wind_kts > 0 else "(tailwind)" if wind_kts < 0 else ""}
      Runway: {runway_slope_pct:+.1f}% slope, {runway_condition}
    
    V-Speeds (KIAS):
      VS0:  {vs0_kts:>6.1f} kts  (Stall, landing config)
      VREF: {vref_kts:>6.1f} kts  (Reference)
      VAPP: {vapp_kts:>6.1f} kts  (Approach)
      VTD:  {vtd_kts:>6.1f} kts  (Touchdown)
    
    Distances:
      Air Distance:      {air_distance_m:>6,.0f} m ({air_distance_ft:,.0f} ft)
      Ground Roll:       {ground_roll_m:>6,.0f} m ({ground_roll_ft:,.0f} ft)
      Total Distance:    {total_distance_m:>6,.0f} m ({total_distance_ft:,.0f} ft)
      Factored ({runway_condition}):  {factored_distance_m:>6,.0f} m ({factored_distance_ft:,.0f} ft)
    
    Braking: μ = {mu_braking} ({runway_condition})
    
    {json.dumps(result, indent=2)}
    """
            return output.strip()
    
        except Exception as e:
            logger.error(f"Landing performance calculation error: {str(e)}", exc_info=True)
            return f"Error calculating landing performance: {str(e)}"
  • Tool metadata/registry schema entry for landing_performance in TOOL_REGISTRY. Defines name='landing_performance', description, category='performance', parameters (weight_kg, pressure_altitude_ft, temperature_c, wind_kts, runway_slope_pct, runway_condition), and keywords for search indexing.
    ToolMetadata(
        name="landing_performance",
        description="Calculate landing distance including approach speed and runway factors",
        category="performance",
        parameters={
            "weight_kg": "Landing weight in kg",
            "pressure_altitude_ft": "Airport pressure altitude",
            "temperature_c": "Outside air temperature",
            "wind_kts": "Headwind (+) or tailwind (-) in knots",
            "runway_slope_pct": "Runway slope in percent",
            "runway_condition": "dry, wet, or contaminated",
        },
  • Import of landing_performance function from aerospace_mcp.tools.performance (line 83) and registration in the CLI's TOOL_MAP dictionary (line 154), mapping string 'landing_performance' to the function for CLI-based tool dispatch.
        landing_performance,
        stall_speed_calculator,
        takeoff_performance,
        true_airspeed_converter,
        weight_and_balance,
    )
    from .tools.propellers import (
        get_propeller_database,
        propeller_bemt_analysis,
        uav_energy_estimate,
    )
    from .tools.rockets import (
        estimate_rocket_sizing,
        optimize_launch_angle,
        rocket_3dof_trajectory,
    )
    from .tools.tool_search import (
        CATEGORIES,
        TOOL_REGISTRY,
        list_tool_categories,
        search_aerospace_tools,
    )
    
    # Complete mapping of tool name -> callable for all 44 tools
    TOOL_MAP: dict[str, Callable[..., str]] = {
        # Discovery
        "search_aerospace_tools": search_aerospace_tools,
        "list_tool_categories": list_tool_categories,
        # Core
        "search_airports": search_airports,
        "plan_flight": plan_flight,
        "calculate_distance": calculate_distance,
        "get_aircraft_performance": get_aircraft_performance,
        "get_system_status": get_system_status,
        # Atmosphere
        "get_atmosphere_profile": get_atmosphere_profile,
        "wind_model_simple": wind_model_simple,
        # Frames
        "transform_frames": transform_frames,
        "geodetic_to_ecef": geodetic_to_ecef,
        "ecef_to_geodetic": ecef_to_geodetic,
        # Aerodynamics
        "wing_vlm_analysis": wing_vlm_analysis,
        "airfoil_polar_analysis": airfoil_polar_analysis,
        "calculate_stability_derivatives": calculate_stability_derivatives,
        "get_airfoil_database": get_airfoil_database,
        # Propellers
        "propeller_bemt_analysis": propeller_bemt_analysis,
        "uav_energy_estimate": uav_energy_estimate,
        "get_propeller_database": get_propeller_database,
        # Rockets
        "rocket_3dof_trajectory": rocket_3dof_trajectory,
        "estimate_rocket_sizing": estimate_rocket_sizing,
        "optimize_launch_angle": optimize_launch_angle,
        # Orbits
        "elements_to_state_vector": elements_to_state_vector,
        "state_vector_to_elements": state_vector_to_elements,
        "propagate_orbit_j2": propagate_orbit_j2,
        "calculate_ground_track": calculate_ground_track,
        "hohmann_transfer": hohmann_transfer,
        "orbital_rendezvous_planning": orbital_rendezvous_planning,
        "lambert_problem_solver": lambert_problem_solver,
        # GNC
        "kalman_filter_state_estimation": kalman_filter_state_estimation,
        "lqr_controller_design": lqr_controller_design,
        # Performance
        "density_altitude_calculator": density_altitude_calculator,
        "true_airspeed_converter": true_airspeed_converter,
        "stall_speed_calculator": stall_speed_calculator,
        "weight_and_balance": weight_and_balance,
        "takeoff_performance": takeoff_performance,
        "landing_performance": landing_performance,
        "fuel_reserve_calculator": fuel_reserve_calculator,
  • Import of landing_performance from aerospace_mcp.tools.performance (line 123) and FastMCP server registration via mcp.tool(landing_performance) on line 235, making it available as an MCP tool endpoint.
        landing_performance,
        stall_speed_calculator,
        takeoff_performance,
        true_airspeed_converter,
        weight_and_balance,
    )
    
    # --- Propellers & UAVs: BEMT analysis, energy estimation ---
    from .tools.propellers import (
        get_propeller_database,
        propeller_bemt_analysis,
        uav_energy_estimate,
    )
    
    # --- Rockets: 3-DOF trajectories, sizing, launch optimization ---
    from .tools.rockets import (
        estimate_rocket_sizing,
        optimize_launch_angle,
        rocket_3dof_trajectory,
    )
    
    # --- Tool Discovery: search and categorize available aerospace tools ---
    from .tools.tool_search import (
        list_tool_categories,
        search_aerospace_tools,
    )
    
    # Configure logging
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)
    
    # Initialize FastMCP server
    mcp = FastMCP("aerospace-mcp")
    
    # =============================================================================
    # TOOL REGISTRATION
    # =============================================================================
    # aerospace-mcp supports deferred tool loading for efficient context usage.
    # When using with Anthropic's API, configure the mcp_toolset like this:
    #
    #   {
    #     "type": "mcp_toolset",
    #     "mcp_server_name": "aerospace-mcp",
    #     "default_config": {"defer_loading": true},
    #     "configs": {
    #       "search_aerospace_tools": {"defer_loading": false},
    #       "list_tool_categories": {"defer_loading": false}
    #     }
    #   }
    #
    # This loads only the discovery tools initially. Claude uses search_aerospace_tools
    # to find relevant tools, which returns tool_reference blocks that the API
    # automatically expands into full tool definitions.
    # =============================================================================
    
    # --- DISCOVERY TOOLS (should NOT be deferred) ---
    # These tools enable Claude to discover other tools dynamically
    mcp.tool(search_aerospace_tools)
    mcp.tool(list_tool_categories)
    
    # --- DISCOVERABLE TOOLS (can be deferred for context efficiency) ---
    # Core flight planning tools
    mcp.tool(search_airports)
    mcp.tool(plan_flight)
    mcp.tool(calculate_distance)
    mcp.tool(get_aircraft_performance)
    mcp.tool(get_system_status)
    
    # Atmospheric tools
    mcp.tool(get_atmosphere_profile)
    mcp.tool(wind_model_simple)
    
    # Coordinate frame tools
    mcp.tool(transform_frames)
    mcp.tool(geodetic_to_ecef)
    mcp.tool(ecef_to_geodetic)
    
    # Aerodynamics tools
    mcp.tool(wing_vlm_analysis)
    mcp.tool(airfoil_polar_analysis)
    mcp.tool(calculate_stability_derivatives)
    mcp.tool(get_airfoil_database)
    
    # Propeller/UAV tools
    mcp.tool(propeller_bemt_analysis)
    mcp.tool(uav_energy_estimate)
    mcp.tool(get_propeller_database)
    
    # Rocket tools
    mcp.tool(rocket_3dof_trajectory)
    mcp.tool(estimate_rocket_sizing)
    mcp.tool(optimize_launch_angle)
    
    # Orbital mechanics tools
    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)
    mcp.tool(lambert_problem_solver)
    
    # GNC tools
    mcp.tool(kalman_filter_state_estimation)
    mcp.tool(lqr_controller_design)
    
    # Performance tools
    mcp.tool(density_altitude_calculator)
    mcp.tool(true_airspeed_converter)
    mcp.tool(stall_speed_calculator)
    mcp.tool(weight_and_balance)
    mcp.tool(takeoff_performance)
    mcp.tool(landing_performance)
  • Error handling wrapper within the handler - catches exceptions during landing performance calculation and returns error message string.
    except Exception as e:
        logger.error(f"Landing performance calculation error: {str(e)}", exc_info=True)
        return f"Error calculating landing performance: {str(e)}"
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description bears full responsibility. It mentions that errors are returned as formatted strings, which is helpful, but it does not disclose other behaviors such as performance characteristics or prerequisites.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a well-structured docstring with clear sections for Args, Returns, and Raises. It is concise yet covers all necessary details without superfluous content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (10 parameters) and lack of parameter descriptions in the schema, the description fully explains inputs and return format, making it complete for use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description provides a detailed explanation for each parameter, including units and roles (e.g., 'weight_kg: Landing weight in kg'). This adds significant value beyond the schema, which only has titles and types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool calculates landing distance for given conditions. The tool name supports this purpose, and among siblings like 'takeoff_performance' and 'stall_speed_calculator', it is distinct.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description lacks explicit guidance on when to use this tool versus alternatives. It only implies usage through the calculation purpose, but does not provide context for exclusion or mention sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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