# Orientation Sensor

## W3C First Public Working Draft, 1 January 1970

This version:
  https://www.w3.org/TR/1970/WD-orientation-sensor-19700101/
Latest published version:
  https://www.w3.org/TR/orientation-sensor/
Editor's Draft:
  https://w3c.github.io/orientation-sensor/
Version History:
  https://github.com/w3c/orientation-sensor/commits/gh-pages/index.bs
Feedback:
  public-device-apis@w3.org with subject line “`[orientation-sensor] … message topic …`” (archives)
Editors:
  Mikhail Pozdnyakov (Intel Corporation)
  Alexander Shalamov (Intel Corporation)
  Kenneth Rohde Christiansen (Intel Corporation)
  Anssi Kostiainen (Intel Corporation)
Bug Reports:
  via the w3c/orientation-sensor repository on GitHub
Test Suite:
  web-platform-tests on GitHub

Copyright © 1970 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.

## Abstract

This specification defines a base orientation sensor interface and concrete sensor subclasses to monitor the device’s physical orientation in relation to a stationary three dimensional Cartesian coordinate system.

## Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document was published by the Devices and Sensors Working Group as a Working Draft. This document is intended to become a W3C Recommendation.

If you wish to make comments regarding this document, please send them to public-device-apis@w3.org (subscribe, archives). When sending e-mail, please put the text “orientation-sensor” in the subject, preferably like this: “[orientation-sensor] …summary of comment…”. All comments are welcome.

This document is a First Public Working Draft.

Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 March 2019 W3C Process Document.

## 1. Introduction

The Orientation Sensor 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 the 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 `DeviceOrientationEvent`, but the Orientation Sensor API has the following significant differences:

1. The Orientation Sensor API represents orientation data in WebGL-compatible formats (quaternion, rotation matrix).

2. The Orientation Sensor API satisfies stricter latency requirements.

3. Unlike `DeviceOrientationEvent`, the `OrientationSensor` subclasses explicitly define which low-level motion sensors are used to obtain the orientation data, thus obviating possible interoperability issues.

4. Instances of `OrientationSensor` subclasses are configurable via `SensorOptions` constructor parameter.

## 2. Use Cases and Requirements

The use cases and requirements are discussed 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.onchange = () => {
      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.

To access the orientation sensor’s latest reading, the user agent must invoke request sensor access abstract operation for each of the low-level sensors used by the concrete orientation sensor. The table below describes mapping between concrete orientation sensors and permission tokens defined by low-level sensors.

OrientationSensor sublass | Permission tokens
--- | ---
`AbsoluteOrientationSensor` | "`accelerometer`", "`gyroscope`", "`magnetometer`"

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 (whole elements are Vx, Vy, and Vz) representing the axis of rotation, and θ is the rotation angle about the axis defined by the unit vector V.

Note: The quaternion components are arranged in the list as [q1, q2, q3, q0] [QUATERNIONS], i.e. the components representing the vector part of the quaternion go first and the scalar part component which is equal to cos(θ/2) goes after. This order is used for better compatibility with the most of the existing WebGL frameworks, however other libraries could use a different order when exposing quaternion as an array, e.g. [q0, q1, q2, q3].

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 the rotation of a device hosting motion sensors in relation to the 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, and

- 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 the 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;
    interface OrientationSensor : Sensor {
      readonly attribute FrozenArray<double>? quaternion;
      void populateMatrix(RotationMatrixType targetMatrix);
    };

#### 6.1.1. OrientationSensor.quaternion

Returns a four-element `FrozenArray` whose elements 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.

To populate rotation matrix, the `populateMatrix()` method must run these steps or their equivalent:

1. If targetMatrix is not of type defined by `RotationMatrixType` union, throw a "`TypeError`" `DOMException` and abort these steps.

2. If targetMatrix is of type `Float32Array` or `Float64Array` with a size less than sixteen, throw a "`TypeError`" `DOMException` and abort these steps.

3. Let quaternion be the value of latest reading["quaternion"]

4. If quaternion is `null`, throw a "`NotReadableError`" `DOMException` and abort these steps.

5. Let x be the value of quaternion[0]

6. Let y be the value of quaternion[1]

7. Let z be the value of quaternion[2]

8. Let w be the value of quaternion[3]

9. If targetMatrix is of `Float32Array` or `Float64Array` type, run these sub-steps:

   1. Set targetMatrix[0] = 1 - 2 * y * y - 2 * z * z

   2. Set targetMatrix[1] = 2 * x * y - 2 * z * w

   3. Set targetMatrix[2] = 2 * x * z + 2 * y * w

   4. Set targetMatrix[3] = 0

   5. Set targetMatrix[4] = 2 * x * y + 2 * z * w

   6. Set targetMatrix[5] = 1 - 2 * x * x - 2 * z * z

   7. Set targetMatrix[6] = 2 * y * z - 2 * x * w

   8. Set targetMatrix[7] = 0

   9. Set targetMatrix[8] = 2 * x * z - 2 * y * w

   10. Set targetMatrix[9] = 2 * y * z + 2 * x * w

   11. Set targetMatrix[10] = 1 - 2 * x * x - 2 * y * y

   12. Set targetMatrix[11] = 0

   13. Set targetMatrix[12] = 0

   14. Set targetMatrix[13] = 0

   15. Set targetMatrix[14] = 0

   16. Set targetMatrix[15] = 1

10. If targetMatrix is of `DOMMatrix` type, run these sub-steps:

    1. Set targetMatrix.m11 = 1 - 2 * y * y - 2 * z * z

    2. Set targetMatrix.m12 = 2 * x * y - 2 * z * w

    3. Set targetMatrix.m13 = 2 * x * z + 2 * y * w

    4. Set targetMatrix.m14 = 0

    5. Set targetMatrix.m21 = 2 * x * y + 2 * z * w

    6. Set targetMatrix.m22 = 1 - 2 * x * x - 2 * z * z

    7. Set targetMatrix.m23 = 2 * y * z - 2 * x * w

    8. Set targetMatrix.m24 = 0

    9. Set targetMatrix.m31 = 2 * x * z - 2 * y * w

    10. Set targetMatrix.m32 = 2 * y * z + 2 * x * w

    11. Set targetMatrix.m33 = 1 - 2 * x * x - 2 * y * y

    12. Set targetMatrix.m34 = 0

    13. Set targetMatrix.m41 = 0

    14. Set targetMatrix.m42 = 0

    15. Set targetMatrix.m43 = 0

    16. Set targetMatrix.m44 = 1

### 6.2. The AbsoluteOrientationSensor Interface

    [Constructor(optional SensorOptions sensorOptions)]
    interface AbsoluteOrientationSensor : OrientationSensor {
    };

To Construct an 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]

## Index

### Terms defined by this specification

- AbsoluteOrientationSensor, in §6.2
- conformant user agent, in §8
- Construct an AbsoluteOrientationSensor Object, in §6.2
- Earth’s reference coordinate system, in §5
- OrientationSensor, in §6.1
- populateMatrix(targetMatrix), in §6.1
- populate rotation matrix, in §6.1.2
- quaternion, in §6.1
- RotationMatrixType, in §6.1

https://w3c.github.io/accelerometer#acceleration Referenced in:

- 5. Model

https://w3c.github.io/accelerometer#local-coordinate-system Referenced in:

- 5. Model (2)

https://www.w3.org/TR/orientation-event#deviceorientation_event Referenced in:

- 1. Introduction (2)

https://www.w3.org/TR/generic-sensor/#sensor Referenced in:

- 5. Model
- 6.1. The OrientationSensor Interface

https://www.w3.org/TR/generic-sensor/#dictdef-sensoroptions Referenced in:

- 1. Introduction
- 6.2. The AbsoluteOrientationSensor Interface

https://w3c.github.io/sensors#construct-sensor-object Referenced in:

- 6.2. The AbsoluteOrientationSensor Interface

https://w3c.github.io/sensors#equivalent Referenced in:

- 6.1.2. OrientationSensor.populateMatrix()

https://w3c.github.io/sensors#high-level Referenced in:

- 5. Model

https://w3c.github.io/sensors#latest-reading Referenced in:

- 5. Model (2) (3) (4)
- 6.1.1. OrientationSensor.quaternion
- 6.1.2. OrientationSensor.populateMatrix() (2)

https://w3c.github.io/sensors#low-level Referenced in:

- 1. Introduction
- 5. Model (2) (3) (4) (5)

https://www.w3.org/TR/generic-sensor/#request-sensor-access Referenced in:

- 5. Model

https://w3c.github.io/sensors#sensor Referenced in:

- 5. Model

https://w3c.github.io/sensors#sensor-fusion Referenced in:

- 5. Model

https://www.w3.org/TR/geometry-1/#dommatrix Referenced in:

- 6.1. The OrientationSensor Interface
- 6.1.2. OrientationSensor.populateMatrix()

https://w3c.github.io/gyroscope#angular-velocity Referenced in:

- 5. Model

https://infra.spec.whatwg.org/#map-entry Referenced in:

- 5. Model

https://infra.spec.whatwg.org/#map-key Referenced in:

- 5. Model

https://infra.spec.whatwg.org/#list Referenced in:

- 5. Model (2) (3)

https://infra.spec.whatwg.org/#map-value Referenced in:

- 5. Model

https://w3c.github.io/magnetometer#magnetic-field Referenced in:

- 5. Model

https://w3c.github.io/motion-sensors#absolute-orientation Referenced in:

- 5. Model

https://heycam.github.io/webidl/#idl-DOMException Referenced in:

- 6.1.2. OrientationSensor.populateMatrix() (2) (3)

https://heycam.github.io/webidl/#idl-Float32Array Referenced in:

- 6.1. The OrientationSensor Interface
- 6.1.2. OrientationSensor.populateMatrix() (2)

https://heycam.github.io/webidl/#idl-Float64Array Referenced in:

- 6.1. The OrientationSensor Interface
- 6.1.2. OrientationSensor.populateMatrix() (2)

https://heycam.github.io/webidl/#idl-frozen-array Referenced in:

- 6.1.1. OrientationSensor.quaternion

https://heycam.github.io/webidl/#notreadableerror Referenced in:

- 6.1.2. OrientationSensor.populateMatrix()

https://heycam.github.io/webidl/#exceptiondef-typeerror Referenced in:

- 6.1.2. OrientationSensor.populateMatrix() (2)

https://heycam.github.io/webidl/#idl-double Referenced in:

- 6.1. The OrientationSensor Interface

https://heycam.github.io/webidl/#dfn-throw Referenced in:

- 6.1.2. OrientationSensor.populateMatrix() (2) (3)

### Terms defined by reference

- [ACCELEROMETER] defines the following terms:
  - acceleration
  - local coordinate system
- [deviceorientation] defines the following terms:
  - DeviceOrientationEvent
- [GENERIC-SENSOR] defines the following terms:
  - Sensor
  - SensorOptions
  - construct a sensor object
  - equivalent
  - high-level
  - latest reading
  - low-level
  - request sensor access
  - sensor
  - sensor-fusion
- [geometry-1] defines the following terms:
  - DOMMatrix
- [GYROSCOPE] defines the following terms:
  - angular velocity
- [INFRA] defines the following terms:
  - entry
  - key
  - list
  - value
- [MAGNETOMETER] defines the following terms:
  - magnetic field
- [motionsensors] defines the following terms:
  - absolute orientation sensor
- [WEBIDL] defines the following terms:
  - DOMException
  - Float32Array
  - Float64Array
  - FrozenArray
  - NotReadableError
  - TypeError
  - double
  - throw

## References

### Normative References

[ACCELEROMETER]
  Anssi Kostiainen. Accelerometer. 7 March 2019. WD. URL: https://www.w3.org/TR/accelerometer/
[GENERIC-SENSOR]
  Mikhail Pozdnyakov; Alexander Shalamov; Tobie Langel. Generic Sensor API. 7 March 2019. WD. URL: https://www.w3.org/TR/generic-sensor/
[GEOMETRY-1]
  Simon Pieters; Chris Harrelson. Geometry Interfaces Module Level 1. 4 December 2018. CR. URL: https://www.w3.org/TR/geometry-1/
[GYROSCOPE]
  Anssi Kostiainen. Gyroscope. 7 March 2019. WD. URL: https://www.w3.org/TR/gyroscope/
[INFRA]
  Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[MAGNETOMETER]
  Anssi Kostiainen; Rijubrata Bhaumik. Magnetometer. 7 March 2019. WD. URL: https://www.w3.org/TR/magnetometer/
[RFC2119]
  S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WEBIDL]
  Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

### Informative References

[QUATCONV]
  Watt, Alan H., and Mark Watt.. Advanced animation and rendering techniques., page 362. 1992. Informational. URL: http://www.cs.cmu.edu/afs/cs/academic/class/15462-s14/www/lec_slides/3DRotationNotes.pdf
[QUATERNIONS]
  Kuipers, Jack B. Quaternions and rotation sequences. Vol. 66.. 1999. Informational. URL: http://www.emis.ams.org/proceedings/Varna/vol1/GEOM09.pdf
[SI]
  SI Brochure: The International System of Units (SI), 8th edition. 2014. URL: http://www.bipm.org/en/publications/si-brochure/

## IDL Index

    typedef (Float32Array or Float64Array or DOMMatrix) RotationMatrixType;
    interface OrientationSensor : Sensor {
      readonly attribute FrozenArray<double>? quaternion;
      void populateMatrix(RotationMatrixType targetMatrix);
    };

    [Constructor(optional SensorOptions sensorOptions)]
    interface AbsoluteOrientationSensor : OrientationSensor {
    };

#earths-reference-coordinate-system Referenced in:

- 1. Introduction
- 5. Model

#typedefdef-rotationmatrixtype Referenced in:

- 6.1. The OrientationSensor Interface
- 6.1.2. OrientationSensor.populateMatrix()

#orientationsensor Referenced in:

- 1. Introduction (2) (3) (4)
- 5. Model (2)
- 6.2. The AbsoluteOrientationSensor Interface

#dom-orientationsensor-populatematrix Referenced in:

- 6.1.2. OrientationSensor.populateMatrix() (2)

#populate-rotation-matrix Referenced in:

- 6.1.2. OrientationSensor.populateMatrix()

#absoluteorientationsensor Referenced in:

- 1. Introduction
- 5. Model (2)