An open-source Python library for planning airborne remote sensing campaigns.
HyPlan helps scientists and engineers design remote sensing flight missions. It handles flight line generation, sensor modeling, swath coverage, solar glint prediction, cloud analysis, terrain-aware calculations, and mission logistics including airport selection and aircraft performance.
Study Area Flight Lines Sensor Swaths Mission Plan
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ ▓▓▓▓▓▓▓ │ │ ──────► │ │▒──────►▒│ │ ✈ ─ ─ ► │
│ ▓▓▓▓▓▓▓ │ ───► │ ◄────── │ ───► │▒◄──────▒│ ───► │ ──────► │
│ ▓▓▓▓▓▓▓ │ │ ──────► │ │▒──────►▒│ │ ◄────── │
└─────────┘ └─────────┘ └─────────┘ │ ─ ─ ✈ ◄ │
define area generate lines compute coverage └─────────┘
plan & optimize
- Flight planning — Define flight lines, generate multi-line coverage patterns, and compute complete mission plans with takeoff, transit, data collection, and landing segments
- Pattern workflows — Build reusable racetrack, rosette, polygon, sawtooth, spiral, and glint-arc patterns as first-class objects that can be edited, serialized, and re-planned
- Flight optimization — Automatically order flight lines with multi-day scheduling, endurance constraints, and refueling stops
- Sensor modeling — Pre-configured NASA instruments (AVIRIS-3, AVIRIS-5, HyTES, PRISM, MASTER, and more) with ground sample distance and swath calculations
- Lidar & radar — LVIS full-waveform lidar and UAVSAR L/P/Ka-band SAR sensor models
- Solar glint prediction — Predict glint angles across flight lines for water observation missions
- Solar illumination — Compute solar position and daily data-collection windows for any site and date
- Terrain-aware analysis — Download DEM data and compute where the sensor field of view intersects the ground
- Cloud cover analysis — Estimate clear-sky probability from ERA5 reanalysis via Open-Meteo (no auth) or MODIS imagery via Google Earth Engine
- Wind correction — Trochoidal Dubins arcs (Sachdev/Moon, 2023) bend ground tracks under wind; per-segment wind from MERRA-2 reanalysis, NOAA GFS forecast, or GMAO GEOS-FP analysis; also constant wind and still-air baselines
- Atmosphere model — ISA standard atmosphere with CAS/TAS/Mach airspeed conversions
- Aircraft performance — 15 pre-configured aircraft models (NASA ER-2, WB-57, G-III, G-V, B200, Twin Otter, and others) with climb/cruise/descent profiles; the NASA ER-2 is calibrated against 17 IWG1 in-situ flight logs (step climb, two-regime descent, empirical 2.51° approach glideslope)
- Airport logistics — Search and filter airports by location, runway length, surface type, and country
- Satellite coordination — Predict satellite overpasses and compute ground-track swaths for 14+ satellites
- Dubins path planning — Minimum-radius turning trajectories between waypoints for realistic aircraft maneuvering
- Flight patterns — Generate racetrack, rosette, spiral, sawtooth, polygon, glint-arc, and coordinated dual-aircraft (five-point line) flight patterns for profiling, survey, and multi-platform missions
- Campaign persistence — Organize free-standing lines and reusable patterns with stable IDs, revision metadata, and plain-folder persistence suitable for interactive planning tools
- Geospatial export — Output to Excel, KML, GPX, ForeFlight CSV, Honeywell FMS, ER-2, ICARTT, and interactive Folium maps
- Python 3.9+
git clone https://github.com/ryanpavlick/hyplan
cd hyplan
pip install -e .mamba env create --name hyplan --file environment.yml
mamba activate hyplan
pip install -e .- Google Earth Engine (
earthengine-api) — optional forhyplan.clouds(MODIS path); the Open-Meteo path requires no extra dependencies - Wind fields (
xarray,netcdf4,earthaccess,pydap,cfgrib) — install withpip install hyplan[winds]for MERRA-2, GFS, and GEOS-FP wind data - Planned-sortie ingest (
openpyxl,pdfplumber) — install withpip install hyplan[planned]to parse Green Card mission data cards (XLSX or PDF) and KML route files (used by the ER-2 calibration / planned-vs-flown workflow)
Some modules require API keys or tokens. Create a .env file in the project root:
# NASA Earthdata — required for MERRA-2 wind data
# Get a token at https://urs.earthdata.nasa.gov/
EARTHDATA_TOKEN=your_token_here
# OpenAIP — required for airspace data
# Get a key at https://www.openaip.net/
OPENAIP_API_KEY=your_key_hereGoogle Earth Engine (required for hyplan.clouds) uses OAuth — run
earthengine authenticate once to store credentials locally.
from hyplan import FlightLine, ureg
flight_line = FlightLine.start_length_azimuth(
lat1=34.05, lon1=-118.25,
length=ureg.Quantity(50, "km"),
az=45.0,
altitude_msl=ureg.Quantity(20000, "feet"),
site_name="LA Northeast",
)from hyplan import KingAirB200, Airport, compute_flight_plan, plot_flight_plan
aircraft = KingAirB200()
departure = Airport("KSBA")
destination = Airport("KBUR")
plan = compute_flight_plan(aircraft, [flight_line], departure, destination)
plot_flight_plan(plan, departure, destination, [flight_line])from hyplan import Campaign, NASA_GIII, racetrack, compute_flight_plan, ureg
campaign = Campaign(
"LA Basin Demo",
bounds=(-119.0, 33.5, -117.5, 34.5),
)
pattern = racetrack(
center=(34.0, -118.2),
heading=90.0,
altitude=12_000 * ureg.meter,
leg_length=80 * ureg.kilometer,
n_legs=3,
offset=8 * ureg.kilometer,
name="Basin Wall",
)
pattern_id = campaign.add_pattern(pattern)
plan = compute_flight_plan(NASA_GIII(), [campaign.get_pattern(pattern_id)])Patterns are first-class objects in HyPlan. They can be regenerated with
parameter overrides, edited line-by-line, saved inside a Campaign, and
expanded directly by compute_flight_plan().
from hyplan import greedy_optimize
result = greedy_optimize(
aircraft=aircraft,
flight_lines=[flight_line],
airports=[departure, destination],
takeoff_airport=departure,
return_airport=destination,
max_endurance=4.0,
max_daily_flight_time=8.0,
max_days=3,
)
print(f"Lines covered: {result['lines_covered']}, Days: {result['days_used']}")from datetime import datetime, timezone
from hyplan import AVIRIS3
from hyplan.glint import compute_glint_vectorized
sensor = AVIRIS3()
obs_time = datetime(2025, 2, 17, 18, 0, tzinfo=timezone.utc)
gdf = compute_glint_vectorized(flight_line, sensor, obs_time)
gdf.to_file("glint_results.geojson", driver="GeoJSON") ┌────────────────────────┐
│ Flight Planning │
├────────────────────────┤
│ flight_line │
│ pattern │
│ flight_box │
│ flight_plan │
│ flight_optimizer │
│ flight_patterns │
│ waypoint · campaign │
└───────────┬────────────┘
│
┌──────────────┬────────────┼────────────┬──────────────┐
▼ ▼ ▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│Instruments │ │ Aircraft │ │ Environ │ │Logistics │ │Utilities │
├────────────┤ ├────────────┤ ├──────────┤ ├──────────┤ ├──────────┤
│instruments/│ │ aircraft │ │ sun │ │ airports │ │ geometry │
│ line_scan │ │ atmosphere │ │ glint │ │ airspace │ │ units │
│ lvis │ │ dubins3d │ │ terrain │ │satellites│ │ plotting │
│ radar │ │ │ │ clouds │ │ exports │ │ │
│ frame_cam │ │ │ │ winds │ │ │ │ download │
│swath │ │ │ │ │ │ │ │exceptions│
└────────────┘ └────────────┘ └──────────┘ └──────────┘ └──────────┘
| Module | Description |
|---|---|
| Flight Planning | |
flight_line |
Create, modify, split, clip, and export individual flight lines |
pattern |
First-class reusable flight-pattern container with regeneration and serialization |
flight_box |
Generate parallel flight lines covering a geographic area |
flight_plan |
Compute complete mission plans with timing and altitude profiles |
flight_optimizer |
Graph-based flight line ordering with multi-day and refueling support |
flight_patterns |
Flight pattern generators returning Pattern objects (racetrack, rosette, spiral, sawtooth, polygon, glint arc, coordinated line) |
waypoint |
Waypoint class for flight planning with altitude, heading, and speed |
campaign |
Campaign manager for organizing free-standing lines and patterns, caching reference data, tracking revisions, and persisting plans |
| Instruments | |
instruments |
All sensor models — line scanners (AVIRIS-3, AVIRIS-5, HyTES, PRISM, MASTER, etc.), LVIS lidar, UAVSAR SAR, and frame cameras |
swath |
Sensor swath coverage with terrain integration |
| Aircraft | |
aircraft |
Aircraft performance models (15 pre-configured research aircraft) |
atmosphere |
ISA standard atmosphere model, airspeed conversions (CAS/TAS/Mach) |
dubins3d |
2D Dubins path planning [@dubins1957curves] with trochoidal wind support (Sachdev/Moon, 2023); used by the planner via Aircraft._hybrid_path (2D horizontal + integrated vertical profile). A constant-pitch 3D Dubins solver (Vana et al., ICRA 2020) is included as a reference for short, near-level transits. |
| Environment | |
sun |
Solar position and timing calculations |
glint |
Solar glint angle prediction for water observations |
terrain |
DEM data acquisition and ray-terrain intersection |
clouds |
Cloud cover analysis and clear-sky probability from ERA5 (Open-Meteo) or MODIS (GEE) |
winds |
Wind field models (MERRA-2, GFS, GEOS-FP, IWG1 trace, constant, still air); supplied to compute_flight_plan to bend ground tracks via trochoidal Dubins arcs |
| Logistics | |
airports |
Airport database with search, filtering, and runway data |
airspace |
Airspace data from OpenAIP with flight line conflict detection |
satellites |
Satellite overpass prediction and swath modeling |
exports |
Export flight plans to Excel, KML, GPX, ForeFlight, Honeywell FMS, ER-2, ICARTT |
| Utilities | |
geometry |
Geospatial utilities (haversine, coordinate transforms, polygons) |
units |
Unit conversions using Pint (meters, feet, knots, etc.) |
plotting |
Interactive Folium map generation and altitude profiles |
download |
File download utility with chunked transfer and timeout support |
exceptions |
HyPlan exception hierarchy for targeted error handling |
The notebooks/ directory contains Jupyter notebooks with interactive tutorials and visualizations covering every HyPlan module:
| Notebook | Description |
|---|---|
| tutorial.ipynb | End-to-end workflow: sensor setup, flight box generation, solar checks, airport selection, optimization, flight planning, and map visualization |
| validation.ipynb | Validates HyPlan calculations against reference values (Vincenty, NOAA solar, analytical swath/GSD) |
| campaign_management.ipynb | Campaign class for multi-flight, multi-day planning: study area, flight-line groups, save/reload across sessions |
| Notebook | Description |
|---|---|
| flight_line_operations.ipynb | Creating, clipping, splitting, offsetting, rotating, and exporting flight lines |
| flight_box_generation.ipynb | Generating parallel flight lines over study areas with swath overlap control |
| flight_plan_computation.ipynb | Segment-by-segment flight plans with altitude profiles and map visualization |
| flight_optimizer_demo.ipynb | Greedy line ordering with endurance constraints, refueling, and multi-day scheduling |
| dubins_path_planning.ipynb | Dubins path basics: turn radius, speed/bank effects, and flight line integration |
| airport_selection.ipynb | Finding, filtering, and comparing airports by location, runway, and aircraft requirements |
| flight_patterns.ipynb | Racetrack, rosette, spiral, sawtooth, polygon, and glint-arc flight patterns |
| airspace_check.ipynb | Detect conflicts between flight lines and FAA / OpenAIP airspace boundaries (restricted, prohibited, controlled) |
| Notebook | Description |
|---|---|
| sensor_comparison.ipynb | Comparing GSD, swath width, and critical speed across imaging spectrometers |
| frame_camera_planning.ipynb | Frame camera FOV, footprints, GSD, and along-track sampling |
| lidar_lvis_planning.ipynb | LVIS lens options, swath geometry, contiguous coverage, and coverage rates |
| radar_sar_missions.ipynb | UAVSAR L/P/Ka-band swath geometry, resolution, and InSAR line spacing |
| profiling_lidar_planning.ipynb | NASA ProfilingLidar family (HSRL-2, HALO, CPL): footprint diameter, horizontal resolution, pulses-per-profile |
| awp_planning.ipynb | NASA Langley Aerosol Wind Profiler: dual-LOS geometry, stable-segment flagging, terrain-aware profile placement |
| stereo_oblique_planning.ipynb | Stereo photogrammetry and oblique-camera mission design: convergence angle, GSD variation across the frame |
| Notebook | Description |
|---|---|
| solar_planning.ipynb | Solar azimuth/elevation, daily collection windows, seasonal and cross-site comparisons |
| glint_analysis.ipynb | Glint angle prediction, heading optimization, and time-of-day effects for aquatic missions |
| glint_arc_planning.ipynb | GlintArc geometry for specular reflection flight paths over water |
| terrain_aware_planning.ipynb | DEM-based terrain profiles, AGL variation effects on GSD and swath |
| cloud_analysis.ipynb | MODIS cloud cover from Google Earth Engine, visit simulation, campaign duration planning |
| cloud_analysis_gee.ipynb | Higher-resolution MODIS cloud analysis via Google Earth Engine (1 km), Terra vs Aqua morning/afternoon discrimination |
| winds.ipynb | Wind field models, flight plan wind correction, MERRA-2 reanalysis demo, direction/speed sensitivity |
| wind_effects.ipynb | Quantitative wind effects on geometry: crab angle, swath rotation, trochoidal turn drift, along-track sampling |
| phenology_analysis.ipynb | MODIS NDVI/EVI/LAI/FPAR + phenological transition dates for selecting optimal collection windows |
| Notebook | Description |
|---|---|
| aircraft_performance.ipynb | Fleet comparison, speed profiles, climb/descent performance, range/endurance, custom aircraft |
| er2_calibration/iwg1_calibration.ipynb | Walkthrough of the NASA ER-2 calibration from 17 IWG1 sorties: per-altitude-bin medians, breakpoint selection, bank-angle analysis |
| er2_calibration/sortie_replay.ipynb | Replay individual ER-2 sorties through the planner; modeled-vs-flown breakdown with multi-sortie scan |
| er2_calibration/planned_vs_flown.ipynb | Compare planned (Green Card / KML) vs flown (IWG1) vs HyPlan-modeled timing for NM17 B / CO07v4 / CO06 |
| satellite_coordination.ipynb | Satellite ground tracks, overpass prediction, and multi-satellite search |
| Notebook | Description |
|---|---|
| export_formats.ipynb | Export flight plans to Excel, KML, GPX, ForeFlight, Honeywell FMS, ER-2, ICARTT, and text formats |
Full API documentation is available at ryanpavlick.github.io/hyplan.
To build the documentation locally:
pip install sphinx myst-parser furo sphinx-autodoc-typehints
cd docs
make html- Flight optimizer — Uses a greedy nearest-neighbor heuristic; does not guarantee globally optimal ordering; still experimental
- Terrain module — DEM downloads require internet access and may be slow for large areas
- Google Earth Engine — The
cloudsmodule's MODIS path requires a Google Earth Engine account; the Open-Meteo path (default) needs no account
Contributions are welcome! To get started:
- Fork the repository and create a feature branch
- Install in development mode:
pip install -e . - Run the notebooks in
notebooks/to verify your changes - Submit a pull request
Please open an issue for bug reports, feature requests, or questions.
If you use HyPlan in your research, please cite it as:
@software{hyplan,
author = {Pavlick, Ryan},
title = {HyPlan: Planning Software for Airborne Remote Sensing Campaigns},
url = {https://github.com/ryanpavlick/hyplan},
license = {Apache-2.0},
version = {1.3.0}
}Machine-readable citation metadata is also available in CITATION.cff.
HyPlan is licensed under the Apache License, Version 2.0. See LICENSE
or LICENSE.md for details.
LICENSE/LICENSE.md— project license and third-party noticesCONTRIBUTING.md— development and pull-request workflowCONTRIBUTORS.md— acknowledged project contributorsCODE_OF_CONDUCT.md— community expectations for collaboration
HyPlan ships the JPL DE421 planetary ephemeris (hyplan/data/de421.bsp)
so solar geometry calculations work fully offline. DE421 is produced by
NASA's Jet Propulsion Laboratory and is in the public domain:
Folkner, W. M., Williams, J. G., & Boggs, D. H. (2009). The Planetary and Lunar Ephemeris DE 421. JPL Interoffice Memorandum 343R-08-003. https://ssd.jpl.nasa.gov/planets/eph_export.html
DE421 is read via the Skyfield
library (Rhodes 2019, ASCL:1907.024). See LICENSE.md for
the full third-party data attribution.
For inquiries or further information, please contact Ryan Pavlick (ryan.p.pavlick@nasa.gov).