Hi, Im new to godot.

Im working on a Carcontroller based on bullets 6dof joints and Rigidbodies. all is working grate so far, but i have problems to get the RPM of a wheel. i need it because i try to make some kind of Lock-Differential~~~~

I Use C# only, but solutions in gdscripts are ok, i will translate it myself.

in unity, the wheel joint have the rpm as property so ther it is easy.

i tryed different things.
The big problem for me, coming from unity, is there is no local transform, since Rigidbodies are not alowed to be child of a Spatial.

The first aproach was to calculate something from Spatial.RotationDegrees, but it flip over and is from -90 to +90 degree and im to dubmb to solve it propperly,

second atempt was:

rpm = Mathf.Abs(Rigidbodie.angularVelocyti.x) (angularVelocity is Global) +Mathf.Abs(Rigidbodie.angularVelocyti.y) +Mathf.Abs(Rigidbodie.angularVelocyti.z);

gives me the angular velocity over all axis together but only positive, and i need it in X Axis only.

next atemt, and current state is;

    Quat qaR = LeftWheel.Transform.basis.Quat();

    float deltaAngleR = Mathf.Rad2Deg(LastRotationR.AngleTo(qaR));

    float RRPM = ((1 / delta) * deltaAngleR) / 6;

   LastRotationL = qaL;

this calculates the rpm by calculating the angle from last frame to now, but same problem, this is the angle of all axis together.

I think you would have to take the whole angular velocity and project it onto the local object x axis (using a basis transform). It's kind of complicated, let me see if I can give you an example.

Actually, I found an easy way. I think this works.

func _physics_process(delta):
	var basis = transform.basis
	var local_velocity = basis.xform_inv(angular_velocity)
	var rpm = (local_velocity.x / (2.0 * PI)) * 60.0;
	print("x rpm = ", rpm)

I tested it out, and it looks like it works! i think i have to use the same for local linear velocity as well.

Thanks a lot! which unit is angular velocity? is it rad/sec ?

in C# its:

    Basis bas = LeftWheel.Transform.basis;
    Vector3 local_velocity = bas.XformInv(LeftWheel.AngularVelocity);
    float rpm = (local_velocity.x / (2.0f * Mathf.Pi)) * 60;
    GD.Print(local_velocity);

for other C# users....

Yes, radians per second. I divide by 2PI to get rotations per second and then times by 60 for minutes.

a year later