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
"""Propeller and UAV energy analysis tools for the Aerospace MCP server."""
import json
import logging
logger = logging.getLogger(__name__)
def propeller_bemt_analysis(
propeller_geometry: dict,
operating_conditions: dict,
analysis_options: dict | None = None,
) -> str:
"""Analyze propeller performance using Blade Element Momentum Theory.
Args:
propeller_geometry: Propeller geometry (diameter_m, pitch_m, num_blades, etc.)
operating_conditions: Operating conditions (rpm_list, velocity_ms, altitude_m)
analysis_options: Optional analysis settings
Returns:
Formatted string with propeller performance analysis
"""
try:
from ..integrations.propellers import (
PropellerGeometry,
)
from ..integrations.propellers import (
propeller_bemt_analysis as _propeller_analysis,
)
# Create geometry object
geometry = PropellerGeometry(**propeller_geometry)
rpm_list = operating_conditions.get("rpm_list", [2000, 2500, 3000])
velocity_ms = operating_conditions.get("velocity_ms", 20.0)
altitude_m = operating_conditions.get("altitude_m", 0.0)
# Run analysis
results = _propeller_analysis(geometry, rpm_list, velocity_ms, altitude_m)
# Format response
result_lines = [
"Propeller BEMT Analysis",
"=" * 60,
f"Propeller: {geometry.diameter_m:.2f}m dia, {geometry.pitch_m:.2f}m pitch, {geometry.num_blades} blades",
f"Conditions: {velocity_ms:.1f} m/s @ {altitude_m:.0f}m altitude",
"",
f"{'RPM':>6} {'Thrust (N)':>10} {'Power (W)':>9} {'Efficiency':>10} {'Adv Ratio':>10}",
]
result_lines.append("-" * 60)
for result in results:
result_lines.append(
f"{result.rpm:6.0f} {result.thrust_n:10.1f} {result.power_w:9.0f} "
f"{result.efficiency:10.3f} {result.advance_ratio:10.3f}"
)
# Add JSON data
json_data = json.dumps(
[
{
"rpm": r.rpm,
"thrust_n": r.thrust_n,
"torque_nm": r.torque_nm,
"power_w": r.power_w,
"efficiency": r.efficiency,
"advance_ratio": r.advance_ratio,
"thrust_coefficient": r.thrust_coefficient,
"power_coefficient": r.power_coefficient,
}
for r in results
],
indent=2,
)
result_lines.extend(["", "JSON Data:", json_data])
return "\n".join(result_lines)
except ImportError:
return "Propeller analysis not available - install propulsion packages"
except Exception as e:
logger.error(f"Propeller analysis error: {str(e)}", exc_info=True)
return f"Propeller analysis error: {str(e)}"
def uav_energy_estimate(
uav_config: dict, battery_config: dict, mission_profile: dict | None = None
) -> str:
"""Estimate UAV flight time and energy consumption for mission planning.
Args:
uav_config: UAV configuration parameters
battery_config: Battery configuration parameters
mission_profile: Optional mission profile parameters
Returns:
Formatted string with energy analysis results
"""
try:
from ..integrations.propellers import (
BatteryConfiguration,
UAVConfiguration,
)
from ..integrations.propellers import (
uav_energy_estimate as _energy_estimate,
)
# Create configuration objects
uav = UAVConfiguration(**uav_config)
battery = BatteryConfiguration(**battery_config)
mission = mission_profile or {}
# Run analysis
result = _energy_estimate(uav, battery, mission)
# Determine aircraft type
aircraft_type = "Fixed-Wing" if uav.wing_area_m2 else "Multirotor"
# Format response
result_lines = [
f"UAV Energy Analysis ({aircraft_type})",
"=" * 45,
f"Aircraft Mass: {uav.mass_kg:.1f} kg",
f"Battery: {battery.capacity_ah:.1f} Ah @ {battery.voltage_nominal_v:.1f}V ({battery.mass_kg:.2f} kg)",
]
if uav.wing_area_m2:
result_lines.extend(
[
f"Wing Area: {uav.wing_area_m2:.2f} m²",
f"Wing Loading: {uav.mass_kg * 9.81 / uav.wing_area_m2:.1f} N/m²",
]
)
elif uav.disk_area_m2:
result_lines.extend(
[
f"Rotor Disk Area: {uav.disk_area_m2:.2f} m²",
f"Disk Loading: {uav.mass_kg * 9.81 / uav.disk_area_m2:.1f} N/m²",
]
)
result_lines.extend(
[
"",
"Energy Analysis:",
f" Battery Energy: {result.battery_energy_wh:.0f} Wh",
f" Usable Energy: {result.energy_consumed_wh:.0f} Wh",
f" Power Required: {result.power_required_w:.0f} W",
f" System Efficiency: {result.efficiency_overall:.1%}",
"",
"Mission Performance:",
f" Flight Time: {result.flight_time_min:.1f} minutes ({result.flight_time_min / 60:.1f} hours)",
]
)
if result.range_km:
result_lines.append(f" Range: {result.range_km:.1f} km")
if result.hover_time_min:
result_lines.append(f" Hover Time: {result.hover_time_min:.1f} minutes")
# Add recommendations
result_lines.extend(["", "Recommendations:"])
if result.flight_time_min < 10:
result_lines.append(
" ⚠ Very short flight time - consider larger battery or lighter aircraft"
)
elif result.flight_time_min < 20:
result_lines.append(
" ⚠ Short flight time - optimize for efficiency or add battery capacity"
)
elif result.flight_time_min > 120:
result_lines.append(
" ✓ Excellent endurance - well optimized configuration"
)
else:
result_lines.append(" ✓ Good flight time for mission requirements")
if result.efficiency_overall < 0.7:
result_lines.append(" ⚠ Low system efficiency - check motor/ESC selection")
else:
result_lines.append(" ✓ Good system efficiency")
# Add JSON data
json_data = json.dumps(
{
"flight_time_min": result.flight_time_min,
"range_km": result.range_km,
"hover_time_min": result.hover_time_min,
"power_required_w": result.power_required_w,
"energy_consumed_wh": result.energy_consumed_wh,
"battery_energy_wh": result.battery_energy_wh,
"efficiency_overall": result.efficiency_overall,
},
indent=2,
)
result_lines.extend(["", "JSON Data:", json_data])
return "\n".join(result_lines)
except ImportError:
return "UAV energy analysis not available - install propulsion packages"
except Exception as e:
logger.error(f"UAV energy analysis error: {str(e)}", exc_info=True)
return f"UAV energy analysis error: {str(e)}"
def get_propeller_database() -> str:
"""Get available propeller database with geometric and performance data.
Returns:
JSON string with propeller database
"""
try:
from ..integrations.propellers import PROPELLER_DATABASE
return json.dumps(PROPELLER_DATABASE, indent=2)
except ImportError:
return "Propeller database not available"
except Exception as e:
logger.error(f"Propeller database error: {str(e)}", exc_info=True)
return f"Propeller database error: {str(e)}"