1. 引言
Orientation Sensor API 扩展了 Generic Sensor API [GENERIC-SENSOR], 以提供描述设备相对于三维笛卡尔坐标系的物理方向的 通用信息。
AbsoluteOrientationSensor
类继承自 OrientationSensor
接口,并
描述设备相对于地球
参考坐标系的物理方向。
其他子类描述相对于其他静止方向(如真北)或 非静止方向的方向,例如相对于设备自身的 z 位置, 并向其最近最稳定的 z 位置漂移。
OrientationSensor
子类提供的数据类似于
DeviceOrientationEvent
的数据,
但 Orientation Sensor API 有以下显著差异:
-
Orientation Sensor API 以兼容 WebGL 的格式(四元数、 旋转矩阵)表示方向数据。
-
Orientation Sensor API 满足更严格的延迟要求。
-
不同于
DeviceOrientationEvent,OrientationSensor子类会明确界定使用哪些低级 运动传感器来获得方向数据,从而避免可能的互操作性 问题。 -
OrientationSensor子类的实例可通过SensorOptions构造函数参数进行配置。
2. 用例和要求
用例和要求在 Motion Sensors Explainer 文档中讨论。
3. 示例
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 尚未更新。 } // 绘制... } window. requestAnimationFrame( draw);
4. 安全和隐私考量
除了 Generic Sensor API [GENERIC-SENSOR] 中描述的内容之外, 没有特定的安全和隐私考量。
5. 模型
OrientationSensor
类扩展 Sensor
类,并提供表示设备方向数据的
通用接口。
要访问 Orientation Sensor 传感器类型的最新读数,用户 代理必须针对具体方向传感器使用的每个低级传感器调用 请求传感器访问抽象操作。下表 描述了具体方向传感器与低级传感器定义的权限令牌之间的映射。
| OrientationSensor 子类 | 权限令牌 |
|---|---|
AbsoluteOrientationSensor
| "accelerometer"、"gyroscope"、"magnetometer"
|
RelativeOrientationSensor
| "accelerometer"、"gyroscope"
|
AbsoluteOrientationSensor
是一个受策略控制的特性,由字符串
"accelerometer"、"gyroscope" 和 "magnetometer" 标识。其默认允许列表是 'self'。
RelativeOrientationSensor
是一个受策略控制的特性,由字符串
"accelerometer" 和 "gyroscope" 标识。其默认允许列表是 'self'。
最新读数对于一个Orientation Sensor
传感器
类型的 Sensor
而言,包含一个条目,
其键为
"quaternion",其值包含一个四元素列表。
该列表的元素等于单位四元数的分量
[QUATERNIONS]
[Vx * sin(θ/2), Vy * sin(θ/2), Vz * sin(θ/2), cos(θ/2)],其中 V 是
表示旋转轴的单位向量(其元素为 Vx、Vy 和 Vz),
θ 是绕单位向量 V 所定义轴的旋转角。
注:四元数分量在列表中排列为 [q1, q2, q3, q0] [QUATERNIONS],也就是说, 表示四元数向量部分的分量在前,而等于 cos(θ/2) 的标量部分分量 在后。采用该顺序是为了更好地兼容大多数现有 WebGL 框架, 但其他库在将四元数暴露为数组时可能使用不同顺序,例如 [q0, q1, q2, q3]。
通过传感器融合低级运动传感器而创建的具体 OrientationSensor
子类如下表所示:
| OrientationSensor 子类 | 低级运动传感器 |
|---|---|
AbsoluteOrientationSensor
| Accelerometer、
Gyroscope、
Magnetometer
|
RelativeOrientationSensor
| Accelerometer、
Gyroscope
|
注:Accelerometer、
Gyroscope
和 Magnetometer
低级传感器分别定义于
[ACCELEROMETER]、[GYROSCOPE] 和 [MAGNETOMETER]
规范。传感器融合是平台特定的,可以发生在软件中,也可以发生在
硬件中,即发生在传感器集线器上。
start()
之前,显式查询 AbsoluteOrientationSensor
的权限。
const sensor= new AbsoluteOrientationSensor(); Promise. all([ navigator. permissions. query({ name: "accelerometer" }), navigator. permissions. query({ name: "magnetometer" }), navigator. permissions. query({ name: "gyroscope" })]) . then( results=> { if ( results. every( result=> result. state=== "granted" )) { sensor. start(); ... } else { console. log( "没有使用 AbsoluteOrientationSensor 的权限。" ); } });
另一种做法是直接调用 start()
并订阅
onerror
事件处理器。
const sensor= new AbsoluteOrientationSensor(); sensor. onerror= event=> { if ( event. error. name=== 'NotAllowedError' ) console. log( "没有使用 AbsoluteOrientationSensor 的权限。" ); }; sensor. start();
5.1. AbsoluteOrientationSensor 模型
Absolute
Orientation Sensor 传感器类型表示 Motion Sensors Explainer
§ absolute-orientation 中描述的传感器。其关联的扩展传感器接口是 AbsoluteOrientationSensor,
它是 OrientationSensor
的子类。
其关联的虚拟传感器类型是
"absolute-orientation"。
对于绝对方向传感器,最新 读数["quaternion"] 的值表示 设备局部 坐标系相对于地球参考 坐标系的旋转,后者被定义为三维笛卡尔坐标系(x、y、z),其中:
-
x 轴是 y.z 的向量积,与地面相切并指向东方,
-
y 轴与地面相切并指向磁北,以及
-
z 轴指向天空,并垂直于由 x 轴和 y 轴组成的平面。
设备的局部坐标系与低级 运动传感器所定义的相同。它可以是设备坐标系,也可以是 屏幕坐标系。
注:下图表示设备的局部坐标系与地球 参考坐标系对齐的情况,因此, 方向传感器的最新读数将表示绕每个轴 0(rad)[SI] 旋转。
5.2. RelativeOrientationSensor 模型
Relative
Orientation Sensor 传感器类型表示 Motion Sensors Explainer
§ relative-orientation 中描述的传感器。其关联的扩展传感器接口是 RelativeOrientationSensor,
它是 OrientationSensor
的子类。
其关联的虚拟传感器类型是
"relative-orientation"。
对于相对方向传感器,最新 读数["quaternion"] 的值表示 设备局部坐标系相对于静止参考坐标系的 旋转。静止参考坐标系可能会由于 陀螺仪传感器引入的偏差而漂移,因此,该传感器提供的旋转值可能会随时间漂移。
静止参考坐标系定义为 惯性三维笛卡尔坐标系,在承载传感器的设备穿过 环境移动时保持静止。
设备的局部坐标系与低级 运动传感器所定义的相同。它可以是设备坐标系,也可以是 屏幕坐标系。
注:相对方向传感器数据可能比绝对 方向传感器提供的数据更准确,因为该传感器不受磁场影响。
6. API
6.1. OrientationSensor 接口
typedef (Float32Array or Float64Array or DOMMatrix ); [RotationMatrixType SecureContext ,Exposed =Window ]interface :OrientationSensor Sensor {readonly attribute FrozenArray <double >?;quaternion undefined (populateMatrix RotationMatrixType ); };targetMatrix enum {OrientationSensorLocalCoordinateSystem ,"device" };"screen" dictionary :OrientationSensorOptions SensorOptions {OrientationSensorLocalCoordinateSystem = "device"; };referenceFrame
6.1.1. OrientationSensor.quaternion
返回一个四元素 FrozenArray,
其元素包含表示设备方向的
单位四元数分量。
换句话说,此属性返回以
6.1.2. OrientationSensor.populateMatrix()
populateMatrix(targetMatrix)
方法步骤为:
-
如果 targetMatrix 的类型为
Float32Array或Float64Array, 且大小小于十六,则抛出一个 "TypeError" 异常并中止这些步骤。 -
如果 quaternion 为
null,则抛出一个 "NotReadableError"DOMException并中止这些步骤。 -
令 rotationMatrix 为以 quaternion[0]、quaternion[1]、 quaternion[2] 和 quaternion[3] 将四元数转换为旋转 矩阵的结果。
-
如果 targetMatrix 属于
Float32Array或Float64Array类型,则运行这些子步骤:-
设置 targetMatrix[0] = rotationMatrix[0]
-
设置 targetMatrix[1] = rotationMatrix[1]
-
设置 targetMatrix[2] = rotationMatrix[2]
-
设置 targetMatrix[3] = rotationMatrix[3]
-
设置 targetMatrix[4] = rotationMatrix[4]
-
设置 targetMatrix[5] = rotationMatrix[5]
-
设置 targetMatrix[6] = rotationMatrix[6]
-
设置 targetMatrix[7] = rotationMatrix[7]
-
设置 targetMatrix[8] = rotationMatrix[8]
-
设置 targetMatrix[9] = rotationMatrix[9]
-
设置 targetMatrix[10] = rotationMatrix[10]
-
设置 targetMatrix[11] = rotationMatrix[11]
-
设置 targetMatrix[12] = rotationMatrix[12]
-
设置 targetMatrix[13] = rotationMatrix[13]
-
设置 targetMatrix[14] = rotationMatrix[14]
-
设置 targetMatrix[15] = rotationMatrix[15]
-
-
如果 targetMatrix 属于
DOMMatrix类型,则运行这些子步骤:-
设置 targetMatrix.m11 = rotationMatrix[0]
-
设置 targetMatrix.m12 = rotationMatrix[1]
-
设置 targetMatrix.m13 = rotationMatrix[2]
-
设置 targetMatrix.m14 = rotationMatrix[3]
-
设置 targetMatrix.m21 = rotationMatrix[4]
-
设置 targetMatrix.m22 = rotationMatrix[5]
-
设置 targetMatrix.m23 = rotationMatrix[6]
-
设置 targetMatrix.m24 = rotationMatrix[7]
-
设置 targetMatrix.m31 = rotationMatrix[8]
-
设置 targetMatrix.m32 = rotationMatrix[9]
-
设置 targetMatrix.m33 = rotationMatrix[10]
-
设置 targetMatrix.m34 = rotationMatrix[11]
-
设置 targetMatrix.m41 = rotationMatrix[12]
-
设置 targetMatrix.m42 = rotationMatrix[13]
-
设置 targetMatrix.m43 = rotationMatrix[14]
-
设置 targetMatrix.m44 = rotationMatrix[15]
-
6.2. AbsoluteOrientationSensor 接口
[SecureContext ,Exposed =Window ]interface :AbsoluteOrientationSensor OrientationSensor {(constructor optional OrientationSensorOptions = {}); };sensorOptions
要构造 AbsoluteOrientationSensor
对象,用户代理必须为 AbsoluteOrientationSensor
接口调用构造方向传感器对象抽象
操作。
AbsoluteOrientationSensor
的支持的传感器选项
是
"frequency" 和 "referenceFrame"。
6.3. RelativeOrientationSensor 接口
[SecureContext ,Exposed =Window ]interface :RelativeOrientationSensor OrientationSensor {(constructor optional OrientationSensorOptions = {}); };sensorOptions
要构造 RelativeOrientationSensor
对象,用户代理必须为 RelativeOrientationSensor
接口调用构造方向传感器对象抽象
操作。
RelativeOrientationSensor
的支持的传感器选项
是
"frequency" 和 "referenceFrame"。
7. 抽象操作
7.1. 构造 Orientation Sensor 对象
- 输入
-
orientation_interface,一个接口标识符,其继承接口包含
OrientationSensor。options,一个
OrientationSensorOptions对象。 - 输出
-
一个
OrientationSensor对象。
-
令 allowed 为以 orientation_interface 标识的接口调用检查传感器受策略控制 特性 的结果。
-
如果 allowed 为 false,则:
-
令 orientation 为由 orientation_interface 标识的接口的一个新实例。
-
以 orientation 和 options 调用 初始化传感器对象。
-
如果 options.
referenceFrame为 "screen",则: -
返回 orientation。
7.2. 将四元数转换为旋转矩阵
将四元数转换为旋转矩阵 算法创建一个按列主序表示的旋转矩阵列表,该矩阵从四元数 [QUATCONV] 转换而来,如下所示:

其中:
-
W = cos(θ/2)
-
X = Vx * sin(θ/2)
-
Y = Vy * sin(θ/2)
-
Z = Vz * sin(θ/2)
-
令 m11 为 1 - 2 * y * y - 2 * z * z
-
令 m12 为 2 * x * y - 2 * z * w
-
令 m13 为 2 * x * z + 2 * y * w
-
令 m14 为 0
-
令 m21 为 2 * x * y + 2 * z * w
-
令 m22 为 1 - 2 * x * x - 2 * z * z
-
令 m23 为 2 * y * z - 2 * x * w
-
令 m24 为 0
-
令 m31 为 2 * x * z - 2 * y * w
-
令 m32 为 2 * y * z + 2 * x * w
-
令 m33 为 1 - 2 * x * x - 2 * y * y
-
令 m34 为 0
-
令 m41 为 0
-
令 m42 为 0
-
令 m43 为 0
-
令 m44 为 1
-
返回 « m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 »。
7.3. 从欧拉角创建四元数
给定一个数 alpha、一个数 beta 和一个数 gamma,要从欧拉角创建四元数:
-
令 alphaInRadians 为从度转换为弧度后的 alpha。
-
令 betaInRadians 为从度转换为弧度后的 beta。
-
令 gammaInRadians 为从度转换为弧度后的 gamma。
-
令 cosZ 为 (0.5 * alphaInRadians) 的余弦。
-
令 sinZ 为 (0.5 * alphaInRadians) 的正弦。
-
令 cosX 为 (0.5 * betaInRadians) 的余弦。
-
令 sinX 为 (0.5 * betaInRadians) 的正弦。
-
令 cosY 为 (0.5 * gammaInRadians) 的余弦。
-
令 sinY 为 (0.5 * gammaInRadians) 的正弦。
-
令 quaternionX 为 (sinX * cosY * cosZ - cosX * sinY * sinZ)。
-
令 quaternionY 为 (cosX * sinY * cosZ + sinX * cosY * sinZ)。
-
令 quaternionZ 为 (cosX * cosY * sinZ + sinX * sinY * cosZ)。
-
令 quaternionW 为 (cosX * cosY * cosZ - sinX * sinY * sinZ)。
-
返回 « quaternionX, quaternionY, quaternionZ, quaternionW »。
8. 自动化
本节通过提供 Orientation Sensor 特有的虚拟传感器元数据,扩展 Generic Sensor API § 9 Automation。
8.1. 对其他规范的修改
本规范按如下方式与 Device Orientation and Motion § automation 集成。
注:本规范目前没有提供一种 在 WebDriver 中直接指定四元数(并因此从四元数推导欧拉角)的方法。 作出此决定是出于简化考虑,并基于如下假设:自动化用户更可能 使用欧拉角作为输入(或选择特定四元数值,并自行提供对应的 欧拉角值)。欢迎有不同用例且有兴趣能够直接提供四元数值的用户,通过本规范的问题跟踪器提供反馈。
8.2. 绝对方向传感器自动化
absolute-orientation 虚拟传感器类型及其在每类型虚拟传感器元数据映射中的对应条目, 定义于 Device Orientation and Motion § automation。
8.3. 相对方向传感器自动化
relative-orientation 虚拟传感器类型及其在每类型虚拟传感器元数据映射中的对应条目, 定义于 Device Orientation and Motion § automation。
9. 致谢
感谢 Tobie Langel 在 Generic Sensor API 上所做的工作。