294 lines
8.7 KiB
Plaintext
294 lines
8.7 KiB
Plaintext
|
The generic communication protocol for FlightGear provides a powerful way
|
||
|
of adding a simple ASCII based or binary input/output protocol, just by
|
||
|
defining an XML encoded configuration file and placing it in the
|
||
|
$FG_ROOT/Protocol/ directory.
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
== file layout ================================================================
|
||
|
|
||
|
A protocol file can contain either or both of <input> and <output>
|
||
|
definition blocks. Which one is used depends on how the protocol
|
||
|
is called (e.g. --generic=file,out,1,/tmp/data.xml,myproto would
|
||
|
only use the <output> definitions block).
|
||
|
|
||
|
<?xml version="1.0"?>
|
||
|
<PropertyList>
|
||
|
<generic>
|
||
|
|
||
|
<output>
|
||
|
<binary_mode>false</binary_mode>
|
||
|
<line_separator></line_separator>
|
||
|
<var_separator></var_separator>
|
||
|
<preamble></preamble>
|
||
|
<postamble></postamble>
|
||
|
|
||
|
<chunk>
|
||
|
... first chunk spec ...
|
||
|
</chunk>
|
||
|
|
||
|
<chunk>
|
||
|
... another chunk etc. ...
|
||
|
</chunk>
|
||
|
</output>
|
||
|
|
||
|
<input>
|
||
|
<line_separator></line_separator>
|
||
|
<var_separator></var_separator>
|
||
|
|
||
|
<chunk>
|
||
|
... chunk spec ...
|
||
|
</chunk>
|
||
|
</input>
|
||
|
|
||
|
</generic>
|
||
|
</PropertyList>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
== input/output parameters ====================================================
|
||
|
|
||
|
Both <output> and <input> blocks can contain information about
|
||
|
the data mode (ascii/binary) and about separators between fields
|
||
|
and data sets, as well as a list of <chunk>s. Each <chunk> defines
|
||
|
a property that should be written (and how), or a variable and which
|
||
|
property it should be written to.
|
||
|
|
||
|
--- ASCII protocol parameters ---
|
||
|
|
||
|
output only:
|
||
|
<preamble> STRING default: "" file header put on top of the file
|
||
|
<postamble> STRING default: "" file footer put at the end of the file
|
||
|
|
||
|
input & output:
|
||
|
<binary_mode> BOOL default: false (= ASCII mode)
|
||
|
<var_separator> STRING default: "" field separator
|
||
|
<line_separator> STRING default: "" separator between data sets
|
||
|
|
||
|
|
||
|
<var_separator> are put between every two output properties, while
|
||
|
<line_separator> is put at the end of each data set. Both can contain
|
||
|
arbitrary strings or one of the following keywords:
|
||
|
|
||
|
Name Character
|
||
|
|
||
|
newline '\n'
|
||
|
tab '\t'
|
||
|
formfeed '\f'
|
||
|
carriagereturn '\r'
|
||
|
verticaltab '\v'
|
||
|
|
||
|
|
||
|
Typical use could be:
|
||
|
|
||
|
<var_separator>tab</var_separator>
|
||
|
<line_separator>newline</var_separator>
|
||
|
|
||
|
or
|
||
|
|
||
|
<var_separator>\t</var_separator>
|
||
|
<line_separator>\r\n</line_separator>
|
||
|
|
||
|
|
||
|
--- Binary protocol parameters ---
|
||
|
|
||
|
To enable binary mode, simply include a <binary_mode>true</binary_mode> tag in
|
||
|
your XML file. The format of the binary output is tightly packed, with 1 byte
|
||
|
for bool, 4 bytes for int, and 8 bytes for double. At this time, strings are not
|
||
|
supported. A configurable footer at the end of each "line" or packet of binary
|
||
|
output can be added using the <binary_footer> tag. Options include the length
|
||
|
of the packet, a magic number to simplify decoding. Examples:
|
||
|
|
||
|
<binary_footer>magic,0x12345678</binary_footer>
|
||
|
<binary_footer>length</binary_footer>
|
||
|
<binary_footer>none</binary_footer> <!-- default -->
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
== variable parameters (chunk spec) ===========================================
|
||
|
|
||
|
Both <input> and <output> block can contain a list of <chunk> specs,
|
||
|
each of which describes the properties of on variable to write/read.
|
||
|
|
||
|
|
||
|
<name> for ease of use (not tranferred)
|
||
|
<node> the property tree node which provides the data
|
||
|
<type> the value type (needed for formatting)
|
||
|
one of string, float, bool, int (default: int)
|
||
|
<format> (ASCII protocol only, not used or needed in binary mode)
|
||
|
defines the actual piece of text which should be sent.
|
||
|
it can include "printf" style formatting options like:
|
||
|
<type>
|
||
|
%s string
|
||
|
%d integer (default)
|
||
|
%f float
|
||
|
|
||
|
<factor> an optional multiplication factor which can be used for
|
||
|
unit conversion. (for example, radians to degrees).
|
||
|
<offset> an optional offset which can be used for unit conversion.
|
||
|
(for example, degrees Celcius to degrees Fahrenheit).
|
||
|
|
||
|
For input chunks there exist some more options:
|
||
|
|
||
|
<rel> optional boolean parameter to enable handling of incoming values
|
||
|
as relative changes (default: false)
|
||
|
(Can be eg. used to realise up/down buttons by just sending 1 or
|
||
|
-1 respectively)
|
||
|
|
||
|
<min> an optional minimum limit for the value to be clamped to. This
|
||
|
limit is always specified as absolute value, also with relative
|
||
|
changes enabled. (default: 0)
|
||
|
<max> an optional upper limit for the input value to be clamped to. If
|
||
|
<min> equals <max> no limit is applied. (default: 0)
|
||
|
<wrap> instead of clamping to minimum and maximum limits, wrap values
|
||
|
around. Values will be in [min, max[ (default: false)
|
||
|
(Usefull for eg. heading selector to start again with 1 for
|
||
|
values higher than 360)
|
||
|
|
||
|
<rel>, <min>, <max> and <wrap> are only used for numeric data types. <rel> can
|
||
|
additionally be used with type 'bool', where it toggles the value, if the received
|
||
|
value evaluates to 'true', otherwise the value is left unchanged.
|
||
|
|
||
|
Chunks can also consist of a single constant <format>, like in:
|
||
|
<format>Data Section</format>
|
||
|
|
||
|
|
||
|
== examples ===================================================================
|
||
|
|
||
|
Writes log of this form:
|
||
|
|
||
|
V=16
|
||
|
H=3.590505
|
||
|
P=3.59
|
||
|
V=12
|
||
|
H=3.589020
|
||
|
P=3.59
|
||
|
|
||
|
|
||
|
|
||
|
<?xml version="1.0"?>
|
||
|
|
||
|
<PropertyList>
|
||
|
<generic>
|
||
|
|
||
|
<output>
|
||
|
<line_separator>newline</line_separator>
|
||
|
<var_separator>newline</var_separator>
|
||
|
<binary_mode>false</binary_mode>
|
||
|
|
||
|
<chunk>
|
||
|
<name>speed</name>
|
||
|
<format>V=%d</format>
|
||
|
<node>/velocities/airspeed-kt</node>
|
||
|
</chunk>
|
||
|
|
||
|
<chunk>
|
||
|
<name>heading (rad)</name>
|
||
|
<format>H=%.6f</format>
|
||
|
<type>float</type>
|
||
|
<node>/orientation/heading-deg</node>
|
||
|
<factor>0.0174532925199433</factor> <!-- degrees to radians -->
|
||
|
</chunk>
|
||
|
|
||
|
<chunk>
|
||
|
<name>pitch angle (deg)</name>
|
||
|
<format>P=%03.2f</format>
|
||
|
<node>/orientation/pitch-deg</node>
|
||
|
</chunk>
|
||
|
</output>
|
||
|
|
||
|
</generic>
|
||
|
</PropertyList>
|
||
|
|
||
|
|
||
|
Control the heading bug by sending relative changes separated by newlines:
|
||
|
|
||
|
<?xml version="1.0"?>
|
||
|
|
||
|
<PropertyList>
|
||
|
<generic>
|
||
|
|
||
|
<input>
|
||
|
<line_separator>newline</line_separator>
|
||
|
|
||
|
<chunk>
|
||
|
<name>heading bug</name>
|
||
|
<type>int</type>
|
||
|
<node>/autopilot/settings/heading-bug-deg</node>
|
||
|
<relative>true</relative>
|
||
|
<min>1</min>
|
||
|
<max>360</max>
|
||
|
<wrap>true</wrap>
|
||
|
</chunk>
|
||
|
|
||
|
</input>
|
||
|
|
||
|
</generic>
|
||
|
</PropertyList>
|
||
|
|
||
|
-- writing data in XML syntax -------------------------------------------------
|
||
|
|
||
|
Assuming the file is called $FG_ROOT/Protocol/xmltest.xml, then it could be
|
||
|
used as $ fgfs --generic=file,out,1,/tmp/data.xml,xmltest
|
||
|
|
||
|
|
||
|
<?xml version="1.0"?>
|
||
|
|
||
|
<PropertyList>
|
||
|
<generic>
|
||
|
<output>
|
||
|
<binary_mode>false</binary_mode>
|
||
|
<var_separator>\n</var_separator>
|
||
|
<line_separator>\n</line_separator>
|
||
|
<preamble><?xml version="1.0"?>\n\n<data>\n</preamble>
|
||
|
<postamble></data>\n</postamble>
|
||
|
|
||
|
<chunk>
|
||
|
<format>\t<set></format>
|
||
|
</chunk>
|
||
|
|
||
|
<chunk>
|
||
|
<node>/position/altitude-ft</node>
|
||
|
<type>float</type>
|
||
|
<format>\t\t<altitude-ft>%.8f</altitude-ft></format>
|
||
|
</chunk>
|
||
|
|
||
|
<chunk>
|
||
|
<node>/velocities/airspeed-kt</node>
|
||
|
<type>float</type>
|
||
|
<format>\t\t<airspeed-kt>%.8f</airspeed-kt></format>
|
||
|
</chunk>
|
||
|
|
||
|
<chunk>
|
||
|
<format>\t</set></format>
|
||
|
</chunk>
|
||
|
</output>
|
||
|
</generic>
|
||
|
</PropertyList>
|
||
|
|
||
|
|
||
|
-- Analyzing the resulting binary packet format -------------------------------
|
||
|
|
||
|
A utility called generic-protocol-analyse can be found under
|
||
|
FlightGear/utils/xmlgrep which can be used to analyze the resulting
|
||
|
data packet for the binary protocol.
|
||
|
|
||
|
The output would be something like:
|
||
|
|
||
|
bintest.xml
|
||
|
Generic binary output protocol packet description:
|
||
|
|
||
|
pos | size | type | factor | description
|
||
|
-----|------|--------|------------|------------------------
|
||
|
0 | 4 | int | | indicated speed (kt)
|
||
|
4 | 4 | float | | pitch att (deg)
|
||
|
8 | 4 | float | | magnetic heading (deg)
|
||
|
12 | 4 | int | | outside air temperarure (degF)
|
||
|
16 | 1 | bool | | autocoord
|
||
|
|
||
|
total package size: 17 bytes
|
||
|
|