Property tree: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
m (courtesy of Lee E: http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg21192.html)
(Fixed broken dump properties command, rewrite for easier understanding)
(21 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{PropertyTree}}The so called '''Property Tree''' in [[FlightGear]] is generally considered FlightGear's central nervous system and one of FlightGear's greatest assets!
{{PropertyTree}}
The '''property tree''' is considered [[FlightGear]]'s central nervous system and one of its greatest assets. It is the interface to low level, run time state variables via a very intuitive tree-like hierarchy, allowing for FlightGear's behavior to be easily controlled and manipulated at run time.


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 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 FlightGear Property Tree is the common denominator for crucial run time state and also the interface to these internal state variables.
== The purpose of the 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 models, or the weather simulation. 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 them change its current state by allowing to write to its own properties.


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.
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 and for external input/output.  


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.
There is some basic property-debugging support to FlightGear and SimGear. In FlightGear, the --trace-read option causes all read access for a property to be traced, and the --trace-write option causes all write access for a property to be traced, both through SG_LOG messages.
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.  
=== Examples of use ===
For example, a left banking joystick input is exposed in the property tree where it is read by the FlightGear FDM sub-system.  The FDM subsystem then in turn outputs an aileron deflection back to the property tree where it is then read by the FG animation subsystem to animate the aileron deflection in the 3D model.


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 the joystick input, once exposed in the property tree, can be read and modified by an external application via the [[FlightGear I/O subsystem]], such as an external FDM. The output from the external FDM can then be fed back to FlightGear by writing its data back to the property tree, once again, via the FlightGear I/O subsystem.


Alternatively data [the joystick input], once exposed in the property tree, can be read and modified by an external application
There are several subsystems that implement a full API by extending the property tree, such as the AI traffic system, the multiplayer mode, but also Canvas - basically, setting certain properties (for example via Nasal's setprop()), triggering certain code (through listener callbacks) - with arguments and return values passed through the property tree, which in turn allows arbitrary 3D models to be placed, but also AI traffic to be created / controlled, as well as OpenGL textures to be created and modified and run-time, which is what we use to implement HUDs, GUIs, instruments, MFD avionics, and even liveries or scenery textures (VGDS).
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
== The organization of the property tree ==
IO sub-system.
Naming a property is very much like naming a file in a file system, with levels of hierarchy. For example:  
 
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.
 
 
To make it easier to manipulate the tree, start FlightGear with the following command line
fgfs --httpd=5480
Then after a few moments open in a new window - [http://localhost:5480 http://localhost:5480]
 
== 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.
 
The "virtual" tree that runs the simulation appears much like a directory/file structure. eg:
<pre>
<pre>
/sim/aircraft = A333
/sim/aircraft = A333
Line 51: Line 32:
/controls/electric/APU-generator
/controls/electric/APU-generator
</pre>
</pre>
Some of these variables are "calculated" within the sim, whilst others can be manipulated. Writing a variable is as easy as
 
Some of these variables are "calculated" within the sim (for example updated regularly, in essence at frame rate), whilst others can be manipulated. Writing a variable is as easy as
  /* Its my turn to play the sim */
  /* Its my turn to play the sim */
  set('/controls/seat/eject/initiate', 1)
  set('/controls/seat/eject/initiate', 1)


The values can also be set from the httpd interface.
What makes FlightGear 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 that will be used within the property tree.
 
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".
== Customizing and manipulating the property tree through Nasal ==
An important feature of the property tree interface is that it can be tailored and new entries added as required through [[Nasal]] scripts, without requiring C++ changes. If you wish to use a custom-written subsystem, such as your own terrain following and avoidance subsystem, for example, and perhaps implemented in [[Nasal]], adding new property tree branches and nodes to handle your unique data presents no problems.


The property tree is read, written, accessed and manipulated in a variety of ways, such as
The property tree is read, written, accessed and manipulated in a variety of ways, such as
* startup arguments via <nowiki>--prop:/sim/foo=bar</nowiki>
* XML files
* internal compiled code within FG - the c/c++ code
* 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.
* [[Nasal]] scripts - this is javascript-like scripting with read/write to the property tree. This is the way most aircraft are implemented.
* sockets that are either in/out/bi - this allows send/recieve to the FG sim via sockets
* Using native protocols, implemented in C++ (see {{fg src file|src/Network}}). [[Property Tree/Sockets]]
* telnet interface - query and fly the plane on the command line (see [[Telnet usage]])
* Using the generic protocol, either in/out/bi - this allows send/receive to the FG sim via the [[Generic Protocol]]
* html interface - fly the plane with a browser or an PDA
* telnet interface - query and fly the plane on the command line or using a scripted session (see [[Telnet usage]])
For example, multiplayer mode is accomplished by exchanging sets of variables from the tree (height, position, speed, etc).
* 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).
 
 
== XML and property lists ==
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.
 
PropertyList-encoded XML files are mapped to a/the property tree - typically, such XML files are not manually processed, they are "transparently" processed by FlightGear, loaded and mapped into a Property Tree.
 
== Network Protocols to access the property tree ==
In addition to the protocols supported by the FlightGear I/O subsystem, other interfaces are provided by a built-in [[Property Tree/Web Server]] and a built-in [[Telnet usage|Telnet server]], which allow property tree data to be read and modified via these interfaces, in essence using a telnet client or a conventional web browser, at run time.
 
Note that you can setup as many of these servers as you want, for instance, just to be obscene you could do:
<pre>
fgfs --httpd=5400 --httpd=5401 --httpd=5402 --telnet=5403 --telnet=5404 --telnet=5405
</pre>
 
Now there are six network interfaces running that you can access from anywhere ;-)
 
>> "can I borrow your ipod please?" "why?"
 
=== 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?
 
==Dumping the Property Tree to an XML File==
 
Nasal command "io.write_properties" is used to dump all or part of the property tree to an xml file.  The command can be entered interactively while using the simulator or as part of a script.
 
To enter the command interactively, select Nasal Console from the Debug menu and enter the command:
 
<code>io.write_properties(getprop("/sim/fg-home") ~ "/PropTree.xml", "/");</code>
 
This will dump the entire property tree, in a file containing more than 50,000 lines
 
We can also dump only part of the property tree. For example, to dump everything in /instrumentation/kma20, we would use this:
 
<code>io.write_properties(getprop("/sim/fg-home") ~ "/PropTree.xml", "/instrumentation/kma20");</code>
 
In addition to debugging, there are other good reasons for doing a dump of portions of the property tree.
 
* [[Howto:Create_animation_XML_files_from_Nasal|Creating Animation XML files]]
* [[State Overlay System|Creating State Overlays for Aircraft]]
 
== Reference documentation to the property tree ==
By what was said above, the property tree is not consistent with fixed variables, they are created dynamically, to represent a propeller plane, a Jumbo or even a "Caspian Sea Monster", or depending on which subsystems are active. Many properties 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


== Flight Dynamics Model (FDM) ==
== Flight Dynamics Model (FDM) ==
Line 75: Line 109:
* [[JSBSim]]  
* [[JSBSim]]  
* [[YASim]]  
* [[YASim]]  
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.
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.


[[Category:Property Tree| ]]
[[Category:Nasal]]
[[Category:Nasal]]
[[Category:XML]]
[[Category:XML]]
[[Category:Property Tree]]

Revision as of 01:24, 4 April 2019

The property tree is considered FlightGear's central nervous system and one of its greatest assets. It is the interface to low level, run time state variables via a very intuitive tree-like hierarchy, allowing for FlightGear's behavior to be easily controlled and manipulated at run time.

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 purpose of the 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 models, or the weather simulation. 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 them change its current state by allowing to write to its 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 and for external input/output.

There is some basic property-debugging support to FlightGear and SimGear. In FlightGear, the --trace-read option causes all read access for a property to be traced, and the --trace-write option causes all write access for a property to be traced, both through SG_LOG messages.

Examples of use

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

Alternatively the joystick input, once exposed in the property tree, can be read and modified by an external application via the FlightGear I/O subsystem, such as an external FDM. The output from the external FDM can then be fed back to FlightGear by writing its data back to the property tree, once again, via the FlightGear I/O subsystem.

There are several subsystems that implement a full API by extending the property tree, such as the AI traffic system, the multiplayer mode, but also Canvas - basically, setting certain properties (for example via Nasal's setprop()), triggering certain code (through listener callbacks) - with arguments and return values passed through the property tree, which in turn allows arbitrary 3D models to be placed, but also AI traffic to be created / controlled, as well as OpenGL textures to be created and modified and run-time, which is what we use to implement HUDs, GUIs, instruments, MFD avionics, and even liveries or scenery textures (VGDS).

The organization of the property tree

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

/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 (for example updated regularly, in essence 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)

What makes FlightGear 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 that will be used within the property tree.

Customizing and manipulating the property tree through Nasal

An important feature of the property tree interface is that it can be tailored and new entries added as required through Nasal scripts, without requiring C++ changes. If you wish to use a custom-written subsystem, such as your own terrain following and avoidance subsystem, for example, and perhaps implemented in Nasal, adding new property tree branches and nodes to handle your unique data presents no problems.

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 $FG_SRC/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).


XML and property lists

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.

PropertyList-encoded XML files are mapped to a/the property tree - typically, such XML files are not manually processed, they are "transparently" processed by FlightGear, loaded and mapped into a Property Tree.

Network Protocols to access the property tree

In addition to the protocols supported by the FlightGear I/O subsystem, other interfaces are provided by a built-in Property Tree/Web Server and a built-in Telnet server, which allow property tree data to be read and modified via these interfaces, in essence using a telnet client or a conventional web browser, at run time.

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?"

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?

Dumping the Property Tree to an XML File

Nasal command "io.write_properties" is used to dump all or part of the property tree to an xml file. The command can be entered interactively while using the simulator or as part of a script.

To enter the command interactively, select Nasal Console from the Debug menu and enter the command:

io.write_properties(getprop("/sim/fg-home") ~ "/PropTree.xml", "/");

This will dump the entire property tree, in a file containing more than 50,000 lines

We can also dump only part of the property tree. For example, to dump everything in /instrumentation/kma20, we would use this:

io.write_properties(getprop("/sim/fg-home") ~ "/PropTree.xml", "/instrumentation/kma20");

In addition to debugging, there are other good reasons for doing a dump of portions of the property tree.

Reference documentation to the property tree

By what was said above, the property tree is not consistent with fixed variables, they are created dynamically, to represent a propeller plane, a Jumbo or even a "Caspian Sea Monster", or depending on which subsystems are active. Many properties 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

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.