Property Tree

From FlightGear wiki
Jump to: navigation, search
The so called Property Tree in FlightGear is generally considered FlightGear's central nervous system and one of FlightGear's greatest assets!

This is because the Property Tree system provides access to low level run time state variables via a very intuitive tree-like hierarchy. This allows FlightGear's behavior to be easily controlled and manipulated at run time.

The FlightGear Property Tree is the common denominator for crucial run time state and also the interface to these internal state variables.

The concepts and mechanisms behind the "Property Tree" may not be immediately obvious to FlightGear beginners. This page is meant to help new users familiarize themselves with the FlightGear property tree.

The property system - or property tree - represents most of the internal state of all systems within FlightGear, like for example the flight dynamics model. The content of these internal state variables are presented in a hierarchically manner and can easily be accessed through a well known API. A system may present its current state to other systems and let other systems change it's current state by allowing them to write to it's own properties. One might think of the property system as a global, normalized communication platform, where subsystems may publish variables and access other subsystem's variables. In addition, callbacks can be registered to invoke code upon read/write access of properties, which serves as the backbone for a very simple, but powerful, signalling mechanism in FlightGear.

Thus, the property system acts as a routing interface, both between different high-level FG sub-systems and the outside world. Data that is required by one FG sub-system can be exposed in the property tree, where it can then be read or modified, either by other internal FG sub-systems, or by & for external input & output.

For example, a left banking joystick input is exposed in the property tree where it is read by the FG FDM sub-system. The FG FDM sub-system then in turn outputs an aileron deflection back to the property tree where it is then read by the FG animation sub-system to animate the aileron deflection in the 3D model.

Alternatively data [the joystick input], once exposed in the property tree, can be read and modified by an external application via the FG IO sub-system, such as an external FDM.

The output from the external FDM can then be fed back in to FG by writing it's data back to the property tree, once again, via the FG IO sub-system.

In addition to the protocols supported by the FG IO sub-system there are also telnet and http interfaces, which allow property tree data to be read and modified via these interfaces, i.e. using a telnet client or a conventional web browser to inspect/access and modify most FlightGear runtime state.

An important feature of the property tree interface is that it can be tailored and new entries added as required, without requiring C++ changes.

If you wish to use a custom-written sub-system, such as your own Terrain Following and Avoidance sub-system, for example, and perhaps implemented or prototyped in Nasal.

Adding new property tree branches and nodes to handle your unique data presents no problems.


Naming a property is very much like naming a file in a file system, with levels of hierarchy.

The property tree maps very nicely to XML. This is convenient for initializing the property tree and saving its state.

Values in the tree are typed, but they can also be untyped strings which will be converted to a typed value when read.

Protocol Options

Usually the "best" way depends on your specific circumstances. Will the two applications be running on the same machine? If not, do the two machines have a high speed network connection or some slow radio modem type connection? How much data are you sending and at what rate? Do you need really tight timing or can you get by with some delays and sloppiness in the communication?

Introduction

When a simulation is running, all the variables such as position, speed, flaps, cabin lights, et all are calculated and manipulated through a property tree, which is exposed through various means, inculding a built-in Property Tree/Web Server and a built-in Telnet server.

Note that you can setup as many of these servers as you want, for instance, just to be obscene you could do:

 fgfs --httpd=5400 --httpd=5401 --httpd=5402 --telnet=5403 --telnet=5404 --telnet=5405

Now there are six network interfaces running that you can access from anywhere ;-) >> can I borrow your ipod please. why ?


The "virtual" tree that runs the simulation appears much like a directory/file structure. eg:

/sim/aircraft = A333

/position/
/position/longitude-deg =	'-122.3576677'	(double)
/position/latitude-deg =	'37.61372424'	(double)
/position/altitude-ft =	'28.24418581'	(double)
/position/altitude-agl-ft =	'22.47049626'	(double)

/controls/seat/eject/initiate
/controls/electric/APU-generator

Some of these variables are "calculated" within the sim (i.e. updated regularly, e.g. at frame rate), whilst others can be manipulated. Writing a variable is as easy as

/* Its my turn to play the sim */
set('/controls/seat/eject/initiate', 1)

The values can also be set from the httpd interface.

What makes FG powerful is that a new aircraft can easily be designed with its unique set of properties that somehow affect the simulation. The Aircraft model has an xml file of properties within the property tree.

This is why the property tree is not consistent with fixed variables, they are created dynamically, to represent a propeller plane vs Jumbo or even a "Caspian Sea Monster".

Many properties will be aircraft-specific, and availability may even depend on the startup/runtime settings you are using. There are a bunch of "common" properties - especially among similar FDMs and aircraft. Obviously, different FDMs/aircraft will use different properties (single piston, helicopter, jet, twin turbine helicopter etc). You may want to have a look at $FG_ROOT/Docs/README.properties. There are a couple ways that they are set, but a fair amount of them just "appear" without being documented anywhere. There are several places to look for properties; one is in the aircraft files, another is all Nasal files, and the last place (and often most useful!) is grepping (searching) through the C++ code. To determine how a property works and what it does often requires looking through any code that uses it. This is a part of FlightGear that we could certainly document better

The property tree is read, written, accessed and manipulated in a variety of ways, such as

  • startup arguments via --prop:/sim/foo=bar
  • XML files
  • internal compiled code within FG - the c/c++ code
  • Nasal scripts - this is javascript-like scripting with read/write to the property tree. This is the way most aircraft are implemented.
  • Using native protocols, implemented in C++ (see $SG_SRC/Network. Property Tree/Sockets
  • Using the generic protocol, either in/out/bi - this allows send/receive to the FG sim via the Generic Protocol
  • telnet interface - query and fly the plane on the command line or using a scripted session (see Telnet usage)
  • html interface - access the property tree using a conventional web browser like firefox/safari or chrome
  • using the built in Property browser
  • using other GUI dialogs
  • using cockpit bindings
  • using joystick bindings etc

So they can come from many places, thus there's no single source file where you'll find ALL properties/types. You will need to look at the corresponding subsystem/component. $FG_SRC/Network is the right pace to look for hardcoded protocols, make sure to also understand their inheritance (the interface being implemented).


For example, multiplayer mode is accomplished by exchanging sets of variables from the tree (height, position, speed, etc).

Flight Dynamics Model (FDM)

FlightGear uses a few Flight Dynamics Models, such as

These flight dynamics models present themselves differently in the tree, using different variables, in different places. That is what an aircraft can be designed around. Most FDMs use so called tied properties, which are directly mapped to memory in C++, so that they cannot be written to - so that you would need to disable the FDM using the null FDM instead.