Aircraft¶
Aircraft performance models with speed profiles, climb/descent rates,
turn radii, and endurance limits. 12 pre-configured research aircraft
are included; custom aircraft can be created by instantiating
Aircraft directly.
Base class¶
- class Aircraft[source]¶
Bases:
objectAircraft performance model.
Holds identity, geometric constraints, phase-specific speed schedules, vertical performance profiles, turn model, and provenance metadata.
- Parameters:
aircraft_type (
str) – Aircraft model name (e.g."Gulfstream V").tail_number (
str) – Tail number or"Unknown".operator (
str) – Operating organization.service_ceiling (
Quantity) – Maximum operational altitude.approach_speed (
Quantity) – Landing approach speed.climb_schedule (
Union[CasMachSchedule,TasSchedule]) – Speed schedule for climb phase.cruise_schedule (
Union[CasMachSchedule,TasSchedule]) – Speed schedule for cruise phase.descent_schedule (
Union[CasMachSchedule,TasSchedule]) – Speed schedule for descent phase.climb_profile (
VerticalProfile) – Rate-of-climb vs altitude.descent_profile (
VerticalProfile) – Rate-of-descent vs altitude. Whenapproach_profileis set, this profile is intended to cover the cruise-altitude → top-of-approach (MSL) regime only; the terminal descent below top-of-approach is owned byapproach_profile. Whenapproach_profileisNone,descent_profilecontinues to cover the full cruise-to-touchdown range as before (legacy behavior).turn_model (
TurnModel) – Turn performance / bank angles.engine_type (
Literal['jet','turboprop','piston']) – Propulsion category —"jet","turboprop", or"piston".confidence (
Optional[PerformanceConfidence]) – Per-submodel confidence ratings.sources (
Optional[List[SourceRecord]]) – List of provenance records.range (
Optional[Quantity]) – Maximum flight range (optional, metadata only).endurance (
Optional[Quantity]) – Maximum flight duration (optional, metadata only).useful_payload (
Optional[Quantity]) – Payload capacity (optional, metadata only).approach_profile (
Optional[ApproachProfile]) – Optional terminal-arrival template covering top-of-approach → touchdown. When set, the planner can estimate terminal-segment timing geometrically from the speed schedule and glideslope. WhenNone, the legacy scalarapproach_speedanddescent_profileare used for arrival behavior.descent_path_angle_max_deg (
Optional[float]) – Maximum sustainable flight path angle during descent (degrees). When set,_hybrid_pathsteepens the descent to fit available lateral distance rather than spiralling at end of leg.climb_path_angle_max_deg (
Optional[float]) – Maximum sustainable flight path angle during climb (degrees). When set,_hybrid_pathsteepens the climb to fit available lateral distance rather than spiralling at departure. WhenNoneandtypical_climb_out.absorbed_in_climb_profileis True, the spiral-up regime acts as the absorption mechanism for mission-typical level-offs / .delay orbits.typical_climb_out (
Optional[ClimbOutPolicy]) – OptionalClimbOutPolicydocumenting the pre-cruise climb-out behaviour the calibratedclimb_profileis tuned to absorb. Pure metadata in v1.5 — names the absorption posture so it’s queryable rather than buried in comments.calibration_status (
Literal['calibrated','inferred','uncalibrated']) –Provenance label for the performance model. One of:
"calibrated"— climb / cruise / descent profiles and TAS schedules are fit to in-situ flight data (IWG1 / ICARTT) per docs/calibration.md."inferred"— performance is mirrored from a calibrated cousin airframe of the same type certificate (e.g.NCAR_GVmirrorsNASA_GV); not directly measured against the target airframe."uncalibrated"— performance comes from brochures, AFM tables, or rough estimates with no measured-data fit. Timing and reachability output for these aircraft should be treated as a best-effort starting point rather than a calibrated model.
Defaults to
"uncalibrated"; calibrated subclasses set this explicitly.
- __init__(aircraft_type, tail_number, operator, service_ceiling, approach_speed, climb_schedule, cruise_schedule, descent_schedule, climb_profile, descent_profile, turn_model, engine_type, confidence=None, sources=None, range=None, endurance=None, useful_payload=None, approach_profile=None, descent_path_angle_max_deg=None, climb_path_angle_max_deg=None, typical_climb_out=None, stall_speed_cas=None, calibration_status='uncalibrated')[source]¶
- Parameters:
aircraft_type (str)
tail_number (str)
operator (str)
service_ceiling (Quantity)
approach_speed (Quantity)
climb_schedule (CasMachSchedule | TasSchedule)
cruise_schedule (CasMachSchedule | TasSchedule)
descent_schedule (CasMachSchedule | TasSchedule)
climb_profile (VerticalProfile)
descent_profile (VerticalProfile)
turn_model (TurnModel)
engine_type (Literal['jet', 'turboprop', 'piston'])
confidence (PerformanceConfidence | None)
sources (List[SourceRecord] | None)
range (Quantity | None)
endurance (Quantity | None)
useful_payload (Quantity | None)
approach_profile (ApproachProfile | None)
descent_path_angle_max_deg (float | None)
climb_path_angle_max_deg (float | None)
typical_climb_out (ClimbOutPolicy | None)
stall_speed_cas (Quantity | None)
calibration_status (Literal['calibrated', 'inferred', 'uncalibrated'])
- property speed_model_fidelity: str¶
Describe the fidelity level of the cruise speed model.
Returns one of:
"cas_mach"— CAS/Mach schedule (atmosphere-aware)."simplified_tas"— piecewise-linear TAS approximation.
- climb_speed_at(altitude)[source]¶
True airspeed during climb at altitude.
Mirrors
descent_speed_at()for the climb schedule. Most aircraft factories aliasclimb_scheduletocruise_schedule, in which case this returns the same value ascruise_speed_at().
- stall_speed_at(altitude)[source]¶
True airspeed at stall at altitude.
Stall is published as a single
stall_speed_casvalue (calibrated airspeed at landing config, MLW). TAS at altitude is derived via standard atmosphere — Vs in CAS is approximately invariant with altitude (stall is a fixed-AoA, fixed-q event) but TAS scales as 1/sqrt(density), so TAS at FL400 is roughly twice the SL value.- Raises:
HyPlanValueError – If
stall_speed_casis None for this aircraft.- Return type:
- Parameters:
altitude (Quantity)
- min_safe_speed_at(altitude, *, margin=1.3)[source]¶
Minimum safe true airspeed at altitude, with margin above stall.
margindefaults to 1.3, mirroring the FAR Part 25 rule that V_ref >= 1.3 * Vs0. Pass a tighter margin (e.g., 1.2) for attentive level orbits in benign conditions, or a looser one (1.4-1.5) for night IFR / unstable atmospheres.Returns
margin * stall_speed_at(altitude)— useful for science planners deciding whether a slow-survey speed at a given altitude is acceptable.- Raises:
HyPlanValueError – If
stall_speed_casis None ormarginis non-positive.- Return type:
- Parameters:
- approach_speed_at(altitude_agl)[source]¶
True airspeed at altitude_agl during the terminal approach.
When
approach_profileis set, this returns the schedule value at altitude_agl. When it isn’t, this returns the legacy scalarapproach_speedfor any altitude (the existing single-speed approximation).
- approach_vertical_rate_at(altitude_agl, groundspeed=None)[source]¶
Approximate vertical rate on the terminal approach.
When
approach_profileis set, returns the geometric rate fromApproachProfile.approx_vertical_rate_at()(using the optional groundspeed override or scheduled TAS in still air). ReturnsNonewhen no approach profile is configured — callers should fall back to legacy descent behavior in that case rather than synthesizing fromdescent_profile, which keeps the regime split crisp.
- climb_gradient_at(altitude)[source]¶
Climb gradient at altitude — dimensionless rise/run.
Computed from the integrated climb performance: the climb rate from
climb_profiledivided by the climb-schedule TAS. Useful for terrain-aware planning (“can the aircraft clear a 10,000 ft ridge in 50 nmi?”) since obstacle clearance is naturally expressed as a horizontal-vs-vertical ratio.Returns 0.0 if TAS is zero (defensive — physically unreachable).
- descent_gradient_at(altitude)[source]¶
Descent gradient at altitude — dimensionless drop/run, positive.
Mirror of
climb_gradient_at()for descent, returning a positive value (the magnitude of the descent slope).
- max_bank_under_budget(pitch_deg=0.0)[source]¶
Maximum bank angle (deg) consistent with the load-factor budget.
For a steady banked climb / descent at pitch angle
pitch_deg, lift balance givesn = 1 / (cos(bank) · cos(pitch)). Solving for the bank that drivesntoturn_model.max_load_factor:cos(bank_max) = 1 / (n_max · cos(pitch))
Returns
0.0when the implied pitch alone exceeds the budget (i.e. the aircraft can’t sustain level flight at that pitch — physically unreachable, included as a defensive guard). Returns90.0when the budget is unbounded (n_max <= 0is treated as “no limit”).The default
pitch_deg=0covers level cruise; callers in the climb / descent paths supply the implicit pitch from the rate-vs-altitude profile.For the calibrated HyPlan aircraft library this returns large values (60-67° depending on aircraft and pitch) — well above every aircraft’s calibrated
bank_by_phaseentry — so the budget is effectively a defensive ceiling. It only narrows the chosen bank when callers force unusually aggressive manoeuvres.
- climb_altitude_profile(start_altitude, end_altitude, n_points=50)[source]¶
Generate altitude-vs-time curve during a climb.
Returns
(times, altitudes)as numpy arrays in minutes and feet.
- step_climb(start_altitude, end_altitude, pauses, wind_along_track=None)[source]¶
Total time and forward distance for a staged climb with pauses.
Real high-altitude aircraft step-climb out of weight-limited ceiling: they climb to an intermediate altitude, level off briefly to burn fuel and reduce gross weight, then continue climbing. For a NASA ER-2 sortie this typically looks like a 25-minute hold at FL611 climbing slowly under reduced weight, before final climb to the FL650 cruise altitude.
Each entry in
pausesis(level_off_altitude, hold_duration). At each pause altitude, the aircraft holds (level orbit) forhold_durationadding only to total time — zero forward distance, since the aircraft is presumed to be orbiting at one location during the hold. Climb segments between pauses use the aircraft’s calibratedclimb_profilevia_climb().Pauses are applied in altitude order; pauses outside the
[start_altitude, end_altitude]range are silently skipped.- Parameters:
start_altitude (
Quantity) – Starting altitude (e.g., airport elevation).end_altitude (
Quantity) – Final altitude (e.g., cruise altitude).pauses (
List[Tuple[Quantity,Quantity]]) – List of(altitude, hold_duration)tuples. Pass an empty list to recover the no-pause behavior of_climb().wind_along_track (Quantity | None)
- Return type:
- Returns:
Tuple of
(total_time, total_forward_distance)aspint.Quantity.
Example
ER-2 NM17 B planned climb-out: 25-min hold at FL611 climbing to FL650.
>>> ac = NASA_ER2() >>> t, d = ac.step_climb( ... start_altitude=6_187 * ureg.foot, ... end_altitude=65_000 * ureg.foot, ... pauses=[(35_600 * ureg.foot, 25 * ureg.minute)], ... )
- time_to_takeoff(airport, waypoint, wind=None, wind_source=None, t_anchor=None, climb_plan='auto', n_samples=20)[source]¶
Calculate time from takeoff to the first waypoint.
Builds the path via
_hybrid_path()withphase="climb"— 2D Dubins horizontally, integratedclimb_profilevertically — so the climb-out timing reflects the aircraft’s calibrated rate-vs-altitude curve, not a constant pitch.climb_plancontrols the pre-cruise hold model:"auto"(default): use this aircraft’stypical_climb_out.explicit_climb_planif defined, otherwise no holds.ClimbPlan: caller-supplied pauses, used as-is.None: no holds; pure active-climb integration.
- time_to_return(waypoint, airport, wind=None, wind_source=None, t_anchor=None, n_samples=20)[source]¶
Calculate time from the last waypoint back to the airport.
Builds the path via
_hybrid_path()withphase="descent"— 2D Dubins horizontally, integrateddescent_profilevertically.When
approach_profileis set, the descent is targeted at top-of-approach MSL (=airport.elevation + approach_profile.top_of_approach_agl) and a terminal"approach"segment is appended usingApproachProfile.time_to_touchdown(). When no profile is set, the legacy single-leg-to-runway behavior is preserved.
- time_to_cruise(start_waypoint, end_waypoint, true_air_speed=None, wind=None, wind_source=None, t_anchor=None, phase='cruise', climb_plan=None, n_samples=20)[source]¶
Calculate time to fly between two waypoints.
Hybrid 2D Dubins (horizontal layout) + integrated vertical profile. Returns a dict with
total_time,phases, anddubins_path(the 2D path; legacy key name kept for backward compatibility — usehorizontal_pathin new code).- Parameters:
wind (
Optional[Tuple[float,float]]) – Optional(u_east, v_north)wind vector in m/s. When provided, horizontal turning arcs become trochoids, the 2D path length and timing account for wind drift, and the vertical phases project the wind onto the great-circle bearing for ground-speed-corrected forward distance.phase (
str) – Which entry ofPhaseBankAnglesdrives the horizontal Dubins turn radius — see_hybrid_path(). Defaults to"cruise".climb_plan (
Optional[ClimbPlan]) – OptionalClimbPlanwith level-off pauses to insert during the climb. Only takes effect whenphase == "climb"and the leg actually climbs.start_waypoint (Waypoint)
end_waypoint (Waypoint)
true_air_speed (Quantity | None)
wind_source (WindField | None)
t_anchor (datetime | None)
n_samples (int)
- Return type:
Pre-configured aircraft¶
- class NASA_ER2[source]¶
Bases:
AircraftNASA ER-2 high-altitude research aircraft.
Operates at 70,000 ft, acquiring data above 95% of the Earth’s atmosphere. Based at NASA Armstrong Flight Research Center (AFRC).
Speed schedules, vertical-rate profile, and approach behavior calibrated from cached NASA AFRC IWG1 in-situ flight logs covering NASA 806 and NASA 809. See [notebooks/calibration/er2/calibration.ipynb] for the full derivation: per-altitude-bin |VS| medians, breakpoint selection rules, and validation against per-sortie observed timing.
Vertical-rate highlights from the calibration:
Weight-management level-offs and holds during climb-out are modeled explicitly via
typical_climb_out; theclimb_profileitself is active-climb-only performance, not wall-clock climb-out timing.Two-regime descent: peak idle-power |VS| ~3675 fpm at top-of- descent, decaying to ~840 fpm at top-of-approach as the aircraft configures for the terminal pattern.
Empirical 2.5° glideslope on the terminal approach (shallower than standard 3° ILS — ER-2’s approach geometry as flown across the IWG1 sortie set; touchdown estimate uses 6 sorties with fixes ≤ 50 ft AGL after ground-taxi trim).
- class NASA_GIII[source]¶
Bases:
AircraftNASA Gulfstream III (NASA 520) research aircraft.
Operated by NASA Langley Research Center (LaRC).
- class NASA_GIV[source]¶
Bases:
AircraftNASA Gulfstream IV (NASA 817) research aircraft.
Twin turbofan operated by NASA Armstrong Flight Research Center (AFRC).
Warning
Uncalibrated. Performance values come from manufacturer brochures / type-certificate data; no in-situ flight-data fit has been performed. Treat planning output as a best-effort starting point.
- class NASA_GV[source]¶
Bases:
AircraftNASA Gulfstream V research aircraft.
Operated by NASA Armstrong Flight Research Center (AFRC). Service ceiling 51,000 ft, cruise speed 500 kt (Mach 0.80). Currently undergoing modifications expected to conclude ~August 2026.
- class NASA_C20A[source]¶
Bases:
AircraftNASA C-20A (Gulfstream III variant, NASA 502) research aircraft.
Obtained from the U.S. Air Force in 2003. Primary platform for UAVSAR missions. Operated by NASA AFRC.
Note
Inferred. Performance is mirrored from the calibrated
NASA_GIIImodel (same type certificate). C-20A-specific IWG1 calibration is deferred pending data access. Output is more reliable than a brochure-only model but may not capture C-20A-specific operational differences.
- class NASA_P3[source]¶
Bases:
AircraftNASA P-3 Orion (NASA 426) airborne science laboratory.
Four-engine turboprop capable of long-duration flights (8–14 hours) and large payloads up to 18,000 lbs. Operated by NASA Wallops Flight Facility (WFF).
- class NASA_WB57[source]¶
Bases:
AircraftNASA WB-57 (NASA 927) high-altitude research aircraft.
Based at NASA Johnson Space Center (JSC), Ellington Field. Operates up to 60,000 ft with 8,800 lbs useful payload.
- class NASA_B777[source]¶
Bases:
AircraftNASA Boeing 777 long-range research aircraft.
Operated by NASA Langley Research Center (LaRC). Very large payload capacity (75,000 lbs) and long endurance (18 hours).
Warning
Uncalibrated. Performance values come from manufacturer brochures / type-certificate data; no in-situ flight-data fit has been performed. Treat planning output as a best-effort starting point.
- class KingAirA90[source]¶
Bases:
AircraftBeechcraft King Air A90 twin-turboprop aircraft.
Warning
Uncalibrated. Performance values come from manufacturer brochures with no in-situ flight-data fit. No public IWG1-grade A-90 data is currently available; calibration is deferred. Treat planning output as a best-effort starting point.