Aircraft

Aircraft performance models with speed profiles, climb/descent rates, turn radii, and endurance limits. 22 pre-configured research aircraft are included; custom aircraft can be created by instantiating Aircraft directly. Performance values for the pre-configured fleet live in editable JSON files at hyplan/data/aircraft/<short_name>.json (see the Profile I/O section below).

Fleet overview

The table below is auto-generated from the live hyplan.aircraft classes by python -m docs._gen_fleet_tables. Re-run it whenever calibration sortie counts or performance values change.

Class

Airframe

Operator

Tail(s)

Ceiling (ft)

Range (nmi)

Endurance (hr)

Engine

Calibration

NASA_ER2

ER-2

NASA AFRC

NASA 806

70,000

5,000

8.0

jet

calibrated

NASA_GIII

Gulfstream III

NASA LaRC

NASA 520

45,000

3,767

7.5

jet

calibrated · n=153

NASA_GIV

Gulfstream IV

NASA AFRC

NASA 817

45,000

5,130

7.5

jet

brochure only

NASA_GV

Gulfstream V

NASA AFRC

NASA 95

51,000

5,500

13.0

jet

calibrated · n=101

NCAR_GV

Gulfstream V

NSF/NCAR EOL

N677F

51,000

6,500

14.0

jet

calibrated

NASA_C20A

C-20A

NASA AFRC

NASA 502

45,000

3,400

6.0

jet

inferred

NASA_P3

P-3 Orion

NASA WFF

NASA 426

27,000

3,800

12.0

turboprop

calibrated · n=252

NOAA_WP3D

P-3 Orion (WP-3D)

NOAA AOC

N42RF + N43RF

27,600

3,800

12.0

turboprop

calibrated · n=96

NOAA_GIV

Gulfstream IV-SP

NOAA AOC

N49RF

47,500

4,220

8.5

jet

calibrated · n=93

NASA_WB57

WB-57

NASA JSC

NASA 926/927

63,000

2,500

6.5

jet

calibrated · n=100

NASA_B777

B777

NASA LaRC

Unknown

43,000

9,000

18.0

jet

brochure only

KingAirA90

King Air 90

Unknown

Unknown

30,000

1,500

6.0

turboprop

brochure only

KingAirB200

King Air 200

NASA (multiple)

multi-tail

30,000

1,632

6.0

turboprop

calibrated

KingAir350

King Air 350

Unknown

Unknown

35,000

2,100

5.0

turboprop

brochure only

NASA_C130

C-130H Hercules

NASA WFF

NASA 436

28,000

2,500

10.0

turboprop

calibrated · n=91

NOAA_TwinOtter

DHC-6 Twin Otter

NOAA

N48RF + N46RF

17,500

800

6.0

turboprop

calibrated · n=164

BAS_TwinOtter

DHC-6 Twin Otter

BAS

VP-FBL + VP-FBB

14,600

800

6.0

turboprop

calibrated · n=105

FAAM_BAe146

BAe-146-301

FAAM

G-LUXE

34,500

1,800

5.0

jet

calibrated · n=125

SAFIRE_ATR42

ATR-42-320

SAFIRE

F-HMTO

24,700

900

5.0

turboprop

calibrated

NERC_DO228

Dornier Do228-101

NERC ARSF

D-CALM

22,000

1,400

5.0

turboprop

calibrated

AWI_BaslerBT67

Basler BT-67

AWI

Polar 5 + Polar 6

25,000

1,600

6.5

turboprop

calibrated

DLR_HALO

Gulfstream G550

DLR

D-ADLR

44,300

6,750

10.0

jet

calibrated · n=18

See docs/calibration.md for the per-aircraft calibration provenance and a breakdown of the underlying data archives.

Base class

class Aircraft[source]

Bases: object

Aircraft 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 (CasMachSchedule | TasSchedule) – Speed schedule for climb phase.

  • cruise_schedule (CasMachSchedule | TasSchedule) – Speed schedule for cruise phase.

  • descent_schedule (CasMachSchedule | TasSchedule) – Speed schedule for descent phase.

  • climb_profile (VerticalProfile) – Rate-of-climb vs altitude.

  • descent_profile (VerticalProfile) – Rate-of-descent vs altitude. When approach_profile is 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 by approach_profile. When approach_profile is None, descent_profile continues 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 (PerformanceConfidence | None) – Per-submodel confidence ratings.

  • sources (list[SourceRecord] | None) – List of provenance records.

  • range (Quantity | None) – Maximum flight range (optional, metadata only).

  • endurance (Quantity | None) – Maximum flight duration (optional, metadata only).

  • useful_payload (Quantity | None) – Payload capacity (optional, metadata only).

  • approach_profile (ApproachProfile | None) – 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. When None, the legacy scalar approach_speed and descent_profile are used for arrival behavior.

  • descent_path_angle_max_deg (float | None) – Maximum sustainable flight path angle during descent (degrees). When set, _hybrid_path steepens the descent to fit available lateral distance rather than spiralling at end of leg.

  • climb_path_angle_max_deg (float | None) – Maximum sustainable flight path angle during climb (degrees). When set, _hybrid_path steepens the climb to fit available lateral distance rather than spiralling at departure. When None and typical_climb_out.absorbed_in_climb_profile is True, the spiral-up regime acts as the absorption mechanism for mission-typical level-offs / .delay orbits.

  • typical_climb_out (ClimbOutPolicy | None) – Optional ClimbOutPolicy documenting the pre-cruise climb-out behaviour the calibrated climb_profile is 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_GV mirrors NASA_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.

property max_bank_angle: float

Maximum bank angle in degrees (for Dubins path geometry).

cruise_speed_at(altitude)[source]

True airspeed at altitude using the cruise speed schedule.

Return type:

Quantity

Parameters:

altitude (Quantity)

climb_speed_at(altitude)[source]

True airspeed during climb at altitude.

Mirrors descent_speed_at() for the climb schedule. Most aircraft factories alias climb_schedule to cruise_schedule, in which case this returns the same value as cruise_speed_at().

Return type:

Quantity

Parameters:

altitude (Quantity)

rate_of_climb(altitude)[source]

Rate of climb at altitude from the climb profile.

Return type:

Quantity

Parameters:

altitude (Quantity)

descent_speed_at(altitude)[source]

True airspeed during descent at altitude.

Return type:

Quantity

Parameters:

altitude (Quantity)

stall_speed_at(altitude)[source]

True airspeed at stall at altitude.

Stall is published as a single stall_speed_cas value (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_cas is None for this aircraft.

Return type:

Quantity

Parameters:

altitude (Quantity)

min_safe_speed_at(altitude, *, margin=1.3)[source]

Minimum safe true airspeed at altitude, with margin above stall.

margin defaults 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_cas is None or margin is non-positive.

Return type:

Quantity

Parameters:
approach_speed_at(altitude_agl)[source]

True airspeed at altitude_agl during the terminal approach.

When approach_profile is set, this returns the schedule value at altitude_agl. When it isn’t, this returns the legacy scalar approach_speed for any altitude (the existing single-speed approximation).

Return type:

Quantity

Parameters:

altitude_agl (Quantity)

approach_vertical_rate_at(altitude_agl, groundspeed=None)[source]

Approximate vertical rate on the terminal approach.

When approach_profile is set, returns the geometric rate from ApproachProfile.approx_vertical_rate_at() (using the optional groundspeed override or scheduled TAS in still air). Returns None when no approach profile is configured — callers should fall back to legacy descent behavior in that case rather than synthesizing from descent_profile, which keeps the regime split crisp.

Return type:

Quantity | None

Parameters:
climb_gradient_at(altitude)[source]

Climb gradient at altitude — dimensionless rise/run.

Computed from the integrated climb performance: the climb rate from climb_profile divided 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).

Return type:

float

Parameters:

altitude (Quantity)

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).

Return type:

float

Parameters:

altitude (Quantity)

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 gives n = 1 / (cos(bank) · cos(pitch)). Solving for the bank that drives n to turn_model.max_load_factor:

cos(bank_max) = 1 / (n_max · cos(pitch))

Returns 0.0 when 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). Returns 90.0 when the budget is unbounded (n_max <= 0 is treated as “no limit”).

The default pitch_deg=0 covers 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_phase entry — so the budget is effectively a defensive ceiling. It only narrows the chosen bank when callers force unusually aggressive manoeuvres.

Return type:

float

Parameters:

pitch_deg (float)

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.

Return type:

tuple[ndarray[tuple[Any, ...], dtype[float64]], ndarray[tuple[Any, ...], dtype[float64]]]

Parameters:
step_climb(start_altitude, end_altitude, pauses, wind_along_track=None, _allow_above_ceiling=False)[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 pauses is (level_off_altitude, hold_duration). At each pause altitude, the aircraft holds (level orbit) for hold_duration adding 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 calibrated climb_profile via _climb().

Pauses are applied in altitude order; pauses outside the climb range are silently skipped. In-range means start_altitude < level_off_altitude <= end_altitude — a pause exactly at end_altitude is kept (a hold at top-of-climb), one exactly at start_altitude is not (no climb has happened yet). See ClimbPlan.

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)

  • _allow_above_ceiling (bool)

Return type:

tuple[Quantity, Quantity]

Returns:

Tuple of (total_time, total_forward_distance) as pint.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() with phase="climb" — 2D Dubins horizontally, integrated climb_profile vertically — so the climb-out timing reflects the aircraft’s calibrated rate-vs-altitude curve, not a constant pitch.

climb_plan controls the pre-cruise hold model:

  • "auto" (default): use this aircraft’s typical_climb_out.explicit_climb_plan if defined, otherwise no holds.

  • ClimbPlan: caller-supplied pauses, used as-is.

  • None: no holds; pure active-climb integration.

Return type:

dict[str, Any]

Parameters:
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() with phase="descent" — 2D Dubins horizontally, integrated descent_profile vertically.

When approach_profile is 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 using ApproachProfile.time_to_touchdown(). When no profile is set, the legacy single-leg-to-runway behavior is preserved.

Return type:

dict[str, Any]

Parameters:
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, and dubins_path (the 2D path; legacy key name kept for backward compatibility — use horizontal_path in new code).

Parameters:
  • wind (tuple[float, float] | None) – 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 of PhaseBankAngles drives the horizontal Dubins turn radius — see _hybrid_path(). Defaults to "cruise".

  • climb_plan (ClimbPlan | None) – Optional ClimbPlan with level-off pauses to insert during the climb. Only takes effect when phase == "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:

dict[str, Any]

Pre-configured aircraft

class NASA_ER2[source]

Bases: Aircraft

NASA 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, with continuous fiscal-year coverage 2012-2026 (618 sorties loaded from a 629-file cache pulled from the public NASA ASP archive plus a local in-house delivery; see notebooks/calibration/NASA_ER2/_fetch_asp.py for the fetcher). See [notebooks/calibration/NASA_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; the climb_profile itself 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).

__init__()[source]
Return type:

None

class NASA_GIII[source]

Bases: Aircraft

NASA Gulfstream III (NASA 520) research aircraft.

Operated by NASA Langley Research Center (LaRC).

__init__()[source]
Return type:

None

class NASA_GIV[source]

Bases: Aircraft

NASA 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.

__init__()[source]
Return type:

None

class NASA_GV[source]

Bases: Aircraft

NASA 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.

__init__()[source]
Return type:

None

class NCAR_GV[source]

Bases: Aircraft

NSF/NCAR HIAPER Gulfstream V research aircraft (N677F).

Operated by NSF NCAR Earth Observing Laboratory (EOL). Same airframe family as NASA_GV but a separate operational tail with different mission profile and avionics. HIAPER routinely cruises FL410-FL510 on long-duration atmospheric campaigns (HIPPO, SOCRATES, ORCAS, ATTREX) and carries a different flight-data suite (high-rate 25-Hz NetCDF).

See also

https://www.eol.ucar.edu/observing_facilities/hiaper

__init__()[source]
Return type:

None

class NASA_C20A[source]

Bases: Aircraft

NASA 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_GIII model (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.

__init__()[source]
Return type:

None

class NASA_P3[source]

Bases: Aircraft

NASA 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).

__init__()[source]
Return type:

None

class NASA_WB57[source]

Bases: Aircraft

NASA WB-57F (NASA 926 / 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.

Calibrated against 127 sorties combining in-house IWG1 deliveries (NASA 926 + 927, 2018-2026) with the ACCLIP 2022 deployment’s MMS-1HZ ICARTT data from NASA LaRC ASDC (collection ACCLIP_MetNav_AircraftInSitu_WB57_Data; covers Lait’s GSFC flight-planner WB-57 tuning window). See notebooks/calibration/NASA_WB57/ for _fetch_acclip.py (the LaRC ASDC fetcher), calibrate.py (the IWG1 + ICARTT-aware fitter), and calibration.ipynb (per-bin diagnostics).

__init__()[source]
Return type:

None

class NASA_B777[source]

Bases: Aircraft

NASA 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.

__init__()[source]
Return type:

None

class KingAirA90[source]

Bases: Aircraft

Beechcraft King Air A90 twin-turboprop aircraft.

Calibrated against 428 ADS-B sorties from airplanes.live daily- trace archives (2026-04-09 → 2026-05-08; 25 active US 65-A90 / 65-A90-1 civilian tails) after filtering skydive jump-run profiles out of the raw 643-sortie sample. No public IWG1-grade A-90 data is currently available, so this calibration is the highest-quality A90 envelope publicly available. See notebooks/calibration/KingAirA90/calibrate.py for the recipe and _fetch_airplanes_live.py for the trace fetcher.

Confidence is moderate (~0.65) — TAS is approximated by groundspeed (still-air baseline), and the active US A90 fleet skews toward skydive / charter / freight operations rather than research missions. v1.6.1 will switch to MERRA-2 wind-triangle TAS reconstruction.

__init__()[source]
Return type:

None

class KingAirB200[source]

Bases: Aircraft

Beechcraft King Air B200 twin-turboprop aircraft.

__init__()[source]
Return type:

None

class KingAir350[source]

Bases: Aircraft

Beechcraft King Air 350 / 350i twin-turboprop research aircraft.

Stretched 200-series airframe with PT6A-60A engines (or Blackhawk XP-67A upgrade with PT6A-67A). Larger cabin, higher MTOW (15,000 lb), longer range, and higher service ceiling than the King Air 200.

Notable research operators include the University of Wyoming (UWKA-2 / N2UW since 2024, replacing UW’s earlier King Air 200T), NCAR, and several university-operated tails.

Calibrated against 22 ADS-B sorties from the University of Wyoming UWKA-2 (N2UW / hex A18F28) pulled from the airplanes.live globe-history archive. 18 active days clustered into 5 science-campaign windows in 2025-01, 2025-03, 2025-06, 2025-07/08, 2025-10, and 2026-04 (10k trace rows total). See notebooks/calibration/KingAir350/calibrate.py for the fitting recipe.

Confidence is moderate-low (~0.5) — sample is single-tail and sparse, with science-mission profile bias (high-altitude measurement legs rather than long-range cruise). UWKA-2 has the Blackhawk XP-67A engine upgrade (PT6A-67A), so calibrated values may run a few percent above stock B300 with PT6A-60A. Approach speed is held to brochure 110 kt because the calibrated 162 kt reflects science-leg descent TAS rather than a normal Vref pattern speed.

See also

https://www.uwyo.edu/atsc/research-facilities/uwka/king-air.html

__init__()[source]
Return type:

None

class NASA_C130[source]

Bases: Aircraft

NASA C-130H Hercules (NASA 436) four-engine turboprop research aircraft.

Operated by NASA Wallops Flight Facility. Calibration is specific to NASA 436’s ACT-America mission profile; other C-130 operators (USAF, NCAR, NRL, FAA) fly different envelopes and would need their own calibration.

__init__()[source]
Return type:

None

class NOAA_TwinOtter[source]

Bases: Aircraft

NOAA DHC-6 Twin Otter (N48RF + N46RF) STOL twin-turboprop.

Operated by the NOAA Chemical Sciences Laboratory and NOAA AOC for boundary-layer atmospheric chemistry, lidar, and aerosol sampling missions. Calibration is specific to NOAA’s mission profile (slow-cruise dwell-time over plumes, FL060-FL150 ops); CIRPAS / Kenn Borek / commercial Twin Otters fly different envelopes and would need their own calibration class.

See also

https://www.omao.noaa.gov/aircraft/de-havilland-dhc-6-twin-otter

__init__()[source]
Return type:

None

class NOAA_WP3D[source]

Bases: Aircraft

NOAA WP-3D Orion atmospheric chemistry / Hurricane Hunter.

Lockheed WP-3D Orion operated by the NOAA Aircraft Operations Center (AOC). Two tails are typically active for atmospheric chemistry research: N42RF “Kermit” and N43RF “Miss Piggy”. Same airframe family as NASA_P3 (LaRC’s NASA 426); calibrated separately because the operator, mission profile, and outfit differ. NOAA WP-3D missions tracked here are NOAA CSL chemistry campaigns, not the hurricane-research deployments.

See also

https://www.omao.noaa.gov/aircraft/lockheed-wp-3d-orion

__init__()[source]
Return type:

None

class NOAA_GIV[source]

Bases: Aircraft

NOAA Gulfstream IV-SP “Gonzo” (N49RF) hurricane synoptic-surveillance jet.

Operated by NOAA Aircraft Operations Center. Hurricane synoptic surveillance — high-altitude (FL420-FL450) sonde drops around developing tropical cyclones in the Atlantic and East Pacific basins. Distinct mission profile and operator from NASA’s brochure-only NASA_GIV; this is the first calibrated G-IV variant in HyPlan.

See also

https://www.aoc.noaa.gov/aircraft-gulfstream-iv.html

__init__()[source]
Return type:

None

class BAS_TwinOtter[source]

Bases: Aircraft

British Antarctic Survey DHC-6-300 Twin Otter (MASIN-equipped).

BAS operates two Twin Otters (VP-FBL, VP-FBB) from Rothera Research Station for Antarctic atmospheric science and from Ny-Ålesund for Arctic missions. Same airframe class as NOAA_TwinOtter but the polar operating profile (sustained low-altitude survey, cold-soak, high-wind ops, short-field gravel landings) is distinct enough to warrant a separate calibration.

See also

https://www.bas.ac.uk/team/operations-team/operational-delivery/airborne-science/

__init__()[source]
Return type:

None

class FAAM_BAe146[source]

Bases: Aircraft

FAAM BAe-146-301 atmospheric research aircraft (G-LUXE).

The Facility for Airborne Atmospheric Measurements operates G-LUXE on behalf of NERC and the UK Met Office. Four-engine regional jet with a uniquely flexible mission envelope: low-altitude (200 ft AGL) boundary-layer surveys to FL350 troposphere/stratosphere transits.

See also

https://www.faam.ac.uk/

__init__()[source]
Return type:

None

class SAFIRE_ATR42[source]

Bases: Aircraft

SAFIRE ATR-42-320 atmospheric research aircraft (F-HMTO).

SAFIRE (Service des Avions Français Instrumentés pour la Recherche en Environnement) operates an ATR-42-320 turboprop for European atmospheric science campaigns. Small, slow, payload-heavy — common European partner platform alongside FAAM and DLR HALO.

See also

https://www.safire.fr/

__init__()[source]
Return type:

None

class NERC_DO228[source]

Bases: Aircraft

NERC ARSF Dornier Do228-101 atmospheric / remote-sensing aircraft.

The NERC Airborne Research and Survey Facility operated D-CALM as a medium-tropospheric, non-pressurised twin-turboprop research platform. This model is calibrated from public CEDA NERC/ARSF DO228 datasets, principally ACTIVE and Eyjafjallajokull core aircraft measurements.

The calibration is useful for timing / reachability but deliberately carries lower confidence than platforms with native TAS and attitude: the CEDA files provide position, altitude, U/V wind, pressure, and temperature, so TAS is reconstructed by wind triangle and turn/bank behaviour remains brochure/default.

See also

https://catalogue.ceda.ac.uk/uuid/d2c5c36981824b71a98a2906394d61f3/

__init__()[source]
Return type:

None

class AWI_BaslerBT67[source]

Bases: Aircraft

AWI Polar 5 / Polar 6 Basler BT-67 polar research aircraft.

The Alfred Wegener Institute operates two broadly similar Basler BT-67 aircraft, Polar 5 and Polar 6, for Arctic and Antarctic airborne science. This model intentionally represents the combined AWI BT-67 operating envelope rather than one tail: the calibration uses public PANGAEA Polar 5 and Polar 6 nav/met records from ACLOUD 2017 and HALO-AC3 2022.

The PANGAEA products include native TAS, ground speed, attitude, U/V/W wind, pressure, and temperature. Vertical rate is derived from 1 Hz altitude, which is quantized to whole metres in these public files; the climb/descent profiles are therefore intentionally simple and lower confidence than the TAS schedules and turn envelope.

__init__()[source]
Return type:

None

class DLR_HALO[source]

Bases: Aircraft

DLR HALO (D-ADLR) Gulfstream G550 high-altitude long-range research aircraft.

HALO (High Altitude and LOng range) is operated by DLR Flugexperimente at Oberpfaffenhofen. Same airframe family as NCAR_GV (HIAPER) — both Gulfstream V/G550 — but operated independently and typically configured for different payloads.

See also

https://www.dlr.de/en/research-and-transfer/research-infrastructure/halo

__init__()[source]
Return type:

None

Profile I/O

Each pre-configured aircraft loads its performance values from hyplan/data/aircraft/<short_name>.json. These functions read, write, and resolve those files; use them to refresh a calibration in place or to roll your own aircraft profile externally.

The schema is documented in hyplan/data/aircraft/README.md: compact JSON with units in field names (e.g. climb_schedule.points_ft_kt), discriminated {"type": "tas" | "cas_mach"} speed schedules, and nested approach_profile / typical_climb_out blocks for the more complex airframes.

load_aircraft_profile(short_name)[source]

Load a JSON profile and parse into kwargs ready for hyplan.aircraft.Aircraft.

Parameters:

short_name (str) – Filename stem of a bundled hyplan/data/aircraft/<short_name>.json file.

Return type:

dict[str, Any]

Returns:

A dict of keyword arguments accepted by Aircraft.__init__(). Schedule / profile / nested-object fields are reconstructed as their respective dataclasses.

Raises:

HyPlanRuntimeError – If the file does not exist or cannot be parsed.

dump_aircraft_profile(aircraft, path)[source]

Serialize an Aircraft instance to its JSON profile.

Inverse of load_aircraft_profile(). Used by notebooks/calibration/<aircraft>/calibrate.py to write refreshed JSON directly from the fit.

Parameters:
  • aircraft (Any) – An Aircraft instance (any subclass).

  • path (str | Path) – Destination filesystem path. Parent directory must already exist.

Return type:

None

write_calibrated_profile(short_name, *, path=None, **overrides)[source]

Apply calibrated overrides to a bundled aircraft JSON in place.

Loads the current <short_name>.json via load_aircraft_profile(), applies any keyword overrides, rebuilds the Aircraft, and writes the updated JSON back to disk. Fields not present in overrides are preserved (brochure metadata, sources, confidence, etc.), so a calibration pass that only refits the climb / cruise / descent schedules can update just those without disturbing the rest of the profile.

Parameters:
  • short_name (str) – Filename stem (e.g. "king_air_350").

  • path (str | Path | None) – Optional override for the output path. Defaults to profile_path() which points at the bundled location inside the installed package.

  • **overrides (Any) – Any keyword accepted by Aircraft.__init__(), e.g. climb_schedule=fit.climb_schedule, climb_profile=fit.climb_profile, service_ceiling=....

Return type:

Path

Returns:

The Path that was written.

Example

>>> from hyplan.units import ureg
>>> write_calibrated_profile(
...     "king_air_350",
...     service_ceiling=35_000 * ureg.feet,
...     climb_schedule=fit.climb_schedule,
...     cruise_schedule=fit.cruise_schedule,
...     descent_schedule=fit.descent_schedule,
...     climb_profile=fit.climb_profile,
...     descent_profile=fit.descent_profile,
... )
profile_path(short_name)[source]

Return the on-disk path to <short_name>.json in the bundled aircraft data directory.

Parameters:

short_name (str) – Filename stem (e.g. "king_air_350").

Return type:

Path

Returns:

Absolute Path to the bundled JSON file. The file may or may not exist yet — callers can check .exists() before reading.