Dubins Path Planning

2D Dubins path planning with optional wind for realistic aircraft maneuvering between waypoints. Used by Aircraft._hybrid_path for the horizontal layout; the vertical profile is integrated separately from each aircraft’s calibrated climb_profile / descent_profile. Trochoidal ground tracks under wind follow Sachdev et al. (2023).

class DubinsPath2D[source]

Bases: object

Horizontal-only Dubins path between two waypoints.

Pure plan-view geometry — bank-angle-constrained turns and straight segments. The vertical profile (altitude vs along-track distance) is intentionally not modeled here. This is the geometry consumed by the hybrid mission planner: solve the horizontal layout once, integrate altitude vs. distance separately from Aircraft.climb_profile / Aircraft.descent_profile.

In still air, uses the standard CSC/CCC Dubins solver. With wind, uses the trochoidal solver (Sachdev et al., 2023) — turning arcs drift with the wind, producing distorted but optimal ground tracks.

Parameters:
  • start (Waypoint) – Starting waypoint (lat / lon / heading required; altitude is ignored).

  • end (Waypoint) – Ending waypoint (same).

  • speed (Union[Quantity, float]) – True airspeed used to size the turn radius given bank_angle. Float (m/s) or pint Quantity with speed units.

  • bank_angle (float) – Maximum bank angle in degrees.

  • wind (Optional[Tuple[float, float]]) – Optional (u_east, v_north) wind vector in m/s. When provided, the horizontal path uses trochoidal geometry.

  • n_samples (int) – Number of sampled points along the path. Defaults to 50.

The reported length is the air-frame path length (time = length / TAS is the time spent traversing it). In still air this equals the ground-track length; with wind, ground distance is via the sampled geometry.

__init__(start, end, speed, bank_angle, *, wind=None, n_samples=50)[source]
Parameters:
property length: Quantity

Air-frame path length (time = length / TAS).

property geometry: LineString

2D (lon, lat) LineString of the path.

property points: ndarray

Sampled path points as a (n, 3) array of (lat, lon, heading_deg).

property min_turn_radius: Quantity

Minimum 2D turn radius (m) — derived from speed and bank angle.

sample_at_distance(distance)[source]

Return (lat, lon, heading_deg) at the given air-frame distance.

Distance is clamped to [0, length] to keep the call safe at endpoints and at floating-point round-off boundaries.

Return type:

Tuple[float, float, float]

Parameters:

distance (Quantity | float)

sublinestring(distance_start, distance_end, *, n_samples=20)[source]

Return a multi-point (lon, lat) LineString covering the path between two air-frame distance offsets along it.

Used by the hybrid mission planner to assign explicit per-phase geometry: each phase (climb / cruise / descent) gets a sub-LineString that follows the actual Dubins curve through its distance range, instead of a proportional time-based slice of a shared 3D path.

Return type:

LineString

Parameters: