DAVE-ML Models
Overview
DAVE-ML (Dynamic Aerospace Vehicle Exchange Markup Language) is an XML-based standard for encoding aerodynamic databases, flight-dynamics models, and control-system definitions in a tool-neutral, human-readable format. It is governed by AIAA Standard S-119 and uses MathML 2.0 Content markup to express both lookup-table interpolation and arbitrary algebraic calculations, while embedding self-contained check-cases that allow any compliant reader to validate its implementation against the original data source.
A DAVE-ML file (.dml) contains four principal element types:
<variableDef>— declares every scalar quantity (constant, input, output, or intermediate calculated variable) with its identifier, units, description, and optionalinitialValueor MathML body.<breakpointDef>— defines a sorted vector of independent-variable breakpoints used to index gridded tables.<griddedTableDef>— stores a row-major, multi-dimensional lookup table and references the<breakpointDef>entries that span each axis.<functionDef>— binds a<griddedTableDef>to a set of input<variableDef>identifiers, making the table callable by name in MathML expressions.
The Aetherion project uses DAVE-ML exclusively to encode the F-16 Fighting Falcon aerodynamic, propulsion, inertia, and control-law data that originated in Stevens & Lewis [SL03] and were adapted by Morelli for NASA TM-2003-212145 [Mo03].
AIAA S-119 conformance level supported: DAVE-ML 2.0.
C++ Architecture
The DAVE-ML subsystem lives under Aetherion/Serialization/DAVEML/ and
provides five public interfaces.
DAVEMLReader
A lightweight, zero-dependency XML reader for .dml files that
contain only constant <variableDef> elements and simple MathML
arithmetic (no gridded tables, no <piecewise> branching, no
comparisons).
Supported MathML operators:
<times>, <plus>, <minus>, <divide>, <power>,
<cn> (numeric literal), <ci> (variable reference).
Typical use: loading inertial properties from F16_inertia.dml.
#include "Aetherion/Serialization/DAVEML/DAVEMLReader.h"
DAVEMLReader r("data/F16_S119_source/F16_inertia.dml");
double Ixx = r.getValueSI("XIXX"); // kg·m²
double mass = r.getValueSI("XMASS"); // kg
// Re-evaluate calculated outputs at a new input value.
r.setInput("CG_PCT_MAC", 30.0);
double dx = r.getValue("DXCG"); // ft (native units)
Key methods:
Method |
Description |
|---|---|
|
Return the variable’s value in its native (file) units. |
|
Return the value after converting to SI (slug→kg, slug·ft²→kg·m², ft→m, pct→–). |
|
Override an input variable and re-evaluate all downstream calculated variables that depend on it. |
|
Return |
Unit conversion factors applied by getValueSI:
DAVE-ML units |
SI units |
Factor |
|---|---|---|
|
kg |
14.593 902 937 |
|
kg·m² |
1.355 817 948 |
|
m |
0.304 8 |
|
(dimensionless) |
0.01 |
DAVEMLAeroModel
A full-featured, CppAD-compatible evaluator for .dml files that
use breakpoint tables, gridded N-D linear interpolation, piecewise
branching, and full MathML arithmetic. It is the evaluation engine
shared by the aerodynamic, propulsion, and control-law models.
Supported MathML operators (full set):
Operator(s) |
Notes |
|---|---|
|
Standard arithmetic; |
|
Absolute value. |
|
Square root; equivalent to |
|
Trigonometric functions (argument in radians). |
|
DAVE-ML named function |
|
Comparison operators; each returns 1.0 (true) or 0.0 (false).
For the AD path the branch condition is extracted as plain
|
|
Conditional selection; first matching |
Output clamping. <variableDef> elements that carry
minValue and/or maxValue XML attributes have their computed
result clamped to the declared range immediately after evaluation.
For S = double the clamp uses std::clamp; for
S = CppAD::AD<double> it is realised through
CppAD::CondExpLt / CondExpGt so the tape remains smooth.
This is required by F16_control.dml, where several variables
(e.g. deltaThetaCmd, totLongStk, totThrottle) carry
explicit saturation limits.
Evaluation order is established once at construction time using Kahn’s topological sort of the variable dependency graph, ensuring each calculated output is evaluated after all its inputs are ready.
CppAD strategy — the class is templated on a scalar type S.
Branching conditions are always extracted as plain double via
CppAD::Value(), so branch selection never enters the AD tape.
Arithmetic inside the selected branch is fully carried out in S,
giving correct first derivatives everywhere except at discontinuous
switching boundaries (where derivatives are undefined in any case).
Generic access via evaluateRaw: accepts and returns a
std::unordered_map<std::string, S> keyed by DAVE-ML variable
identifiers, making it usable for any DML file without needing a
typed wrapper.
#include "Aetherion/Serialization/DAVEML/DAVEMLAeroModel.h"
DAVEMLAeroModel model("data/F16_S119_source/F16_aero.dml");
DAVEMLAeroModel::Inputs<double> in;
in.vt_fps = 300.0; // ft/s
in.alpha_deg = 5.0; // deg
in.beta_deg = 0.0;
in.p_rps = in.q_rps = in.r_rps = 0.0;
in.el_deg = in.ail_deg = in.rdr_deg = 0.0;
auto out = model.evaluate(in);
// out.cx, out.cy, out.cz, out.cl, out.cm, out.cn
// AD path — identical call, different scalar type:
DAVEMLAeroModel::Inputs<CppAD::AD<double>> in_ad;
// ... fill in_ad ...
auto out_ad = model.evaluate(in_ad);
Lower-level access is available through evaluateRaw, which accepts
and returns a std::unordered_map<std::string, S> keyed by DAVE-ML
variable identifiers.
DAVEMLPropModel
A thin propulsion wrapper around DAVEMLAeroModel for
F16_prop.dml. It converts the model’s native outputs (lbf, ft·lbf)
to SI (N, N·m) before returning them.
#include "Aetherion/Serialization/DAVEML/DAVEMLPropModel.h"
DAVEMLPropModel prop("data/F16_S119_source/F16_prop.dml");
DAVEMLPropModel::Inputs<double> pin;
pin.pwr_pct = 50.0; // military (dry) throttle
pin.alt_ft = 0.0; // sea level
pin.mach = 0.0;
auto pout = prop.evaluate(pin);
// pout.fx_N — forward thrust force [N]
// pout.fy_N, pout.fz_N — lateral/normal thrust [N]
// pout.mx_Nm, pout.my_Nm, pout.mz_Nm — thrust moments [N·m]
// Scalar convenience helper (double only):
double T_lbf = prop.thrustX_lbf(50.0, 0.0, 0.0);
Unit conversion constants:
Native |
SI |
Factor |
|---|---|---|
lbf |
N |
4.448 221 615 260 751 |
ft·lbf |
N·m |
1.355 817 948 329 279 |
DAVEMLControlModel
A double-only wrapper around DAVEMLAeroModel evaluateRaw()
that provides a typed interface for .dml files defining flight
control or GNC laws — specifically F16_control.dml and
F16_gnc.dml.
Unlike DAVEMLAeroModel, the control model is never placed on a
CppAD differentiation tape: control surface commands are computed in
plain double once per integration step (zero-order hold) and then
applied to the vector-field policies before the ODE stepper runs.
#include "Aetherion/Serialization/DAVEML/DAVEMLControlModel.h"
DAVEMLControlModel ctrl("data/F16_S119_source/F16_control.dml");
DAVEMLControlModel::Inputs in;
// Mode flags
in.sasOn = 1.0; in.apOn = 1.0;
// Autopilot commands
in.altCmd_ft = 10113.0; // commanded altitude [ft]
in.keasCmd_kt = 287.81; // commanded EAS [kt]
in.baseChiCmd_deg = 45.0; // commanded course [deg]
// Sensor feedbacks
in.altMsl_ft = 10013.0;
in.Vequiv_kt = 287.98;
in.alpha_deg = 2.65;
in.theta_deg = 2.65;
in.phi_deg = -0.17;
in.qb_rad_s = 0.0;
// (remaining fields default to zero)
DAVEMLControlModel::Outputs out = ctrl.evaluate(in);
// out.el_deg — elevator [deg, TED+]
// out.ail_deg — aileron [deg, LWD+]
// out.rdr_deg — rudder [deg, TEL+]
// out.pwr_pct — throttle [0–100 %]
The Inputs struct covers every <isInput/> variable in both
F16_control.dml and F16_gnc.dml:
Field |
varID |
Description |
|---|---|---|
|
|
Pilot throttle [0, 1]; ignored when |
|
|
Pilot longitudinal stick [−1, +1]; ignored when |
|
|
Pilot lateral stick [−1, +1]; ignored when |
|
|
Pilot rudder pedal [−1, +1]; ignored when |
|
|
Stability-augmentation engage flag (0/1) |
|
|
Autopilot engage flag (0/1; forces SAS on) |
|
|
Commanded altitude [ft] |
|
|
Commanded equivalent airspeed [kt] |
|
|
Commanded ground-track course [deg] |
|
|
Lateral offset from course [ft, +right] |
|
|
Current altitude MSL [ft] |
|
|
Current equivalent airspeed [kt] |
|
|
Angle of attack [deg] |
|
|
Sideslip angle [deg] |
|
|
Roll angle [deg] |
|
|
Pitch angle [deg] |
|
|
Yaw angle [deg] |
|
|
Body roll rate [rad/s] |
|
|
Body pitch rate [rad/s] |
|
|
Body yaw rate [rad/s] |
|
|
Trim throttle fraction (default 0.139 from DML) |
|
|
Trim longitudinal stick fraction (default 0.130 from DML) |
|
|
Ownship latitude [deg] — |
|
|
Ownship longitude [deg] — |
|
|
Navigation mode selector — |
LoadInertiaFromDAVEML
A convenience free function that reads F16_inertia.dml and
returns a populated RigidBody::InertialParameters struct with all
values converted to SI.
#include "Aetherion/Serialization/DAVEML/LoadInertiaFromDAVEML.h"
// Default CG position (35 % MAC):
auto I = LoadInertiaFromDAVEML(
"data/F16_S119_source/F16_inertia.dml");
// Override CG to 30 % MAC (5 % forward of reference):
auto I_fwd = LoadInertiaFromDAVEML(
"data/F16_S119_source/F16_inertia.dml",
{{"CG_PCT_MAC", 30.0}});
The variable-ID-to-struct-member mapping is:
VarID |
Field |
Native units |
Notes |
|---|---|---|---|
|
|
slug |
Total aircraft mass |
|
|
slug·ft² |
Roll moment of inertia |
|
|
slug·ft² |
Pitch moment of inertia |
|
|
slug·ft² |
Yaw moment of inertia |
|
|
slug·ft² |
XZ cross-product of inertia |
|
|
slug·ft² |
XY cross-product (zero for F-16) |
|
|
slug·ft² |
YZ cross-product (zero for F-16) |
|
|
ft |
Longitudinal CG offset from moment reference (calculated) |
|
|
ft |
Lateral CG offset (zero for F-16) |
|
|
ft |
Vertical CG offset (zero for F-16) |
F-16 DAVE-ML Data Files
All five .dml files reside in data/F16_S119_source/. They
implement the F-16 model described in Stevens & Lewis [SL03] as adapted
and corrected by Morelli (NASA TM-2003-212145 [Mo03]), encoded to
DAVE-ML 2.0 conformance. The dataset was obtained from the NASA NESC
Academy Flight Simulation Resources page.
F16_aero.dml — Aerodynamic Coefficients
Purpose. Computes the six non-dimensional aerodynamic coefficients used to form body-axis forces and moments via the standard aerodynamic expansion
where \(\bar{q} = \tfrac{1}{2}\rho V_T^2\) is dynamic pressure.
Reference geometry (embedded in the file):
Wing reference area \(S\) |
300.0 ft² |
27.87 m² |
Mean aerodynamic chord \(\bar{c}\) |
11.32 ft |
3.450 m |
Wing span \(b\) |
30.0 ft |
9.144 m |
Inputs:
VarID |
Units |
Description |
|---|---|---|
|
ft/s |
True airspeed \(V_T\) |
|
deg |
Angle of attack \(\alpha\) |
|
deg |
Angle of sideslip \(\beta\) |
|
rad/s |
Body roll rate |
|
rad/s |
Body pitch rate |
|
rad/s |
Body yaw rate |
|
deg |
Elevator deflection (+ trailing-edge down) |
|
deg |
Aileron deflection (+ right trailing-edge down) |
|
deg |
Rudder deflection (+ trailing-edge left) |
Outputs:
VarID |
Sign |
Description |
|---|---|---|
|
|
Body-axis X-force coefficient |
|
|
Body-axis Y-force coefficient |
|
|
Body-axis Z-force coefficient |
|
|
Rolling-moment coefficient |
|
|
Pitching-moment coefficient |
|
|
Yawing-moment coefficient |
Gridded tables. The database contains multi-dimensional breakpoint sets spanning angle of attack, Mach number, sideslip angle, and control deflection, as defined in Morelli’s adaptation of the Stevens & Lewis nonlinear model. Interpolation is bilinear in each table dimension; extrapolation clamps to the nearest breakpoint.
Embedded check-case (nominal, all rates and deflections zero):
Input |
Value |
|---|---|
|
300 ft/s |
|
5 deg |
All others |
0 |
Output |
Expected value |
Tolerance |
|---|---|---|
|
−0.004 |
±1 × 10⁻⁴ |
|
0.000 |
±1 × 10⁻⁴ |
|
−0.416 |
±1 × 10⁻⁴ |
|
0.000 |
±1 × 10⁻⁴ |
|
−0.005 |
±1 × 10⁻⁴ |
|
0.000 |
±1 × 10⁻⁴ |
Revision history. The file has undergone 14 revisions (A–P, 2003–2013). The most recent, revision P (2013-10-21), corrected variable-name references inside the embedded check-data blocks. Earlier revisions updated the DAVE-ML namespace from 1.9 to 2.0 and corrected minor transcription errors in the breakpoint vectors.
C++ class: DAVEMLAeroModel (see DAVEMLAeroModel).
F16_prop.dml — Propulsion Model
Purpose. Computes engine thrust forces and moments as a function of power lever angle, altitude, and Mach number. The engine is modelled as a GE F100 turbofan with a two-regime thrust law: idle-to-military and military-to-maximum (afterburner).
Inputs:
VarID |
Units |
Description |
|---|---|---|
|
% |
Power lever angle (0 = idle, 50 = military/dry, 100 = max/afterburner) |
|
ft |
Altitude above mean sea level |
|
— |
Flight Mach number |
Outputs:
VarID |
Units |
Description |
|---|---|---|
|
lbf |
Body-axis X thrust (positive forward) |
|
lbf |
Body-axis Y thrust (positive starboard); zero for this model |
|
lbf |
Body-axis Z thrust (positive down); zero for this model |
|
ft·lbf |
Rolling thrust moment (positive right-wing-down) |
|
ft·lbf |
Pitching thrust moment (positive nose-up) |
|
ft·lbf |
Yawing thrust moment (positive nose-right) |
Breakpoints. The thrust tables are indexed by two independent variables:
Variable |
Breakpoints |
|---|---|
Mach |
0.0, 0.2, 0.4, 0.6, 0.8, 1.0 |
Altitude (ft) |
0, 10 000, 20 000, 30 000, 40 000, 50 000 |
Gridded tables (6 × 6 each, row = Mach, column = altitude):
T_IDLE_table — idle thrust (PWR = 0 %):
Mach\Alt: 0 10k 20k 30k 40k 50k [lbf]
0.0: 1 060 670 880 590 960 225
0.2: 635 425 690 445 725 170
0.4: 60 25 345 250 400 - (extrapolated)
…
T_MIL_table — military (dry) thrust (PWR = 50 %):
Mach\Alt: 0 10k 20k 30k 40k 50k [lbf]
0.0: 12 680 9 150 6 200 3 950 2 450 1 400
0.2: 12 680 9 150 6 313 4 113 2 600 1 400
…
T_MAX_table — maximum/afterburner thrust (PWR = 100 %):
Mach\Alt: 0 10k 20k 30k 40k 50k [lbf]
0.0: 20 000 15 000 10 800 7 165 4 000 2 500
0.6: 22 700 16 800 12 150 8 600 5 250 2 900
1.0: 28 885 20 950 14 700 9 500 5 700 3 570
…
Thrust interpolation law. Given the bilinearly interpolated idle, military, and maximum thrust values at the current Mach and altitude:
Check-cases:
PWR (%) |
ALT (ft) |
Mach |
Expected |
Notes |
|---|---|---|---|---|
0 |
0 |
0.0 |
1 060 |
Idle, sea level, static |
50 |
0 |
0.0 |
12 680 |
Military, sea level, static |
100 |
0 |
0.0 |
20 000 |
Max, sea level, static |
100 |
0 |
1.0 |
28 885 |
Max, sea level, Mach 1 |
100 |
50 000 |
1.0 |
5 057 |
Max, high altitude, Mach 1 |
C++ class: DAVEMLPropModel (see DAVEMLPropModel).
F16_inertia.dml — Inertial Properties
Purpose. Defines the mass, rotational inertia tensor, and center-of-gravity offset of the F-16 at a user-specified longitudinal CG position. All values correspond to the nominal clean configuration from Stevens & Lewis [SL03].
Input:
VarID |
Units |
Description |
|---|---|---|
|
% |
Longitudinal CG position as a percentage of the mean aerodynamic chord, measured aft of the leading edge. Default: 35.0 (moment reference center). |
Constant outputs:
VarID |
Value |
Units |
Description |
|---|---|---|---|
|
637.1595 |
slug |
Total aircraft mass (≈ 20 500 lbm ≈ 9 295 kg) |
|
9 496.0 |
slug·ft² |
Roll moment of inertia \(I_{xx}\) |
|
55 814.0 |
slug·ft² |
Pitch moment of inertia \(I_{yy}\) |
|
63 100.0 |
slug·ft² |
Yaw moment of inertia \(I_{zz}\) |
|
982.0 |
slug·ft² |
XZ cross-product of inertia \(I_{xz}\) |
|
0.0 |
slug·ft² |
XY cross-product \(I_{xy}\) (lateral symmetry) |
|
0.0 |
slug·ft² |
YZ cross-product \(I_{yz}\) (lateral symmetry) |
|
0.0 |
ft |
Lateral CG offset (lateral symmetry) |
|
0.0 |
ft |
Vertical CG offset |
Calculated output:
The longitudinal CG offset from the moment reference center (positive aft):
where \(\bar{c} = 11.32\) ft. At the reference CG (35 % MAC) the offset is zero; a CG forward of 35 % MAC produces a positive (aft-of-CG) offset.
Example: CG_PCT_MAC = 30 → DXCG = 0.01 × 11.32 × 5 = 0.566 ft.
C++ function: LoadInertiaFromDAVEML (see LoadInertiaFromDAVEML).
F16_control.dml — Flight Control Laws
Purpose. Implements an F-16 flight control system comprising an inner-loop Stability Augmentation System (SAS) based on a pre-computed LQR gain matrix and an outer-loop autopilot with altitude hold, heading hold, and airspeed command modes.
Design trim condition:
Altitude |
10 013 ft MSL |
True airspeed |
565.7 ft/s (≈ 287.8 kt EAS) |
Mach |
0.525 |
Trim angle of attack \(\alpha_0\) |
2.654 deg |
Trim pitch angle \(\theta_0\) |
2.654 deg |
Throttle trim |
13.90 % |
Longitudinal stick trim |
12.96 % |
Inputs (DAVE-ML varID identifiers as they appear in the file):
varID |
Units |
Description |
|---|---|---|
|
frac [0–1] |
Pilot throttle; zeroed when |
|
frac [−1…+1] |
Pilot longitudinal stick; zeroed when |
|
frac [−1…+1] |
Pilot lateral stick; zeroed when |
|
frac [−1…+1] |
Pilot rudder pedal; zeroed when |
|
bool (0/1) |
Enable stability-augmentation system |
|
bool (0/1) |
Enable autopilot (forces |
|
ft |
Current altitude MSL |
|
nmi/h (kt) |
Current equivalent airspeed |
|
deg |
Angle of attack |
|
deg |
Sideslip angle |
|
deg |
Euler roll, pitch, yaw |
|
rad/s |
Body roll, pitch, yaw rates |
|
ft |
Commanded altitude MSL |
|
nmi/h (kt) |
Commanded equivalent airspeed |
|
ft (+right) |
Lateral offset from desired course |
|
deg |
Desired base-course ground-track angle |
|
frac |
Trim throttle feed-forward (default 0.1390 from file) |
|
frac |
Trim stick feed-forward (default 0.1296 from file) |
Outputs:
varID |
Units |
Description |
|---|---|---|
|
deg |
Elevator deflection command (+ trailing-edge down) |
|
deg |
Aileron deflection command (+ left-wing down) |
|
deg |
Rudder deflection command (+ trailing-edge left) |
|
% |
Power lever angle command (0–100) |
Control law structure.
The SAS inner loop uses pre-computed LQR gain matrices. The longitudinal loop stabilises the state vector \([V, \alpha, q, \theta]^\top\) and drives two outputs (elevator, throttle):
and the lateral-directional loop stabilises \([\phi, \beta, p, r]^\top\) and drives (aileron, rudder):
Outer-loop autopilot logic:
Altitude hold — altitude error feeds a pitch-angle command that is added to the LQR trim pitch demand.
Heading hold — lateral track error and course-angle error are combined into a roll-angle command.
Mode switching —
<piecewise>blocks disable the pilot stick when the autopilot is active (AP_on > 0.5); SAS gains are similarly defeated if bothSAS_onandAP_onare false.
Note. This file defines the control law only; it does not integrate actuator dynamics. Actuator rate and position limits must be applied externally if required.
C++ class: DAVEMLControlModel (see DAVEMLControlModel).
Validation and Test Suite
Unit tests for the DAVE-ML subsystem live in tests/Serialization/ and
are written using the Catch2 framework. All tests are parameterised to
skip gracefully when the data files are not found, so the test suite
remains usable in environments where data/F16_S119_source/ is absent.
test_DAVEMLReader.cpp
All inertia variable IDs are present in the file.
Constant values match Stevens & Lewis Table B.1 (double precision).
getValueSIapplies the correct conversion factors.DXCGevaluates to zero at the reference CG (35 % MAC).setInput("CG_PCT_MAC", 30.0)causesDXCGto re-evaluate to0.566 ftto within machine precision.LoadInertiaFromDAVEMLpopulatesInertialParameterscorrectly.
test_DAVEMLAeroModel.cpp
Reference geometry fields match the file constants.
Nominal check-case (
vt= 300 ft/s,alpha= 5 deg, all others zero) produces the expected six coefficients to within ±10⁻⁴.The same inputs via
CppAD::AD<double>produce values consistent withCppAD::Value()extraction.czis negative for positivealphathroughout the flight envelope (physical sanity).
test_DAVEMLPropModel.cpp
Idle, military, and maximum check-case thrust values match the table to within ±0.5 lbf.
Intermediate power settings interpolate monotonically between the regime endpoints.
High-altitude, high-Mach point (PWR = 100 %, ALT = 50 000 ft, Mach = 1.0) returns 5 057 lbf.
CppAD::AD<double>path returns values consistent with the double path.Thrust is non-decreasing in
PWRat any fixed (ALT, Mach) point.