⟵ Back to projects

Flight Path Planning for a Cargo UAV

December 20258 min read

Flight Path Planning for a Cargo UAV cover

Navigation for the Windracers ULTRA, an autonomous cargo plane that hauls up to 200 kg of payload. A year of flight systems research with AIDA3, Purdue’s aviation AI center.

  • Airport-to-graph pipeline. OSMnx turns any airport OpenStreetMap has mapped into a routable graph. O’Hare comes out as 6,209 nodes. The same code ran unmodified on LAX and Atlanta.
  • Taxi routing. Closure rerouting around blocked nodes, plus a 71-waypoint gate-to-runway route under simulated ATC clearances.
  • Runway corridor geofence. Built from FAA endpoint data, 250 ft each side of the centerline, stress-tested with a wind-disturbed sim at 120 ft/s.
  • From notebook to hangar. Gazebo sim first, then testbed flights in Purdue’s PURT hangar under Qualisys motion capture with live ROS 2 trajectory tracking.

O’Hare in 6,209 nodes, a runway in one yes-or-no check, and a foam airplane in a hangar to prove both.

In spring 2025 I joined AIDA3, Purdue’s Center on AI for Digital, Autonomous and Augmented Aviation, as a Flight Systems Researcher. The deliverable of a research position is whatever moves the aircraft closer to flying itself.

Context

The Windracers ULTRA is a fixed-wing autonomous cargo plane built for humanitarian delivery and wildfire monitoring. It hauls up to about 200 kg. Purdue’s airframe is named Earhart, after the aviator Purdue once employed, which might be the most Purdue thing possible.

The aircraft cannot hover and it cannot pull over. Once the takeoff roll starts, there is no calling it off. My work was the navigation problem, figuring out how the ULTRA gets itself around an airport.

The Windracers ULTRA, named Earhart, parked on the ramp
Earhart on the ramp with twin engines and Purdue livery.

The spring semester started with a literature review. How does an aircraft know where it is while taxiing, without GPS? It is the same question my delivery drones run into. The short answer is lidar, and lots of it. Researchers in the field fuse lidar odometry, a running count of how far the aircraft has moved, with inertial data to track position with no satellite in sight. The newest papers at the time had neural nets reading motion straight from point clouds.

The Airport as a Graph

Before the ULTRA ever takes off, it has to taxi. An airport is secretly already a graph, with taxiways as edges and intersections as nodes. I built a pipeline that turns any airport in OpenStreetMap into one.

OSMnx pulls the geometry straight from OpenStreetMap. The pipeline chops every polyline into graph edges:

tags = {"aeroway": ["taxiway", "runway"]}
gdf = ox.features_from_place("O'Hare International Airport, Chicago, Illinois, USA", tags)

for line in gdf.geometry:
    coords = list(line.coords)
    for p1, p2 in zip(coords, coords[1:]):
        G.add_edge(p1, p2, geometry=LineString([p1, p2]))

O’Hare comes out as 6,209 nodes and 6,857 edges. LAX and Atlanta went through the same pipeline without a line changed.

O'Hare's taxiway network rendered as a graph of nodes and edges
All of O'Hare as a NetworkX graph. Every dot is a routable node.

With the graph in hand, routing becomes textbook graph search. Three things fall out:

Original and rerouted taxi paths around a blocked node at O'Hare
A blocked node (X) forces the replan. Original route in blue, new route in red.

The prototype routes with plain shortest-path search. Next, A* looks for a smaller slice of the graph, LPA* repairs a broken route in place, and edge costs are weighted by real taxi speeds. A separate notebook parses real controller transcripts into structured commands, where “runway four left” becomes data and NINER collapses back to 9, which it always was. One day the planner should take its taxi clearances straight from the tower.

Staying Inside the Lines

Takeoff and landing hinge on one blunt question. Is the aircraft where it is supposed to be? My answer is a runway corridor, a geofence built from FAA runway endpoint data.

I tested it with a simulated aircraft flying 120 ft/s (about 80 mph) down the centerline. Random wind gusts shoved it sideways and a proportional controller pulled it back. Because I classified every timestep, the run flagged the exact moment the aircraft left the corridor. The first airport I pointed it at was Purdue’s own field, runway 5/23.

Disturbance, correction, tolerance band. Once I noticed that loop, I see it everywhere. Funnily enough, it is also how I pour latte art at my other job.

Simulated wind-disturbed UAV trajectory through the runway corridor
The wind-disturbed run at Purdue's runway, with dots inside the corridor and crosses outside.

From Notebook to Hangar

An algorithm that only lives in a Jupyter notebook has never been wrong in a way that hurts. So I moved it in stages. Gazebo first, the physics sim the flight code cannot tell from a real airfield, then real hardware. I ran flight tests with a lightweight autonomous fixed-wing UAV inside the Purdue UAS Research and Test Facility (PURT). The hangar and the aircraft belong to the lab. The test missions were mine.

The hangar is instrumented with a Qualisys motion capture system, which quietly solves the very problem the lit review chased. The mocap rig delivers position indoors at millimeter accuracy, with no GPS in sight. The full loop runs live:

One flight, three views. The testbed in the PURT hangar, the ground control station, and the ROS 2 trajectory tracking.

A crash here costs a foam wing and a re-flight. The same crash on the real ULTRA costs a $500k+ cargo plane.

Where It Stands

The Ultimate Takeaway

The taxi graphs, the closure rerouting, the corridor geofence, all of it was about closing the gap between the map and the machine. A 6,209-node graph is only worth building if a 200 kg airplane can fly the route that comes out of it.