Generic protocol: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(http://www.mail-archive.com/flightgear-devel@flightgear.org/msg32560.html)
Line 165: Line 165:
  </PropertyList>
  </PropertyList>


===Writing data in XML format====
===Writing data in XML format===
Assuming the file is called [[$FG ROOT]]/Protocol/xmltest.xml, then it could be used as  
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
  fgfs --generic=file,out,1,/tmp/data.xml,xmltest
Line 190: Line 190:
       </chunk>
       </chunk>
   
   
For more examples, see [http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg37892.html].
       <chunk>
       <chunk>
         <node>/velocities/airspeed-kt</node>
         <node>/velocities/airspeed-kt</node>
Line 202: Line 203:
  </generic>
  </generic>
  </PropertyList>
  </PropertyList>


== Analyzing the resulting binary packet format ==
== Analyzing the resulting binary packet format ==

Revision as of 19:36, 26 March 2013

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.

The generic protocol can be easily set up for both input and output. And it supports not just a single medium, but can be easily made to use files, FIFOs, sockets etc. The generic protocol is really good for things like exporting to a delimited ascii file for import into excel for instance.

XML 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. The following example would only use the <output> definitions block.

--generic=file,out,1,/tmp/data.xml,myproto

If you're using a serial port under Windows, you must use a special escape sequence for COM port numbers higher than COM9.

Ex: --generic=\\.\COM10,out,1,/tmp/data.xml,myproto

More detail can be found in this Microsoft KB article: http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx

Overview of the XML file

<?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 <input> 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> is put between every two output properties
  • <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>                 

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 and not tranferred (like a notes tag)

<node>

The property tree node which provides the data

<type>

The value type which is needed for formatting, one of string, float, bool, int (default: int). Its recommended that this tag is present otherwise spurious results can occur.

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

<format>

Chunks can also consist of a single constant <format>, like in:

<format>Data Section</format>


Examples

Example 1

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>  
     </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 format

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>

For more examples, see [1].

     <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

Generic Protocol

FlightGear has an inbuilt "generic" protocol to push and pull data. (todo)

To interface with FlightGear on a socket for example, the following steps need to be taken.

  1. Establish which "properties" you want to appear "on the wire"
  2. Create a my_protocol.xml file containing those properties
  3. Start flight gear on a socket using my_protocol.

For this simple example say were interested in heading and altitude, and we want to "listen" ie output to a socket at port 6789, udp and receiving 10 times a second in the format:

alt\thead\n 
// ie altitude - tab - heading - newline

The first step is establishing the nodes, in this example

/position/altitude-agl-ft  eg (22.4713923)
/orientation/heading-deg  eg (297.966325)

Next create a file my_protocol.xml. This needs to be located at

$FG_ROOT/Protocol/my_protocol.xml

The XML looks like this:

<?xml version="1.0"?>
<PropertyList>
<generic>
   <output>
       <line_separator>newline</line_separator>
       <var_separator>tab</var_separator>

       <chunk>
          <node>/position/altitude-agl-ft</node>
          <name>altitude to go</name>
          <type>float</type>
          <format>%03.2f</format>
        </chunk>

       <chunk>
          <node>/orientation/heading-deg</node>
          <name>Heading</name>
          <type>float</type>
          <format>%03.3f</format>
        </chunk>

   </output>
 </generic>
</PropertyList>
  • The output tag indicates the protocol for output. The same "protocol" file can contain an "input" section, absent in this example (more later).
  • line_seperator - the end of line (todo ? is this \r\n??)
  • var_seperator - the delimiter for the properties, this could be "|", "###", any string.
  • The two chunk blocks contain our data. Note that these appear in the order presented within the xml file.
    • node - the node of data we want
    • name - it there for a reference, its not transmitted and note necessary (like a note)
    • type - the way this xml is to interpret the value. This is quite important tag. For example if its not there or a string, then "floats" go wild and end up being a string of 32 characters with two decimal places!
    • format - same syntax as printf
    • There's more that can be done {todo - link to a full blown example/reference}

We can now start FlightGear and listen with:

fgfs --generic=socket,out,10,localhost,6789,udp,my_protocol

[todo] - link here to the tutorial



External links