Unity: Input.gyro.attitude Accuracy

In my application, I need to know about device rotation. I am trying to derive the y axis value from a gyroscope using the following:

var y = Input.gyro.attitude.eulerAngles.y;

If I simply display it on the screen and turn it in a circle (holding my phone straight up and down ... as if you are looking at the screen), I get the following:

<270> 270, 270, 270, etc., etc ... thanks ...

Is there any way to account for this jump in numbers?

+5
source share
3 answers

Frame lock

What you see is called gimbal lock more here . This happens when Euler angles intersect a plane of 360 or more specifically (two of the three axes are in parallel configuration), and that is why people use Quaternions.

Quaternions

You should not hide the corners of the eulers directly. I would recommend something like this:

 Quaternion q = Input.gyro.attitude.rotation; 

Using Quaternion and not Euler angles, we will avoid locking the universal joint and, therefore, avoid the problem with 360, 0.

If you just want to show the angle in which they are facing in the y direction, I could recommend something like this, this will wrap the angle y to 0 to 180 degrees:

 /// <summary> /// This method normalizes the y euler angle between 0 and 180. When the y euler /// angle crosses the 180 degree threshold if then starts to count back down to zero /// </summary> /// <param name="q">Some Quaternion</param> /// <returns>normalized Y euler angle</returns> private float normalizedYAngle(Quaternion q) { Vector3 eulers = q.eulerAngles; float yAngle = eulers.y; if(yAngle >= 180f) { //ex: 182 = 182 - 360 = -178 yAngle -= 360; } return Mathf.Abs(yAngle); } 
+4
source

You can set the maximum rotation to prevent quick transitions.

 y_diff = new_y - last_y; y = y + Mathf.Clamp(y_diff, -limit, limit); 
+2
source

You can use linear interpolation to achieve this effect. The only thing you need to consider is how quickly you do it, because the phone will constantly rotate and you do not want your values ​​to lag.
Example using Mathf.Lerp :

  // Your values var y = 0; // speed for the Lerp static float t = 1.0f; void Update() { float old = y float new = Input.gyro.attitude.eulerAngles.y; // Interpolate y = Mathf.Lerp(old, new, t * Time.deltaTime); } 

Link to here

+1
source

Source: https://habr.com/ru/post/1265690/


All Articles