Skip to content

Glide Computer: Tactical Flight Planning

Library:

Example:

This advanced example implements a simplified tactical glide computer for sailplane (glider) flight planning. It demonstrates how mp-units can model a complex real-world aviation application with multiple interacting subsystems, geographic coordinates, and mixed unit systems.

What is a Glide Computer?

A glide computer is an avionic instrument used in soaring (glider) aviation to help pilots make tactical decisions about:

  • Whether they can reach their destination from current altitude
  • How long a flight will take given weather conditions
  • When and where to climb in thermals (rising air columns)
  • Optimal speeds to fly between waypoints

This example simulates these calculations for various glider types and weather conditions.

Domain Modeling

Custom Quantity Types

The example defines aviation-specific quantities:

glide_computer_lib.h
QUANTITY_SPEC(rate_of_climb_speed, mp_units::isq::speed, mp_units::isq::height / mp_units::isq::time);

This creates a distinct quantity type for vertical speed (rate of climb/sink), which is different from horizontal speed even though both have dimensions of length/time.

Type-Safe Aliases

The example uses type aliases for code clarity:

glide_computer_lib.h
using distance = mp_units::quantity<mp_units::isq::distance[mp_units::si::kilo<mp_units::si::metre>]>;
using height = mp_units::quantity<mp_units::isq::height[mp_units::si::metre]>;

// time
using duration = mp_units::quantity<mp_units::isq::duration[mp_units::si::second]>;
using timestamp = mp_units::quantity_point<mp_units::isq::time[mp_units::si::second],
                                           mp_units::chrono_point_origin<std::chrono::system_clock>>;

// speed
using velocity = mp_units::quantity<mp_units::isq::speed[mp_units::si::kilo<mp_units::si::metre> / mp_units::si::hour]>;
using rate_of_climb = mp_units::quantity<rate_of_climb_speed[mp_units::si::metre / mp_units::si::second]>;

These aliases:

  • Make code more readable (height vs generic length)
  • Encode domain intent (these are specific aviation measurements)
  • Don't sacrifice type safety (still checked at compile-time)

Complex Data Structures

The glider is modeled with its performance characteristics:

glide_computer_lib.h
struct glider {
  struct polar_point {
    velocity v;
    rate_of_climb climb;
  };

  std::string name;
  std::array<polar_point, 1> polar;
};

Each point on the polar curve describes the glider's sink rate at a given airspeed - fundamental aerodynamic data needed for flight planning.

Geographic Integration

The example uses a separate geographic module that provides type-safe geographic primitives.

Position and Coordinates

geographic.h
template<typename T = double>
using latitude = mp_units::quantity_point<mp_units::si::degree, equator, ranged_representation<T, -90, 90>>;

template<typename T = double>
using longitude = mp_units::quantity_point<mp_units::si::degree, prime_meridian, ranged_representation<T, -180, 180>>;

Latitude and longitude are modeled as quantity_point with:

  • Distinct origins (equator, prime_meridian)
  • Range-validated representations (±90° for latitude, ±180° for longitude)
  • Custom user-defined literals (_N, _S, _E, _W)

Great Circle Distance

geographic.h
template<typename T>
// NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
distance spherical_distance(position<T> from, position<T> to)

The spherical_distance function calculates the shortest distance between two points on Earth's surface using the great-circle formula, automatically handling all unit conversions and trigonometric operations with proper dimensional analysis.

Waypoint Definition

With these geographic primitives, waypoints become simple and type-safe:

glide_computer_lib.h
struct waypoint {
  std::string name;
  geographic::position<long double> pos;
  geographic::msl_altitude alt;
};

Each waypoint contains:

  • Name (airport ICAO code)
  • Geographic position with latitude/longitude using custom literals
  • MSL altitude in aviation-standard feet

This shows how mp-units integrates with domain-specific abstractions while maintaining type safety across module boundaries.

Multi-System Units

The example naturally mixes unit systems as aviators actually do:

glide_computer.cpp
auto get_gliders()
{
  using namespace mp_units::si::unit_symbols;
  MP_UNITS_DIAGNOSTIC_PUSH
  MP_UNITS_DIAGNOSTIC_IGNORE_MISSING_BRACES
  static const std::array gliders = {glider{"SZD-30 Pirat", {83 * km / h, -0.7389 * m / s}},
                                     glider{"SZD-51 Junior", {80 * km / h, -0.6349 * m / s}},
                                     glider{"SZD-48 Jantar Std 3", {110 * km / h, -0.77355 * m / s}},
                                     glider{"SZD-56 Diana", {110 * km / h, -0.63657 * m / s}}};
  MP_UNITS_DIAGNOSTIC_POP
  return gliders;
}

auto get_weather_conditions()
{
  using namespace mp_units::si::unit_symbols;
  static const std::array weather_conditions = {std::pair{"Good", weather{1900 * m, 4.3 * m / s}},
                                                std::pair{"Medium", weather{1550 * m, 2.8 * m / s}},
                                                std::pair{"Bad", weather{850 * m, 1.8 * m / s}}};
  return weather_conditions;
}

auto get_waypoints()
{
  using namespace geographic::literals;
  using namespace mp_units::international::unit_symbols;
  static const std::array waypoints = {
    waypoint{"EPPR", {54.24772_N, 18.6745_E}, mean_sea_level + 16. * ft},   // N54°14'51.8" E18°40'28.2"
    waypoint{"EPGI", {53.52442_N, 18.84947_E}, mean_sea_level + 115. * ft}  // N53°31'27.9" E18°50'58.1"
  };
  return waypoints;
}
  • SI units (km/h, m/s) for glider performance
  • Imperial/International units (ft) for altitude (standard in aviation)
  • Latitude/longitude in degrees with custom literals

mp-units handles these conversions automatically and safely.

Key Features Demonstrated

1. Quantity Points for Absolute Values

glide_computer_lib.h
using timestamp = mp_units::quantity_point<mp_units::isq::time[mp_units::si::second],
                                           mp_units::chrono_point_origin<std::chrono::system_clock>>;

Timestamps are absolute points in time, not durations - correctly modeled using quantity_point with chrono_point_origin.

2. Custom Quantity Specifications

QUANTITY_SPEC(rate_of_climb_speed, mp_units::isq::speed,
              mp_units::isq::height / mp_units::isq::time);

Creates a specialized speed quantity specifically for vertical movement, distinct from general speed.

3. Dimensionless Ratios

glide_computer_lib.h
constexpr mp_units::QuantityOf<mp_units::dimensionless> auto glide_ratio(const glider::polar_point& polar)
{
  return polar.v / -polar.climb;
}

The glide ratio (distance traveled per unit altitude lost) is a dimensionless quantity, correctly computed as a ratio of two speeds.

4. Complex Calculations

The library performs sophisticated calculations including:

  • Distance between geographic coordinates
  • Time-to-climb to thermal top
  • Ground speed vs airspeed
  • Safety margins and minimum altitudes
  • Multi-leg route planning

All with full compile-time dimensional analysis.

5. Formatted Output

glide_computer.cpp
      std::cout << MP_UNITS_STD_FMT::format("  * {::N[.4f]} @ {::N[.1f]} -> {::N[.1f]} ({::N[.1f]})\n", p.climb, p.v,
                                            ratio, si::asin(1 / ratio).force_in(si::degree));

Custom formatting for all quantity types makes the output readable for pilots.

Scenario Simulation

The main program runs multiple scenarios:

  • 4 different glider types (from trainer to high-performance)
  • 3 weather conditions (good, medium, bad thermals)
  • Multi-waypoint tasks with varying distances

For each combination, it calculates whether the flight is possible and estimates the time required.

Sample Output

The program outputs detailed flight plans with proper unit formatting:

Safety:
=======
- Min AGL separation: 300 m

Gliders:
========
- Name: SZD-56 Diana
- Polar:
  * -0.6366 m/s @ 110.0 km/h -> 48.0 (1.2°)

Waypoints:
==========
- EPPR: 54.24772° N 18.6745° E, 4.9 m AMSL
- EPGI: 53.52442° N 18.84947° E, 35.1 m AMSL

Weather:
========
- Good
  * Cloud base:        1900 m AGL
  * Thermals strength: 4.3 m/s

Task:
=====
- Start: EPPR
- Finish: EPPR
- Length:  162.5 km
- Legs:
  * EPPR -> EPGI (81.2 km)
  * EPGI -> EPPR (81.2 km)

Tow:
====
- Type:        aircraft
- Height:      400 m
- Performance: 1.6 m/s

Scenario: Glider = SZD-56 Diana, Weather = Good
===============================================

| Flight phase | Duration                    | Distance                  | Height                |
|--------------|-----------------------------|---------------------------|-----------------------|
| Tow          | 4.2 min (Total:   4.2 min)  | 0.0 km (Total:   0.0 km)  | 400 m ( 405 m AMSL)   |
| Glide        | 2.6 min (Total:   6.8 min)  | 4.8 km (Total:   4.8 km)  | -100 m ( 305 m AMSL)  |
| Circle       | 7.3 min (Total:  14.1 min)  | 0.0 km (Total:   4.8 km)  | 1602 m (1907 m AMSL)  |
| Glide        | 41.9 min (Total:  56.0 min) | 76.8 km (Total:  81.6 km) | -1600 m ( 307 m AMSL) |
| Circle       | 6.3 min (Total:  62.3 min)  | 0.0 km (Total:  81.6 km)  | 1383 m (1690 m AMSL)  |
| Final Glide  | 44.1 min (Total: 106.4 min) | 80.8 km (Total: 162.5 km) | -1685 m (   5 m AMSL) |
Note

The above is just a part of the actual text output.

Each flight phase shows:

  • Duration - time for this phase and cumulative total
  • Distance - distance covered and total so far
  • Height - altitude change and resulting MSL altitude

The output demonstrates:

  • Tow - initial climb to release altitude (400 m AGL)
  • Glide - descending flight between thermals
  • Circle - climbing in thermals to regain altitude
  • Final Glide - direct glide to destination without further thermals

All with automatic unit formatting showing proper aviation notation (km/h, m, m/s, AMSL).

Practical Applications

This example is close to what a real glide computer might do (though simplified). Real aviation software needs:

  • Type safety - mixing altitude and distance is dangerous
  • Multiple unit systems - aviation uses nautical miles, feet, meters, knots, etc.
  • Exact conversions - no room for approximation errors
  • Performance - zero runtime overhead from the units library
  • Maintainability - clear, self-documenting code

mp-units provides all of these guarantees.

Key Takeaways

  • Complex real-world applications can be fully typed with mp-units
  • Custom quantity specifications capture domain-specific knowledge
  • Multiple unit systems integrate seamlessly
  • Geographic and physical quantities work together naturally
  • Type safety scales to large, multi-module codebases
  • The library doesn't get in the way of domain logic

This example shows that mp-units is production-ready for safety-critical aviation software where correctness is paramount.