Steering Game Objects with P.I.D. Control

lunar lander

In a video game, objects move around, otherwise it could be a boring game. And movement means that the object position changes over time. How these position changes are implemented in code fall in one of three levels of indirectness:

  1. Direct: every frame, the code sets a position.
  2. Indirect: the code sets velocity, then every frame a new position is derived.
  3. Doubly indirect: the code sets an acceleration, then every frame a new velocity is derived with which a new position is derived.

Early games with digital controls, like e.g. Pacman, directly set a position as there is no concept of acceleration, and no real concept of velocity (other than a travel direction.)

As computer games got more sophisticated, physics simulations took over the control of calculating the object's position. Now, forces are used (which for a given body mass directly correspond to acceleration vectors) to move objects.

With this added realism, a new challenge cropped up for the steering of computer controlled objects, like Non Player Characters (NPCs.) If the game with a physics simulation wants to move an NPC to a location in the world, it cannot simply set the position, or even set the velocity as that would be a discontinuity in the simulation. The game needs to calculate the forces that can be applied to the NPC so that the NPC will end up at the desired location in the world.

Think for a moment on how you would achieve this. A naive approach of applying a force in the direction towards the goal does not work, as the NPC would overshoot its goal. If the NPC is close to its goal, but it is rapidly approaching the goal at high speed, we should be applying an opposite force that points away from the goal, not towards it so that we will come to a halt at the target location.

Because we are setting a force (acceleration) which leads to a change of velocity, and the velocity leads to a change in position, the game's control over the position is doubly indirect. This makes steering the NPC non-trivial.

Fortunately for us, the problem of steering with lag has already been solved for us in other industries. Consider for instance, the process of heating a room. A thermostat is set to 20℃ and the room temperature is 19℃. What should the heater do? Well, if the heater had been running at full blast in the last ten minutes, in which the room temperature went from 10℃ to 19℃ then the heater better shut off, because it will overshoot.

The tool of choice to use in both cases is a Proportional Integral Differential Controller, or a P.I.D. Controller. Don't let the math and the confusing terms on that wikipedia entry scare you. P.I.D. just means that you will be steering based on the current error, based on the historic error, and based on how the error is changing over time.

The tool is quite magical in that appears almost prescient. It will know how to avoid overshoot. And it can also handle changing conditions. For instance, if the wind is pushing against the NPC (or the room temperature is influenced by a harsh winter or open doors.) The P.I.D. Controller will make the NPC still come to a nice halt on the target spot, and make the room reach the desired temperature without overshoot.

Before P.I.D. Controllers can work their magic, they need to be tuned tough. I wrote a primer on P.I.D. that walks you through the process of tuning, and also comes with an implementation in C. If hope I made a convincing case for the use of P.I.D. Control and that my primer will help you implement it.

H2
H3
H4
3 columns
2 columns
1 column
Join the conversation now
Logo
Center