1. Introduction
The OrientationSensor API extends the Generic Sensor API [GENERIC-SENSOR] to provide generic information describing the device’s physical orientation in relation to a three dimensional Cartesian coordinate system.
The AbsoluteOrientationSensor
class inherits from the OrientationSensor
interface and
describes the device’s physical orientation in relation to Earth’s reference coordinate system.
Other subclasses describe the orientation in relation to other stationary directions, such as true north, or non stationary directions, like in relation to a devices own z-position, drifting towards its latest most stable z-position.
The data provided by the OrientationSensor
subclasses are similar to data from deviceorientation Event, but the OrientationSensor API has some significant differences:
-
The OrientationSensor API represents orientation data in WebGL-compatible formats (quaternion, rotation matrix).
-
The OrientationSensor API satisfies stricter latency requirements.
-
Unlike deviceorientation Event the
OrientationSensor
subclasses explicitly define which low-level motion sensors are used to obtain the orientation data, thus obviating possible interoperability issues. -
Instances of
OrientationSensor
subclasses are configurable viaSensorOptions
constructor parameter.
2. Use Cases and Requirements
The use cases and requirements are addressed in the Motion Sensors Explainer document.
3. Examples
const sensor = new AbsoluteOrientationSensor(); const mat4 = new Float32Array(16); sensor.start(); sensor.onerror = event => console.log(event.error.name, event.error.message); sensor.onreading = () => { sensor.populateMatrix(mat4); }
const sensor = new AbsoluteOrientationSensor({ frequency: 60 }); const mat4 = new Float32Array(16); sensor.start(); sensor.onerror = event => console.log(event.error.name, event.error.message); function draw(timestamp) { window.requestAnimationFrame(draw); try { sensor.populateMatrix(mat4); } catch(e) { // mat4 has not been updated. } // Drawing... } window.requestAnimationFrame(draw);
4. Security and Privacy Considerations
There are no specific security and privacy considerations beyond those described in the Generic Sensor API [GENERIC-SENSOR].
5. Model
The OrientationSensor
class extends the Sensor
class and provides generic interface
representing device orientation data.
The OrientationSensor has an associated PermissionName
which is "orientation-sensor".
A latest reading per sensor of orientation type includes an entry whose key is "quaternion" and whose value contains a four element list. The elements of the list are equal to components of a unit quaternion [QUATERNIONS] [Vx * sin(θ/2), Vy * sin(θ/2), Vz * sin(θ/2), cos(θ/2)] where V is the unit vector representing the axis of rotation.
The AbsoluteOrientationSensor
class is a subclass of OrientationSensor
which represents the Absolute
Orientation Sensor.
The absolute orientation sensor is a high-level sensor which is created through sensor-fusion of the low-level motion sensors:
-
accelerometer that measures acceleration,
-
gyroscope that measures angular velocity, and
-
magnetometer that measures magnetic field.
Note: Corresponding low-level sensors are defined in [ACCELEROMETER], [GYROSCOPE], and [MAGNETOMETER]. Regardless, the fusion is platform specific and can happen in software or hardware, i.e. on a sensor hub.
For the absolute orientation sensor the value of latest reading["quaternion"] represents rotation of a device hosting motion sensors in relation to a Earth’s reference coordinate system defined as a three dimensional Cartesian coordinate system (x, y, z), where:
-
x-axis is a vector product of y.z that is tangential to the ground and points east.
-
y-axis is tangential to the ground and points towards magnetic north.
-
z-axis points towards the sky and is perpendicular to the plane made up of x and y axes.
The device’s local coordinate system is the same as defined by low-level motion sensors.
Note: Figure below represents the case where device’s local coordinate system and Earth’s reference coordinate system are aligned, therefore, orientation sensor’s latest reading would represent 0 (rad) [SI] rotation about each axis.
6. API
6.1. The OrientationSensor Interface
typedef (Float32Array or Float64Array or DOMMatrix)RotationMatrixType
; interfaceOrientationSensor
: Sensor { readonly attribute FrozenArray<double>?quaternion
; voidpopulateMatrix
(RotationMatrixTypetargetMatrix
); };
6.1.1. OrientationSensor.quaternion
Returns a four-element FrozenArray
the elements of which contain the components of the unit quaternion representing the device orientation.
In other words, this attribute returns latest reading["quaternion"].
6.1.2. OrientationSensor.populateMatrix()
The populateMatrix()
method populates the given object with rotation matrix
which is converted from the value of latest reading["quaternion"] [QUATCONV], as shown below
where:
-
W = cos(θ/2)
-
X = Vx * sin(θ/2)
-
Y = Vy * sin(θ/2)
-
Z = Vz * sin(θ/2)
The rotation matrix is flattened in targetMatrix object according to the column-major order, as described in populate rotation matrix algorighm.
populateMatrix()
method must
run these steps or their equivalent:
-
If targetMatrix is not of type defined by
RotationMatrixType
union, throw a "TypeError
"DOMException
and abort these steps. -
If targetMatrix is of type
Float32Array
orFloat64Array
with a size less than sixteen, throw a "TypeError
"DOMException
and abort these steps. -
Let quaternion be the value of latest reading["quaternion"]
-
If quaternion is
null
, throw a "NotReadableError
"DOMException
and abort these steps. -
Let x be the value of quaternion[0]
-
Let y be the value of quaternion[1]
-
Let z be the value of quaternion[2]
-
Let w be the value of quaternion[3]
-
If targetMatrix is of
Float32Array
orFloat64Array
type, run these sub-steps:-
Set targetMatrix[0] = 1 - 2 * y * y - 2 * z * z
-
Set targetMatrix[1] = 2 * x * y - 2 * z * w
-
Set targetMatrix[2] = 2 * x * z + 2 * y * w
-
Set targetMatrix[3] = 0
-
Set targetMatrix[4] = 2 * x * y + 2 * z * w
-
Set targetMatrix[5] = 1 - 2 * x * x - 2 * z * z
-
Set targetMatrix[6] = 2 * y * z - 2 * x * w
-
Set targetMatrix[7] = 0
-
Set targetMatrix[8] = 2 * x * z - 2 * y * w
-
Set targetMatrix[9] = 2 * y * z + 2 * x * w
-
Set targetMatrix[10] = 1 - 2 * x * x - 2 * y * y
-
Set targetMatrix[11] = 0
-
Set targetMatrix[12] = 0
-
Set targetMatrix[13] = 0
-
Set targetMatrix[14] = 0
-
Set targetMatrix[15] = 1
-
-
If targetMatrix is of
DOMMatrix
type, run these sub-steps:-
Set targetMatrix.m11 = 1 - 2 * y * y - 2 * z * z
-
Set targetMatrix.m12 = 2 * x * y - 2 * z * w
-
Set targetMatrix.m13 = 2 * x * z + 2 * y * w
-
Set targetMatrix.m14 = 0
-
Set targetMatrix.m21 = 2 * x * y + 2 * z * w
-
Set targetMatrix.m22 = 1 - 2 * x * x - 2 * z * z
-
Set targetMatrix.m23 = 2 * y * z - 2 * x * w
-
Set targetMatrix.m24 = 0
-
Set targetMatrix.m31 = 2 * x * z - 2 * y * w
-
Set targetMatrix.m32 = 2 * y * z + 2 * x * w
-
Set targetMatrix.m33 = 1 - 2 * x * x - 2 * y * y
-
Set targetMatrix.m34 = 0
-
Set targetMatrix.m41 = 0
-
Set targetMatrix.m42 = 0
-
Set targetMatrix.m43 = 0
-
Set targetMatrix.m44 = 1
-
6.2. The AbsoluteOrientationSensor Interface
[Constructor
(optional SensorOptionssensorOptions
)] interfaceAbsoluteOrientationSensor
: OrientationSensor { };
To Construct a AbsoluteOrientationSensor Object the user agent must invoke the construct a Sensor object abstract operation.
7. Acknowledgements
Tobie Langel for the work on Generic Sensor API.
8. Conformance
Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.
All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]
A conformant user agent must implement all the requirements listed in this specification that are applicable to user agents.
The IDL fragments in this specification must be interpreted as required for conforming IDL fragments, as described in the Web IDL specification. [WEBIDL]