Inertia Tensor magnitude to find Angular Acceleration

Started by
5 comments, last by Normalized 8 years, 3 months ago

I am using unity 3d and rolling my own semi physical vehicle physics.

Is taking the Inertia Tensor magnitude a legitimate way to find angularAcceleration?

Vector3 angularAcceleration = torque / myRigidbody.inertiaTensor.magnitude;

Advertisement
That's ok only if the body has uniform inertia (a sphere).
But for a general body inertia depends on the direction you want to measure.

To find inertia on any direction:

inline float GetInertia (const sVec3 &localaxis, const float Ixx, const float Iyy, const float Izz)
{
	sVec3 axis = localaxis;
	axis[0] /= Ixx;
	axis[1] /= Iyy;
	axis[2] /= Izz;
	return 1.0f / axis.Length();
}
So, four your example you need:


vec3 axis = torque.Unit();
vec3 localAxis = body.orientation.Unrotate(axis);
float inertia = GetInertia (localaxis, body.inertiaTensor.x, body.inertiaTensor.y, body.inertiaTensor.z);
vec3 angularAcceleration = torque / inertia;

Thanks

What does body.orientation.Unrotate() do?

Am I right in thinking that body.orientation.Unrotate() takes a eulerAngle and returns the difference between the rigidbody’s rotation and said axis?

What does body.orientation.Unrotate() do?


No, it just transforms the torque direction ('axis') from world space to the local body space.
This is necessary because inertia tensor is usually given in body space.

Instead of body.orientation you most prabably have a 4x4 matrix containing body position and orientation.
Then you need to ignore position (like transforming a normal in graphics).
Or if you have a quaternion for orieantation you can use that (Don't know Unity / PhysX).

The correct way is to multiply the torque vector by the inverse of the world-space inertia tensor for the object. You should precompute the object-local inverse inertia tensor, then transform it to world space on each frame via a similarity transform: R' * I^-1 * R where ' is the transpose and R is the rotation matrix.

The correct way is to multiply the torque vector by the inverse of the world-space inertia tensor for the object. You should precompute the object-local inverse inertia tensor, then transform it to world space on each frame via a similarity transform: R' * I^-1 * R where ' is the transpose and R is the rotation matrix.


I assume that's mathematically the same as in this snippet (correct me if i'm wrong):

inline sVec3 ConvertTorqueToAngAcc (sVec3 &torque, sMat4 &matrix, float Ixx, float Iyy, float Izz)
{
	sVec3 angAcc = matrix.Unrotate (torque);
	angAcc[0] /= Ixx;
	angAcc[1] /= Iyy;
	angAcc[2] /= Izz;
	return matrix.Rotate (angAcc);
}
The difference is:
In method 1 from my first post acceleration and torque have the same direction.
In Method 2 their directions are different because the nonuniform scale from inertia.

I'm unsure which of those two methods is more 'correct', but I have had a lot of use cases where only one of the two gave me the desired results.
Any clarification welcome (it may be worth to try both).

Unity gives me

1: Quaternion inertiaTensorRotation : The rotation of the inertia tensor.

2:Vector3 inertiaTensor : The diagonal inertia tensor of mass relative to the center of mass.

I assume that I should rotate the inertiaTensor by the inertiaTensorRotation.

http://answers.unity3d.com/questions/398353/how-do-i-programmatically-combine-inertia-tensors.html

https://khlphy.wordpress.com/2011/03/13/meaning-of-the-off-diagonal-elements-of-an-inertia-tensor-an-elementary-explanation/

Using a matrix may work if its true that.

Matrix4x4 m = Matrix4x4.TRS(rigidbody.centerofmass, rigidbody.inertiaTensorRotation, rigidbody.inertiaTensor);

I guess I will need to test this out.

This topic is closed to new replies.

Advertisement