How to manipluate angular velocity

Hi there, since the current iteration of DOTS Physics does not support
joint motors i wanted to improvise a temporary solution and got quite confused
by the angular velocity.

In PhysX it was determined in rad/s, and when manually set to about 6.2, the object
would rotate 360° in one second (or there about), as expected.

Now in DOTS with either Havok or UnityPhysics I can’t get the hang of angular
velocity: rad/s does not work, and neither does deg/s. In both cases, the object spins
at a seemingly arbitrary speed, although the Entity displays the correct angular velocity
in its debugger. Disabling angular damping did not help either.
So all I have managed thus far is to get an object to rotate around the desired axis, at some speed.

I am very sure I got it completely wrong in concept here. Sadly the documentation
did not shed any light on this and I failed to get any insight from the Physics Samples.

TL;DR How does angular velocity work in DOTS and how can I set and read it in such a way
that I get consistent results.

Angular Velocities in DOTS Physics are based on rad/s but the confusion is probably because they need set in the ‘Motion Space’ of the dynamic body, where you may be trying to apply things in ‘World Space’.

Here is the code for the Component Extension that applies an impulse at a specific point:

        public static void ApplyImpulse(ref this PhysicsVelocity pv, PhysicsMass pm, Translation t, Rotation r, float3 impulse, float3 point)
        {
            // Linear
            pv.ApplyLinearImpulse(pm, impulse);

            // Angular
            {
                // Calculate point impulse
                var worldFromEntity = new RigidTransform(r.Value, t.Value);
                var worldFromMotion = math.mul(worldFromEntity, pm.Transform);
                float3 angularImpulseWorldSpace = math.cross(point - worldFromMotion.pos, impulse);
                float3 angularImpulseInertiaSpace = math.rotate(math.inverse(worldFromMotion.rot), angularImpulseWorldSpace);

                pv.ApplyAngularImpulse(pm, angularImpulseInertiaSpace);
            }
        }

        public static void ApplyLinearImpulse(ref this PhysicsVelocity velocityData, PhysicsMass massData, float3 impulse)
        {
            velocityData.Linear += impulse * massData.InverseMass;
        }

        public static void ApplyAngularImpulse(ref this PhysicsVelocity velocityData, PhysicsMass massData, float3 impulse)
        {
            velocityData.Angular += impulse * massData.InverseInertia;
        }

Notice how it converts the world space angular impulse before applying the impulse.
The other elements that you might be hitting is that the default in PhysX is that the ForceMode is defaulting to Force. Things are a little more raw with DOTS Physics at the minute and everything is in impulses (i.e. ForceMode.Impulse). To apply forces rather than impulses, multiply your impulse by the deltaTime, which will give you a much smaller magnitude.

TLDR;

  1. Angular Impulses are currently in Inertia Space
  2. Impulses need multiplied by deltaTime to be converted to Forces
1 Like

That clears up why I could not make any sense of it.
I will try my hands at the conversion, to see if I can figure it out now.

Thank you very much for the detailed explanation

So I have had some time to try out your suggestions and sadly I could not fix the issue. The transformation example helped me to convert my Mathf code to Unity.Math, which is nice, but since I was directly setting
the velocity, your advice on impulses did not work for me.

Is setting the velocity directly not desirable? I would be fine with switching to ApplyImpulse instead, but I would still be stuck on the core issue, that the rotation times do not seem to match the expected times. The cube in the image rotates around the x-axis and has just about completed one full cycle, which took 2.7 seconds. These times vary between each test, ranging from 2.7 and 3.3 seconds. The PhysicsVelocity reads the expected 6.2 rad/s.

The whole point is to eventually simulate a robot arm using DOTS physics (both Havok and Unity).
For now the simulation has to be a good estimate at best, but nothing too precise. Maybe I am approaching this whole thing wrong.

How could I make a joint rotate at a set rad/s speed, so that it properly collides with other objects and
has its movement obstructed by them? Directly rotating it through the Rotation component results in
jittering collisions, which is why I switched over to using velocities in PhysX and the same held true
for DOTS.



Is float3 point here in local space or world space?