Howto:Design an autopilot: Difference between revisions

Jump to navigation Jump to search
heading hold added, thanks Torsten!
No edit summary
(heading hold added, thanks Torsten!)
Line 5: Line 5:
For a technical reference of the used elements, check [[Autopilot Configuration Reference]].
For a technical reference of the used elements, check [[Autopilot Configuration Reference]].


===Pre-design===
==Pre-design==
Why not make things slightly easier, before we start working on the autopilot? Since we will be updating the autopilot hunderts of times, making tiny adjustments each time, we don't want to reload FlightGear every time. Therefore, we assign an "reload autopilot configuration" action to a key on our keyboard. We've chosen Shift-F5, but it could be any key. Add the code to your <tt>[[$FG_ROOT]]/keyboard.xml</tt> file.
Why not make things slightly easier, before we start working on the autopilot? Since we will be updating the autopilot hunderts of times, making tiny adjustments each time, we don't want to reload FlightGear every time. Therefore, we assign an "reload autopilot configuration" action to a key on our keyboard. We've chosen Shift-F5, but it could be any key. Add the code to your <tt>[[$FG_ROOT]]/keyboard.xml</tt> file.
  <key n="261">
  <key n="261">
Line 22: Line 22:
  </key>
  </key>


===Creating the autopilot configuration file===
==Creating the autopilot configuration file==
Create an autopilot.xml file with the following content, somewhere inside your aircraft's root (eg. <tt>Aircraft/747-400/Systems/autopilot.xml</tt>).
Create an autopilot.xml file with the following content, somewhere inside your aircraft's root (eg. <tt>Aircraft/747-400/Systems/autopilot.xml</tt>).
  <?xml version="1.0"?>
  <?xml version="1.0"?>
Line 30: Line 30:
  </PropertyList>
  </PropertyList>


===A first controller: heading hold===
==A first controller: wing leveler==
Let's start with a simple wing leveler that keeps your bank angle at zero (or any arbitrary value later). This could be a PID controller with the input from your current roll and a reference of zero. Output should go to your aileron-cmd. Start with:
Let's start with a simple wing leveler that keeps your bank angle at zero (or any arbitrary value later). This could be a PID controller with the input from your current roll and a reference of zero. Output should go to your aileron-cmd. Start with:
* '''Kp:'''  0.00
* '''Kp:'''  0.00
Line 73: Line 73:
** '''u_max:''' the maximum output.
** '''u_max:''' the maximum output.


To get an idea of the Kp-value, you need to do a simple calclulation. The PID controller computes "reference - input". If you want wings leveled (zero roll) and your current bank angle is, say 30 degrees, the result of "reference - input" is -30. If you think you need full aileron deflection to get from 30 degrees bank to zero in a reasonable time, you need a factor of 1/30=0.033, because aileron-cmd is in the range of -1 to +1. This is the approximate value for your Kp.
To get an idea of the Kp-value, you need to do a simple calclulation. The PID controller computes "reference - input". If you want wings leveled (zero roll) and your current bank angle is, say 30°, the result of "reference - input" is -30. If you think you need full aileron deflection to get from 30 degrees bank to zero in a reasonable time, you need a factor of 1/30=0.033, because aileron-cmd is in the range of -1 to +1. This is the approximate value for your Kp.


Now enter your aircraft and climb to cruise altitude and cruise speed. Bank your aircraft, to 15-20 degrees. Enable your controller (in our example that is by setting <tt>/autopilot/locks/heading=wing-leveler</tt>. [[Property Browser|Look here]] if you need help on setting properties.) and - nothing happens (because Kp is still zero). Set the value of Kp to 0.01 and hit Shift-F5 to reload your configuration and check what happens. Does the controller tries to level the wings or do things go worse? If the ailerons move in the wrong direction, you need to reverse the sign of Kp.  
Now enter your aircraft and climb to cruise altitude and cruise speed. Bank your aircraft, to 15°-20°. Enable your controller (in our example that is by setting <tt>/autopilot/locks/heading=wing-leveler</tt>. [[Property Browser|Look here]] if you need help on setting properties.) and - nothing happens (because Kp is still zero). Set the value of Kp to 0.01 and hit Shift-F5 to reload your configuration and check what happens. Does the controller tries to level the wings or do things go worse? If the ailerons move in the wrong direction, you need to reverse the sign of Kp.  


Once you found the correct sign for Kp, slowly (in steps as little as 0.005) increase the value of Kp to get a fast response. Don't forget to reload the config with Shift-F5 after every edit of your file. There is one pitfall that can drive you crazy: the PID-controller computes delta-values for its correction and it starts with the current setting of your aileron when it is enabled or reloaded. If you have your aileron set to -0.2 when you hit Shift-F5, the controller will apply its corrections to a value of -0.2 which will most certainly fail! Make sure that you have your flight controls neutral (press 5) when (re-)enabling PID-controllers!
Once you found the correct sign for Kp, slowly (in steps as little as 0.005) increase the value of Kp to get a fast response. Don't forget to reload the config with Shift-F5 after every edit of your file. There is one pitfall that can drive you crazy: the PID-controller computes delta-values for its correction and it starts with the current setting of your aileron when it is enabled or reloaded. If you have your aileron set to -0.2 when you hit Shift-F5, the controller will apply its corrections to a value of -0.2 which will most certainly fail! Make sure that you have your flight controls neutral (press 5) when (re-)enabling PID-controllers!
Line 110: Line 110:
This is the base for any lateral hold mode, so try to spend some time on it. It can take some hours if this is your first autopilot.
This is the base for any lateral hold mode, so try to spend some time on it. It can take some hours if this is your first autopilot.


===Pitch hold===
==Pitch hold==
So, let's move over to a pitch hold. Our goal is to have a controller that maintains an arbitrary pich. The only difference to the wing leveler is that you are only interested in elevator position changes, not absolute values. To put it in other words: increase elevator for more pitch, decrease for less pitch and maintain elevator position if the pitch is right. This calls for a pid-controller, because it only computes offset values. And you will end up with a relative small value for Kp to avoid rapid imediate movements and a relative small value for Ti to have a greater effect over time.
So, let's move over to a pitch hold. Our goal is to have a controller that maintains an arbitrary pich. The only difference to the wing leveler is that you are only interested in elevator position changes, not absolute values. To put it in other words: increase elevator for more pitch, decrease for less pitch and maintain elevator position if the pitch is right. This calls for a pid-controller, because it only computes offset values. And you will end up with a relative small value for Kp to avoid rapid imediate movements and a relative small value for Ti to have a greater effect over time.


Line 117: Line 117:
Again increase you Kp slowly and check each step in FlightGear. I'd expect something like -0.025 resulting in an instanteanous full elevator deflection on a 40 degrees pitch offset. Do not try too large values; it results in instable behaviour very quickly. Now, decrease the value of Ti, probably down to 10 or so. The smaller it gets, the faster the elevator moves and the easier it is to get an unstable loop. Again it is very likely that you won't need Td to get a stable controller.
Again increase you Kp slowly and check each step in FlightGear. I'd expect something like -0.025 resulting in an instanteanous full elevator deflection on a 40 degrees pitch offset. Do not try too large values; it results in instable behaviour very quickly. Now, decrease the value of Ti, probably down to 10 or so. The smaller it gets, the faster the elevator moves and the easier it is to get an unstable loop. Again it is very likely that you won't need Td to get a stable controller.


===Simulating servos===
==Simulating servos==
Once you have this two axies running, you might want to think about simulating the slow movements of the servo or hydraulic motors that drive the control surfaces. You might have noticed, that the controls react rapidly when enabled which is unrealistic. In a [[Seneca]], the aileron servo takes 12 seconds to move from left to right. The elevator needs 26 seconds and the pitch trim takes 45 seconds for full travel.
Once you have this two axies running, you might want to think about simulating the slow movements of the servo or hydraulic motors that drive the control surfaces. You might have noticed, that the controls react rapidly when enabled which is unrealistic. In a [[Seneca]], the aileron servo takes 12 seconds to move from left to right. The elevator needs 26 seconds and the pitch trim takes 45 seconds for full travel.


Line 211: Line 211:
You probably have to adjust the property names. Note the condition element in the <enable> section - it has the same syntax as in the well-known <animation> elements. As long as the roc-lock property is false, input is copied to output. When it becomes true, the output property is no longer written by this filter and the next step can use this value as a start.  
You probably have to adjust the property names. Note the condition element in the <enable> section - it has the same syntax as in the well-known <animation> elements. As long as the roc-lock property is false, input is copied to output. When it becomes true, the output property is no longer written by this filter and the next step can use this value as a start.  


Right behind this filter, add a pid-controller using your current rate-of-climb as input and a target-rate-of-climb as reference. Enable this pid if your pitch sample-and-hold is not enabled (use the same condition, just remove the <not> elements). Your output goes to target-pitch-deg which should be the same property as the input of your pitch-hold controller. Use the same procedure to obtain the values for Kp and Ti. Kp will be small. The offset computes in feet per minute and 100fpm should result in a few degrees pitch change. Something like 0.01 or smaller will probably do. I'd expect Integrator time around 10-50. You should clamp the target-pitch to something less than +/- 90 degrees - probably -10 and +20 degrees or whatever is a reasonable value for your aircraft. It could look like this:
Right behind this filter, add a pid-controller using your current rate-of-climb as input and a target-rate-of-climb as reference. Enable this pid if your pitch sample-and-hold is not enabled (use the same condition, just remove the <not> elements). Your output goes to target-pitch-deg which should be the same property as the input of your pitch-hold controller. Use the same procedure to obtain the values for Kp and Ti. Kp will be small. The offset computes in feet per minute and 100fpm should result in a few degrees pitch change. Something like 0.01 or smaller will probably do. I'd expect Integrator time around 10-50. You should clamp the target-pitch to something less than +/- 90° - probably -10° and +20° or whatever is a reasonable value for your aircraft. It could look like this:


  <pid-controller>
  <pid-controller>
Line 280: Line 280:


This is nearly all for altitude-hold with altitude-preselect. You can add an altitude-sample-and-hold stage to add a "hold my current altitude" function.
This is nearly all for altitude-hold with altitude-preselect. You can add an altitude-sample-and-hold stage to add a "hold my current altitude" function.
==Heading hold==
For heading hold, you build a two stage system. The first is a comparator comparing your selected heading and the indicated heading. 1. Stage, compute heading offset. Note the period element at the bottom, it normalizes the output into the periodic -180 to +180 range
<filter>
  <name>Heading Offset Computer</name>
  <debug>false</debug>
  <type>gain</type>
  <gain>1.0</gain>
  <input>/autopilot/settings/heading-bug-deg</input>
  <reference>/orientation/heading-magnetic-deg</reference>
  <output>/autopilot/internal/heading-offset-deg</output>
  <period>
  <min>-180</min>
  <max>180</max>
  </period>
</filter>
The second stage computes a bank angle from a heading offset. At least for smaller planes, a rule of thumb says "roll out at half the bank angle". If you fly a right hand turn at a bank angle of, say, 20° and want to end at a heading of 270°, you start your roll out at 20°/2 = 10° before your target heading. So you start rolling out at 280°. We turn this rule around and say our bank angle is twice the heading error but not more that 30° This results in a simple gain filter:
<filter>
  <name>Target Roll Computer</name>
  <debug>false</debug>
  <enable>
  <prop>/autopilot/locks/heading</prop>
  <value>dg-heading-hold</value>
  </enable>
  <type>gain</type>
  <input>/autopilot/internal/heading-offset-deg</input>
  <output>/autopilot/internal/target-roll-deg</output>
  <gain>2.5</gain>
  <min>-30.0</min>
  <max>30.0</max>
</filter>
This filter feeds your wing leveler which is already done. You might want to make the target roll computer switchable with an enable element, otherwise it will overwrite your target-roll-deg. Decreasing the gain of two should help, if your roll-rate is to slow. You can also play with the min/max values to have a nice standard rate turn. The bank angle for the standard turn is a function of your true airspeed; you can build a controller calculating the correct bank angle and feed this value into min/max (which is a commen feature on airliners).


[[Category:Aircraft enhancement|Design an autopilot]]
[[Category:Aircraft enhancement|Design an autopilot]]
[[Category:Howto|Design an autopilot]]
[[Category:Howto|Design an autopilot]]

Navigation menu