Shipped FMUs and Their Ports
Aetherion ships three FMI 2.0 Co-Simulation FMUs. Each is a self-contained
archive carrying its own Radau IIA RKMK integrator, its DAVE-ML data files under
resources/, and a modelDescription.xml naming every port below.
The general FMI background — model exchange versus co-simulation, and how an SVA wrench model maps onto FMU variables — is in the FMU appendix. This page is the concrete interface contract: the port names a consumer binds against.
Model |
Role |
Physics |
|---|---|---|
|
Truth plant |
F-16 6-DoF, DAVE-ML aero and propulsion decks, J2 gravity, trim solved at initialisation. NASA TM-2015-218675 scenarios 11–16. |
|
Controller |
LQR SAS inner loop with altitude, airspeed and heading hold, from the
NASA LaRC |
|
Truth plant |
Two-stage rocket 6-DoF with variable inertia, propellant burn and stage separation. NASA TM-2015-218675 scenario 17. |
The two plant FMUs declare canGetAndSetFMUstate and
canSerializeFMUstate, so a master may checkpoint a step and roll back to
it; the autopilot keeps no state beyond its registered variables and declares
neither. A checkpoint is the model’s state record together with the FMU’s
clock and, for F16Plant, the position of the turbulence noise stream, so a
rolled-back run reproduces the original one gust for gust. (Until v0.17.2
the clock was not part of it and the first fmi2DoStep after a rollback was
rejected, and the noise stream was not, so a rolled-back turbulent run diverged
at once – pre-DOI audit findings F05 and F06.) test_fmu4cpp_state pins the
clock contract in process; src/FMU/F16Plant/test_f16plant.py drives the
packaged FMU through FMPy and is part of CTest whenever a Python with fmpy
is found at configure time.
Pinning a version floor
Each modelDescription.xml carries the Aetherion release it was built from in
the FMI version attribute of fmiModelDescription:
<fmiModelDescription fmiVersion="2.0"
modelName="F16Plant"
version="0.14.0"
generationTool="fmu4cpp v0.14.0">
</fmiModelDescription>
A consumer enforcing a minimum Aetherion version should read that attribute out
of the located .fmu archive, rather than trusting a CMake package config.
The failure mode worth guarding against is a stale build tree: a package config
reports the version of the source it was configured from, while the .fmu on
disk may still carry older ports. The attribute above is written by the same
build step that packages the archive, so the two cannot disagree.
Note
Do not read generationTool for this. It names the exporting library
(fmu4cpp), not the model, even though the two version numbers happen to
coincide because fmu4cpp is built as part of this project.
specificForce_{x,y,z}_m_s2 on F16Plant and TwoStageRocket first ship
in 0.14.0. circumnavigate, cmd.circlePoleSW, fb.lat_deg and
fb.lon_deg on F16Autopilot first ship in 0.15.0; the same release
is the first in which F16Plant trims against the level-flight apparent
weight and starts wings-level (see F16Plant). The environment
ports — wind.*, atm.* on both plants and turb.*, out.wind_*,
out.gust_* on F16Plant — first ship in 0.16.0 (see
Environment on the Vehicle Policies); at their defaults every earlier output is
unchanged bit for bit.
Conventions common to all ports
Naming. Ports are grouped by a dotted prefix: out. for outputs, ctrl.
for control-surface signals, cmd. and fb. for autopilot commands and
feedback, solver. and stg2. for tuning. Parameters carry no prefix.
Body axes. x forward, y right, z down — the standard aircraft
body frame, matching the sign convention of the DAVE-ML force and moment
coefficients. All aero_F*, aero_M* and specificForce_* ports share these
axes.
Navigation frame. out.v_{north,east,down}_m_s is NED, Earth-relative;
out.{yaw,pitch,roll}_rad are ZYX Euler angles for the body → NED rotation.
Body rates. out.{p,q,r}_rad_s are with respect to the ECI frame, not
the local level frame. The difference is Earth’s rotation rate, 7.29 × 10⁻⁵
rad/s, which matters for a strapdown gyro model and — because it is steady — for
aerodynamic damping: F16Plant evaluates its damping derivatives at the rate
relative to the air mass, \(\omega_{B/\mathrm{ECEF}}\), not at these
outputs.
Units are SI in the out. block, with the unit carried in the port name
suffix. Initial-condition parameters keep the units of the source NASA scenario
definition (feet, knots, degrees) and are converted internally.
Parameter timing. Ports with variability fixed must be written before
fmi2ExitInitializationMode; that call is what runs the trim solve and builds
the initial state. Only stg2.ignition_time_s is tunable and may be
changed between steps.
Communication step. Each FMU integrates internally with the master’s
communication step unless solver.max_step_s is set, in which case the step is
subdivided. For F16Plant at the scenario-11 trim point, communication steps
from 0.01 s to 0.5 s give trajectories identical to plotting precision; at 1 s
the Radau step visibly degrades, and derived quantities such as out.specificForce_*
degrade with it. If outputs are only needed at a coarse rate, set
solver.max_step_s rather than slowing the master.
Specific force: out.specificForce_*
F16Plant and TwoStageRocket publish body-frame specific force at the
centre of gravity:
the non-gravitational acceleration an ideal accelerometer at the CG would sense. This is the truth input an IMU sensor model consumes.
The name reads as an acceleration, so the semantics are worth stating plainly:
Gravitation is excluded entirely. A vehicle in free fall reads exactly zero, not \(-g\). The implementation sums the non-gravitational wrench forces and never consults a gravity policy, so there is no gravity term to get wrong.
out.g_m_s2— a mass-attraction magnitude, J2 included — plays no part in it.It is not \(R\,(\mathbf{a}_I - \mathbf{g})\) with plumb-bob gravity. The centrifugal term is something a real strapdown accelerometer genuinely senses; subtracting it would double-count.
The reference point is the CG, where \(\mathbf{F} = m\,\mathbf{a}\) holds exactly. This is true even for
TwoStageRocket, which integrates its equations of motion about the moment reference centreDXCGmetres aft of the CG: the origin choice affects moment bookkeeping, not the force sum.An accelerometer mounted a lever arm \(\mathbf{r}\) off the CG also senses the transport terms \(\dot{\boldsymbol{\omega}} \times \mathbf{r} + \boldsymbol{\omega} \times (\boldsymbol{\omega} \times \mathbf{r})\). These are not applied. They need \(\dot{\boldsymbol{\omega}}\), which the plant has and a consumer does not, so off-CG support — if ever wanted — belongs on the FMU side of the boundary.
The thrust axis comes from the vehicle’s own propulsion policy. A consumer
forming specific force from out.thrust_N and out.mass_kg instead has to
assume where the engine points; out.specificForce_* removes that assumption, which
matters for any vehicle with an installation angle or more than one engine.
Sanity checks that catch the gravity-inclusion error, in decreasing sharpness:
a gravity-only vehicle reads identically zero; a drag-only vehicle reads
\(-\mathrm{drag}/m\), antiparallel to airspeed; a trimmed aircraft in level
flight reads \(|\mathbf{f}_B| \approx g\) with a negative z channel, since
lift acts up and body z points down. These are exercised in
tests/Simulation/test_BodySpecificForce.cpp.
F16Plant
F-16 six-degree-of-freedom plant. fmi2ExitInitializationMode loads the
DAVE-ML decks, runs a CppAD-backed Newton trim solve at the requested flight
condition, and seeds the integration state from the trim point; the elevator and
throttle inputs are initialised to their trim values, so an open-loop run with
untouched inputs starts in trim.
The trim balances the apparent weight of level flight, not the static one:
J2 attraction at lat0_deg / alt0_ft, less the centripetal acceleration
of a constant-altitude path over the rotating Earth at vt0_fps along
heading0_deg. The relief is 0.42 % of the weight at the scenario-11
defaults and 1.34 % at the Mach 2 scenario-12 point, and it depends on heading:
an eastbound trim carries less lift than a westbound one. See
Aetherion/FlightDynamics/Trim/TrimWeight.h.
Parameters
Port |
Unit |
Default |
Meaning |
|---|---|---|---|
|
ft/s |
565.685 |
True airspeed at the trim point. |
|
ft |
10013 |
Altitude above MSL at the trim point. |
|
deg |
36.0192 |
Initial geodetic latitude (Kitty Hawk, NC). |
|
deg |
−75.6744 |
Initial geodetic longitude. |
|
deg |
45 |
Initial heading, azimuth from North in NED. |
|
deg |
0 |
Initial pose roll angle. Wings-level, as NASA reference simulations 04 and 05; up to 0.14.1 the default was −0.172°, the initial bank of simulation 02. |
|
ft |
1.132 |
CG aft of the aerodynamic reference centre, (35 % − 25 %) × c̄. Feeds both the trim solve and the aero AC → CG pitch-moment transfer. |
|
– |
1e-12 |
Radau IIA Newton absolute residual tolerance. |
|
– |
1e-10 |
Radau IIA Newton relative residual tolerance. |
|
s |
0 |
Maximum internal sub-step. 0 uses the communication step directly. |
|
m/s |
0 |
Steady wind, NED north component at the initial position (positive = blowing northward). Fixed in NED at the start point and converted to ECEF once. The trim is air-relative; the initial ground velocity is the trim airspeed along the heading plus the wind. |
|
m/s |
0 |
Steady wind, NED east component. |
|
m/s |
0 |
Steady wind, NED down component. |
|
m/s |
0 |
Dryden RMS gust along body x. All three sigmas zero = turbulence off. MIL-F-8785C spectra, see Environment on the Vehicle Policies. |
|
m/s |
0 |
Dryden RMS gust along body y. |
|
m/s |
0 |
Dryden RMS gust along body z (down). |
|
m |
533.4 |
Dryden longitudinal scale length (MIL-F-8785C definition; 1750 ft above 2000 ft). |
|
m |
533.4 |
Dryden lateral scale length. |
|
m |
533.4 |
Dryden vertical scale length. |
|
– |
1 |
Seed of the turbulence noise stream, integer-valued. The same seed and parameters reproduce the same gust record. The filters are stepped once per integrator sub-step at the current airspeed; keep the step fixed (the FMU warns once if it varies). |
|
K |
0 |
ISA temperature deviation, added uniformly to the US1976 profile.
Density, pressure and speed of sound are re-integrated hydrostatically
for the forces, the trim and the |
|
Pa |
0 |
Sea-level pressure minus 101 325 Pa (a QNH offset). A barometer that inverts the standard ISA reads about 84 m high per −1000 Pa at low altitude. |
Inputs
Port |
Unit |
Meaning |
|---|---|---|
|
deg |
Elevator deflection. Seeded to the trim value at initialisation. |
|
deg |
Aileron deflection. |
|
deg |
Rudder deflection. |
|
% |
Throttle, 0–100. Seeded to the trim value at initialisation. |
Outputs
Port |
Unit |
Meaning |
|---|---|---|
|
m |
Altitude above MSL (WGS-84 geodetic). |
|
deg |
Geodetic latitude. |
|
deg |
Geodetic longitude. |
|
rad |
ZYX Euler yaw, body → NED. |
|
rad |
ZYX Euler pitch, body → NED. |
|
rad |
ZYX Euler roll, body → NED. |
|
rad/s |
Body roll rate with respect to ECI. |
|
rad/s |
Body pitch rate with respect to ECI. |
|
rad/s |
Body yaw rate with respect to ECI. |
|
m/s |
NED north velocity, Earth-relative. |
|
m/s |
NED east velocity. |
|
m/s |
NED down velocity. |
|
deg |
Angle of attack, from atmosphere-relative body velocity. |
|
deg |
Sideslip angle. |
|
– |
Mach number. |
|
Pa |
Dynamic pressure. |
|
m/s |
True airspeed. |
|
N |
Aerodynamic body-X force. |
|
N |
Aerodynamic body-Y force. |
|
N |
Aerodynamic body-Z force. |
|
N·m |
Aerodynamic roll moment. |
|
N·m |
Aerodynamic pitch moment, reported about the AC (25 % MAC) to match the DAVE-ML output convention, not about the CG the EOM uses. |
|
N·m |
Aerodynamic yaw moment. |
|
kg/m³ |
Air density, US 1976 standard atmosphere. |
|
K |
Ambient static temperature. |
|
Pa |
Ambient static pressure. |
|
m/s |
Speed of sound. |
|
m/s² |
Local gravitational acceleration magnitude — mass attraction only, J2 included, no centrifugal term. Do not use it to reconstruct specific force; see Specific force: out.specificForce_*. |
|
m/s² |
Body-X specific force at the CG. See Specific force: out.specificForce_*. |
|
m/s² |
Body-Y specific force at the CG. |
|
m/s² |
Body-Z specific force at the CG. Negative in level flight. |
|
N |
Net propulsive force along body +X. The F-16 engine deck carries no body-Y or body-Z thrust component, so this is the whole thrust vector. |
|
kg |
Vehicle mass. Constant for this vehicle; published for debugging and
for symmetry with |
|
m/s |
Total wind at the CG, NED north: the steady wind plus the gust rotated body → NED. |
|
m/s |
Total wind at the CG, NED east. |
|
m/s |
Total wind at the CG, NED down. |
|
m/s |
Dryden gust velocity along body x. |
|
m/s |
Dryden gust velocity along body y. |
|
m/s |
Dryden gust velocity along body z (down). |
|
rad/s |
Angular velocity of the gust field about body x. The aero model sees
|
|
rad/s |
Angular velocity of the gust field about body y. |
|
rad/s |
Angular velocity of the gust field about body z. |
F16Autopilot
LQR stability-augmentation inner loop with altitude, airspeed and heading hold,
driving F16Plant in closed loop. The control law is purely algebraic, so
the FMU carries no state.
Wiring is direct: every fb.* input is fed from the identically named
F16Plant output, and the four ctrl.* outputs go back to the plant’s
ctrl.* inputs.
Every input starts at the scenario-11 trim point, so the initial outputs are at
trim when the master sets nothing. Values written during initialisation mode
are honoured — up to 0.14.1 the FMU re-seeded its inputs on
fmi2ExitInitializationMode, which silently replaced, for instance, a
10 000 ft altitude command with 10 013 ft unless the master wrote it again
before the first step.
Control law selection
The archive carries two NASA control laws. F16_gnc.dml is
F16_control.dml with a navigator in front of the heading loop: the course
and lateral-offset commands stop being inputs and are computed from the ownship
position so as to fly a 3 nmi counter-clockwise circle. The DAVE-ML model has
no “navigator off” state — its switch only picks which circle — so the choice
between the two laws is a parameter, fixed at initialisation.
|
Control law |
Steering |
|---|---|---|
|
|
|
|
|
Navigator, from |
The closed-loop scenarios 15 and 16 are exercised against the NASA reference
trajectories in src/FMU/F16Autopilot/test_f16autopilot.py.
Parameters
Port |
Unit |
Default |
Meaning |
|---|---|---|---|
|
Boolean |
false |
Load |
Inputs
Port |
Unit |
Default |
Meaning |
|---|---|---|---|
|
ft |
10013 |
Commanded altitude. |
|
kt |
287.809 |
Commanded equivalent airspeed. |
|
deg |
45 |
Commanded course angle. A step on this port is the Atmos_13.3 heading change. |
|
ft |
0 |
Commanded lateral track offset. |
|
– |
0 |
Navigator select, the DAVE-ML |
|
m |
3051.96 |
Altitude feedback, from |
|
m/s |
172.42 |
True airspeed feedback. |
|
kg/m³ |
0.9042 |
Air density feedback, used for the TAS → EAS conversion. |
|
deg |
2.6538 |
Angle-of-attack feedback. |
|
deg |
0 |
Sideslip feedback. |
|
rad |
0 |
Roll-attitude feedback. |
|
rad |
0.0463 |
Pitch-attitude feedback. |
|
rad |
0.7854 |
Yaw-attitude feedback. |
|
rad/s |
0 |
Roll-rate feedback. |
|
rad/s |
0 |
Pitch-rate feedback. |
|
rad/s |
0 |
Yaw-rate feedback. |
|
deg |
36.0192 |
Geodetic latitude feedback, from |
|
deg |
−75.6744 |
Geodetic longitude feedback, from |
Outputs
Port |
Unit |
Meaning |
|---|---|---|
|
deg |
Commanded elevator deflection. |
|
deg |
Commanded aileron deflection. |
|
deg |
Commanded rudder deflection. |
|
% |
Commanded throttle, 0–100. |
TwoStageRocket
Two-stage rocket ascent with a zero-order-hold per-step update of thrust, propellant flow and spatial inertia, plus a discontinuous mass drop at stage separation. There are no control inputs: the vehicle flies an open-loop gravity turn from the initial pitch attitude.
Parameters
Port |
Unit |
Default |
Meaning |
|---|---|---|---|
|
deg |
0 |
Launch geodetic latitude. |
|
deg |
0 |
Launch geodetic longitude. |
|
m |
0 |
Launch altitude above MSL. |
|
deg |
90 |
Initial heading, azimuth from North. |
|
deg |
55.22 |
Initial pitch, nose-up from horizontal. |
|
deg |
0 |
Initial roll angle. |
|
m/s |
0 |
Initial NED north velocity. |
|
m/s |
0 |
Initial NED east velocity. |
|
m/s |
0 |
Initial NED down velocity. |
|
s |
0 |
Maximum internal sub-step. 0 uses the communication step directly. |
|
s |
0 |
Tunable. Absolute simulation time gating stage-2 ignition; 0 ignites immediately once stage 1 has separated. Set to (end time − S2 burn duration) to reproduce the NASA TM coast-then-fire sequencing. |
|
m/s |
0 |
Steady wind, NED north component at the launch point (positive =
blowing northward), converted to ECEF once. The aero is air-relative;
|
|
m/s |
0 |
Steady wind, NED east component. |
|
m/s |
0 |
Steady wind, NED down component. |
|
K |
0 |
ISA temperature deviation, as on |
|
Pa |
0 |
Sea-level pressure minus 101 325 Pa. |
Outputs
Ports shared with F16Plant — out.alt_m, out.lat_deg, out.lon_deg,
out.g_m_s2, the three Euler angles, the three body rates, the three NED
velocities, out.a_m_s, out.rho_kg_m3, out.P_Pa, out.T_K, the six
out.aero_* forces and moments, out.mach, out.qbar_Pa, out.vt_m_s
and the three out.specificForce_* channels — carry the same meaning and units as in
F16Plant, with two differences: out.aero_My_Nm is reported about
the MRC rather than an aerodynamic centre, and this vehicle’s mass genuinely
varies. The ports below are specific to this model.
Port |
Unit |
Meaning |
|---|---|---|
|
m/s |
Altitude rate, \(\dot{h} = -v_\mathrm{down}\). |
|
N |
Total axial thrust along body +x, zero-order held over the step just taken. |
|
kg/s |
Propellant consumption rate, positive while burning. |
|
kg |
Vehicle mass. Drops by 35 000 kg at stage separation. |
|
kg |
Cumulative stage-1 propellant consumed. |
|
kg |
Cumulative stage-2 propellant consumed. |
|
Boolean |
True once the stage-1 dry mass has been jettisoned. Discrete. |
Note
On the single step in which separation occurs, out.thrust_N reports the
zero-order-hold thrust that was actually applied over that step — stage 1 —
while out.mass_kg has already dropped to the post-separation value.
out.specificForce_* deliberately does not pair those two: it uses the
post-separation thrust, which is what matches the post-separation mass, so it
carries no spurious stage-1-thrust-over-stage-2-mass spike. Away from that
one step the two agree exactly.