Subsections

XML Autopilot Config File

FlightGear implements this PID algorithm in a flexible and reusable way. It reads an autopilot config file that can define any number of PID controllers. Each controller can specify it's own process value, it's own reference point, any number of output values, as well as values for all the other tuning constants.

You can create cascading controllers by specify multiple PID controllers (all with the same enabling condition) where the output of the first stage is used as the input to the second, and the output of the second is used as the input to the third, etc.

Specifying the Autopilot Configuration

The FlightGear .../data/preferences.xml file contains a reference to the default autopilot file:

 <sim>
  <systems>
   <autopilot>
    <path>Aircraft/Generic/generic-autopilot.xml</path>
   </autopilot>
  </systems>
 </sim>

If you would like to specify a different autopilot configuration file for a particular aircraft, you can override this definition in the aircraft's <aircraft>-set.xml file.

Configuration file overview

The autopilot configuration file is a standard FlightGear .xml file. It's basic structure is as follows:

<?xml version="1.0"?>
<PropertyList>
  <pid-controller>
    <!-- First PID controller params -->
  </pid-controller>
  <pid-controller>
    <!-- Second PID controller params -->
  </pid-controller>
  <pid-controller>
    <!-- Third PID controller params -->
  </pid-controller>
  .
  .
  .
</PropertyList>

PID Controller Specification

Each PID controller section can list a name, the input (or process) property, the target (or reference) property, and any number of output properties. Here ``property'' means the name of an internal FlightGear property from the FG property system. You also specify a property name and value that is check to see if the controller is activated or not, and you can turn debugging output on or off for this controller. Finally there is a <config> section listing all the parameters you can tune. Here is an example of a simple PID controller which holds a fixed pitch.

 <!-- Simple pitch hold --> 
 <pid-controller>
    <name>Pitch hold</name>
    <debug>false</debug>
    <enable>
      <prop>/autopilot/locks/altitude</prop>
      <value>pitch-hold</value>
    </enable>
    <input>
      <prop>/orientation/pitch-deg</prop>
    </input>
    <reference>
      <prop>/autopilot/settings/target-pitch-deg</prop>
    </reference>
    <output>
      <prop>/controls/flight/elevator-trim</prop>
    </output>
    <config>
      <Kp>-0.05</Kp>      <!-- proportional gain -->
      <beta>1.0</beta>    <!-- input value weighing factor -->
      <alpha>0.1</alpha>  <!-- low pass filter weighing factor -->
      <gamma>0.0</gamma>  <!-- input value weighing factor for -->
                          <!-- unfiltered derivative error -->
      <Ti>1.0</Ti>        <!-- integrator time -->
      <Td>0.00001</Td>    <!-- derivator time -->
      <u_min>-1.0</u_min> <!-- minimum output clamp -->
      <u_max>1.0</u_max>  <!-- maximum output clamp -->
    </config>
   </pid-controller>

In this example we give the <pid-controller> a <name> of ``Pitch Hold''. This name is only used when outputting debug information.

You can set <debug> to be true or false.

The controller will be activated when ever /autopilot/locks/altitude has a value of pitch-hold.

The <input> (or process) value is /orientation/pitch-deg. This is the value that we are trying to control indirectly via this PID controller.

The <reference> (or target) value is /autopilot/settings/target-pitch-deg. The PID controller is trying to make the input value equal the reference value. (In other words it is trying to make the error or difference between the two be as close to zero as possible.)

The <output> tag list the property where the output of the PID algorithm will be written. This is typically something in the /controls/ section of the property tree. In this example, we know that adjusting elevator trim will affect the aircraft's pitch. We hope that the PID magic will figure out what trim setting will produce our target pitch.

Finally we have the <config> section. Please see the xml comments in this example as well as the previous section for a more complete explanation of what they are and how they plug into and affect the PID algorithm.

Cascading Controllers

Cascading controllers are useful for more complex situations. Cascading controllers link the output from one PID unit as the input to another PID unit.

For example, a heading hold autopilot could be constructed with two PID units. The first unit would have the current heading as the ``process value'' and the target heading as the ``reference value''. It would output a ``target roll'' proportional to the heading error. The second unit would have the current roll angle as it's process value and the target roll as it's reference value. Notice that in this case, the reference value can be a moving target. The second PID controller would then output an aileron deflection to achieve the desired roll angle.

The autopilot system evaluates each PID controller in the order they are specified. You are allowed to use (or make up) any property name for the <input>, <output>, and <reference> sections.

This allows you to easily build cascading controllers. The generic-autopilot.xml file has several examples of these. I usually choose a property name called /autopilot/internal/abcdefg as the intermediate value which is output from the first stage as input to the second stage.

It is important to think through your design very carefully so you can get the proper process value, reference value, and output value for each stage.

Curtis L. Olson 2004-02-04