version: X-Plane 11

Joystick Datarefs

Below you’ll find a reference for the meaning of the joystick axis assignments values from the dataref sim/joystick/joystick_axis_assignments.

Assigned Value Meaning
0 None
1 Pitch
2 Roll
3 Yaw
4 Throttle
5 Collective
6 Left toe brake
7 Right toe brake
8 Prop
9 Mixture
10 Carb heat
11 Flaps
12 Thrust vector
13 Wing sweep
14 Speedbrakes
15 Displacement
16 Reverse
17 Elevator trim
18 Aileron trim
19 Rudder trim
20 Throttle 1
21 Throttle 2
22 Throttle 3
23 Throttle 4
24 Prop 1
25 Prop 2
26 Prop 3
27 Prop 4
28 Mixture 1
29 Mixture 2
30 Mixture 3
31 Mixture 4
32 Reverse 1
33 Reverse 2
34 Reverse 3
35 Reverse 4
36 Landing gear
37 Nosewheel tiller
38 Backup throttle
39 Cowl flaps
40 [Old, unused]
41 View left/right
42 View up/down
43 View zoom
44 Camera left/right
45 Camera up/down
46 Camera zoom
47 Gun/bomb left/right
48 Gun/bomb up/down
49 VR Touchpad X
50 VR Touchpad Y
51 VR Trigger
52 Custom command(s)
53 Throttle 5
54 Throttle 6
55 Throttle 7
56 Throttle 8
57 Cowl flaps 1
58 Cowl flaps 2
59 Cowl flaps 3
60 Cowl flaps 4
61 Cowl flaps 5
62 Cowl flaps 6
63 Cowl flaps 7
64 Cowl flaps 8
65 Throttle Vertical
66 Throttle Horizontal
Leave a comment

Overriding TCAS and providing traffic information

With X-Plane 11.50, plugins that display traffic in X-Plane, whether auto-generated or from an online multiplayer network, have to use the XPLMInstance API to draw these aircraft in X-Plane’s world. Drawing with XPLMInstance places the 3D object in the world, but does not actually tell X-Plane or other interested third parties, such as EFBs, about the existence of another aircraft in the airspace around the user. Various techniques have been used by authors, which are commonly known as “TCAS hack” that involve taking control of X-Plane AI aircraft, but not drawing them, by inhibiting drawing from a 3D callback. Some plugins also get around this by providing “invisible” aircraft to be moved by X-Plane. With Vulkan and Metal, the 3D callback that was previously used to change the AI plane count for the “TCAS hack” no longer works. It is therefore necessary to adopt the new TCAS override, which provides an official and compatible way to notify both X-Plane and third-party plugins of traffic.

override_TCAS: Existing datarefs made useful

The new supported and recommended variant of the “TCAS hack”, now called “TCAS override”, relies entirely on datarefs and existing XPLM functions, so it requires no SDK update. It uses the following, well known datarefs, simply expanded in array size:

sim/operation/override/override_TCAS int
sim/cockpit2/tcas/indicators/relative_bearing_degs float[64]
sim/cockpit2/tcas/indicators/relative_distance_mtrs float[64]
sim/cockpit2/tcas/indicators/relative_altitude_mtrs float[64]

Using the new TCAS override requires that the plugin does the following:

  1. Acquire the AI planes with XPLMAcquirePlanes – This should be done with a null pointer for the desired model paths, so it is fast. You should only call this when you are ready to supply planes right now. That is, an online network plugin should not acquire planes before it is actually connected to the network! Since acquiring planes with no model load is fast, this should be deferred until the user is actually connected to a server.
  2. Activate TCAS override by setting the sim/operation/override/override_TCAS dataref to 1. Only the plugin that has successfully acquired the AI planes can set this dataref!
  3. Tell X-Plane how many planes you want to fill in with TCAS override (up to 63) by calling XPLMSetActiveAircraftCount.
    Note that you will get to update all 19 multiplayer planes then, even if the user has a lower AI aircraft count setting. It is not necessary for the user to increase AI aircraft count or provide special models to be loaded as AI. In fact, TCAS override works even if the user has 0 AI planes configured.
  4. Assign each target a unique 24bit number between 1 and 16777215 and set it to sim/cockpit2/tcas/targets/modeS_id[N]. This will be the mode S ID of the target and is used to track your target even if you move it between slots.
  5. Tell X-Plane about the traffic targets by writing to the existing relative_bearing_degs, relative_distance_mtrs and relative_altitude_mtrs datarefs or to the new sim/cockpit2/tcas/targets/position/double/ datarefs. Only the plugin who has acquired the AI planes can write these datarefs!
  6. Optional: Fill in more information than just the position into the new sim/cockpit2/tcas/targets/position/ datarefs. This way, you can keep X-Plane and other plugins updated about the state of up to 63 other planes.
  7. Optional: Provide a map layer to the X-Plane map with icons for the planes you are providing. If you are doing that, set sim/operation/override/override_multiplayer_map_layer to 1 to stop X-Plane from drawing its own icons.
  8. If you have fewer targets than anticipated, you can simply stop writing the positional data to a target slot. X-Plane will forget the target (and forget its unique ID). There is no need to set a lower XPLMSetActiveAircraftCount because X-Plane will drop TCAS targets that haven’t been updated in 10 frames.
  9. When you are done providing traffic (the user has disconnected from the online network) set the override_TCAS dataref to 0 and call XPLMReleasePlanes. This will re-enable X-Plane traffic or allow other plugins, like a real world traffic provider, to then take over traffic from you. This will also re-enable the X-Plane default map behavior, so you will want to tear down your custom map layer as well!

This will allow X-Plane to display your traffic on X-Plane’s default navdisplays, the G1000, the map and IOS console and also disseminate the information via ADS-B output to external EFB apps like FlyQ and ForeFlight.

For full source code, check out the code example!

Plugins and cockpit displays using existing datarefs

Existing aircraft most likely require no changes to pick up 19 traffic targets injected by TCAS override, since they are synced to the multiplayer datarefs.

Many third party aircraft use the absolute position datarefs to find out about traffic around them and show it on their navdisplay. These datarefs

sim/multiplayer/position/planeN_x double N = 1..20
sim/multiplayer/position/planeN_y double N = 1..20
sim/multiplayer/position/planeN_z double N = 1..20

will be updated by X-Plane, when a traffic plugin is using TCAS override, along with the derived velocity vector for ADS-B out.
XPLMCountAircraft will return the number of TCAS targets actively updated in the last 10 frames by the plugin owning the override, regardless of the user setting for AI aircraft. Therefore, all instruments can display all aircraft that are being written to, without requiring the user to change any settings.

The same number is also available from the new dataref

sim/cockpit2/tcas/indicators/tcas_num_acf int

Third-party aircraft are also free to adopt the relative position datarefs to display traffic around them, since they now will be filled in with useful information by the traffic provider.

New datarefs

New plugins can use the new set of datarefs that is not limited to 19 planes, but instead supports 63 aircraft currently. It is advisable to query the array size of sim/cockpit2/tcas/targets/modeS_id to find out how many targets the current version of X-Plane supports. Note that index 0 is reserved for the user plane.

X-Plane does not infer any information from the mode-S ID, nor does it make any guarantees about the user plane’s mode-S ID, other than that it is unique in the session, and that it fits in 24bits. Traffic providers can set the MSB of the 32bit integer (i.e. the_modeS_id | 0x80000000) to indicate their 24bit ID is a “real” ID that corresponds to the actual airframe they are providing. You would do this if you are replaying real-life ADS-B data. By default, the MSB should not be set: in that case you must not use the mode-S ID to look up aircraft type, airline, livery or other such information. The user airplane is simply assigned a unique ID at random, so it might well be that the user is flying a 172 with a mode-S code that in the real world belongs to a 747. Only if your plugin has reliable information about the mode-S code of its traffic (replaying real world ADS-B data), you can assign real IDs rather than randomized ones and set the MSB. You must not assume other plugins or X-Plane assign IDs matching real world aircraft databases when they don’t set the MSB.

You can optionally also provide a 7-byte flight ID (tailnumber or flightnumber) for each target which is used to identify the target on the X-Plane map.

Which of the positional datarefs are writable depends on how you update your targets:

  • In relative mode (writing the relative bearing, distance and altitude) X-Plane will calculate the world position, derive the velocity, and estimate the body angles for you. This is useful if all you care for is a blip on the display with roughly accurate data. Do not write to the xyz positions in that case!
  • In absolute mode (writing the x/y/z coordinates) your plugin should also write the vx, vz, vy velocities and roll/pitch/yaw body angles, as X-Plane will not estimate them. X-Plane will then fill in the relative bearing and distance information for you, and derive hpath and vpath from your cartesian velocities. X-Plane will also fill in the lat/lon/elevation global coordinates. This is useful for applications that know a lot about the state of the other plane, such as when it comes from an online network. Do not write to the bearing/distance/relativealtitude datarefs in this case!

Relative vs absolute updating is a per-target property, so your plugin can update different targets in different modes if required. The last dataref you write wins.

Coordinate transformation

X-Plane will do the conversion from Cartesian coordinates to latitude, longitude and elevation for you.

To convert from Cartesian x/y/z to relative bearings, use a polar coordinate transformation, with

sim/flightmodel/position/local_x and local_z

as the origin and

sim/flightmodel/position/true_psi

as the polar axis, with the relative bearing counting clockwise as is usual in all cockpit indicators. Note that we use elevation (sim/flightmodel/position/elevation and sim/multiplayer/position/planeN_el) and not local_y to calculate the altitude difference! This is important for targets that are far away from the coordinate origin, as the earth curves away under the local tangent plane and elevation will be higher than y.

Map icons

X-Plane will update the map showing other planes. However, it cannot know what the appropriate icon for the plane type you are supplying would be. If you want to make meaningful icons, you can supply your own map layer and tell X-Plane to stop drawing generic icons by setting sim/operation/override/override_multiplayer_map_layer to 1. This override is automatically cancelled when you give up TCAS_override, so don’t forget to remove your map layer when you’re done providing traffic!

Plugin coordination

Since only one plugin can be providing the other planes at a time, it is important that plugins play nice with each other when it comes to deciding who gets to control the aircraft in the world. This is facilitated by the new plugin message XPLM_MSG_RELEASE_PLANES that is sent to a plugin owning the planes when another plugin requests them.

Playing nice starts with choosing the right time to call XPLMAcquirePlanes:
Do not call XPLMAcquirePlanes because you might at some point in the future maybe connect to some network. Do call XPLMAcquirePlanes only when the user actually decided to connect to the network.

Do register a callback with XPLMAcquirePlanes so that X-Plane can call you when another plugin gives up control over the planes.

Playing nicely requires receiving the XPLM_MSG_RELEASE_PLANES message and acting accordingly:
Do give up the planes if you are providing synthetic traffic and an online network now wants the planes. Traffic flown by humans should always take precedence over generated traffic. Do call XPLMReleasePlanes when appropriate.
Do not give up the planes to a synthetic traffic provider if you are currently connected to online flying, obviously.

Finally, give up the planes as soon as you no longer have a source. That is, if the user disconnects from their online flying network, do call XPLMReleasePlanes to give synthetic traffic providers a chance to provide AI traffic again.

For a full example, refer to the example plugin.

List of datarefs

sim/cockpit2/tcas/indicators/relative_bearing_degs	float[64]	y	degrees	Relative bearing of each other plane in degrees for TCAS - relative to sim/flightmodel/position/true_psi not ground track or anything else
sim/cockpit2/tcas/indicators/relative_distance_mtrs	float[64]	y	meters	Distance to each other plane in meters for TCAS
sim/cockpit2/tcas/indicators/relative_altitude_mtrs	float[64]	y	meters	Relative altitude (positive means above us) for TCAS
sim/cockpit2/tcas/indicators/tcas_alert	int	y	boolean	True if a TCAS alert is currently issued.
sim/cockpit2/tcas/indicators/tcas_num_acf	int	n	integer	If TCAS is not overriden by plgugin, returns the number of planes in X-Plane, which might be under plugin control or X-Plane control. If TCAS is overriden, returns how many targets are actually being written to with the override. These are not necessarily consecutive entries in the TCAS arrays. 
sim/cockpit2/tcas/targets/modeS_id	int[64]	y	integer	24bit (0-16777215 or 0 - 0xFFFFFF) unique ID of the airframe. This is also known as the ADS-B "hexcode".
sim/cockpit2/tcas/targets/modeC_code	int[64]	y	integer	Mode C transponder code 0000 to 7777. This is not really an integer, this is an octal number.
sim/cockpit2/tcas/targets/flight_id	byte[512]	y	string	7 character Flight ID, terminated by 0 byte. ICAO flightplan item 7.
sim/cockpit2/tcas/targets/icao_type	byte[512]	y	string	7 character ICAO code, terminated by 0 byte. C172, B738, etc... see https://www.icao.int/publications/DOC8643/Pages/Search.aspx
sim/cockpit2/tcas/targets/position/x	float[64]	y	meter	local X coordinate, meter. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/y	float[64]	y	meter	local Y coordinate, meter. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/z	float[64]	y	meter	local Z coordinate, meter. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/lat	float[64]	n	degrees	global coordinate, degrees.
sim/cockpit2/tcas/targets/position/lon	float[64]	n	degrees	global coordinate, degrees.
sim/cockpit2/tcas/targets/position/ele	float[64]	n	meter	global coordinate, meter.
sim/cockpit2/tcas/targets/position/vx	float[64]	y	meter/s	local X velocity. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/vy	float[64]	y	meter/s	local Y velocity. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/vz	float[64]	y	meter/s	local Z velocity. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/vertical_speed	float[64]	y	feet/min	absolute vertical speed feet per minute. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/hpath	float[64]	n	degrees	ground track in true degrees. Derived from velocity vector.
sim/cockpit2/tcas/targets/position/vpath	float[64]	n	degrees	flight path angle in degrees. Derived from velocity vector.
sim/cockpit2/tcas/targets/position/V_msc	float[64]	n	meter/s	total true speed, norm of local velocity vector. That means it includes vertical speed!
sim/cockpit2/tcas/targets/position/psi	float[64]	y	degrees	true heading orientation. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/the	float[64]	y	degrees	pitch angle. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/phi	float[64]	y	degrees	bank angle. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/weight_on_wheels	int[64]	y	boolean	ground/flight logic. Writeable only when override_TCAS is set.
sim/cockpit2/tcas/targets/position/gear_deploy	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_gear_deploy[0]
sim/cockpit2/tcas/targets/position/flap_ratio	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_flap_ratio
sim/cockpit2/tcas/targets/position/flap_ratio2	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_flap_ratio2
sim/cockpit2/tcas/targets/position/speedbrake_ratio	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_speedbrake_ratio
sim/cockpit2/tcas/targets/position/slat_ratio	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_slat_ratio
sim/cockpit2/tcas/targets/position/wing_sweep	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_wing_sweep
sim/cockpit2/tcas/targets/position/throttle	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_throttle[0]
sim/cockpit2/tcas/targets/position/yolk_pitch	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_yolk_pitch 
sim/cockpit2/tcas/targets/position/yolk_roll	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_yolk_roll
sim/cockpit2/tcas/targets/position/yolk_yaw	float[64]	y	ratio	mirror of sim/multiplayer/position/planeN_yolk_yaw
sim/cockpit2/tcas/targets/position/lights	int[64]	y	bitfield	beacon=1, land=2, nav=4, strobe=8, taxi=16
sim/cockpit2/tcas/targets/position/double/plane1_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane1_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane1_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane2_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane2_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane2_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane3_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane3_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane3_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane4_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane4_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane4_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane5_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane5_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane5_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane6_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane6_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane6_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane7_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane7_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane7_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane8_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane8_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane8_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane9_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane9_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane9_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane10_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane10_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane10_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane11_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane11_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane11_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane12_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane12_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane12_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane13_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane13_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane13_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane14_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane14_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane14_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane15_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane15_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane15_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane16_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane16_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane16_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane17_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane17_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane17_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane18_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane18_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane18_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane19_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane19_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane19_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane20_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane20_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane20_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane21_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane21_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane21_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane22_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane22_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane22_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane23_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane23_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane23_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane24_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane24_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane24_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane25_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane25_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane25_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane26_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane26_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane26_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane27_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane27_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane27_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane28_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane28_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane28_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane29_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane29_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane29_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane30_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane30_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane30_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane31_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane31_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane31_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane32_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane32_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane32_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane33_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane33_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane33_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane34_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane34_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane34_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane35_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane35_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane35_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane36_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane36_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane36_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane37_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane37_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane37_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane38_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane38_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane38_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane39_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane39_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane39_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane40_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane40_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane40_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane41_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane41_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane41_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane42_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane42_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane42_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane43_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane43_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane43_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane44_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane44_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane44_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane45_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane45_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane45_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane46_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane46_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane46_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane47_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane47_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane47_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane48_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane48_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane48_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane49_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane49_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane49_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane50_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane50_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane50_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane51_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane51_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane51_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane52_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane52_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane52_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane53_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane53_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane53_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane54_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane54_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane54_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane55_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane55_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane55_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane56_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane56_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane56_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane57_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane57_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane57_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane58_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane58_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane58_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane59_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane59_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane59_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane60_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane60_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane60_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane61_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane61_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane61_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane62_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane62_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane62_ele	double	n	meter	global coordinate, meter. 
sim/cockpit2/tcas/targets/position/double/plane63_lat	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane63_lon	double	n	degrees	global coordinate, degrees
sim/cockpit2/tcas/targets/position/double/plane63_ele	double	n	meter	global coordinate, meter. 
Comments Off on Overriding TCAS and providing traffic information

Plugin Guidance for OpenGL Drawing

This document provides guidelines for using OpenGL to draw from X-Plane plugins running inside X-Plane’s process.

While X-Plane can use OpenGL, Vulkan, or Metal drivers to render to a graphics card, plugin-drawing is supported only via OpenGL. OpenGL is not the fastest or most modern API, but it does provide a robust way to draw in 3-d without exposing complicated and error prone implementation details like memory management, resource barriers, or concurrency, making it an appropriate choice for custom user interface and custom aircraft glass displays.

General principles

In our work with third party add-ons, we see three kinds of add-on behavior that cause almost all of the compatibility problems, bugs, performance loss, and crashes. Here are three guiding principles for interacting with X-Plane.

Do Not Lie to X-Plane

If your add-on uses plugin APIs for purposes other than their intended uses, you may have performance or compatibility problems later. Avoid things like using drawing callbacks for non-drawing purposes, using 3-d drawing callbacks for 2-d drawing, or non-window callbacks for UI.

If your add-on lies to X-Plane about your intentions, X-Plane no longer has optimal situational awareness and can no longer run plugins in an optimal way. Achieving the best possible performance is only possible if everyone plays fair and by the rules.

Minimize XPLM and OpenGL Use

X-Plane users care deeply about performance; minimize your use of OpenGL and the XPLM to minimize your add-on’s negative impact on framerate. Only perform operations that are necessary, and cache values retrieved through XPLM API, except for OpenGL resources, to be reused later if possible. When drawing, avoid repeated OpenGL state changes and adopt modern OpenGL techniques where feasible. Using shaders and vertex buffer objects for static geometry is much faster than using pre OpenGL 2.0 immediate mode rendering.

Do Not Use Undocumented Behavior

Do not use the SDK in ways that are not covered by the documentation; undocumented use of the SDK can appear to work but destabilize the sim or interfere with other add-ons, or can break in a future X-Plane update. If you are not sure from the documentation whether something is legal, ask us!

Drawing Callbacks

Plugins receive an opportunity to draw inside X-Plane via drawing callbacks; the following section provides guidelines for when and how to use drawing callbacks correctly.

Register only the drawing callbacks that you need at the time you need them to do actual drawing! Dispatching any drawing callback requires a not-insignificant CPU time overhead and requires heavy synchronization in the case of Vulkan and Metal, both of which are completely wasted if no drawing actually happens.

Use Drawing Callbacks Only for Drawing

Use drawing callbacks only for drawing, not for updating simulation state, bookkeeping, network IO, etc. Drawing callbacks can be called multiple or zero times per frame based on the user’s monitor configuration, so add-ons that use drawing callbacks for other purposes both hurt performance and may not work correctly in some situations.

Use Real Windows for UI

Using real windows and the XPLM 3.x window API (XPLMCreateWindowEx, etc.) is highly recommended over using legacy draw callbacks. This provides the sim with the most situational awareness to improve dispatching and compositing of plugin windows. The real window API also provides correct UI interaction for floating windows and focus.

Use Drawing Callbacks for Panels

The panel and gauge drawing callbacks let you draw under or on top of the 2-d and 3-d panel. Be sure to check the draw-type datarefs for the callbacks – see Datarefs for Panel Drawing below. Your panel draw callback can be called for both the albedo layer and the emissive layer of the panel separately; make sure your code draws the appropriate content for each.

Use a Flight Loop Callback for Off-Screen FBOs

Use a flight loop callback to draw into your offscreen framebuffer. When you do this, X-Plane will not have set an FBO up for you to draw into, so you will bypass the overhead of synchronizing with our drawing on the GPU.

Use XPLMInstance and Particles for 3-d Drawing Where Possible

Avoid using the 3D drawing callbacks unless absolutely necessary. Dispatching 3D drawing callbacks comes with potentially negative performance impacts and isn’t necessary most of the time.

The best interface for drawing “stuff” in the 3-d world is the XPLM instancing API to draw objects into the world or tie particle effects to your custom datarefs in order to create custom effects. The instancing API is straightforward to use, available since X-Plane 11.0, and replaces XPLMDrawObject and XPLMDrawAircraft.

See also the Plugin Compatibility Guide for X-Plane 11.50.

Use a 2-d Callback for “Coach Marks”

When drawing overlays or other kinds of scene annotations, a 2D drawing callback is much better suited than a 3D drawing callback. You can use the projection matrices provided by X-Plane to efficiently transform 3D coordinates to 2D screen coordinates.

A sample of this can be found here: https://developer.x-plane.com/code-sample/coachmarks/

See also the Plugin Compatibility Guide for X-Plane 11.50.

Use a Panel Texture to Draw “on” the Aircraft

If you need to draw onto the aircraft, e.g. to simulate damage to the fuselage, rain on a wind-screen, or a livery change, you can map a panel texture to that section of the aircraft and then use a panel drawing callback for drawing. This can be used for dynamic decals or other effects, for example, that would otherwise require complicated use of the 3D drawing callbacks.

Panel texturing is available for all parts of the aircraft, not just the cockpit object, but is more expensive than using disk-based textures – use it only where the dynamic effect is absolutely necessary.

If your add-on needs more panel texture space, you can use panel regions to get access to four separate dynamic textures.

Use the New 3-d Callback on Windows Only When Necessary

Using the new 3D drawing callback under Vulkan is not recommended unless absolutely necessary! It comes with a lot of gotchas and caveats and is intended only for add ons that truly need to do custom scenery drawing in 3D, like weather add ons. Before using the 3D drawing callback, evaluate all alternatives to see if there isn’t a better solution for what you are trying to achieve.

The new 3-d drawing callback works with OpenGL and Vulkan but not Metal; when running under Vulkan, a number of aspects of the drawing environment will be different:

  • The depth buffer will be in reverse-float-Z, not standard integer format; the clip control will be DirectX style and the depth compare function will be inverted.
  • The origin of the frame buffer may be inverted.

See the appendix for datarefs that let a plugin dynamically detect these conditions.

See also: Plugin Compatibility Guide for X-Plane 11.50.

OpenGL State Management

Your plugin shares an OpenGL context with other plugins and sometimes with X-Plane itself; this section provides guidance on how to change OpenGL state correctly.

Don’t Call glGetXXXX

Do not use glGet to retrieve OpenGL state. This usually results in some kind of stall for the driver and has detrimental effects on performance. For custom state management it is usually much better to potentially set OpenGL state again and then cache that known value for future state changes.

X-Plane provides access to the transform stack (upon entrance to your call stack) and viewports via datarefs, as well as the currently bound FBO (although ideally this should not be changed).

If you need a state that isn’t covered here, please contact us – there may be a different way to approach your rendering code.

Call glGetError in Debug Builds Only

Please call glGetError in debug builds and don’t ship code that breaks the OpenGL state machine. Your plugin should never execute code that leaves an OpenGL error in place.

When shipping your plugin, do notcall glGetError as it can hurt performance. A simple macro that wraps glGetError() calls and makes it easy to toggle usually works best and makes it easy to ship the version of code you want.

If your add-on creates framebuffers, please do check for framebuffer completeness once when you create the FBO; your add-on should not create and destroy FBOs on a regular basis.

Use the XPLM APIs to Manage State Where Possible

The XPLM APIs provide a number of calls to manage state; where these functions exist, please use them; they will avoid setting state multiple times.

  • XPLMSetGraphicsState controls blend enable, fixed function alpha test enable, depth mask and depth test enable, fixed function fog and lighting, and fixed function texture enabling.
  • XPLMBindTexture2d controls the 2-d texture binding point.
  • XPLMGenerateTextureIDs wraps texture object generation.

Restore all Other State Except Attributes When Done

Any OpenGL state other than vertex attributes that is not covered by the APIs above must be restored to its initial state when your callback completes. This includes:

  • Unbinding any bound shaders, VAOs, VBOs and non-2d textures to 0.
  • Restoring the drawing array state (only the fixed function vertex array should be enabled).

You do not need to reset the client array pointerstate, nor should you assume upon entrance to a callback that it contains anything sane.

Restore the Current FBO By Dataref

If you must render to an offscreen FBO in a draw callback for some reason, you must restore the currently active FBO before returning from it. Don’t call glGet() to retrieve it, instead use the sim/graphics/view/current_gl_fbo dataref to figure out what FBO to restore.

XPLMDrawString and Friends May Change State

XPLMDrawString and the other API drawing calls can change all of the states mentioned above; while you do not need to clean up after them, do not assume your own state setup is correct after they have been called.

Illegal OpenGL Usage

The following techniques are not allowed from plugins running inside X-Plane.

Do Not Draw from Non-Drawing Callbacks

Non-drawing callbacks aren’t necessarily dispatched in a way that supports drawing. Drawing in a non drawing callback will lead to undefined behavior with regards to your own rendering and the effects on the rest of the sim.

Do Not Mutate X-Plane’s OpenGL Resources

Resources obtained through the XPLM API should be seen as immutable, with the exception of the contentsof the active FBO during draw callbacks. Attempting to change any internal X-Plane resources can lead to heavily decreased performance or have other unexpected side effects, like crashing.

Do Not Locate and Use Private X-Plane OpenGL Resources

Resources not exposed through the XPLM API are not fair game for use. These resources aren’t guaranteed to remain stable between or even within X-Plane runs or future versions. X-Plane is assumed to be the only consumer of these resources and will not attempt synchronizing with plugins when modifying them.

Do Not Hold on to X-Plane OpenGL Resources

While it might be tempting to hold on to OpenGL resources obtained in previous draw callbacks and then reuse them in other callbacks, doing so can have disastrous consequences. This is especially true under Vulkan and Metal, where resources require special synchronization. If missing, this can lead to driver or system crashes and desktop freezes.

Do Not Change State to Affect X-Plane

Attempting to change OpenGL state to trick X-Plane into rendering differently is heavily discouraged. This can lead to X-Plane doing improper bookkeeping of its own state, which can lead to heavily impacted performance. This is also not guaranteed to work between versions or even between runs and can break at any time.

Performance

This section contains performance guidelines for OpenGL plugins.

Pre-Initialize Your Add-on

Perform heavy initialization at aircraft load or flight start time. At runtime, a plugin should be able to just work without lazily initializing any state or computing expensive look up tables. The goal should be to never add unpredictable latency to the frame time.

Do Less

Avoid unnecessary work; preload resources and precompute expensive results.

Follow standard OpenGL performance practices:

  • Move computing work from fragment to vertex shaders.
  • Reduce API calls that change state.
  • Reduce the number of draw calls by merging them where possible.

Do More but Consistently

Attempting to improve framerate by adopting a flip-flop mechanism where one frame doesn’t do heavy work and the other does is highly discouraged. Schemes like this help nothing with the perceived performance of the sim, on the contrary, the very uneven frame times will have a noticeable impact on the user experience. It is much better to instead do the work every frame and provide a slightly lower but much more consistent framerate. Consistently drawing frames on the screen makes the sim appear much smoother to the user.

Consider Using Multicore

If your add-on needs to compute values per frame that are expensive (e.g. take several milliseconds to compute) and you cannot optimize the computation, consider doing the work on a separate thread.

Moving work to a separate thread in a plugin is quite complex because:

  • The SDK provides no built-in facilities to help with this.
  • No SDK APIs may be called from worker threads you create.
  • You do not have access to the SDK-provided OpenGL context from a worker thread.
  • You cannot block waiting for data completion from an SDK callback.

Typically to make this work you will need to launch a worker thread once and have it block on a semaphore to pick up tasks that can be computed independently without XPLM calls and then returned to the main thread via some kind of thread-safe queue.

Appendix A – DataRefs

This section covers datarefs that can be used to get more information about the rendering environment or interact with X-Plane during drawing callbacks. All callbacks should be resolved via XPLMFindDataref at plugin startup but should be read from inside the drawing callback to get information contextual to a particular draw callback. Read results may be undefined outside of or in the wrong draw callback.

Datarefs for Panel Drawing

These drawing callbacks are appropriate from panel drawing callbacks (before/after panel and gauges).

sim/graphics/view/panel_render_type (int, read-only)

This dataref indicates the type of panel rendering being done:

  • 0 render the entire panel (day time and lit elements with full lighting for 2-d panels)
  • 1 albedo only (render solid elements without lighting)
  • 2 emissive only (render lit elements only)

sim/graphics/view/panel_render_new_blending (int, read-only)

This dataref indicates whether the blending mode for the 3-d panel for the current aircraft is the deprecated, legacy “max” alpha blending mode or the modern preferred alpha blending with correct alpha treatment.

  • 0 blending mode is legacy max mode
  • 1 blending mode is modern

The blending equation for legacy max mode is:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);

The blending equation for modern blending mode is:

glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,

GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

glBlendEquation(GL_FUNC_ADD);

Modern blending mode will correctly composite multiple translucent elements over a translucent or clear panel; legacy max mode gives incorrect but often acceptable results.

Warning: legacy max mode is deprecated and will be dropped from X-Plane in the future. At that point all aircraft will render using blend mode regardless of the content of their art assets.

Datarefs for Panel Clicking

When the mouse is being used over a 3-d panel (via a region mapped with ATTR_cockpit), the following datarefs provide information about the click location.

sim/graphics/view/click_3d_x (float, read-only)

sim/graphics/view/click_3d_y (float, read-only)

This is the location of the mouse in the UV map coordinates of the underlying object.

sim/graphics/view/click_3d_x_pixels (float, read-only

sim/graphics/view/click_3d_y_pixels (float, read-only)

This is the location of the mouse in panel pixel coordinates, or -1 if the mouse is not over the panel.

For all of these datarefs, they are only valid during draw callbacks for the monitor that the mouse is over. Therefore if your plugin is multi-monitor aware, you need to read these from the draw callback for the window that you are using to capture clicks.

(We do not recommend using these datarefs to implement mouse interactions; to capture clicks on a 2-d screen, use a generic instrument on the panel, or consider a real 3-d manipulator on the object itself.)

Datarefs for Panel Location and Scrolling

The location of the panel is provided via two sets of rectangles during panel and gauge drawing callbacks:

sim/graphics/view/panel_total_pnl_l (float, read-only)

sim/graphics/view/panel_total_pnl_b (float, read-only)

sim/graphics/view/panel_total_pnl_r (float, read-only)

sim/graphics/view/panel_total_pnl_t (float, read-only)

These four datarefs form the total bounds of the panel in the modelview coordinate system of the panel drawing callback. You can use these datarefs from inside a panel drawing callback to “calibrate” the location of your drawing. Due to scrolling of panels, the origin of the panel bitmap is not guaranteed to be in any one location on the panel.

sim/graphics/view/panel_visible_pnl_l (float, read-only)

sim/graphics/view/panel_visible_pnl_b (float, read-only)

sim/graphics/view/panel_visible_pnl_r (float, read-only)

sim/graphics/view/panel_visible_pnl_t (float, read-only)

These four datarefs provide the rectangle within the panel that is visible within the current OpenGL viewport. If the panel does not completely fill the viewport, some values could be outside the total bounds of the panel.

These datarefs can be used to identify which panel region is being rendered, for aircraft that use cockpit panel regions. They can also be used to cull gauge drawing that is not going to be visible.

Note that these datarefs are not the same as the current viewport – they are specified in modelview coordinates – that is, the current transform in effect for OpenGL drawing.

sim/graphics/view/panel_total_win_l (float, read-only)

sim/graphics/view/panel_total_win_b (float, read-only)

sim/graphics/view/panel_total_win_r (float, read-only)

sim/graphics/view/panel_total_win_t (float, read-only)

For 2-d panels that are visible on-screen, these datarefs provide the location of the total panel in modelview coordinates during UI drawing callbacks (e.g. post-window draw callbacks and XPLMDisplay window draw callbacks). These datarefs can be used to calibrate the panel location to user interface elements.

sim/graphics/view/panel_visible_win_l (float, read-only)

sim/graphics/view/panel_visible_win_b (float, read-only)

sim/graphics/view/panel_visible_win_r (float, read-only)

sim/graphics/view/panel_visible_win_t (float, read-only)

These datarefs provide the visible extent of the panel in current modelview coordinates during UI callbacks; they can be used for culling gauges that are drawn in UI layers but must match the panel’s location.

Datarefs for 3-d Drawing Callbacks

These datarefs can be read during 3-d drawing callbacks to find details about 3-d drawing.

sim/graphics/view/world_render_type (int, read-only)

This dataref indicates the type of rendering that X-Plane is trying to accomplish with its 3-d callback. The following render passes are visible to plugins:

  • 0 Regular 3-d rendering pass
  • 1 Prep source imagery for water reflections
  • 3 Render depth for shadow maps
  • 6 Prep source imagery for environment cube maps

3-d draw callbacks may be called more than once, so opting out of drawing based on this enumeration can have performance benefits.

Note: by default only regular 3-d render passes are dispatched to plugins; you must enable the capability “XPLM_WANTS_REFLECTIONS“ to receive other types of 3-d drawing callbacks.

Note: the modern 3-d callback does not dispatch shadows; use XPLM object instances for shadow-casting solid geometry.

sim/graphics/view/plane_render_type (int, read-only)

Before X-Plane 11.40, the aircraft drawing phases were the only ones that correctly separated solid and blended drawing; during an aircraft-phase drawing callback this dataref contains:

  • 1 Solid geometry is being drawn for the aircraft. If HDR is enabled and the drawing pass is normal, drawing is going into the G-Buffer.
  • 2 Blended geometry is being drawn for the aircraft. If HDR is enabled, this will be after the G-Buffer is resolved.

For plugins using the modern 3-d drawing callback, the one callback that a plugin receives is equivalent to a post-aircraft drawing callback for blending. Solid drawing is not available – use instancing to add models to the X-Plane world.

sim/graphics/view/draw_call_type (int, read-only)

For 3-d drawing callbacks, this dataref indicates the type of drawing being done for VR multi-eye rendering:

  • 1 Mono (regular) drawing is in progress
  • 3 Stereo drawing is in effect and this call is to render the left eye
  • 4 Stereo drawing is in effect and this call is to render the right eye.

When the left and right eye are dispatched, the transform stack will have been modified to take into account per-eye offsets.

sim/graphics/settings/HDR_on (int, read-only)

This boolean dataref tells whether the HDR deferred renderer is enabled.

  • 0 HDR is not enabled
  • 1 HDR is enabled

sim/graphics/settings/scattering_on (int, read-only)

This boolean dataref tells whether atmospheric scattering is enabled; since atmospheric scattering is always on in X-Plane 11, it will always have a value of 1.

Datarefs for OpenGL State and Modes

All drawing callbacks provide datarefs that provide access to the transform stack at the time your drawing callback is called.

sim/graphics/view/projection_matrix (float[16], read-only)

sim/graphics/view/modelview_matrix (float[16], read-only)

sim/graphics/view/viewport (int[4], read-only)

These three datarefs provide complete access to the modelview, projection and viewport transformations, allowing you to map between modelview and OS window coordinates.

sim/graphics/view/world_matrix (float[16], read-only)

sim/graphics/view/acf_matrix (float[16], read-only)

sim/graphics/view/projection_matrix_3d (float[16], read-only)

These three datarefs can be read during a 2-d drawing callback or window drawing callback to gain access to the transform stack that was used to render the 3-d world, if there was a 3-d render. The world matrix provides the model-view matrix for standard OpenGL world coordinates (e.g. for XPLMWorldToLocal).

The acf matrix provides a modelveiw matrix whose origin is the aircraft’s nominal CG and whose axes are aligned with the aircraft. This is equivalent to starting with the world matrix, translating to the aircraft location and rotating by the aircraft Eulers, but may provide better precision.

sim/graphics/view/is_reverse_float_z (int, read-only)

This dataref indicates whether the depth buffer for the current drawing callback is using regular linear depth encoding or reverse-float-Z conventions.

ValueDepth FormatDepth FunctionDepth Range

0GL_DEPTH_COMPONENT_24GL_LEQUAL-1..1

1GL_DEPTH_COMPONENT_32FGL_GEQUAL0..1

The depth buffer will have an attached 8 bit stencil buffer.

sim/graphics/view/is_reverse_y (int, read-only)

This dataref indicates whether the current rendering pass uses OpenGL conventions for the framebuffer (origin in lower left, Y axis points up) or DirectX/Metal Conventions (origin in upper right, Y axis points down). Even when X-Plane is running in reverse Y mode, the transform stack will be set up such that the model view matrix has the same input coordinate system, e.g. Y is up in 3-d, and Z is south.

Legacy Datarefs for Object Animation

When datarefs are read from a plugin to compute an object’s animation pose or to calculate the setup of its lights, the following datarefs are available to read to learn which object is being rendered.

sim/graphics/animation/draw_object_x (float, read-only)

sim/graphics/animation/draw_object_y (float, read-only)

sim/graphics/animation/draw_object_z (float, read-only)

sim/graphics/animation/draw_object_psi (float, read-only)

This technique for determining which object is being animated is deprecated and is made obsolete by XPLMInstancing.

1 Comment

Plugin compatibility guide for X-Plane 11.50

Starting with X-Plane 11.50, users have the ability to change the graphics API that is used by X-Plane. They now have the option to choose between OpenGL (all platforms), Vulkan (Windows and Linux) and Metal (macOS). This has potential implications for third party code that interacts with X-Plane’s rendering. The main goal with Vulkan and Metal is to deliver a more consistent and higher framerate, while also maintaining compatibility with the existing add on ecosystem as much as possible.

Compatibility with existing plugins

As a general note, existing plugins running under the OpenGL renderer in X-Plane 11.50 should behave exactly the same as in X-Plane 11.41. Assuming the plugins behaved nicely and played by the rules of the SDK, compatibility between 11.50 OpenGL and 11.41 is provided.

Whether a user selects OpenGL, Vulkan or Metal, the following kinds of operations don’t require any changes to existing add-ons:

  • Scenery add ons. All renderers support the existing scenery features and texture formats and will look the same on all platforms.
  • Plugins that don’t interact with the rendering system and instead provide additional functionality without the need to draw in the world.
  • Window drawing using the XPLM 3 SDK windows. This includes UI elements drawn using the XPWidgets library as well as custom OpenGL drawing.
  • 2D drawing callbacks. This includes UI elements drawn using the XPWidgets library as well as custom OpenGL drawing.
  • Panel drawing callbacks. This includes 2D panels as well as 3D panels drawn inside the aircraft.
  • 3D drawing using the XPLM instancing API.

Breaking changes have been made to the 3D drawing callbacks. All 3D drawing phases have been deprecated as of X-Plane 11.50 and will no longer be called under either the Vulkan or Metal renderer. Additionally, the XPLMDrawObjects() and XPLMDrawAircraft() APIs have been deprecated and also no longer works with either Vulkan or Metal. 3D drawing callbacks, XPLMDrawObjects(), and XPLMDrawAircraft() will continue to work under OpenGL in 11.50 like they did in 11.41.

X-Plane has offered an alternative to the XPLMDrawObjects() and XPLMDrawAircraft() APIs since X-Plane 11.10 in the form of the instancing API, which we highly encourage developers to adopt. While not a direct, drop in replacement, it offers much more flexibility for plugin authors and X-Plane than the previous system did. You can read the documentation for the instancing API here and check out our example code here.

OpenGL compatibility notes

When a user runs X-Plane with either Vulkan or Metal, X-Plane itself will exclusively run with the selected backend and no rendering is done using OpenGL. To provide compatibility with plugins X-Plane will create a OpenGL context that is exclusively for use by plugins. X-Plane will create minimal resources in this OpenGL context to enable support for APIs like XPLMGetTexture() and to facilitate sharing of framebuffers across Vulkan/Metal and OpenGL. Plugins should not assume the existence of any resources in an OpenGL context and should instead use public APIs to retrieve resources. No guarantee is made with regards to availability of resources in the OpenGL context across versions or even runs of X-Plane. Plugins that try to sniff resources from the OpenGL context, whether running under Vulkan, Metal or OpenGL, are considered misbehaved and no compatibility guarantees are made.

Plugins that use Vulkan/Metal compatible drawing operations don’t need to do any special processing or precautions. X-Plane provides all synchronization and resource sharing across the rendering APIs as part of its internal plugin bridge system. We expect this OpenGL plugin bridge to exist for the foreseeable future as something that plugins can be authored against. OpenGL provides an easy to use API for plugin needs without any of the complications that come with Vulkan or Metal.

Alternatives to 3D drawing

As mentioned above, the X-Plane 11.41 3D drawing phases have been deprecated in X-Plane 11.50 and are no longer called on Vulkan and Metal. This should not be a problem for most plugins, although a few might require changing to the XPLM instancing API. However, we have found that a lot of third party plugins rely on the 3D drawing phases to read datarefs or do internal bookkeeping, without actually doing any real drawing. This will no longer work under either Vulkan or Metal with 11.50 due to these drawing phases no longer being dispatched, although it is still possible under OpenGL.

We strongly recommend authors avoid doing this in general, even on OpenGL. 3D drawing phases are meant exclusively for 3D drawing, and dispatching them isn’t free in terms of CPU overhead on X-Plane’s end. Plugins that don’t require 3D drawing capability should instead use the flight loop callbacks to do all of their bookkeeping.

We also discovered that a lot of 3D drawing is actually in the form of overlays or other kinds of markers or labels on 3D objects. These can be done from a 2D drawing callback instead of a 3D drawing callback by transforming the 3D world coordinates onto the 2D screen and then using those coordinates to draw. This will work regardless of whether a user runs OpenGL, Vulkan or Metal. Example code that deals with the 3D world to 2D screen coordinate transform can be found here. Note though that this will always draw over world objects since there is no depth information available.

We expect most plugins to be able to entirely phase out their usage of the 3D drawing phases with minimal code changes necessary, either by adopting the instancing API, moving bookkeeping to the flight loop, or using a 2D drawing callback to draw overlays. We highly recommend exploring these alternatives to the previous 3D drawing approaches as they allow X-Plane to run much more efficiently.

3D drawing using the modern drawing phase

Plugins that require completely custom drawing in the X-Plane world with the ability to be occluded by other objects won’t work with the above work arounds. We don’t expect very many plugins to be in this category, with custom weather rendering plugins being the notable exception. For plugins like this, X-Plane 11.50 offers a new 3D drawing phase as part of the XPLM 302 SDK: xplm_Phase_Modern3D. For technical reasons this drawing phase is not available on Metal and only runs on Vulkan and OpenGL!

This new drawing phase has many caveats and gotchas and comes with the big fat warning that it isn’t very cheap in terms of CPU overhead. We highly discourage the use of it unless it’s absolutely necessary to perform real, custom 3D drawing! As mentioned before, the biggest caveat is that this drawing phase will not be called under Metal. Additionally there is only a single drawing phase now which conceptually sits right where the old before xplm_Phase_Airplanes draw phase used to be. The before and after phase of the modern 3D drawing phase are called directly in succession and no X-Plane rendering happens in between.

There are two additional things to watch out for when doing 3D rendering in general:

First, X-Plane can run with reverse-z semantincs. Meaning that the depth range is [0, 1] as opposed to the traditional [-1, 1] and the depth comparison is GEQUAL instead of LEQUAL. As a side effect, this means that the depth buffer is cleared to 0 instead of 1. When in reverse-z mode, the depth buffer will be in floating point format (DEPTH_32F) instead of the traditional 24bit integer format. X-Plane will set up the OpenGL state and projection matrices for you to reflect these changes when dispatching plugins, but it’s something you might want to be aware of if you do any depth buffer readbacks, set the depth state yourself, or calculate your own projection matrices. Whether X-Plan is in reverse-z mode can be observed through the sim/graphics/view/is_reverse_float_z dataref. When running under Vulkan, X-Plane will always run in reverse-z mode, when running under OpenGL it’ll only be in reverse-z mode for VR rendering.

Second, X-Plane can run with reverse-y semantics. In reverse-y mode, the colour and depth buffer are flipped along the y-axis (the origin is top left and grows downward). When running in reverse-y mode, it’s the responsibility of the plugin author to flip the front face winding to avoid polygons from getting incorrectly backface culled. The projection matrix provided by X-Plane takes care of the changed projection parameters, but if you do your own projection matrix set-up you’ll have to do this change yourself. Whether X-Plane is in reverse-y mode can be observed through the sim/graphics/view/is_reverse_y dataref. When running under Vulkan, only 3D drawing with the HDR renderer is in reverse-y mode. 2D rendering phases and OpenGL rendering are never in reverse-y mode.

6 Comments

Wheel steering parameters

X-Plane 11.36 adds a new parameter to the steering/castor setup for nose and tailwheels, that makes it possible to add a castoring range onto a steered wheel.

Up and including to 11.35, a wheel could be one of three things:

  • Fixed: a main gear wheel is usually fixed and does not steer.
  • Steered: a nose or tail wheel that is actuated with a tiller or rudder linkage is steered up to a certain angle, where the maximum angle can be dependent on the speed.
  • Free Castoring: on many taildraggers and also some modern tricycle aircraft like the Cirrus SR22 or Columbia 400 there is no wheel steering at all, they instead rely on rudder and differential braking to steer on the ground, with the wheel just trailing.

11.36 adds another option, that is commonly found on aircraft like the C152, C172, etc.:

  • Non-rigid steering with castoring range: The wheel can be steered through rudder linkage up to a (small) deflection angle. By using differential brakes, the plane can turn tighter, in which case the wheel deflects further than it would from rudder linkage alone.

The new parameter is found in Plane Maker as: “castor limit (deg) This is the maximum amount that the nosewheel or tailwheel of the aircraft can steer from full rudder deflection and pulling the plane into a turn with differential brake. Enter zero if the nose wheel does not steer more than the rudder-linked values or the tail wheel is not limited in castoring at all.”

That means, the nose wheel steering limit (fast and slow) for the 172 is 10 degrees, as can be found in the TCDS of the aircraft (or the POH).
However, the new castor limit is 45 degrees.
Now what happens is:

  • With the rudder pedal, the nosewheel is deflected with the rudder up to 10 degrees left or right.
  • At 10 degrees deflection, differential braking can be used. If the differential braking causes a tighter turn, the wheel will turn in, following the steering impulse from the differential braking, and allow a tighter turn without slipping the nose wheel, to a maximum of the “castor limit” of 45 degrees.
  • While in this situation, relaxing the differential braking will not immediately cause the wheel to spring back to 10 degrees. It will come out of this deflection depending on the forces that turn the plane. So you can get the plane out of the turn by relaxing the rudder pedal deflection – once the rudder is not hard over one way anymore, the springs will pull on the wheel once again, or you can increase thrust, apply brakes or even diff-brake in the other direction.

Note that all of that also works on a tailwheel as well.

For users without brake pedal axes, the “auto-toe brakes” follows the existing “left and right brake power to help with steering (if no rudder pedals present)” setting. This way, the toe brakes can be activated on full rudder deflection, leading to the tighter turn naturally.
If that parameter is 0, no auto-toe braking happens. The parameter is ignored if the user has hardware pedals with independent toe-brake axes.

Do not use the “tailwheel spring force” parameter on anything but a tailwheel any more. In the past, you could abuse it to get auto toe-braking, but you can get this explicitly with the toe brake parameter. The tailwheel spring force has unintended side effects if used on planes that aren’t tail-wheel configuration, so it must be 0 unless you actually have a taildragger with a spring steering.

Use the deflection time parameter to model the delay introduced into the nosewheel steering by a non-rigid linkage (bungee cords in a Cessna). Wheel deflection follows the rudder (or tiller) deflection with the speed constant “nosewheel steering full deflection time (sec)”. This can be used for a hydraulic actuator that takes time, or the bungees pulling the wheel around rather than a fixed linkage. That time would be 0 in a Piper with fixed linkage.

If the castor limit is 0 (which it is for existing planes not modified in Plane Maker 11.36) the nosewheel steering will work as it did before, so it is suitable for Airliners or Pipers.

If the castor limit is non-zero and applied to a castoring wheel (which has no steering angle) it will limit how far the wheel can be deflected by castoring. While not particularly useful for tail-wheels, this is useful for castoring nose-wheels, like on a Grumman or Cirrus.

Comments Off on Wheel steering parameters

Datarefs for the CDU screen

X-Plane 11.35b5 adds datarefs to read the contents of the X-Plane default FMS Control and Display Unit (CDU) screen.

The CDU is limited to 16 lines of text with 24 characters per line. Note that not all CDUs use all 16 lines – Some use a combined scratchpad/message line, others have an additional line under the scratchpad for messages. Some CDUs have four line selectable rows of data, others have 6. So while you can read data from CDUs of all sizes up to 16 lines, not all CDUs will fill 16 lines with content.

Text

The datarefs

sim/cockpit2/radios/indicators/fms_cdu1_text_line0

to

sim/cockpit2/radios/indicators/fms_cdu1_text_line15

and

sim/cockpit2/radios/indicators/fms_cdu2_text_line0

to

sim/cockpit2/radios/indicators/fms_cdu2_text_line15

contain the contents of each line as an UTF-8 string. Note that one character might need more than one byte of the dataref to display. You are expected to be able to read at least the following UTF-8 characters:

  • U+00B0 (degree sign): (0xC2 0xB0)
  • U+2610 (ballot box): (0xE2 0x98 0x90)
  • U+2190 (left arrow): (0xE2 0x86 0x90) to U+2193 (downwards arrow): (0xE2 0x86 0x93)
  • U+0394 (greek capital letter delta): (0xCE 0x94)
  • U+2B21 (white hexagon): (0xE2 0xAC 0xA1)
  • U+25C0 (left-point triangle): (0xE2 0x97 0x80)
  • U+25B6 (right-pointing triangle): (0xE2 0x96 0xb6)

More special characters might be added in future versions.

Formatting info

The datarefs

sim/cockpit2/radios/indicators/fms_cdu1_style_line0

to

sim/cockpit2/radios/indicators/fms_cdu1_style_line15

and

sim/cockpit2/radios/indicators/fms_cdu2_style_line0

to

sim/cockpit2/radios/indicators/fms_cdu2_style_line15

contain the formatting information for each character in the line as one byte (unsigned char) with the following special meaning:

  • The highest bit is set for a text displayed in large font. So use mask (1<<7) for the bit that tells you large vs small font.
  • The second highest bit is set for a text displayed in reverse video (colored background, black text). So use mask (1<<6) for the bit that tells you to invert the colors.
  • The third highest bit is set for a text displayed flashing (text being turned an and off periodically). So use mask (1<<5) for the bit that tells you to flash.
  • The fourth highest bit is set for a text with an underscore. So use mask (1<<4) for the bit that tells you to display an underscore under the character.
  • The remaining four bits encode the color of the text (or the background for reverse video): BLACK(0),CYAN(1),RED(2),YELLOW(3),GREEN(4),MAGENTA(5),AMBER(6),WHITE(7).
12 Comments

The X-Plane fuel system

X-Plane 11.35 comes with a few additions to the fuel system, in order to make it more flexible for third-party developers, hopefully removing the need to override it in many cases.

Fuel-arm for oddly shaped tanks

New to X-Plane 11.35 is the possibility to enter two longitudinal arms for the fuel tank position, one for empty and for full (by default, X-Plane just copies the arm of the empty tank to the full tank). Normally, the moment of the fuel in a tank is expressed by the arm of the fuel tank, multiplied by the fuel weight. On some planes the arm itself changes as fuel is used from an oddly-shaped tank, and the moment changes by both the weight difference and the arm difference. King Airs are notable examples of where the fuel arm changes with fuel level. By setting a different arm for the full tank, X-Plane will accurate simulate the mass and balance effect of the fuel in such tank arrangements.

Fuel pump pressure per tank setting

This is a setting in Plane Maker that has existed for a long time, even before X-Plane 11. By giving tanks individual fuel pump pressures, designers can control the order in which X-Plane is going to empty the tanks.

When multiple tanks are available according to the fuel selector setting (e.g. fuel selector to “left” with multiple tanks on the left side), the pump with the highest pressure will supply the fuel until its tank is empty. This is comparable to the system of override pumps, found for example on a 747.

New to X-Plane 11.35 is the ability to change fuel pump pressure at run-time via a dataref, allowing precise control over which tanks will be providing fuel at any given time.

For example, on a 737 the center tank pumps provide a higher pressure than the wing tanks, therefore, the center tank is first emptied before any fuel is taken from the wing tanks.

Firewall shutoff valves

Commands for the left and right firewall shutoff valves (sim/fuel/fuel_firewall_valve_lft_open, etc.) have existed in X-Plane since before version 11. X-Plane 11.35 adds data refs, too. Use them to your advantage.

Fuel tank Role – NEW to X-Plane 11.35

In addition to the pressure, a tank can now be assigned a role:

  • Normal – this is the default and retains the logic directed by the pump pressure
  • Feeder – this is a tank that feeds an engine and is always kept full from the other tanks on this side with an automatic transfer pump. If a feeder tank exists, the engine will only get its fuel from the feeder, while other tanks can provide fuel to keep the feeder full.
  • Aux – this is the opposite of a feeder tank: it cannot feed the engine directly, but it is used to keep the feeder tank full as long as possible with the automatic transfer pump
  • Trim – like an AUX tank, but never automatically transferred to or from. You need to use “fuel transfer from” or “fuel transfer to” to change this tank’s fuel level

Note that this is not necessarily what the POH calls the tank! For example, in a Cessna Golden Eagle the tip tank is called “Aux” tank, but it can be selected to feed the engine directly, with the fuel selector. Therefore, it is not an “Aux” tank for X-Plane, since that would mean it is not selectable to feed the engine directly. In order to model the preference for main or aux tank, one would use the new pressure dataref.

Note that a stabilizer tank on a 767-400ERX or a 747-400 is not a “trim” tank. Despite being in the stabilizer, it contains useable fuel for both in flight or on the ground. On the other hand, Tank 11 in a Concorde is a “trim” tank, because it cannot be filled on the ground without the plane tipping over!

Automatic transfer pumps

With tanks on each side of the airplane being configured as Feeder and Aux, the transfer pump on each side will keep the feeder tank full until the aux tank runs dry, and then turn on the “NO TRANSFER” warning light.

A feeder pump can be operated in automatic mode (where you can specify a difference that triggers the pump to operate) or override mode, where the pump runs continuously.

Automatic cross feed

This is also new for 11.35. The common crossfeed manifold allows an electric boost pump to supply pressure to the engine on the other side and thus cross-feed an engine if the on-side boost pump has failed.

If the cross feed is operated in auto mode, the same limit value that triggers the low fuel pressure annunciator will also trigger the crossfeed valve. In manual mode, the crossfeed valve can be open or closed.

Datarefs

sim/cockpit2/fuel/transfer_pump_left	int	y	enum	Transfer from left AUXes to left FEEDers: 0: Off, 1: Auto, 2: On/Override 
sim/cockpit2/fuel/transfer_pump_right	int	y	enum	Transfer from right AUXes to right FEEDers: 0: Off, 1: Auto, 2: On/Override
sim/cockpit2/fuel/transfer_pump_activation	float	y	kg	Automatically transfer from AUXes to FEEDers in auto mode when feeder has more than X kg left to full
sim/cockpit2/fuel/fuel_level_indicated_left	float	n	kg	Indicated fuel level left, shows total or only nacelle tanks depending if user is holding down the aux-tank button.
sim/cockpit2/fuel/fuel_level_indicated_right	float	n	kg	Indicated fuel level right, shows total or only nacelle tanks depending if user is holding down the aux-tank button.
sim/cockpit2/fuel/firewall_closed_left	int	y	boolean	Firewall valve closed, left
sim/cockpit2/fuel/firewall_closed_right	int	y	boolean	Firewall valve closed, right
sim/cockpit2/fuel/auto_crossfeed	int	y	enum	0=Off 1=Auto 2=On - If fuel pressure on one side is low, due to fuel pump failure for example, cross-feed is opened to allow one pump to supply pressure to both engines.
sim/cockpit2/fuel/no_transfer_left	int	n	boolean	Warning light, will illuminate when transfer from aux to feeder is requested, but aux tank is empty
sim/cockpit2/fuel/no_transfer_right	int	n	boolean	Warning light, will illuminate when transfer from aux to feeder is requested, but aux tank is empty
sim/cockpit2/fuel/transfer_test	int	y	boolean	Transfer test switch. 0 = normal, -1 = test left, +1 = test right
sim/cockpit2/fuel/tank_pump_pressure_psi	float[9]	y	psi	Pressure generated by the fuel pump per tank. If multiple tanks are accesible per the fuel selector, fuel will be consumed from the tanks in order of pump pressure

Commands

"sim/fuel/left_xfer_override" ,"Aux to feeder transfer left override."
"sim/fuel/left_xfer_on" ,"Aux to feeder transfer left on."
"sim/fuel/left_xfer_off" ,"Aux to feeder transfer left off."
"sim/fuel/left_xfer_up" ,"Aux to feeder transfer left off->on->overide."
"sim/fuel/left_xfer_dn" ,"Aux to feeder transfer left override->on->off."
"sim/fuel/right_xfer_override" ,"Aux to feeder transfer right override."
"sim/fuel/right_xfer_on" ,"Aux to feeder transfer right on."
"sim/fuel/right_xfer_off" ,"Aux to feeder transfer right off."
"sim/fuel/right_xfer_up" ,"Aux to feeder transfer right off->on->overide."
"sim/fuel/right_xfer_dn" ,"Aux to feeder transfer right override->on->off."
"sim/fuel/left_xfer_test" ,"Aux to feeder transfer test left."
"sim/fuel/right_xfer_test" ,"Aux to feeder transfer test right.
"sim/fuel/auto_crossfeed_on_open","Crossfeed valve open."
"sim/fuel/auto_crossfeed_auto" ,"Open crossfeed valve when pressure difference detected."
"sim/fuel/auto_crossfeed_off" ,"Close crossfeed valve and turn off auto-crossfeed."
"sim/fuel/auto_crossfeed_up" ,"Auto-crossfeed off->auto->on."
"sim/fuel/auto_crossfeed_down" ,"Auto-crossfeed on->auto->off."

We have always had independent left and right fuel selectors for twins as datarefs, but not as commands. These are the new commands:

"sim/fuel/left_fuel_selector_none"
"sim/fuel/left_fuel_selector_lft"
"sim/fuel/left_fuel_selector_ctr"
"sim/fuel/left_fuel_selector_rgt"
"sim/fuel/left_fuel_selector_all"
"sim/fuel/right_fuel_selector_none"
"sim/fuel/right_fuel_selector_lft"
"sim/fuel/right_fuel_selector_ctr"
"sim/fuel/right_fuel_selector_rgt"
"sim/fuel/right_fuel_selector_all"

Finally, we can now distinguish between center and aft tanks in the transfer logic, so these commands are added for the transfers:

"sim/fuel/fuel_transfer_to_aft"
"sim/fuel/fuel_transfer_from_aft"

to enable fuel transfer to and from an aft trim tank.

8 Comments

The X-Plane bleed air and pressurization systems

X-Plane 11.35’s bleed air system is an extension of the earlier X-Plane bleed air system, designed both for versatility and compatibility.

At the center of the new bleed air system is the center manifold which serves as the backward-compatible portion that is used by all airplanes, designed to provide basic bleed air and pressurization capabilities for existing aircraft.

Aircraft modernized for X-Plane 11.35 and later can make use of the left and right extensions of the bleed air system, and opt to use 1, 2 or 3 air conditioning and pressurization packs.

The system design is best understood with this diagram:

The center components provided for compatibility are clearly marked.

X-Plane legacy aircraft know only one pressurization pack, and one selector that selects the sources for this pack: left hand side of the aircraft, right hand side of the aircraft, and APU. Both APU and the center engine in a one- or three-engined plane are considered to be providing air from the center of the aircraft.

New to X-Plane 11.35 are: GPU bleed, left pack, right pack, wing-anti ice supply, and per-engine shut-off valves.

Another way to understand the system is as a Lancair (legacy X-Plane) overlaid with a King Air overlaid with a 747 – you will then understand how to design many more aircraft types with it:

1. Single-engine plane (Lancair Evolution or similar)

The center pack is the single source of cabin pressure. Packs L and R are always off because they don’t exist.

The bleed selector doesn’t care for left or right or both, the isolation valves have no function, the only available settings are: Bleed “off” meaning engine shut-off valve off and Bleed “on” (any of L, R or BOTH) meaning engine shut-off valve on. Bleed “auto” adds APU valve on (the single engine plane most likely doesn’t have an APU, but if it has, it would work), GPU adds GPU off or on. There’s only one duct, and only one available pressurization pack, center.

2. Two-engine plane with single pressurization (old King Air or similar)

The center duct supplies the one center pack that provides air to the cabin. The pack can be fed from the left engine, the right engine, or both. The bleed air mode thus maps to the isolation valves: left bleed air means left isol valve open, right bleed means right isol valve open, bleed both or auto mean both isolation valves open. If an APU was installed, it would feed into the center duct regardless of the isolation valve settings, controlled by the APU valve, just like the GPU.

3. Four-engine plane (resembling 747)

The system operates exactly like a 747 would: Three packs are available, per-engine SOVs, APU SOV and GPU SOV and two isolation valves work exactly like you’d expect when comparing the above graphic to the schematic of a 747.

4. Twin engine plane (737, A320, CRJ, ERJ, etc.):

Here’s where it gets interesting. For correct operation, one must turn off the legacy center pack and never turn it on again. That must be done actively by script or plugin, since X-Plane will never turn off the center pack – that would break existing aircraft!

The plugin can turn pack C off and pretend it doesn’t exist.

One can then turn on pack L and pack R as per the pack switches.

One can turn off or on the per-engine SOVs as per the engine switches.

Now the only remaining switch is the (single) isolation valve found in such aircraft.

This is where it gets airplane specific and one needs to look at a diagram for the specific airplane: Look up whether the APU and GPU feed into the left or the right from the single isolation valve. For the sake of explanation, let’s assume we are looking at the 737, where the APU feeds into the left duct and GPU feeds into the right duct.

For operation with the APU, the isolation happens to the right of the APU. That is, the isolation valve of the 737 with APU feed is the ISOL R valve in the X-Plane system (and ISOL L is always open). This way, center and left duct belong together, and are fed by left engine and APU. To the right of the isolation valve is the right engine.

For operation on GPU, the isolation happens to the left of the GPU! That is, the isolation valve of the 737 in GPU feed is now the ISOL L valve in the X-Plane system (and ISOL R is always open). This way, the left engine is to the left of the isolation, and GPU and right engine are to the right of the isolation.

Note that GPU and APU can never feed together – in real planes, the APU load control valve is also a one-way check valve. If theAPU valve was commanded to open while the system is pressurized from the GPU, it simply wouldn’t open. In that case, the system operates as GPU-fed until the GPU is off.

5. Twin engine plane (McDonnell-Douglas)

For a plane like the MD-80, which has two isolation valves, operation becomes very simple:
The center pack is turned off (by script or plugin) and never turned on again.

Pack L and pack R are turned on as per the Air Cond Cockpit and Air Cond Shutoff switches.

One can then turn off or on the per-engine SOVs as per the supply switches and fire handles. Both pulling a fire handle or turning off a supply switch should close the engine valve.

The left and right isolation valves separate the side systems with their respective packs from the center duct, into which the APU and GPU feed. These valves are thus direct mappings between X-Plane and and the MD-8x cockpit.

6. Three engined-planes

Because three-engined planes are very dissimilar in design between a 727, DC-10 or Tu-154, X-Plane makes no effort to resemble either – it is expected that custom plugin code will be needed to accurately simulate a three-engine plane.

Electrical power consumption

Having covered the pneumatic side of the system, let’s look at the electric side.

X-Plane has one electrical consumer for “HVAC” that until X-Plane 11.34 could not be controlled via datarefs or commands. From X-Plane 11.35 onwards, the following electrical loads are simulated with the various components of the system:

  • AC compressor and fan take 100% of the amp load that is specified
  • Fan only takes 10% of the amp load that is specified
  • Fan and heater in flight mode take 100% of the amp load that is specified
  • Fan and heater in ground mode take 200% of the amp load that is specified

Note that most of this is only relevant to GA planes, not airliners. Airliners do neither have electrical AC compressors nor electric heaters. Heat is supplied by the bleed air alone, it comes out of the engines so hot that it does not need to be heated. The cooling is provided by an air cycle machine driven by bleed air pressure itself, so it does not need lots of electrical power to run the air conditioning to cool it down.

So in an airliner, one would only ever use the fan function, so in Plane Maker, the amp load of the fan times 10 needs to be specified for the whole system, since we are never going to use the remaining 90%.

In a GA plane, the AC compressor is driven by electrical power, so using it will put you in the situation where X-Plane will use 100% of the specified amps.

Some turboprop planes, notably the King Airs and Cheyennes, have not enough heat from the engines to sustain cabin heating alone, so they use an electric heater grid consisting of 8 grids at 36amps each (that is the value for a King Air 90), four of them operate in flight, and an additional four can be activated on the ground when enough power is supplied either by both generators running, or by a GPU. That “ground max” heat setting will double the power consumption, as explained.

Datarefs

sim/cockpit2/pressurization/actuators/air_cond_on int y boolean Electrical air conditioning compressor on, consuming all the amps of rel_HVAC - not needed on airplanes with air cycle machines that drive the air conditioner off the bleed air power itself.
sim/cockpit2/pressurization/actuators/heater_on int y boolean Electrical heater grid on, 0 = off, 1 = flight max (consumes rel_HVAC amps), 2 = ground max (consumes 2x rel_HVAC amps, turned off by weight-off-wheels) - not needed on airplanes that are using hot bleed air and have no heaters
sim/cockpit2/pressurization/actuators/fan_setting int y enum Electric fan (vent blower) setting, consuming 0.1 of rel_HVAVC amps when running. 0 = Auto (Runs whenever air_cond_on or heater_on is on), 1 = Low, 2 = High
sim/cockpit2/bleedair/actuators/engine_bleed_sov int[8] y boolean Engine bleed air shut off valve, close or open
sim/cockpit2/bleedair/actuators/apu_bleed int y boolean APU bleed air valve, close or open. APU must be running at 100%N1 to provide bleed air
sim/cockpit2/bleedair/actuators/gpu_bleed int y boolean GPU bleed air valve, close or open. A GPU is supposed to be always available.
sim/cockpit2/bleedair/actuators/isol_valve_left int y boolean Isolation Valve for left duct, close or open. This separates all engines on the left side of the plane, the left wing, and the left pack from the rest of the system
sim/cockpit2/bleedair/actuators/isol_valve_right int y boolean Isolation Valve for right duct, close or open. This separates all engines on the right side of the plane, the right wing, and the right pack from the rest of the system
sim/cockpit2/bleedair/actuators/pack_left int y boolean Left pressurization pack, off or on. The left pack is supplied from the left side of the plane or through the left isolation valve and only available for airplanes made for 11.35 or newer
sim/cockpit2/bleedair/actuators/pack_center int y boolean Center pressurization pack, off or on. The center pack is supplied from center duct, which can be supplied from a center engine, APU, GPU, or, via the isolation valves, the left and/or right ducts. This pack is the only pack available for airplanes made for X-Plane 11.33 or older
sim/cockpit2/bleedair/actuators/pack_right int y boolean Right pressurization pack, off or on. The right pack is supplied from the right side of the plane or through the right isolation valve and only available for airplanes made for 11.35 or newer
sim/cockpit2/bleedair/indicators/bleed_available_left float n ratio Bleed air available in the left duct, which can come from left engines or through the left isolation valve.
sim/cockpit2/bleedair/indicators/bleed_available_center float n ratio Bleed air available in the center duct, which can come from a center engine, APU, GPU, or, via the isolation valves, the left and/or right ducts.
sim/cockpit2/bleedair/indicators/bleed_available_right float n ratio Bleed air available in the right duct, which can come from right engines or through the right isolation valve.
sim/cockpit2/bleedair/indicators/engine_loss_from_bleed_air_ratio float[8] y ratio Bleed air being sapped from the engine, stealing efficiency from the compressor. Writeable only with override_pressurization set

Commands

sim/bleed_air/engine_1_off
sim/bleed_air/engine_2_off
sim/bleed_air/engine_3_off
sim/bleed_air/engine_4_off
sim/bleed_air/engine_5_off
sim/bleed_air/engine_6_off
sim/bleed_air/engine_7_off
sim/bleed_air/engine_8_off
sim/bleed_air/engine_1_on
sim/bleed_air/engine_2_on
sim/bleed_air/engine_3_on
sim/bleed_air/engine_4_on
sim/bleed_air/engine_5_on
sim/bleed_air/engine_6_on
sim/bleed_air/engine_7_on
sim/bleed_air/engine_8_on
sim/bleed_air/engine_1_toggle
sim/bleed_air/engine_2_toggle
sim/bleed_air/engine_3_toggle
sim/bleed_air/engine_4_toggle
sim/bleed_air/engine_5_toggle
sim/bleed_air/engine_6_toggle
sim/bleed_air/engine_7_toggle
sim/bleed_air/engine_8_toggle
sim/bleed_air/gpu_off
sim/bleed_air/gpu_on
sim/bleed_air/gpu_toggle
sim/bleed_air/apu_off
sim/bleed_air/apu_on
sim/bleed_air/apu_toggle
sim/bleed_air/isolation_left_shut
sim/bleed_air/isolation_left_open
sim/bleed_air/isolation_left_toggle
sim/bleed_air/isolation_right_shut
sim/bleed_air/isolation_right_open
sim/bleed_air/isolation_right_toggle
sim/bleed_air/pack_left_off
sim/bleed_air/pack_left_on
sim/bleed_air/pack_left_toggle
sim/bleed_air/pack_center_off
sim/bleed_air/pack_center_on
sim/bleed_air/pack_center_toggle
sim/bleed_air/pack_right_off
sim/bleed_air/pack_right_on
sim/bleed_air/pack_right_toggle

sim/pressurization/aircond_on
sim/pressurization/aircond_off
sim/pressurization/heater_on
sim/pressurization/heater_grd_max
sim/pressurization/heater_off
sim/pressurization/heater_up
sim/pressurization/heater_dn
sim/pressurization/fan_auto
sim/pressurization/fan_low
sim/pressurization/fan_high
sim/pressurization/fan_up
sim/pressurization/fan_down
Comments Off on The X-Plane bleed air and pressurization systems

Generating Icons for Aircraft

The new X-Plane 11 UI includes aircraft icons arranged in a grid on the Flight Configuration screen. The new icon style is a simple picture of the aircraft, seen from a particular angle, over a transparent background. By keeping your icons consistent with the X-Plane 11 default icons, your aircraft will both look professional and be identifiable at a glance.

Generate Icons

You have two options for creating X-Plane 11 icons for your aircraft:

  • X-Plane can automatically generate an icon for each livery of your aircraft. This is the preferred method. To do so, start a flight in your aircraft, then, in the menu bar, click Developer > Regenerate icons for current aircraft (shift + R by default).
    • Note that we control for some variables in generating these images by moving the aircraft to PMDY and changing the window size.
  • Alternatively, you can use your own 3-D modeling tool to generate the icons, following the specifications below.

X-Plane 11 aircraft icons are stored as follows within your aircraft folder:

  • [Your aircraft directory]
    • [your ACF name].acf
    • [your ACF name]_icon11.png
    • [your ACF name]_icon11_thumb.png
      liveries

      • [your livery name]
        • [your ACF name]_icon11.png
        • [your ACF name]_icon11_thumb.png
      • [another livery name]
        • [your ACF name]_icon11.png
        • [your ACF name]_icon11_thumb.png

Note that there are actually two images on disk for each livery: the normal “_icon11.png” and the “_thumb” version. The former is an 800×450 image used when you click “Customize” for an aircraft; the latter is a 174×107 image used in the aircraft grid view. (The smaller size gives you both a better image quality and improved performance when scrolling through the grid.)

10 Comments