Measuring the gap between the spec and browser implementations

Hi,

we've been doing a lot of R&D and testing across the different browser 
using the DeviceOrientation API recently as part of the preparation for 
releasing our Augmented Web open source library (see 
https://github.com/buildar/awe.js)

You can see a video here of the DeviceOrientation/Geolocation based AR 
demo working in Firefox 26 on Android.

http://youtu.be/OJHgBSRJNJY

Our awe.js library is designed to make it easy for anyone to create 
Augmented Web applications like this and as you can see this now 
provides just as good a user experience as any of the mainstream 
dedicated AR browsers for geolocation based AR (more to come soon).

However, our testing has shown that the browser implementations are 
quite different from what is defined in the spec.  Below is a detailed 
description of what we have found, along with a few questions and 
recommendations.

I'll look forward to hearing your feedback 8)

PS: Apologies for the long email but there is a lot of information and 
test results to cover. I hope you find it clear and useful. We've tried 
to be as detailed and thorough as possible.

roBman


NOTE: All comments about the spec are referencing "W3C Working Draft 1 
December 2011" published here http://www.w3.org/TR/orientation-event/

alpha
In the spec this is defined as rotation around the z axis of the 
device's coordinate frame. However, in Safari on iOS devices and Chrome, 
Firefox and Opera on Android devices this has been implemented as 
"rotation around the Z axis of the Earth's coordinate frame". Basically 
alpha is the digital compass heading, and in reality as a developer this 
is a much more useful and pragmatic choice.

Where the spec states:
"1. Rotate the device frame around its z axis by |alpha|degrees, with 
|alpha|in [0, 360)."

The real implementations are:
"1. Rotate the device frame around the Earth's Z axis by |alpha|degrees, 
with |alpha|in [0, 360]."

e.g. I can spin my devices 180deg around their z axis (spin it upside 
down) but alpha still equals 0 when the back of the device is pointed to 
North.

recommendation
Perhaps we should just accept that this is what has been universally 
implemented and update the spec to reflect that. If in the worst case 
the spec's "rotation around the z axis of the device's coordinate frame" 
were to be "enforced" then at least the spec should be extended to allow 
this compass style "rotation around the Z axis of the Earth's coordinate 
frame" so we don't lose this already implemented and useful data. In 
effect this is really what Safari's webkitCompassHeading is (excluding 
the alpha inversion to make it match wgs84's compass heading values).


beta
In the spec this is defined as rotation around the x axis of the 
device's coordinate frame. However, only Firefox on Android seem to have 
implemented this correctly. All the other main mobile browsers (Safari 
on iOS and Chrome and Opera on Android) have implemented this as ranging 
from +90 to -90 where 0 is the screen parallel to the Earth's ground 
plane with the screen facing up, +90 is with the screen perpendicular to 
the ground plane with the top of the screen at the top, and -90 is with 
the screen perpendicular to the ground plan with the top of the screen 
at the bottom (e.g inverted). So it seems like all the blink/webkit 
browsers share the same bug/misinterpretation. I'd speculate they have 
accidentally used the gamma range as defined in the spec...but more 
about that below.
NOTE - Even the Safari documentation has these swapped - see "beta 
discussion" and "gamma discussion" vs the spec:
https://developer.apple.com/library/safari/documentation/SafariDOMAdditions/Reference/DeviceOrientationEventClassRef/DeviceOrientationEvent/DeviceOrientationEvent.html

comment
I'll raise this as a bug with the blink and webkit communities once I've 
received some initial feedback from this working group.


gamma
In the spec this is defined as "half" the rotation around the y axis for 
the device's coordinate frame. Again, Firefox on Android are the only 
browser to implement what is defined in the spec. Chrome and Opera range 
from -90 to 270 where 0 is the screen parallel to the ground plane 
facing up and -90/270 is with the screen facing to the left. Safari on 
iOS devices range from 180 to -180 where 0 is the screen parallel to the 
ground plane facing up, rotates from 0 to -180 to the left and 0 to 180 
to the right with 180/-180 facing down.

question
Why was gamma only specified to be aware of half the world? (e.g. only 
90 to -90 or more clearly "relationship to up and relationship to 
down"). When this is implemented as specified it is impossible to tell 
if the device is facing forwards at 45deg or backwards at 45deg around 
this axis. So in our AR example listed at the top, we are forced to 
abandon up/down adjustment of the virtual camera based on gamma if the 
device is in landscape mode.
NOTE - If you look at the CMAttitude class in objective-c this 
limitation is not implied. And all of the IMU specs I could find also 
seem to return a full 360deg in all 3 axes.

recommendation
Update the spec to make gamma range from 180 to -180 just like beta is 
specified to. Since most of the browsers need to fix this anyway, now 
seems like a good time to make this change 8)

comment
I'll raise this as a bug with the blink and webkit communities once I've 
received some initial feedback from this working group on the 
recommendation above.


absolute
Safari on iOS always seems to return absolute as undefined. If anyone 
has seen a case where this value was returned I'd like to know, 
otherwise I'm happy to raise this as a bug with them.



SUMMARY:
The spec at http://www.w3.org/TR/orientation-event/ says:

East -> X
North -> Y
Up -> Z

alpha (around Z): 0 to 360 (0 North)
beta (around X): -180 to 180 (0 Up)
gamma (around Y): -90 to 90 (0 Up)
absolute: boolean


And here are the results from our testing:
safari
alpha: 0 to 360 (0 roughly North)
beta: 0 screen up, 90 screen top perpendicular to ground plane, -90 
screen inverted
gamma: 0 screen up, rotates from 0 to -180 to the left and 0 to 180 to 
the right (180/-180 down)
absolute: undefined
result:
Seems like beta/gamma have been swapped and absolute not implemented.

chrome
alpha: 0 to 360 (0 roughly North)
beta: 0 screen up, 90 screen top perpendicular to ground plane, -90 
screen inverted
gamma: 0 screen up, rotates from -90 to 270 (to the left)
absolute: true
result:
Seems like beta/gamma have been swapped and gamma has not implemented as 
specified.

opera
alpha: 0 to 360 (0 roughly North)
beta: 0 screen up, 90 screen top perpendicular to ground plane, -90 
screen inverted
gamma: 0 screen up, rotates from -90 to 270 (to the left)
absolute: true
result:
Seems like beta/gamma have been swapped and gamma has not implemented as 
specified.

firefox
alpha: 0 to 360 (0 roughly North)
beta: 0 screen up, rotates from 0 to -180 (-90 screen top up) and 0 to 
180 (90 screen top down)
gamma: 0 screen up, rotates from 0 to -90 and back again to the right 
and 0 to 90 and back again to the left
absolute: true
result:
Standards compliant - but would be better if gamma ranged from 180 to -180.

Received on Monday, 13 January 2014 08:00:44 UTC