Inertia of each axis

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
templar_vii
Posts: 17
Joined: Wed Nov 06, 2013 2:56 pm

Inertia of each axis

Post by templar_vii »

Is it possible to decompose the InertiaTensor to the inertia of each axis?

Maybe I missunderstand the InertiaTensor.
I'd like to know which axis can rotate the object easiest (X, Y or Z).

So I thought I could decompose the InertiaTensor to the moment of inertia of each axis.
Afterwards I just look for the lowest value.

But since the InertiaTensor is a Tensor, I don't know if it's possible to split it to the three axis.

Does anybody know if it's possible and how this could be done?
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Inertia of each axis

Post by Norbo »

Many simple shapes (sphere, box...) are built in local space such that the principal moments of inertia line up nicely with the axes of the local coordinate system. In this case, the inertia tensor is just a diagonal matrix and you can grab the moments of inertia from M11, M22, and M33 of the matrix without needing to do any extra work.

More complicated shapes like the ConvexHullShape, MinkowskiSumShape, TransformableShape, WrappedShape, and MobileMeshShape have no such guarantee of alignment. In this case, there's a couple of options:

1) Grab a few arbitrary axes, check the scalar moment of inertia around them, and pick the lowest one.

The scalar moment of inertia Ia around a given axis a for a body with inertia tensor I is:

Ia = aT * I * a

where aT is a transposed.

2) Choose a new reference basis such that the inertia tensor becomes diagonal, and then check the diagonal elements.

This is a bit trickier. It amounts to diagonalizing the matrix:

Io = R * I * RT

where Io is the original unaligned inertia tensor, R is a rotation matrix, I is a diagonal matrix, and RT is R transposed.

I will contain the principal moments of inertia in the diagonals, and R will contain the principal axes.
templar_vii
Posts: 17
Joined: Wed Nov 06, 2013 2:56 pm

Re: Inertia of each axis

Post by templar_vii »

Thank you norbo for your great detailed answer.
I think I understand your explanations.
But there's still something I don't know how to handle.

I have a ConvexHullShape.
I'd like to know the inertia on the x-axis in the global coordinate system.

First I thoght thats easy.
Just take the vector (1,0,0) and do the calculation you described: Ia = aT * I * a
But I realized thats not the solution.
Probably because the principal axes of inertia are not aligned with the global axes.

Do you know how I could get the inertia on the global axes?
I think I should know the rotation between the principal axes of inertia and the global axes.
Attachments
This is a screenshot out of the CAD Solidworks. I guess the pink axes are the principal axes of inertia. As you told, the axes of inertia are not aligned with the global axes. But does BEPU know this rotationmatrix?
This is a screenshot out of the CAD Solidworks. I guess the pink axes are the principal axes of inertia. As you told, the axes of inertia are not aligned with the global axes. But does BEPU know this rotationmatrix?
principal axes of inertia.jpg (14.92 KiB) Viewed 8945 times
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Inertia of each axis

Post by Norbo »

First I thoght thats easy.
Just take the vector (1,0,0) and do the calculation you described: Ia = aT * I * a
But I realized thats not the solution.
Probably because the principal axes of inertia are not aligned with the global axes.
While it's true that the principal axes are not aligned with the global axes in general, performing that calculation should still get the scalar moment of inertia around the given axis properly.

If you are getting incorrect results, make sure the world space inertia tensor (entity.InertiaTensor) is used as opposed to the local space inertia tensor (entity.LocalInertiaTensor). Presumably, if a world axis is being used, the entity rotation is supposed to be taken into account.
I think I should know the rotation between the principal axes of inertia and the global axes.
...
As you told, the axes of inertia are not aligned with the global axes. But does BEPU know this rotationmatrix?
The engine never diagonalizes the inertia tensor matrix, so no, it doesn't know. Getting this information would amount to diagonalizing the world space inertia tensor or diagonalizing the local space inertia tensor and taking into account the entity.OrientationMatrix.
templar_vii
Posts: 17
Joined: Wed Nov 06, 2013 2:56 pm

Re: Inertia of each axis

Post by templar_vii »

While it's true that the principal axes are not aligned with the global axes in general, performing that calculation should still get the scalar moment of inertia around the given axis properly.
As you told, to get the Inertia of the global x-axis I can just perform this calculation: Ia = aT * I * a.
To get the Inertia of the x-Axis I set the parameter a = (1,0,0).
But the multiplication with (1,0,0)T and (1,0,0) is the same as just taking the element M11:
inertia.jpg
inertia.jpg (11.8 KiB) Viewed 8934 times
But as you told, for a ConvexHullShape you can't jsut grab the moments of inertia from M11.
So to get the inertia of the x-axis, I can't just multiply with the vector (1,0,0), rather I should know the direction of the x-axis.

I made a small example:

Code: Select all

var box1 = new Box(new Vector3(0, 0, 0), 1, 1, 1, 1);
var box2 = new Box(new Vector3(0, 0, 0), 1, 1, 1, 1);

var compundShape1 = new CompoundShapeEntry(box1.CollisionInformation.Shape);
var compundShape2 = new CompoundShapeEntry(box2.CollisionInformation.Shape);

compundShape1.LocalTransform = new RigidTransform(new Vector3(10, 10, 0));
var compoundBody = new CompoundBody(new List<CompoundShapeEntry> { compundShape1, compundShape2 });
compoundBody.Mass = 1;

var inertiaTensor = compoundBody.InertiaTensor;
The inertiaTensor of the compound Body looks like this:

Code: Select all

 61 -62   0
-62  62   0
  0   0 125
The multiplication with (1,0,0)T and (1,0,0) would result in 61. But I guess that's wrong, because the matrix is not diagonalized.

I don't want to waste your time norbo. You already helped me a lot.
I do some more experiments and if I can't figure out what I'm doing wrong, I just calculate the inertia over every triangle. That's ok for me.
Thank you norbo!
templar_vii
Posts: 17
Joined: Wed Nov 06, 2013 2:56 pm

Re: Inertia of each axis

Post by templar_vii »

I realized something interesting.
A body just rotates smoothly if the rotation axis is one of it's principal axis of inertia.
If not, the body begins to wobble.

Maybe this means, it's not possible to calculate the inertia of an axis other than a principal axis of inertia...
That's just a assumption.

Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Inertia of each axis

Post by Norbo »

But as you told, for a ConvexHullShape you can't jsut grab the moments of inertia from M11.
So to get the inertia of the x-axis, I can't just multiply with the vector (1,0,0), rather I should know the direction of the x-axis.
Using the world space vector (1,0,0) and the world space inertia tensor does essentially grab M11 from the tensor, but it is still the correct moment of inertia around the axis (1,0,0).

It is not generally a principal moment of inertia, because (1,0,0) is not generally a principal axis.

If you want the principal axes and moments of inertia, the matrix needs to be diagonalized.
If you just want the moment of inertia around an arbitrary axis, the formula is all that's needed.
The multiplication with (1,0,0)T and (1,0,0) would result in 61. But I guess that's wrong, because the matrix is not diagonalized.
61 isn't a principal moment, but it would be the correct scalar moment of inertia for that axis given that inertia tensor.

It can be a little difficult to visualize 'correctness' for nonprincipal axes, since they don't have the property that an angular impulse results in a parallel change in angular velocity. Applying an angular impulse around an off-axis can produce an angular velocity with an unintuitive axis of rotation, unlike with principal axes.

For example, applying an impulse around (1,0,0) for that particular compound body produces an angular velocity almost perfectly aligned with the principal axis of lowest inertia instead of anything near (1/61, 0, 0).

Another way to think about it: the scalar moment of inertia does show the relationship between an impulse around an axis and the resulting velocity about the axis, but the scalar moment does not give you information about the additional off-axis rotations which make the change in angular velocity not parallel to the impulse.

To see it more clearly, try constraining the compound to behave as if it's anchored on an axis, and then apply an angular impulse:

Code: Select all

            Space.Add(new RevoluteJoint(null, compoundBody, compoundBody.Position, momentMeasurementAxis));

            //Keep the object from deactivating or slowing down artificially.
            compoundBody.AngularDamping = 0;
            compoundBody.ActivityInformation.IsAlwaysActive = true;
            compoundBody.ActivityInformation.AllowStabilization = false;

            var impulse = momentMeasurementAxis;
            compoundBody.ApplyAngularImpulse(ref impulse);
            //Do a bunch of updates to give the constraint time to converge.
            //The default settings on the joint are pretty rigid, but it still has some softness. 
            //The initial impulse will introduce some error that these iterated updates will eliminate.
            for (int i = 0; i < 100; ++i)
                Space.Update();

            var velocity = compoundBody.AngularVelocity;
After the Space.Updates (required for the constraint to have an effect), you should see the velocity be suspiciously close to 1/moment.


It's also possible to work to a similar answer from a different direction. Sum the moment of inertia contributions for a given axis from point masses:
I = sum(m * r^2)
where I is the scalar moment of inertia around the axis, m is the mass of each contributor, and r is the perpendicular distance from the axis.

The boxes are taken to be point masses at (0,0,0) and (10,10,0) with 0.5 mass each. The moment of inertia is to be measured around the axis (1,0,0). The axis goes through the center of mass at (5,5,0).

This gives:
I = 0.5 * 5^2 + 0.5 * 5^2 = 25

BEPUphysics scales the inertia tensor by InertiaHelper.InertiaScaleFactor which defaults to 2.5. The moment computed from the BEPUphysics tensor in your example is then 62.9/2.5 = 25.16. So, with some error introduced by the point mass approximation, the same result is found.
templar_vii
Posts: 17
Joined: Wed Nov 06, 2013 2:56 pm

Re: Inertia of each axis

Post by templar_vii »

Hello Norbo.
First let me say thank you for the great support.

Unfortunately, untill now, I was not able to calculate the inertia.
I attached a small example, in which I calculate the InertiaTensor of the same body (200 x 10 x 1) in three different ways.
  • 1. of a Box
    2. of a MobileMesh
    3. of a CompoundBody
Unfortunately I get three different results.
It would be great, if you could tell me what I'm doing wrong. Or could it be a bug?
Maybe this could solve my problem.
Attachments
inertiaSample.cs
(3.61 KiB) Downloaded 356 times
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Inertia of each axis

Post by Norbo »

Those are physically distinct shapes. A Box is a solid volume, while the MobileMesh in the example is hollow. The CompoundBody is made from two adjacent hollow shapes, with extra mass contributions at the split.

If the MobileMeshes are made Solid (MobileMeshSolidity.Solid) rather than hollow (MobileMeshSolidity.CounterClockwise), the results should be closer (though solidity does require consistent closed winding).

Also, some inertia tensor calculations are intentionally just approximations. For example, hollow meshes are treated as a series of point masses instead of area integrals (but solid meshes use an exact volume integration). Capsules are another one (for no particularly good reason). TransformableShapes, MinkowskiSumShapes, and WrappedShapes all use a numerical volume integration which comes close, but can still be a little off (increasing the sample detail in the InertiaHelper decreases that error at the cost of performance).
templar_vii
Posts: 17
Joined: Wed Nov 06, 2013 2:56 pm

Re: Inertia of each axis

Post by templar_vii »

That's it norbo!

With MobileMeshSolidity.Solid all my calculations are as I expected.

Many thank's!
Post Reply