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?

MazeBot

My brother and I make it a point to get together about four weekends a year to do projects. We started this “tradition” a couple years ago, and it’s become something I look forward to every time.

Last weekend I met him in Southern California. He suggested we do a robotics projects, specifically, to make a small robot that can navigate a maze. First we needed a maze, so we headed to Home Depot with the idea of getting some lumber we could cut into various lengths and layout to make a reconfigurable maze. After settling on some 1×4 pine boards, we discovered some 2×16×6 concrete blocks. They worked beautifully, and were much cheaper than even the cheap wood we had originally selected.

To build the actual robot, which I dubbed MazeBot, we used LEGO (Mindstorms NXT). Working with the NXT, which is the second generation of the LEGO robotics line, was much easier than trying to get the original Mindstorms brick to do much. We used ROBOTC, which is a C compiler from the folks at CMU made especially for robotics projects. We used Bluetooth to transfer the compiled programs from our development PC to the robot. The whole process was a snap, which made it very easy to do lots of iterations.

Adrian with MazeBot

Adrian with MazeBot

Did I say lots of iterations? We made eight major versions of the software (about four pages of C code) in one weekend. In the end, MazeBot could explore and map the maze. The next step would have been to give it more explicit goals, like finding a route to a particular cell in the maze, but we ran out of weekend. This video shows MazeBot in action.

The robot uses a sonar sensor in front to detect the maze walls. It has a compass sensor on a mast to determine its orientation. (The mast is necessary because the magnets in the drive motors interfered with the accuracy of the compass readings. Late in the weekend, we figured out that our mast had to be even taller to get good readings.) The software assumes everything in the maze is at right angles and that the robot begins aligned with one of the walls. The LEGO motors also have feedback, which we used to determine how far the robot has traveled.

MazeBot 8.0 from Adrian on Vimeo.

I certainly learned a lot about PID servo control. Well, PI control anyway—our robot doesn’t use a derivative term.