I find it fascinating how computer games are often built to resemble real-world by actually using models of the real-world. Rather than trying to replay movement patterns, you use forces, torque, momentum, etc. As in the real world, it might sometimes be hard to get them to work together the way you want. Sure, since it’s not real, you could just ignore the laws of physics and force your objects to go wherever you want them to go, but it rarely feels like a natural motion. So we try to control the ‘real-world’ models using ‘real-world’ actuators.
A common choice for industrial control systems is a so called PID-controller, PID in this case stands for proportional, integral, and derivative, referring to the three linearly combined terms producing the controller output. The coefficients, usually called gain, are the ones determining the behavior of the controller, and are (usually) not time dependant.
Since it’s usually good enough to approximate the error as a piecewise linear function, we get simply
The error, e, is the difference between the currently measured output of the system and the value we would like it to produce, called a set-point. The output of the function is whatever actuating force is available to us.
The proportional, or P-, part of the controller is compensating the current error by by simply setting its output to be proportional (duh) to the error. If the error is zero, i.e. output equals the set-point reference value, the P-controller does nothing.
The integral, or I-, part of the controller is compensating errors over time by integrating the error and using that multiplied by a factor to control the system. This allows small errors to be compensated faster if they persist over time, where the correction issued by the P-controller would be too small to be adequately responsive.
The derivative, or D-, part of the controller is primarily used to compensate the other two by reducing the rate of change of the error, effectively damping any quick and overreacting efforts.
You could compare this to yourself driving a car. Let’s say you’re currently cruising at 40 — this is the measured output — but the speed limit was just raised to 60 — this is your set-point — so you push the accelerator, which is your means of control (i.e. controller output). This is the P-portion at work, identify a difference in current and requested speed, and act accordingly. After a while, you’re not picking up speed as fast as you’d like, so you push the accelerator even further down. This is the I-part, noting that the error has persisted over time. And finally, you’re picking up speed quickly, and you’re approaching 60, so you ease up on the accelerator in order to not overshoot the target. This is the D-part at work, compensating a high rate of change in the error, i.e. we’re getting closer, and fast.
Use in animations
Controllers aren’t suitable for every kind of animations, but they are very easy to handle, and if they are appropriate it might very well be worth your while to consider them. Here are two examples, where I’ve used controllers to create a natural feel.
Rotating menu items
In a game I wrote a couple of years ago, I used this technique to control the motion of menu items for the in-game menu. The items where basically blocks hanging in mid-air, and when the user selected one it would spin 360 (or 180 for on-off type options) degrees, overshoot a bit and start swinging slightly back and forth before coming to rest.
The beauty of using a controller is that all I had to do was set the required rotation (actually, I set the current rotation, to have it always work toward 0, but it doesn’t really matter), and let the controller do the rest. I chose to let the controller affect the angular velocity, and in order to get the slight overshoot, I used a P-controller and used its output as angular acceleration (proportional to torque). I combined that with the exponential sliding window from my last post to determine when the oscillations had dropped below a certain threshold, so I could stop the animation to keep pixels from flickering due to some minor movement.
There are other alternatives of course, a damped spring model is mathematically equivalent to a P-controller controlling acceleration, so I could’ve used that here as well.
Controlling a camera dolly
I recently prototyped some camera movement routines, where I had a top-down view and basically set up a PID-controller to track the cameras position above ground, again taking the output as acceleration. This had the effect that I could simply set the new height as a set-point reference whenever I wanted to zoom in or out, and it would move there smoothly without a hitch. Rapidly updating the value, such as when moving laterally across different ground levels, was also handled very elegantly, and the movement felt natural.
The true benefit presented itself as I wanted to have the camera dolly away from the ground when an explosion went off, as if pushed away. Here I simply set the velocity of the camera to move away from the ground, and the controller handled the rest.
One of the biggest caveats with using controllers is that you might end up with stability issues. A controller loop becomes unstable when the controller starts to overcompensate, causing larger and larger oscillations. Tuning a control loop is pretty much a whole research field, and there are plenty of fat text books on the subject, but since we’re not dealing with life-critical or power plant control systems, I find it easier (and more fun) to just play around with the coefficients until I get something which is good enough.
Note: Cross posted on my own blog, excu.se