Should inertia tensor apply to torque or to momentum?

Started by
6 comments, last by Dirk Gregorius 8 years, 8 months ago

I've recently picked up Game Physics Engine Development to clear up some of the gaps on the subject and I ran into something that doesn't fit with what I've known so far.

As far as I'm aware, rotational momentum is conserved, i.e. L = const. Also, L = I*w, so inertia tensor determines the conversion from rotational momentum into angular velocity. This apparently also means that the actual axis of rotation can change due to assymetry even if the object is left alone.

However, in chapter 10 of the book, the inertia tensor is applied directly to torque before applying it to angular velocity, which means that if no torque is applied, the body will spin around the same axis, at the same speed. If we use the classic example of an ice skater, this means that drawing in your arms won't make you spin faster. Of course, we could say that our objects have a fixed shape, but they still spin, so their world inertia tensor is not constant.

Is it an oversight in the book or am I missing something?

Advertisement

First: I'm not familiar with the book you're talking about. And it's not clear exactly what you mean in a mathematical sense by a tensor being "applied" to the torque "before applying" it to angular velocity. If you mean something like T/I = delta-w, that's true.


am I missing something?

I think so. In general, you may get a better feeling for torque, angular momentum and angular velocity by considering those as parallels with classical Newtonian linear force, linear momentum and linear velocity. I.e., stuff like linear momentum P = m * v, and F = m * a. So, angular momentum L = I * w, and Torque = I * dw/dt (angular acceleration).


rotational momentum is conserved

That applies to a system, not a single object. Obviously, an object's angular momentum can change through the application of torque. But, for the torque applied, an equal and opposite torque must be applied to something else in the system. That's similar to linear Newtonian physics: linear momentum is conserved for a system. The linear momentum of a rigid object, if no external force is applied, remains constant. If an external force is applied, an equal and opposite force must be applied to something else. In that case, both the rigid object and the "something else" must be considered as the system in question, and the momentum of the system remains constant.


... if no torque is applied, the body will spin around the same axis, at the same speed. If we use the classic example of an ice skater, this means that drawing in your arms won't make you spin faster.

Your assumptions are incorrect. If no external torque is applied, then there will be no angular acceleration due to external torque. Drawing your arms in changes the moment of inertia. So, because L = I*w, and I has changed, w must change. That is, I is the integral of mass * radius-from-axis. Mass is conserved, so when the radius decreases, the moment of inertia decreases. If I decreases, w must increase. The change in w results from the torque that results from the force the skater applies to the arms to draw them in. Force-at-a-distance is torque.

I suspect you know all that. Perhaps if you provide the exact context of your question, a better explanation can be provided.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

What I meant is that world inertia tensor depends on the orientation, so a correct implementation should maintain the angular momentum, and calculate the angular velocity at each frame by multiplying it by inverse world inertia tensor.

The code in the book instead updates angular velocity by adding (I^-1) * T to it.

Here's the code in question:


// Calculate angular acceleration from torque inputs.
Vector3 angularAcceleration =
inverseInertiaTensorWorld.transform(torqueAccum);
// Adjust velocities
// Update angular velocity from both acceleration and impulse.
rotation.addScaledVector(angularAcceleration, duration);


... implementation should maintain the angular momentum, and calculate the angular velocity at each frame by multiplying it by inverse world inertia tensor.

Not sure what you mean by "maintain angular momentum." If you mean maintain constant, that's incorrect. As mentioned, angular momentum is constant for a system, not a single object, and angular momentum would be equal to I * w, not I-1 * w. As a result, for a single object, angular momentum might change if torque is applied externally.

The current angular velocity is the sum of the previous angular velocity + the change in angular velocity. The change in the angular velocity is torque / I * dt. The angular momentum would be I*w, but, because w changed, the angular momentum for that single object changed.


the code in question: ...

That code implements (or appears to implement): w += T / I * dt, which is correct. That is, as mentioned** above, T / I = dw/dt, so delta-w = T / I * dt. The latter is the change in angular velocity, which is added to the angular velocity to update it.

** My previous post was incomplete, in that I did not include the time. Sorry about that.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Angular momentum is defined as:

L = I * w

Torque is the change of angular momentum over time (I use primes ' to denote the time derivative here and x for the cross product):

tau = L' = I * w' + I' * w = I * w' + w x ( I * w ) <=> w' = I^-1 * [ tau - w x ( I * w ) ]

You can integrate this using e.g. Euler integration:

(w2 - w1) / dt = I1^-1 * [ tau - w1 x ( I1 * w1 ) ] <=> w2 = w1 + I1^-1 * [ tau - w1 x ( I1 * w1 ) ] * dt

The right hand side w x ( I * w ) is often referred to as gyroscopic term and ignored in most physics engines because it is very unstable with simple Euler integration. You miss nice effects like this dropping this term:

https://www.youtube.com/watch?NR=1&v=LR5hkgfRPno

Other artifacts are e.g. capsules that don't fall correctly and wobble unnaturally. E. Catto presented a way how to integrate the gyroscopic term at the GDC this year using implicit Euler:

http://box2d.org/files/GDC2015/ErinCatto_NumericalMethods.pdf

Bullet added an implementation of this approach recently. Here is a video showing the different integration approaches:

Sometimes people keep angular momentum as a state. E.g. you then would simple do:

L += tau * dt

In practice it has the same issues as dropping the gyroscopic term. The reason is that you still need to compute the angular velocity in order to find the new orientation. Integrating angular momentum gives:

L' = tau => (L2 - L1) / dt = tau <=> L2 = L1 + tau * dt

So far so good, but now we want to compute the angular velocity to e.g. use q' = 0.5 * w * q to find the new orientation. Of course we have:

L2 = I2 * w2

The problem is that you don't know the inertia tensor at the end of time step I2 since you don't know the new orientation yet (e.g. I2 = R2 * I_Local * R2^T) and in practice people simply use the inertia tensor from the beginning of the time step I1. So what they actually do is:

w2 = L2 / I1

Obviously this is not correct and, as mentioned already above, leads to similar issues as dropping the gyroscopic term when integrating angular velocity.

The problem is that you don't know the inertia tensor at the end of time step I2 since you don't know the new orientation yet (e.g. I2 = R2 * I_Local * R2^T) and in practice people simply use the inertia tensor from the beginning of the time step I1. So what they actually do is:

w2 = L2 / I1

Obviously this is not correct and, as mentioned already above, [background=#fafbfc]leads to similar issues as dropping the gyroscopic term when integrating angular velocity. [/background]

Is it really severe though? The error should be quite small, and generally not noticeable. If you use angular velocity as a state, though, it is very easy to notice that objects don't change their speed/direction at all while spinning, which is quite wrong for certain shapes. Besides, storing angular momentum instead of velocity has no drawbacks besides possibly having to re-calculate the actual velocity several times, depending on how you're resolving contacts.

Not sure what you mean by "maintain angular momentum." If you mean maintain constant, that's incorrect. As mentioned, angular momentum is constant for a system, not a single object, and angular momentum would be equal to I * w, not I-1 * w. As a result, for a single object, angular momentum might change if torque is applied externally.

The current angular velocity is the sum of the previous angular velocity + the change in angular velocity. The change in the angular velocity is torque / I * dt. The angular momentum would be I*w, but, because w changed, the angular momentum for that single object changed.


I think you are missing my point completely. By 'maintaining' I mean keep it as part of the object state. If no torque is being applied, then angular momentum should be constant (because in this case we can treat the object as a closed system). But since the object's orientation changes, so does its world inertia tensor. Since L=I * w, where L is constant and I changes, angular velocity is *not* constant. So saying that current angular velocity is the sum of the previous angular velocity plus torque / I * dt (which is zero in our case) is not correct for non-symmetrical objects. Dirk brings a point about the other (technically more accurate) method being not-quite-correct either, and causing stability issues when combined with naive integration methods, so maybe there is some merit to sticking with the simpler model, even though it is not fully accurate.

Severity depends on the geometry of the object and the angular velocity. The error can become quite significant.

Yes, you can store angular momentum or global angular velocity or body space angular velocity. Since the solver usually operates on global angular velocity you use this.

This topic is closed to new replies.

Advertisement