Servo Animation

One of the (far too many) projects I’ve been working on is a video game. You might call it a sports simulations—then again, you might not, depending on your idea of what constitutes a sport. Nevertheless, it involves players waving sticks at balls, trying to get the balls to go in the right direction.

Physics

For the core of the game engine, I’ve built a physics simulator. Back in college, I had a tenuous grasp on Newtonian physics, which came in handy as I was earning my degree in physics. As with many things, you have to use it or lose it, and I haven’t exercised my knowledge of physics much since graduating. So, in addition to the figuring out how to translate conservation of energy into floating point math, I had to relearn some physics and, especially, some calculus. If you find yourself in the same boat, I recommend this series of articles from Chris Hecker as a warm-up:

Those will help you (re-)learn the physics and math necessary to make a nice 2D simulator (think Crayon Physics). With those as inspiration, these heavy-duty tutorials from David Baraff will help you build a nearly-complete 3D simulator:

My simulator is built almost directly from the latter two references. While these are hard-core articles, there is a lot more to this field. Fortunately for me, this was plenty to do the basic bouncing balls simulation that are necessary for my game.

At least, I thought it was. I have the balls bouncing, rolling, and smacking into each other, all under the control of the physical simulation. What I need now is to blend the simulation with canned animations and with input from the user. The question is, how do I handle the interaction of the animation-controlled objects with the simulation-controlled ones?

Consider a canned animation of a 3D character swinging a bat. There’s a ball hurtling toward the player’s avatar. The player presses a button to start the animation. Frame by frame, the bat’s position is updated. If the bat hits the ball, an impulse needs to be imparted to the ball. But since the swing is just a series of positions, we don’t have all the physical values necessary to compute an accurate force to apply to the ball. You could probably guesstimate the change in momentum and send the ball flying off in a plausible way, but what about the bat? If I continue with the animation of the player’s follow-through, you won’t see any recoil on the bat itself. The bat will continue on its trajectory as though the player had missed the ball.

This is a quandary I’ve been pondering off-and-on for a while. But after the MazeBot project, the answer came to me: servo control.

Servo

MazeBot has a compass sensor that gives its orientation in degrees with respect to magnetic north. At any point in time, MazeBot’s software has a desired orientation. The difference between the desired orientation and the measured orientation is the error. The error is used to compute how much power to apply to the left and right motors in order to turn the robot back to the desired heading. This is repeated many times per second in order to keep the robot on track. This is called servo control.

Now here’s the neat part. To execute a turn, the software “animates” the desired heading from its original value to the desired value. For example, if the robot is at heading 18 and it wants to turn 90 degrees, the software changes the desired heading to 19, then to 20, then 21, and so on, until it reaches 108. That’s it. It doesn’t directly issue any commands to the motors.

In the background, the servo controller is always running, trying its darndest to keep the robot aligned to the desired heading—even when the desired heading is a moving target. Thus the robot turns. How closely it follows the animated path depends on how well-tuned the servo controller is and how responsive the mechanism is.

Servo Animation

Suppose we applied the same idea to the animation of the bat. The bat could be just another object that the physics simulator controls. Rather than telling us where the bat is, the animation path tells us where we want the bat to be. We feed that desired position into a servo controller just like the desired heading is given to MazeBot’s servo controller. The servo controller returns the force (and torque) that should be applied to the bat to keep it on the animation path.

Now that the bat is a first-class citizen of the simulation, we have all the physical parameters we need to resolve any ball-bat collisions. The ball experiences a change in momentum and heads away to the outfield. The bat will also experience a recoil impulse causing it to momentarily fall behind the animation path. The servo controller will increase the forces to try to get the bat back on track, resulting in a swing that—while animation-driven—still responds in a realistically different way than if there had been no collision.

I haven’t tried this out yet. Given my project backlog, it might be a while, but I wanted to write up this idea while it was still fresh in my head. What do you think? Will it work?