Hacker News new | ask | show | jobs
by manchego 905 days ago
My wife has had to listen to me complain for the last week about what a pain it is to get the absolute orientation of an iPhone from the browser.

On Android you can use AbsoluteOrientationSensor or deviceorientationabsolute event. These will provide a quaternion or Euler angles describing how to rotate the device from the default orientation (flat on the ground, screen up, with the top pointing north) to its current orientation.

The situation on the iPhone has almost reduced me to tears. As far as I can tell, it only provides Euler angles relative to some implementation defined reference frame, along with the actual compass heading. In practice, the Euler angles given are absolute with respect to gravity, but always treat north as the direction the phone was pointed when the first sensor reading took place. To deal with this, you can use the actual compass heading to rotate the relative orientation to the absolute orientation. But this will have problems near the poles, as the Euler angles and heading will give conflicting values. Beyond this the compass heading field is really weird. If you want to experience its behavior for yourself, take the iPhone compass app and starting from flat, rotate the phone 360 degrees through the pitch axis. Notice at what points the heading flips between its start heading and start heading+180. I bet it will surprise you!

5 comments

To me it sounds like the solution is "We have detected you're using an unsupported browser, iOS does not allow websites to properly access device orientation and therefore this app cannot function"
I wish I had come to that conclusion a week ago, but I'm in too deep now. It's for a little side project, and it seems like the majority of people I want to show it to have iPhones.
Or even just not caring about users at the poles? How many users are you expecting to have in Greenland or Antarctica?
I should have said zenith, not poles. The issues occur when the device is pointed up at the sky or down at the ground. Edit: Though I would imagine it won't work too well at the poles either!
Are you saying you have to fight gimbal lock just to find which way to rotate the screen on iPhone? That was a problem on the 1960s lunar missions, no idea it'd happen in such a mundane application
This is why orientation should always be reported as a unit quaternion (or if you strongly care about using only 3 vs. 4 numbers, using "modified Rodrigues parameters", the stereographic projection of a unit quaternion).
Pretty much. The iPhone browser api only exposes compass data in one dimension, around the z-axis. So there is indeed gimbal lock-like behavior near the axis. Which is crazy since the magnetometer is 3 dimensional.
Can you use media queries and guess orientation from screen width?
For my use case, I want to know the exact way the phone is pointed in all three axis. Which requires more information than determining the screen orientation (and which I believe can be done as you say). Unfortunately, the term "orientation" seems to be overloaded and used to describe both concepts.
Makes sense. Then it's 100% because Apple wants to force developers to implement an app.
Same thing I thought.
Just out of curiosity because you might know: does the deviceorientation event (without absolute) work on iOS? Because I've just used it for a toy website of mine and have no iPhone to test.
I have used in this app: https://mhealth.jmir.org/2020/1/e13756 it's OK for relative orientation, but not for absolute values
Agreed, the deviceorientation does work fine for relative orientation. I've been able to hack it for absolute orientation. What I am doing is: 1) taking the relative orientation euler angles from the event and converting them to a quaternion for easier manipulation. 2) taking the webkitCompassHeading from same deviceorientation event. 3) Calculating the "relative heading", eg how far the relative orientation is from its fake north. 4) calculating the difference between the relative and actual heading. 5) building a quaternion to describe the bearing difference, eg how far the relative orientation need to be corrected by spinning around the z-axis. 6) Multiply the two quaternions to get the final absolute orientation quaternion. This does work, though has the issues I mentioned previously, and relies on the undocumented fact the the relative orientation is actually absolute with respect to the down/gravity vector.
I haven't tested it on iPhone, but on Android my browser code for Euler angles works just fine. You can find the demonstration at the end of this blog post https://dandanua.github.io/posts/the-spin-of-a-human-body/