Property tree: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(Fixed broken dump properties command, rewrite for easier understanding)
(40 intermediate revisions by 17 users not shown)
Line 1: Line 1:
== Property Server ==
{{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.


For instance, start FlightGear with the following option:
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.


--httpd=5400
== 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.


You can pick any port number, but 5400 will probably work just fine.
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.


Now on the same machine, fire up a web browser and open up the following url:
=== 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.


http://localhost:5400/
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.


Now you can browse the entire FG property tree "live" and even change values if you like. You can configure autopilot modes and even set control inputs so you can literally fly the airplane from your web browser, although it's not the most convenient interface for doing that. ;-)
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).


There is a similar interface minus the html wrappings that you can enable with the following option:
== 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:  
<pre>
/sim/aircraft = A333


--props=5401
/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
</pre>


Note that you can setup as many of these as you want ... for instance, just to be obscene you could do:
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)


--httpd=5400
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.
--httpd=5401
--httpd=5402
--props=5403
--props=5404
--props=5405


== 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.


Now you have 6 different network interfaces running that you can access from anywhere. We can't find a wiki named Note.
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
* [[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 file|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


If you have a 'props' inteface configured you can now "telnet localhost 5401" and interact with the property system (again live) and set and examine values using a 'command line' style interface.
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).


The cool thing is that you can easily write scripts to access this --props=<port#> interface.


Take a look at:
== 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.


FlightGear/source/scripts/perl/examples/
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 there is no requirement that you do this with perl. You could just as easily interact with FlightGear this way using perl, C, C++, java, probably even <ack> visual basic or anything else that can do tcpip network communication ... matlab? netcat?
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>


Also note that the downside to this interface is that you can't blast a lot of data across it. It's fine if you want to monitor location and speed every second or 1/4 second and occasionally set some values (such as dump in a new weather configuration, reset the aircraft location, or read a set of values, etc.)
Now there are six network interfaces running that you can access from anywhere ;-)


But if you need to track 100 different variables at 60hz, this isn't the interface for you.
>> "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.


== Property Tree ==
To enter the command interactively, select Nasal Console from the Debug menu and enter the command:
A detailed list of all nodes within the property tree and their purpose, as well as possible values


==== accelerations/ ====
<code>io.write_properties(getprop("/sim/fg-home") ~ "/PropTree.xml", "/");</code>
==== ai/ ====
==== autopilot/ ====
==== command/ ====
==== consumables/ ====


* fuel/
This will dump the entire property tree, in a file containing more than 50,000 lines
** tank/
** tank[1]/
** tank[2]/
** tank[3]/
** total-fuel-gals
** total-fuel-lbs
** total-fuel-norm


==== controls/ ====
We can also dump only part of the property tree. For example, to dump everything in /instrumentation/kma20, we would use this:
==== devices/ ====
==== engines/ ====
==== environment/ ====
==== fdm/ ====
==== gear/ ====
==== input/ ====
==== instrumentation/ ====
==== logging/ ====
==== models/ ====
==== nasal/ ====
==== orientation/ ====
The set of properties in orientation/ detail the orientation of the aircraft (pitch, yaw and roll).


* alpha-deg
<code>io.write_properties(getprop("/sim/fg-home") ~ "/PropTree.xml", "/instrumentation/kma20");</code>
* heading-deg
* heading-magnetic-deg
* pitch-deg
* pitch-rate-degps
* roll-deg
* roll-rate-degps
* side-slip-deg
* side-slip-rad
* yaw-deg
* yaw-rate-degps


==== position/ ====
In addition to debugging, there are other good reasons for doing a dump of portions of the property tree.
The set of properties in position/ track the lat/lon location of the user's aircraft, as well as altitude and ground elevation immediately below the aircraft.


* longitude-deg -- Current longitude of the aircraft in degrees.
* [[Howto:Create_animation_XML_files_from_Nasal|Creating Animation XML files]]
* latitude-deg -- Current latitude of the aircraft in degrees.
* [[State Overlay System|Creating State Overlays for Aircraft]]
* altitude-ft -- Current altitude of the aircraft above mean sea level.
* ground-elev-m -- elevation of the ground below the aircraft, in meters.  Note that for this property,  ground structures are considered part of the ground.  Thus, flying over any ground structure (a building, a sign, a radio tower, whatever) will raise the value of this property for as long as the aircraft is over the structure.
* altitude-agl-ft -- Current altitude of the aircraft above ground/ground structures below.


==== sim/ ====
== Reference documentation to the property tree ==
* aero --
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.
* ai
* ai-traffic
* aircraft --
* aircraft-dir --
* aircraft-min-status --
* alarms --
* allow-toggle-cockpit --
* ATC
* atc
* author --
* auto-coordination -- boolean (true/false) flag indicating whether auto-coordination is on or off.
* chase-distance-m --
* control-mode --
* current-view
* description --
* flight-model --
* frame-rate --
* freeze
* hud
* input
* instrumentation
* instrument-options
* intl
* logging
* model-hz --
* multiplay
* panel
* presets
* rendering
* sound
* speed-up --
* startup
* status --
* time
* view-mode --
* menubar/
* model/
* mouse/
* navdb/
* number-views =  '6'    (int)
* replay/
* sceneryloaded = 'true'  (bool)
* submodels/
* systems/
* temp/
* tower/
* traffic-manager/
* user/
* view/
* view[1]/
* view[2]/
* view[3]/
* view[4]/
* view[5]/
* virtual-cockpit =      'false' (bool)


==== surface-positions/ ====
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.
==== systems/ ====
 
==== velocities/ ====
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
<nowiki>   
 
</nowiki>
== Flight Dynamics Model (FDM) ==
[http://www.beispiel.de Link-Text]
FlightGear uses a few [[Flight Dynamics Models]], such as
[[Media:Beispiel.mp3]]
* [[JSBSim]]
[[Image:Beispiel.jpg]]
* [[YASim]]
fgfs --aircraft=(beispiel-737)
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:XML]]

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.