Sunday 4 December 2011

Flash PID Controlled Steering



I was introduced to the concept of using a PID-Controller during one of my university modules in games, and I had always thought it was an easy and useful algorithm for game AI, especially for missile-like behaviour, but I had not attempted to implement it until today. Fortunately, I'm equipped with the original source, i.e. AI Game Programming Wisdom 2, Chapter 2.8 Intelligent Steering Using PID Controllers by Euan Forrester (EA, Black Box).

I started by reading the text and trying to implement the algorithm based off my understandings of the text alone. However, I got a little stuck at several parts, after which I had to reference the source code to solve them. Overall, I think that helped me learn more as I could compare my original understanding and the source code to see where I went wrong. Here is what I learned:

  1. The PID Controller should be used to influence the direction or angle of the missile, not the position. Originally, I rushed into the code and got "bitten" because I instinctively tried to calculate the difference between the positions of the target and the missile, rather than the angle.
  2. The output of the PID Controller for missiles behaviour should be an angular acceleration. This means that the missile is required to have an angular velocity as well. This does not seem to be mentioned in the text, so it may be hard to figure out by yourself unless you have an engineering background where PID Controllers are used.
  3. The output of the PID Controller should be a negative feedback to the system. This was only obvious to me when I saw the diagram on Wikipedia where it is clearly shown that the feedback should be negative. If the feedback is positive, what you would see is that the missile would start turning away from the target rather than towards it. Perhaps this behaviour can also be exploited for other purposes.
  4. The movement of the missile can and should be independent of the PID Controller. I.e. the missile should move based on its own velocity or acceleration and should be agnostic to the presence of the PID Controller. The PID Controller should only be used to influence the angular acceleration of the missile, somewhat like the wind.
  5. Angular velocity drag force and Clamping the angular acceleration is a good idea. At first when the algorithm was not properly implemented, I found the missile spinning like crazy, so it's a good idea to have a drag force to always reduce the angular velocity as well as a cap for angular acceleration so as to avoid crazy spinning.
  6. The rest of the algorithm is actually pretty straightforward! Aside from the above, it does seem my original implementation was not too far apart, but I definitely would not have been able to complete this demo in time if not for the source code.
  7. P stands for Proportional Gain and it is useful to think of it as the "now" variable. The higher it is, the more the result will react to its current situation. Too little might seem lazy, too high might cause the result to be unstable because it is always overreacting.
  8. I stands for Integral term and it is useful to think of it as the "past" variable. The higher it is, the more inertia the result will have as it puts more emphasis on what its past errors has been. Therefore, it tends to overshoot the target.
  9. D stands for Derivative term and it is useful to think of it as the "future" variable. The higher it is, the more it will try to predict the future and will try to slow the rate of change of the result, especially if it is going to overshoot.

Get Adsense

Want to earn money like me? Get Google Adsense now by clicking this