How do I calculate the magnitude of pitch, yaw and roll of a rigidbody?

Hey,

I’m trying to learn 3d programming and I have a hard time this problem though sounds like it should be extremely easy but nothing I tried seem to work.

I currently have a spaceship, I want to build a steering thruster which applies force to the spaceship depending on the current rotation magnitude.

Something like this,

  private Quaternion GetEulerAngels()
  {
      Quaternion currentRotation = _ship.transform.localRotation;
      Quaternion previousRotation = pRotation;   
      Quaternion deltaRotation = currentRotation * Quaternion.Inverse(previousRotation);

      return deltaRotation;
  }

  private float GetRoll()
  {
      var deltaEulerAngles = GetEulerAngels();

      float rollSpeed = deltaEulerAngles.x;

      if (rollSpeed> 180f)
      {
          rollSpeed-= 360f;
      }

      Debug.unityLogger.Log($"roll speed: {rollSpeed}");
      return rollSpeed;
  }

I assume I’m using the math functions incorrectly but I can’t understand what I should use instead. Most of my issues stem from that what I do works as long as I don’t rotate the ridgidbody, I tried using local rotation instead but that didn’t work either.

You’re close.

The .rotation of a Rigidbody is actually more of an “orientation” than a rate of turn.

You want .angularVelocity, and then inverse that to find your local yaw, pitch, roll rates.

This is how I compute local roll / pitch / yaw rates for control stabilization computations:

                var iq = Quaternion.Inverse( rb.rotation);
                Vector3 localAngularVelocity = iq * rb.angularVelocity;

With the above, localAngularVelocity means:

localAngularVelocity.x => pitch rate

localAngularVelocity.y => yaw rate

localAngularVelocity.z => roll rate

This is from my Jetpack Kurt game, which needed control stabilization to make it flyable:

1 Like

Thank you, that helped a lot I still have som issues but I think they are unrelated to this problem.

Cool game!

The Unity “Euler Angles” concept should not be used anywhere near flight systems. They’re always applied in the order of Z first, X next, Y last, which is helpful for land-based vehicles in a Y-up world, but will completely mess your orientation up if you’re trying to work in terms of flight dynamics like yaw, pitch, and roll. For flight dynamics, you want to apply your composite angles in the order of Yaw first, Pitch next, Roll last, which in Unity’s Z-forward world is Y X Z.

This converts a given yaw, pitch, roll into a suitable Quaternion for your aircraft.

    public static Quaternion YawPitchRoll(float yaw, float pitch, float roll)
    {
        Quaternion heading = Quaternion.AngleAxis(yaw, Vector3.up);
        Quaternion attitude = Quaternion.AngleAxis(pitch, Vector3.right);
        Quaternion bank = Quaternion.AngleAxis(roll, Vector3.forward);
        return heading * attitude * bank;
    }

Unfortunately, even with a fair bit of experimentation and searching on my part, I have not yet found a good solution that implements the reverse: given a normalized Quaternion in Unity’s left-handed universe, return the angles for yaw, pitch, roll.

Were you and to solve the reverse yet? I’ve been experimenting and searching as well for the last two weeks and it seems impossible to get y,p,r local to the ships local orientation.

I’m trying to export orientation telemetry for a motion rig .

its a 6dof game , i would like it so that regardless of which way your nose is facing . eg if rolled right , turning left and right would still be yaw(around local y-axis) and not pitch(around global x-axis).

i tried to realign the objects rotation with Vector3.forward so i can measure

private static float MeasureRoll(Transform transform)
{
    var rotation = transform.rotation;

    var qFwd = transform.forward.ToQuaternion();
    var unfwd = Quaternion.Inverse(qFwd);

    var fwdAlignedRot = (rotation * unfwd).Normalized();

    return fwdAlignedRot.eulerAngles.z;
}

doesn’t quite work