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