Monday, September 17, 2007

Not much

My family and I have been sick this weekend so I haven't gotten much done.

I've been working on implementing a piston-type joint in the Chipmunk physics library. This is a joint that allows one object to move freely along a straight track, but stops it at the endpoints. The sliding object is allowed to rotate freely. Obviously this is to simulate wheels on suspension; it will be combined with a damped spring to do the suspension.

To do this, I need to solve for an impulse which, when applied to the two bodies at the joint, will eliminate relative velocity in the cross-track direction. Additionally, if the sliding object has reached a track extent, I must generate an impulse which will kill any relative velocity that would carry it past the end of the track. This latter velocity adjustment is essentially the same as a contact non-penetration constraint, in that we don't want to ever produce an impulse that would keep the sliding object from being able to move the other direction, away from the track's endpoint.

Here's some initial math going the opposite direction: given an impulse, what is the change in relative velocity at the joint? I've used the Greek letter Delta (the triangle) to indicate change, as in “change in velocity”. Here are the variable definitions:

And here is development of the equation for change in relative velocity at point r, given an impulse j at that same point:

It's built up from the changes in linear and angular velocities at the two bodies' centers of mass.

By inverting this, it's possible to solve for an impulse which will produce a desired change in local relative velocity. I'll also need to rotate the coordinate system so that velocities along and across the track are easily separated. As I said before, the along-the-track velocity changes are really like contact constraints so they'll need to be handled slightly differently from the cross-track velocity constraint.


Scott said...

Nifty. Another Chipmunk user. You might be happy to hear that the next version of Chipmunk will play much better with C++.

I too implemented piston joints recently. (I call them groove joints) I thought about implementing them as you did, but ultimately chose to treat it as a pivot joint and clamp the calculated impulse. That worked out rather well.

James McNeill said...

Thanks for the library!

I really didn't have any trouble with it. I converted it to C++ since that's my primary language these days, and it was a good way to familiarize myself with all of the code. Some things looked like they wanted to be C++: the joint hierarchy, for instance, or cpArray --> std::vector, or the constructors and virtual destructors. Other things turned out to be more of a wash: I tried implementing the collision dispatch as a two-layer virtual method system, which I'm sure is slower than the table lookup in the C version.

One thing I've wondered, with both Chipmunk and Box2D: How much value does the arbiter class add? I'm thinking you could just store contacts independently and hash directly to them. There'd be slightly more data in them since they'd need the body pointers, but it would eliminate a layer from the system. Do they do something I've missed, or get more valuable in a 3D context (with more contacts per body pair)?

Scott said...

Well, it mostly has to do with having a place to store precalculated values. Not there are that many right now, but I do intend to add more for things like rolling friction and such. You are correct though, they don't really serve that much of a purpose.