Computing the iOS device tilt
The tilt of a device is probably the most useful information you can get from the acceleration data of your iPhone, iPad or iPod touch. Besides, a lot of games are using it. The question is, how to get this tilt value ?
I’ve looked into the Core Motion documention and found out that Apple is computing some values for us, which is available within a
CMAttitude class instance.
An instance of the CMAttitude class represents a measurement of the device’s attitude at a point in time.
And you have guessed, the
yaw value is the rotation against the red axis. It seems pretty straight forward so let’s implement that.
And I thought “easy, problem solved”. In fact, it was terrible and unusable because the
yaw value was impacted by the iPhone
pitch. I mean, if we keep the iPhone vertical and twist it against the blue axis, it will modify the
Check out the gimbal lock problem if you want to understand more about it.
So back to square one, I had to find a way to compute the
yaw by myself and I felt that math may rescue me!
The beauty of Quaternions
If you don’t know what a quaternion is yet, please don’t freak out by this strange word that seems coming right out of Star Trek.
Quaternions were first described by Hamilton in 1843 and applied to mechanics in three-dimensional space.
It eases the way we deal with the orientation of a body in a 3D space, and is better suited than the Euler angles that Apple is computing for us because of three reasons :
- it’s easier to compose rotations or to extract values from it.
- it avoids the gimbal lock problem.
- and Apple provides a quaternion in the
And because we only want to compute the
yaw we do not have to worry about the gimbal lock problem, since our goal is not to describe the complete iPhone orientation in the 3D space but only the tilt of it.
There is a very simple formula to compute
yaw from a quaternion :
motionRefresh: method described above become :
The icing on the cake
We can improve the code a bit to have a perfectly smooth
yaw signal, or to have some kind of internia in the tilt movement (just like I needed in my DPMeterView project).
In order to do that, we need a very simple one dimensional Kalman-filter. I’m not discussing the details of how it works because it’s not the purpose of the article. However, you can experiment by yourself the impact of changing some of those values.
Fork it !
If you have some ideas of improvement, or just want to play with a working example, don’t hesitate to fork the DPMeterView project hosted on GitHub.
iPhone 5 model created by Pixeden.comments powered by Disqus