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 determined 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.“machupX_solver_params” : dict, optional
Specifies arguments for the solver in MachUpX. The available parameters are the same as found in the MachUpX documentation under “solver”.“stall_model” : string, optional
Defines the type of stall model to be used in correcting adjusting the aerodynamic coefficients as the aircraft approaches stall. May be “none” or “exponential”. “none” means no stall corrections will be made. “exponential” uses an exponential blending function with a modified flat plate model. This stall model is not meant to be accurate for the specific airframe but rather gives the user a sense of the onset of stall. Defaults to “exponential”.“stall_angle_of_attack” : float, optional
Angle of attack in degrees at which the flight surfaces stall. Required for “exponential” stall model. Defaults to 15.“stall_sideslip_angle” : float, optional
Sideslip angle in degrees at which the flight surfaces stall. Required for “exponential” stall model. Defaults to 200.
Beyond 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).