% % `AltitudeHold.tex' -- describes the FGFS Altitude Hold % % Written by Curtis Olson. Started December, 1997. % % $Id$ %------------------------------------------------------------------------ \documentclass[12pt]{article} \usepackage{anysize} \papersize{11in}{8.5in} \marginsize{1in}{1in}{1in}{1in} \usepackage{amsmath} \usepackage{epsfig} \usepackage{setspace} \onehalfspacing \usepackage{url} \begin{document} \title{ Flight Gear Autopilot: \\ Altitude Hold Module } \author{ Curtis Olson \\ (\texttt{curt@me.umn.edu}) } \maketitle \section{Introduction} Working on scenery creation was becoming stressful and overwhelming. I needed to set it aside for a few days to let my mind regroup so I could mount a fresh attack. As a side diversion I decided to take a stab at writing an altitude hold module for the autopilot system and in the process hopefully learn a bit about control theory. \section{Control Theory 101} Before I get too far into this section I should state clearly and up front that I am not a ``controls'' expert and have no formal training in this field. What I say here is said \textit{to the best of my knowledge.} If anything here is mistaken or misleading, I'd appreciate being corrected. I'd like to credit my boss, Bob Hain, and my coworker, Rich Kaszeta, for explaining this basic theory to me, and answering my many questions. The altitude hold module I developed is an example of a PID controller. PID stands for proportional, integral, and derivative. These are three components to the control module that will take our input variable (error), and calculate the value of the output variable required to drive our error to zero. A PID needs an input variable, and an output variable. The input variable will be the error, or the difference between where we are, and where we want to be. The output variable is the position of our control surface. The proportional component of the PID drives the output variable in direct proportion to the input variable. If your system is such that the output variable is zero when the error is zero and things are mostly linear, you usually can get by with proportional control only. However, if you do not know in advance what the output variable will be when error is zero, you will need to add in a measure of integral control. The integral component drives the output based on the area under the curve if we graph our actual position vs. target position over time. The derivative component is something I haven't dealt with, but is used to drive you towards your target value more quickly. I'm told this must be used with caution since it can easily yield an unstable system if not tuned correctly. Typically you will take the output of each component of your PID and combine them in some proportion to produce your final output. The proportional component quickly stabilizes the system when used by itself, but the system will typically stabilize to an incorrect value. The integral component drives you towards the correct value over time, but you typically oscillate over and under your target and does not stabilize quickly. However, each of these provides something we want. When we combine them, they offset each others negatives while maintaining their desirable qualities yielding a system that does exactly what we want. It's actually pretty interesting and amazing when you think about it. the proportional control gives us stability, but it introduces an error into the system so we stabilize to the wrong value. The integral components will continue to increase as the sum of the errors over time increases. This pushes us back the direction we want to go. When the system stabilizes out, we find that the integral component precisely offsets the error introduced by the proportional control. The concepts are simple and the code to implement this is simple. I am still amazed at how such a simple arrangement can so effectively control a system. \section{Controlling Rate of Climb} Before we try to maintain a specific altitude, we need to be able to control our rate of climb. Our PID controller does this through the use of proportional and integral components. We do not know in advance what elevator position will establish the desired rate of climb. In fact the precise elevator position could vary as external forces in our system change such as atmospheric density, throttle settings, aircraft weight, etc. Because an elevator position of zero will most likely not yield a zero rate of climb, we will need to add in a measure of integral control to offset the error introduced by the proportional control. The input to our PID controller will be the difference (or error) between our current rate of climb and our target rate of climb. The output will be the position of the elevator needed to drive us towards the target rate of climb. The proportional component simply sets the elevator position in direct proportion to our error. \[ \mathbf{prop} = K \cdot \mathbf{error} \] The integral component sets the elevator position based on the sum of these errors over time. For a time, $t$ \[ \mathbf{integral} = K \cdot \int_{0}^{t} { \mathbf{error} \cdot \delta t } \] I do nothing with the derivative component so it is always zero and can be ignored. The output variable is just a combination of the proportional and integral components. $w_{\mathit{prop}}$ and $w_{\mathit{int}}$ are weighting values. This allows you to control the contribution of each component to your final output variable. In this case I found that $w_{\mathit{prop}} = 0.9$ and $w_{\mathit{int}} = 0.1$ seemed to work quite well. Too much integral control and your system won't stabilize. Too little integral control and your system takes excessively long to stabilize. \[ \mathbf{output} = w_{\mathit{prop}} \cdot \mathbf{prop} + w_{\mathit{int}} \cdot \mathbf{int} \] We are trying to control rate of climb with elevator position, so the output of the above formula is our elevator position. Using this formula to set a new elevator position each iteration quickly drives our climb rate to the desired value. \section{Controlling Altitude} Now that we have our rate of climb under control, it is a simple matter to leverage this ability to control our absolute altitude. The input to our altitude PID controller is the difference (error) between our current altitude and our goal altitude. The output is the rate of climb needed to drive our altitude error to zero. Clearly, our climb rate will be zero when we stabilize on the target altitude. Because our output variable will be zero when our error is zero, we can get by with only a proportional control component. All we need to do is calculate a desired rate of climb that is proportional to how far away we are from the target altitude. This is a simple proportional altitude controller that sits on top of our slightly more complicated rate of climb controller. \[ \mathbf{target\_climb\_rate} = K \cdot ( \mathbf{target\_altitude} - \mathbf{current\_altitude} ) \] Thus we use the difference in altitude to determine a climb rate and we use the desired climb rate to determine elevator position. \section{Parameter Tuning} I've explained the basics, but there is one more thing that is important to mention. None of the above theory and math is going to do you a bit of good for controlling your system if all your parameters are out of whack. In fact, parameter tuning is often the trickiest part of the whole process. Expect to spend a good chunk of your time tweaking function parameters to fine tune the behavior and effectiveness of your controller. \end{document} %------------------------------------------------------------------------ % $Log$ % Revision 1.1 1999/03/09 19:09:41 curt % Initial revision. %