Input Files

The basic input file for Pylot is a JSON object describing the simulation parameters, control inputs, and aircraft initial state. A separate JSON object is used to specify the aerodynamic and mass properties of the aircraft. Examples of both of these files can be found in the examples/ directory.

JSON Format

The basic structure of a JSON object is a set of key-value pairs, analogous to a Python dictionary. Examples can be found in the examples/ directory. The following sections describe the structure of the JSON objects used to interface with Pylot. Only one JSON object is specified per .json file. When using the JSON objects, only the simulation object is passed to Pylot. Pylot will automatically locate the aircraft object specified in the simulation object.

Units

Pylot allows the user to specify the units for each value if they desire. For float values, this is done by making the value a list where the first element is the actual value and the second element is a string specifying the units. For example:

"area" : [6.75, "ft^2"]

For vector inputs, such as position and velocity, the units are simply appended to the vector:

"velocity" : [100.0, 13.0, 0.0, "ft/s"]

For array inputs, such as a density profile or chord distribution, the units are appended as another row in the array:

"rho" : [[0.0, 1.225],
         [2000.0, 1.0066],
         [4000.0, 0.81935],
         ["m", "kg/m^3"]]

When specifying column units in files, these are also appended as another row:

# File: density_profile.csv
0.0, 1.225,
2000.0, 1.0066,
4000.0, 0.81935,
"m", "kg/m^3"

The following measurements can be defined with the accompanying units:

Measurement Acceptable Units
Position/displacement/length: "ft", "m", "in", "cm"
Area: "ft^2", "m^2"
Velocity: "ft/s", "m/s", "mph", "kph", "kn"
Angular deflection/position: "deg", "rad"
Angular rate: "deg/s", "rad/s"
Density: "slug/ft^3", "kg/m^3"
Weight/Force: "lbf", "N"
Moment: "ft lbf", "Nm"
Mass Moment of Inertia "slug ft^2", "kg m^2"
Angular Momentum "slug ft^2/s", "kg m^2/s"

Note the carat is required in units containing powers. Otherwise, Pylot will not recognize the unit specification.

Except for angular measurements, the first unit listed is the default for “English” units. The second is the default for “SI”. For angular measurements of state and control deflections, as well as airframe geometry, the default is always degrees. For airfoil parameters, measurements may only be expressed in radians. When specifying units in an array and one of the measurements is dimensionless (e.g. span fraction), “-“ should be used. Any results generated by Pylot will be output in the default unit for the given system, regardless of how units were specified for the inputs.

Simulation Object

The following are keys which can be specified in the simulation JSON object. NOTE: all keys not marked as optional are required. Key names typed in all capitals between carats (e.g. <KEY_VALUE>) are to be deterimined by the user.

“tag” : string, optional

A note on the specific input. Does not affect execution.

“simulation” : dict

Defines simulation parameters.

“real_time” : boolean, optional

Whether the physics should be solved in real time. If true, the physics will be solved at as high of a rate as the CPU can handle. Defaults to true.

“timestep” : float, optional

Timestep used in the physics if not set to solve in real time (note that “real_time” defaults to true). Defaults to 0.05 s.

“start_time” : float, optional

Time index at which to start the simulation. Defaults to 0.0 s.

“final_time” : float, optional

Time index at which to stop the simulation. Defaults to infinity, meaning the simulator will run indefinitely.

“quit_on_crash” : boolean, optional

Whether the simulator should exit if the aircraft origin goes below the ground. Has no effect if the graphics are turned off. Defaults to True.

“enable_graphics” : boolean, optional

Whether to render a visual display of the aircraft in a simulated environment. Defaults to false.

“simple_graphics” : boolean, optional

If this is set to true, nonessential graphics objects will not be loaded. This can speed up loading. Defaults to false.

“target_framerate” : int, optional

Desired number of graphics updates per second. Max is 60. The graphics will update no faster than the value specified here. Defaults to 30.

“enable_interface” : boolean, optional

Whether to allow the user to affect the simulation during execution (pause, quit, toggle views). Defaults to the same value as “enable_graphics”.

“screen_resolution” : list, optional

Desired resolution of the simulator window in pixels. Note the window cannot be resized manually. Defaults to [1800, 900].

“integrator” : str, optional

Numerical integration scheme to use in the simulator. Can be “RK4” (4th-order Runge-Kutta) or “ABM4” (4th-order Adams-Bashforth-Moulton). Defaults to “RK4”. We recommend not using the “ABM4” integrator unless you understand the implications of using that method.

“units” : string, optional

Specifies the unit system to be used for inputs and outputs. Can be “SI” or “English”. Any units not explicitly defined for each value in the input objects will be assumed to be the default unit for that measurement in the system specified here. Defaults to “English”.

“atmosphere” : dict, optional Specifies the state of the atmosphere the aircraft exists in.

“density” : float or string, optional

If a float, the atmospheric density is assumed constant at this value. The following standard profiles can also be specified:

“standard”

Defaults to density at sea-level.

“aircraft” : dict

Describes the aircraft being simulated.

“name” : string

Name of the aircraft.

“file” : string

Path to file containing the JSON object describing the aircraft.

“trim” : dict, optional

If this key is specified, the simulator will start the aircraft trimmed in a climbing turn described by the following keys. If this key is not specified, “initial_state” or “landed” must be alternately specified.

“velocity” : float

Initial airspeed.

“position” : vector

Initial position in Earth-fixed coordinates.

“climb_angle” : float, optional

Initial climb angle in degrees. Defaults to 0.0.

“bank_angle” : float, optional

Initial bank angle in degrees. Defaults to 0.0.

“heading” : float, optional

Initial heading in degrees. Defaults to 0.0.

“trim_controls” : list, optional

Names of the controls used to trim the aircraft. Exactly 4 controls must be specified here. If the aircraft only has 4 controls, this is optional. If the aircraft has fewer than 4 controls, trim will not be possible. If the aircraft has more than 4 controls, the remaining controls are assumed to remain at a fixed value, given in “fixed_controls”.

“fixed_controls” : dict, optional

Specifies the fixed values of the controls not used to trim the aircraft.

“<CONTROL_NAME>” : float, optional

Trim setting of this specific control. Defaults to 0.0.

“verbose” : boolean, optional

Whether to output intermediate guesses at each step of the iterative trim algorithm. Helps inform the user as to the progress/convergence of trim. Defaults to false.

“initial_state” : dict, optional

If this key is specified, the simulator will start the aircraft in the given state. No trimming will be performed. If this key is not specified, “trim” or “landed” must be alternately specified.

“position” : vector

Position of the origin of the aircraft’s body-fixed coordinate system in earth-fixed coordinates.

“velocity” : vector

Body-fixed velocity components.

“orientation” : vector, optional

Orientation of the aircraft, going from earth-fixed frame to body-fixed frame. If this is a 3-element vector it is assumed the ZYX Euler angle formulation is used, arranged as [bank, elevation, heading]. If this is a 4-element vector it is assumed the quaternion formulation is used where the first element is the scalar (i.e. [e0, ex, ey, ez]). Defaults to [1.0, 0.0, 0.0, 0.0], which will align the body-fixed frame with the earth-fixed frame.

“angular_rates” : vector, optional

Angular rates of the aircraft in body-fixed coordinates, corresponding to p, q, and r. Defaults to [0.0, 0.0, 0.0].

“control_state” : dict, optional

Describes the control settings. The number and names of controls are arbitrary and may be specified by the user.

“<CONTROL_NAME>” : float, optional

Control setting. Defaults to neutral setting.

“landed” : dict, optional

If this key is specified, the simulator will start the aircraft landed at the given position and heading. If this key is not specified, “initial_state” or “landed” must be alternately specified.

“position” : list, optional

Initial position of the aircraft. Any altitude value given will be overridden to place the aircraft on the ground. Defaults to [0.0, 0.0, 0.0].

“heading” : float, optional

Initial heading angle in degrees. Defaults to 0.0.

“elastic_launch” : dict, optional

If this key is specified, the simulator will start the aircraft in the given state with an elastic attached between the hook on the aircraft and the given anchor position. THis elastic will then tow the aircraft into the air, given the parameters are properly specified. The full state of the aircraft can be specified as well to allow the aircraft to be launched from various orientations and initial velocities. The elastic will stop exerting a force on the aircraft as soon as it would exert a force in the negative body-x direction (i.e. the elastic is pulled off the hook).

“position” : vector

Position of the origin of the aircraft’s body-fixed coordinate system in earth-fixed coordinates.

“velocity” : vector, optional

Body-fixed velocity components. Defaults to [0.0, 0.0, 0.0].

“orientation” : vector, optional

Orientation of the aircraft, going from earth-fixed frame to body-fixed frame. If this is a 3-element vector it is assumed the ZYX Euler angle formulation is used (i.e. [psi, theta, phi]). If this is a 4-element vector it is assumed the quaternion formulation is used where the first element is the scalar (i.e. [e0, ex, ey, ez]). Defaults to [1.0, 0.0, 0.0, 0.0], which will align the body- fixed frame with the earth-fixed frame.

“angular_rates” : vector, optional

Angular rates of the aircraft in body-fixed coordinates, corresponding to p, q, and r. Defaults to [0.0, 0.0, 0.0].

“control_state” : dict, optional

Describes the control settings. The number and names of controls are arbitrary and may be specified by the user.

“<CONTROL_NAME>” : float, optional

Control setting. Defaults to neutral setting.

“anchor_position” : list, optional

Where the end of the elastic is anchored to the Earth. Will determine in which direction the aircraft is launched. Defaults to [0.0, 0.0, 0.0].

“unstretched_length” : float, optional

Unstretched length of the elastic. If the elastic is calculated to be shorter than this length, no force will be applied. Defaults to 0.0.

“stiffness” : float

Spring constant of the elastic.

“launch_time” : float, optional

Time in the simulation at which the airplane will be released and the elastic will be allowed to pull on it. Defaults to 0.0.

“state_output” : string, optional

If specified, the simulator will write the 13 element state vector of the aircraft to this file at each time step. THIS WILL OVERWRITE ANY EXISTING FILE OF THE SAME NAME. Defaults to no output.

“control_output” : string, optional

If specified, the simulator will write the control inputs to this csv file at each time step. THIS WILL OVERWRITE ANY EXISTING FILE OF THE SAME NAME. Must be “.csv”. Can only be used if “column_index” is specified for each control (see [Aircraft Object](Aircraft Object)). Defaults to no output.

“controller” : string

Specifies how the aircraft is to be controlled. Can be “joystick”, “keyboard”, a filename, or “user-defined”.

Basic, real-time, direct user control is chosen by specifying “joystick” or “keyboard”. This allows for basic 4-channel control where the user selects the mapping between the input axes and the controls. For more information on this, see User Interface.

The aircraft can also be controlled using a pre-defined control sequence. This sequence should be stored in a .csv file, the name of which is given here. Note, the filename given here must include “.csv”, otherwise it will not be recognized by Pylot. The controls should be formatted in columns where the first column is the time index and each successive column corresponds the control settings. The order of the columns is determined by the “column_index” key in the “controls” object within the “aircraft” object. For example, if the aircraft has a control called “flaps” which was given the “column_index” of 1, then the second column in the csv file given here will be used as the “flaps” control setting. Angular deflections should be listed in degrees; other control settings should vary from 0.0 to 1.0. Using this type of control, the simulation will quit when the end of the control file is reached.

The aircraft can also be controlled using a user-defined controller, allowing for complex control algorithms, more channels, differential thrust, and more! This is done by specifying “user-defined” for this key. Specific details for implementing this type of control can be found under Building Custom Controllers.

Aircraft Object

Describes an aircraft. The aerodynamics of the aircraft may be determined in one of two ways. The first is using a model of linearized aerodynamic coefficients, as described by Phillips (Mechanics of Flight, 2nd ed., pp. 1067-8). The second is using MachUpX, a Python implementation of general numerical lifting-line theory. The method is specified using the “aero_model” key. If the linearized model is to be used, then the “coefficients” key must be specified. Else, “wings” must be specified. All other keys are the same between the two methods. Examples of both can be found in the examples/ directory. Unless specifically noted otherwise, all locations are given relative to the aircraft origin, rather than the center of gravity.

“units” : string, optional

Specifies the unit system to be used when importing the aircraft object. Can be “SI” or “English”. Any units not explicitly defined for each value in the input objects will be assumed to be the default unit for that measurement in the system specified here. Defaults to “English”.

“CG” : vector, optional

Location of the aircraft’s center of gravity in body-fixed coordinates. Defaults to [0.0, 0.0, 0.0], as the origin of the body-fixed coordinate system is typically the aircraft’s center of gravity.

“weight” : float

Weight of the aircraft.

“inertia” : dict”

Describes the mass moments of inertia of the aircraft. These are assumed to be taken about the center of gravity.

“Ixx” : float

Mass moment of inertia parallel to the body x-axis.

“Iyy” : float

Mass moment of inertia parallel to the body y-axis.

“Izz” : float

Mass moment of inertia parallel to the body z-axis.

“Ixy” : float

Product of inertia parallel to the body x and y-axes.

“Ixz” : float

Product of inertia parallel to the body x and z-axes.

“Iyz” : float

Product of inertia parallel to the body y and z-axes.

“angular_momentum” : vector, optional

Angular momentum vector of aircraft conponents relative to the body-fixed frame. This is typically generated by spinning powerplant components. Defaults to [0.0, 0.0, 0.0].

“reference” : dict, optional

Specifies the reference lengths and areas used to redimensionalize coefficients. If the aircraft is to be modelled using MachUpX, all or none of these may be specified. If the aircraft is to be modelled using a set of linearized coefficients, at least two of these must be given, from which the third will be calculated, if not provided. It is assumed area = longitudinal_length * lateral_length.

“area” : float

The reference area.

“longitudinal_length” : float

Longitudinal reference length.

“lateral_length” : float

Lateral reference length.

“controls” : dict, optional

Defines the control inputs of the aircraft. If the joystick or keyboard are selected for user input, at most 4 controls may be listed here. For information on using the joystick/keyboard, see User Interface.

If a user-defined controller or time-sequence control file are being used, the number and names of inputs are arbitrary and may be specified by the user. A simple aircraft, such as a chuck glider may have no controls, whereas a more complex aircraft may have controls for aileron, elevator, rudder, and multiple flaps. Defining the controls here can be thought of as deciding which control knobs/switches/sticks you want to make available to the pilot.

“<CONTROL_INPUT_NAME>” : dict

“is_symmetric” : bool, optional

Specifies whether this control causes symmetric or asymmetric control surface deflections (e.g. for a typical aircraft, the elevator control causes symmetric deflections whereas the aileron causes asymmetric deflections). This is only required when MachUpX is used as the aerodynamic model.

“max_deflection” : float, optional

Specifies the maximum control deflection in degrees. If this is not specified, the control is assumed to vary from 0.0 to 1.0, as with a throttle control. Only required if the built-in keyboard or joystick controller is being used. Does not affect other controllers.

“input_axis” : int, optional

Specifies which input axis maps to this control. The input axes are as follows
Index Joystick Keyboard
0 roll LEFT-RIGHT
1 pitch UP-DOWN
2 yaw A-D
3 throttle W-S
Only required if the built-in keyboard or joystick controller is being used. Does not affect other controllers.

“column_index” : int, optional

Specifies the column of the time-sequence control input file that corresponds to this control. Note that zero-based indexing is used and the zeroth column is always the time index (i.e. the first column after the time indices is denoted 1). Only required if a time sequence control input is used. Does not affect other controllers

“trim_tab” : bool, optional

Specifies whether this control is tied to the trim tab. Only required if the built-in joystick controller is being used. Does not affect other controllers. Defaults to False.

“engines” : dict, optional

Specifies the propulsion system(s) of the aircraft. The aircraft may have any number of engines. If more than one is desired, the following set of keys is simply repeated. Can also be used to simulate external stores and nacelles.

“<ENGINE_NAME>” : dict

Describes a single engine. The thrust produced is assumed to be modelled by the function

T = t*(d/d0)^a*(T0+T1*V+T2*V^2)

where T is the thrust, t is the control setting, d is the air density at the current altitude, d0 is the air density at sea level, V is the airspeed, and a, T0, T1, and T2 are engine-specific parameters. This object can also be used to simulate the effect of nacelles and external stores, simply by specifying a drag coefficient and reference area, but not thrust parameters.

“position” : vector, optional

Location of the engine in body-fixed coordinates. Defaults to [0.0, 0.0, 0.0].

“direction” : vector, optional

Direction of the thrust force vector exerted by the engine on the aircraft in body-fixed coordinates. Defaults to [1.0, 0.0, 0.0].

“T0” : float, optional

Corresponds to T0 in the above thrust equation. Represents full-throttle, static thrust. Defaults to 0.0.

“T1” : float, optional

Corresponds to T1 in the above thrust equation. Represents the linear change in thrust produced due to airspeed for the same throttle setting and density. This value is typically negative. Defaults to 0.0.

“T2” : float, optional

Corresponds to T2 in the above thrust equation. Represents the quadratic change in thrust produced due to airspeed for the same throttle setting and density. Defaults to 0.0.

“a” : float, optional

Corresponds to a in the above thrust equation. Represents level of nonlinearity in the change in thrust due to changes in atmospheric density. Defaults to 1.0.

“control” : string or int, optional

Name of the control which governs the throttle setting for this engine. If the default joystick/keyboard is used, all engines are governed by the throttle control and this parameter is ignored. If a user-defined controller is used, this is the name of the control setting for this engine given by the controller. If a time-sequence control file is used, this is the column index of the control setting for this engine (as with “input_index” above).

“CD” : float, optional

Coefficient of drag for the powerplant. This should be a positive value. Defaults to 0.0.

“area” : float, optional

Reference area for redimensionalizing the drag coefficient. Defaults to 1.0.

“landing_gear” : dict, optional

Specifies the ground contact point(s) of the aircraft. The aircraft may have any number of landing gear. If more than one is desired, the following set of keys is simply repeated. Can also be used to simulate external stores and nacelles.

“<LANDING_GEAR_NAME>” : dict

Describes a single landing gear fixture (i.e. the back right wheel).

“position” : vector

Location of the tip of the landing gear in body-fixed coordinates.

“stiffness” : float

Spring constant of the gear.

“damping” : float, optional

Damping constant of the gear. Defaults to 0.0.

“rolling_friction_coef” : float, optional

The resistance of the gear to rolling (i.e. travel in the axis of the gear) as a fraction of the normal force applied. If the gear is not a wheel, this should be the same as or close to “sliding_friction_coef”. Defaults to 0.0.

“sliding_friction_coef” : float, optional

The resistance of the gear to sliding (i.e. travel perpendicular the axis of the gear) as a fraction of the normal force applied. Defaults to 0.0.

“steering_control” : string or int, optional

Name of the control which steers this landing gear. If not specified, the landing gear is assumed fixed.

“steering_reversed” : bool, optional

Whether the angle of the gear is mirror that of the control. For example, a tail dragger would not have reversed steering, since the wheel/skid track the rudder. But for an aircraft with a nose wheel, the steering should be reversed. Defaults to False.

“CD” : float, optional

Coefficient of drag for the gear. This should be a positive value. Defaults to 0.0.

“area” : float, optional

Reference area for redimensionalizing the drag coefficient. Defaults to 1.0.

“launch_hook_position” : list, optional

Position of the launching hook on the aircraft. Defaults to [0.0, 0.0, 0.0].

“graphics” : dict, optional

Optionally provides graphics objects for rendering the aircraft in the simulator. If nothing is specified here, the aircraft will be rendered as a single-engine Cessna, unless the MachUpX aerodynamic model is being used.

If MachUpX is being used and nothing is specified here, Pylot will attempt to use MachUpX to automatically generate an obj file of the aircraft. For this to work, the FreeCAD python libraries must be configured on your computer. instructions for doing this can be found in the MachUpX documentation.

“obj_file” : str, optional

Object file for rendering the aircraft.

“texture_file” : str, optional

Texture file for coloring the skin of the aircraft.

“vertex_shader_file” : str, optional

File describing the response of vertices to light.

“face_shader_file” : str, optional

File describing the response of faces to light.

“aero_model” : dict

Describes how the aerodynamics are to be modelled within the simulator.

“type” : string

May be “linearized_coefficients” to select a linearized model of aerodynamic coefficients or “MachUpX” to select a full numerical lifting-line solution.

“solver” : string, optional

May be “linear” or “nonlinear”. Specifies whether the linear approximation or full nonlinear correction should be used in computing the lifting-line solution. Has no effect on computation if “type” is specified as “linearized_coefficients”. Defaults to “linear”.

“stall_angle_of_attack” : float, optional

Angle of attack in degrees at which the flight surfaces stall. At this angle of attack, the aerodynamics will transition to a flat-plate model. This is not meant to be accurate for the specific airframe being modelled, but rather to give the user a sense of the onset of stall. Defaults to 15.

“stall_sideslip_angle” : float, optional

Sideslip angle in degrees at which the flight surfaces stall. At this angle of attack, the aerodynamics will transition to a flat-plate model. This is not meant to be accurate for the specific airframe being modelled, but rather to give the user a sense of the onset of stall. Defaults to 1000 (no stall).

At this point, the structure of the airplane object for the two types of aerodynamic models diverges.

Model of Linearized Coefficients

As mentioned above, this model relies on a set of equations given by Phillips. The inputs to this set of equations are the aerodynamic coefficients described below. These are all contained within a key called “coefficients”.

“coefficients” : dict

Aerodynamic coefficients and dreivatives describing the behavior of the aircraft at small perturbations from the given reference state. Note that aerodymanic moments and damping derivatives are defined relative to the body-fixed axes, rather than stability axes. All coefficients use the traditional definition of dynamic pressure:

q = 0.5*rho*V^2

For a full explanation and derivation of the aerodynamic model used here, see Hunsaker and Thurgood, “Aerodynamic Model and Trim Algorithm for Fixed-Wing Aircraft”, AIAA SciTech Conference, 2021 (not yet published). The damping derivatives are fully nondimensional. It is assumed that the moment coefficients are defined relative to the aircraft center of gravity (this will automatically be the case if the model was generated by MachUpX).

“CL0” : float

Lift coefficient at zero angle of attack, sideslip, angular rates, and control deflections.

“CL,a” : float

Lift slope.

“CL,a_hat” : float

Derivative of lift with respect to vertical acceleration.

“CL,q_bar” : float

Derivative of lift coefficient with respect to pitching rate.

“CD0” : float

Drag coefficient at zero-lift

“CD1” : float

Linear coefficient of quadratic drag polar with respect to lift (i.e. CD=CD0+CD1*CL+CD2*CL*CL).

“CD2” : float

Quadratic coefficient of quadratic drag polar with respect to lift (i.e. CD=CD0+CD1*CL+CD2*CL*CL).

“CD3” : float

Sets the proportionality of drag coefficient to the sideforce coefficient squared.

“CD,q_bar” : float

Derivative of drag coefficient with respect to pitching rate.

“CD,a_hat” : float

Derivative of drag coefficient with respect to vertical acceleration.

“CS,b” : float

Derivative of sideforce coefficient with respect to sideslip angle.

“CS,b_hat” : float

Derivative of sideforce coefficient with respect to lateral acceleration.

“CS,p_bar” : float

Derivative of sideforce coefficient with respect to roll rate.

“CS,r_bar” : float

Derivative of sideforce coefficient with respect to yawing rate.

“Cl,b” : float

Roll stability derivative.

“Cl,b_hat” : float

Derivative of rolling moment coefficient with respect to lateral acceleration.

“Cl,p_bar” : float

Roll damping derivative.

“Cl,r_bar” : float

Derivative of rolling moment coefficient with respect to yaw rate.

“Cm0” : float

Pitching moment coefficient at zero angle of attack, sideslip, angular rates, and control deflection.

“Cm,a” : float

Pitching moment slope.

“Cm,a_hat” : float

Derivative of pitching moment coefficient with respect to vertical acceleration.

“Cm,q_bar” : float

Pitch damping derivative.

“Cn,b” : float

Yaw stability derivative.

“Cn,b_hat” : float

Derivative of yawing moment coefficient with respect to lateral acceleration.

“Cn,p_bar” : float

Derivative of yawing moment coefficient with respect to roll rate.

“Cn,r_bar” : float

Yaw damping derivative.

“<CONTROL_NAME>” : dict

Describes the change in aerodynamic coefficients with respect to deflections of this control. This parameter is repeated for as many controls are specified in the “controls” parameter of the aircraft. Derivatives should be defined with respect to a change in deflection in radians, as is standard. The aerodynamic coefficients that may be affected by a control are “CL”, “CD”, “CS”, “Cl”, “Cm”, and “Cn”. Any coefficients not listed are assumed to not be affected by that specific control.

MachUpX Model

This method relies on the implementation of general, numerical lifting-line, MachUpX, developed by the USU AeroLab (website). MachUpX relies on definitions of the aircraft geometry and wing section properties. The last two keys required within the aircraft object are “airfoils” and “wings”. Descriptions of these keys can be found in the MachUpX documentation and the user should follow these instructions. The aircraft object for Pylot has been designed with MachUpX in mind and should be natively compatible with MachUpX (i.e. you should be able to pass your airplane object file to MachUpX and MachUpX will be able to parse it).