How to obtain roll / tilt angle from gyroscope?
Asked Answered
C

3

0

Imagine that the user is holding the device with both hands in landscape mode. I need to determine the roll / tilt angle. The picture below show three different angles.

9958-iphone-rotation.gif

This is the only kind of rotation I am interested in. So I tried using Input.gyro.attitude.eulerAngles.z. That works if the forward vector of the gyroscope is pointing at the horizon like the top image below. But if the forward vector is pointing downwards (3rd image) it fails.

9960-phone.jpg

So I was wondering if anyone has an idea of how to determine the angles (z rotation) shown in the first image regadles of x rotation. I know that this a typical case of gimbal lock, but there must be a work-around. How do racing games tackle this problem when using the gyro for steering??

Note: I do not want to use Input.gyro.rotationRate and apply it as a delta to some kind of starting orientation, because that will become more and more inaccurate over time. Input.gyro.attitude (which is a quaternion) is the way to go. I just don’t know how to get roll / tilt if the device is facing down (or up).

Credendum answered 6/6, 2023 at 2:48 Comment(0)
C
0

As it turns out, the solution is pretty easy. After having spent way too much time with manual calculation I came up with this few lines instead:

Quaternion referenceRotation = Quaternion.identity;
Quaternion deviceRotation = DeviceRotation.Get();
Quaternion eliminationOfXY = Quaternion.Inverse(
	Quaternion.FromToRotation(referenceRotation * Vector3.forward, 
							  deviceRotation * Vector3.forward)
);
Quaternion rotationZ = eliminationOfXY * deviceRotation;
float roll = rotationZ.eulerAngles.z;

Rotating the quaternion so that its forward vector points to referenceRotation * Vector3.forward eliminates x and y rotation while maintaining z.

Still, the resulting roll angle will get a little bit unstable if you turn yourself 180° around real worlds y axis while playing (e.g. if you’re sitting in a moving vehicle). That’s what referenceRotation is for, which could either be reset manually by the user or even better via compass. That’s what’s next on my to do list :slight_smile:

PS:

DeviceRotation.Get() is a wrapper for gyro input which adjusts the forward axis and takes different device orientations into account. Read more about it here.

Credendum answered 5/2 at 13:22 Comment(5)

Where can I find information about the DeviceRotation.Get()? The content on the website you have posted the link to seems to have changed. Thanks!

Dexter

Oh thanks for that! Do you know how I could modify this to get only the values of the z axis?

Dexter

That's what the code in the original answer is for :)

Credendum

How can I calculate pitch instead? Sorry, but I dont understand quaternions at all

Dewaynedewberry

@Credendum Is GetRotation() the same as Get() ?

Harken
O
0

@Credendum we are dealing with a similar situation right now where we need the X and Y axis.
You describe this working for the Z axis, do you mean the “heading” rotation as used in regular aeronautics?

much appreciated, and sorry for the gravereply!

Oleaster answered 6/6, 2023 at 1:57 Comment(0)
E
0

When I use Chris’ code for the z-axis (the most upvoted post), I am able to change the referenceRotation to my own value (using DeviceRotation.Get), and measure the difference from that. It works perfectly, as I set my referenceRotation to the player’s resting hand position on startup. And I use that as my reference point.

But as soon as I try to do the same with the y-axis (using Vector3.up), it does not work and the reading goes completely crazy. This axis only seems to work with a referenceRotation of Quaternion.identity, nothing else. Can anyone please advise why this might be? I really need to do the same thing as the z-axis and I do not understand why it won’t work.

@Credendum any ideas?
__

EDIT: I suspect it has something to do with when he says “DeviceRotation.Get() is a wrapper for gyro input which adjusts the forward axis and takes different device orientations into account”. I suspect I need to do the same for the up axis, but unfortunately the tutorial he posted no longer works!! Does anyone know how to do this?

Edina answered 6/6, 2023 at 2:41 Comment(1)

The linked article is available via the WayBack Machine here: https://web.archive.org/web/20180904151819/http://blog.heyworks.com/how-to-write-gyroscope-controller-with-unity3d/

Sanitarium

© 2022 - 2024 — McMap. All rights reserved.