磁力计

W3C 工作草案,

关于本文档的更多信息
本版本:
https://www.w3.org/TR/2025/WD-magnetometer-20250212/
最新发布版本:
https://www.w3.org/TR/magnetometer/
编辑草案:
https://w3c.github.io/magnetometer/
以往版本:
历史记录:
https://www.w3.org/standards/history/magnetometer/
反馈:
public-device-apis@w3.org 邮件主题为“[magnetometer] … 消息主题 …” (存档)
磁力计问题仓库
编辑:
Anssi Kostiainen (英特尔公司)
Rijubrata Bhaumik (英特尔公司)
测试套件:
GitHub上的web-platform-tests

摘要

本规范定义了一个用于测量 X、Y 和 Z 轴磁场的具体传感器接口。

本文档状态

本部分描述了本文档发布时的状态。W3C 当前出版物及本技术报告的最新修订可在 W3C 技术报告索引 https://www.w3.org/TR/ 查阅。

本文档由设备与传感器工作组基于推荐标准流程以工作草案形式发布。本文档计划成为 W3C 推荐标准。

如需对本文档发表评论,请发送至 public-device-apis@w3.org订阅存档)。 发送邮件时,请注明“magnetometer”于主题行,建议格式为: “[magnetometer] …评论摘要…”。 欢迎提出任何意见和建议。

作为工作草案的发布并不表示 W3C 及其成员的认可。本文为草稿,可能随时更新、替换或废止。除“进行中工作”外,不应引用本文档。

本文档由W3C 专利政策下运作的小组制定。 W3C 维护公开专利披露列表,记录与本小组交付物相关的专利披露; 该页面也包括专利披露相关说明。如有知晓包含必要权利要求的专利,须依据 W3C 专利政策第 6 节 进行披露。

本文档受 2023年11月3日 W3C流程文档 管理。

本规范正在征集开发者反馈和高价值用例。请通过 GitHub 提供反馈。

本文档可随时维护与更新,部分内容处于持续完善中。

1. 简介

磁力计扩展了 Generic Sensor API [GENERIC-SENSOR],用于提供设备主磁力计传感器检测到的磁场信息。 磁力计传感器测量所有三个物理轴(x, y, z)上的磁场,单位为 μT(微特斯拉)。

本规范定义了两个新接口:

磁场是由于电流、磁性材料或地球磁力引起的磁力对磁力计传感器施加的一种场,这种力源于行星自转和地核熔化铁的运动的综合作用。

硬铁畸变由产生磁场的物体(如带磁性的铁)造成。

软铁畸变会拉伸或扭曲磁场,由镍、铁等金属引起。

已校准磁场 是指对磁场应用硬铁畸变软铁畸变校正后的结果。

未校准磁场 是指磁场未进行硬铁畸变校正、但已应用软铁畸变校正的结果。 因此该读数会反映靠近磁力计的带磁物体运动导致的磁场变化。

2. 示例

let sensor = new Magnetometer();
sensor.start();

sensor.onreading = () => {
    console.log("Magnetic field along the X-axis " + sensor.x);
    console.log("Magnetic field along the Y-axis " + sensor.y);
    console.log("Magnetic field along the Z-axis " + sensor.z);
};

sensor.onerror = event => console.log(event.error.name, event.error.message);

3. 安全与隐私注意事项

磁力计提供了磁场信息,从理论上讲,可以暴露用户的位置。例如,攻击方式可能是预先磁化某一特定地点的表面,或将某地的持续磁场扰动与建筑物进行映射。由于地球磁场强度不均匀,另一种攻击向量可能是暴露或验证用户的位置。例如,当终端用户通过 VPN 连接时,可将绑定的地理 IP 对应的磁场信息与真实地点的磁力计数据进行对比,从而判断用户是否使用了 VPN。实现者应注意磁场强度与其他因素(如 CPU 执行)相关性带来的旁道泄漏潜在风险,在某些情况下甚至可能泄露关于当前应用或其它标签页已访问网站的信息。[MAGSPY]

未校准磁力计读数可能受周边磁化物体(如饰品)影响,从而泄露可用于按键监控的信息。

为减轻这些特定威胁,用户代理应采用以下一种或两种缓解策略:

这些缓解措施补充了 Generic Sensor API [GENERIC-SENSOR]通用缓解策略的定义。

4. 权限策略集成

本规范采用了策略控制特性,其关键字为 "magnetometer" ,由 [DEVICE-ORIENTATION] 定义。

5. 模型

磁力计传感器类型关联如下数据:

扩展传感器接口

Magnetometer

传感器权限名称

"magnetometer"

传感器特性名称

"magnetometer"

权限撤销算法

用 "magnetometer" 调用 通用传感器权限撤销算法

虚拟传感器类型

"magnetometer"

最新读数,当Sensor传感器类型Magnetometer时,必须包括:

未校准磁力计传感器类型关联如下数据:

扩展传感器接口

UncalibratedMagnetometer

传感器权限名称

"magnetometer"

传感器特性名称

"magnetometer"

权限撤销算法

用 "magnetometer" 调用 通用传感器权限撤销算法

虚拟传感器类型

"uncalibrated-magnetometer"

最新读数,当Sensor传感器类型Uncalibrated Magnetometer时,必须包括:

磁场值的正负号,必须符合本地坐标系的右手系规则(见下图)。

Magnetometer coordinate system.

5.1. 参考系

本地坐标系表示MagnetometerUncalibratedMagnetometer 读数的参考系, 可以为设备坐标系屏幕坐标系

6. API

6.1. 磁力计接口

[SecureContext,
  Exposed=Window]
interface Magnetometer : Sensor {
  constructor(optional MagnetometerSensorOptions sensorOptions = {});
  readonly attribute double? x;
  readonly attribute double? y;
  readonly attribute double? z;
};

enum MagnetometerLocalCoordinateSystem { "device", "screen" };

dictionary MagnetometerSensorOptions : SensorOptions {
  MagnetometerLocalCoordinateSystem referenceFrame = "device";
};
new Magnetometer(sensorOptions) 构造步骤是以构造磁力计对象抽象操作,并用thissensorOptions做参数调用。

Magnetometer Magnetometer 支持的选项为“frequency”和“referenceFrame”。

6.1.1. Magnetometer.x

x 属性(Magnetometer 接口)表示 X 轴方向的磁场。 换言之,该属性返回以 this 和 "x" 为参数调用 get value from latest reading 的结果。

6.1.2. Magnetometer.y

y 属性(Magnetometer 接口)表示 Y 轴方向的磁场。 换言之,该属性返回以 this 和 "y" 为参数调用 get value from latest reading 的结果。

6.1.3. Magnetometer.z

z 属性(Magnetometer 接口)表示 Z 轴方向的磁场。 换言之,该属性返回以 this 和 "z" 为参数调用 get value from latest reading 的结果。

6.2. 非校准磁力计接口

[SecureContext,
  Exposed=Window]
interface UncalibratedMagnetometer : Sensor {
  constructor(optional MagnetometerSensorOptions sensorOptions = {});
  readonly attribute double? x;
  readonly attribute double? y;
  readonly attribute double? z;
  readonly attribute double? xBias;
  readonly attribute double? yBias;
  readonly attribute double? zBias;
};
new UncalibratedMagnetometer(sensorOptions) 构造步骤是以构造磁力计对象抽象操作,参数为 thissensorOptions

UncalibratedMagnetometer UncalibratedMagnetometer 支持的选项为“frequency”和“referenceFrame”。

6.2.1. UncalibratedMagnetometer.x

x 属性(UncalibratedMagnetometer 接口)表示 X 轴方向的未校准磁场。 换言之,该属性返回以 this 和 "x" 为参数调用 get value from latest reading 的结果。

6.2.2. UncalibratedMagnetometer.y

y 属性(UncalibratedMagnetometer 接口)表示 Y 轴方向的未校准磁场。 换言之,该属性返回以 this 和 "y" 为参数调用 get value from latest reading 的结果。

6.2.3. UncalibratedMagnetometer.z

z 属性(UncalibratedMagnetometer 接口)表示 Z 轴方向的未校准磁场。 换言之,该属性返回以 this 和 "z" 为参数调用 get value from latest reading 的结果。

6.2.4. UncalibratedMagnetometer.xBias

xBias 属性(UncalibratedMagnetometer 接口)表示 X 轴方向的硬铁畸变校正量。 换言之,该属性返回以 this 和 "xBias" 为参数调用 get value from latest reading 的结果。

6.2.5. UncalibratedMagnetometer.yBias

yBias 属性(UncalibratedMagnetometer 接口)表示 Y 轴方向的硬铁畸变校正量。 换言之,该属性返回以 this 和 "yBias" 为参数调用 get value from latest reading 的结果。

6.2.6. UncalibratedMagnetometer.zBias

zBias 属性(UncalibratedMagnetometer 接口)表示 Z 轴方向的硬铁畸变校正量。 换言之,该属性返回以 this 和 "zBias" 为参数调用 get value from latest reading 的结果。

7. 抽象操作

7.1. 构造磁力计对象

输入

object,一个 MagnetometerUncalibratedMagnetometer 对象

options,一个 MagnetometerSensorOptions 对象。

  1. allowed 为以 object传感器类型 调用 检查传感器策略控制特性 的结果。

  2. 如果 allowed 为 false,则:

    1. 抛出 SecurityError DOMException

  3. objectoptions 调用 初始化传感器对象

  4. 如果 options.referenceFrame 为 "screen",则:

    1. object本地坐标系 设为 屏幕坐标系

  5. 否则,将 object本地坐标系 定义为 设备坐标系

8. 自动化

本节通过提供磁力计专用虚拟传感器元数据扩展了Generic Sensor API § 9 自动化

8.1. 磁力计自动化

每类型虚拟传感器元数据 映射 必须包含如下条目

"magnetometer"

一个虚拟传感器元数据,其读数解析算法解析 XYZ 读数

8.2. 非校准磁力计自动化

每类型虚拟传感器元数据 映射 必须包含如下条目

"uncalibrated-magnetometer"

一个虚拟传感器元数据,其读数解析算法非校准磁力计读数解析算法

8.2.1. 非校准磁力计读数解析算法

输入

parameters,一个 JSON 对象

输出

一个传感器读数undefined

  1. reading 为以 parameters 调用 解析 XYZ 读数 的结果。

  2. 如果 readingundefined

    1. 返回 undefined

  3. keys列表 « "xBias", "yBias", "zBias" »。

  4. 对于 keys 中的每一个 key

    1. value 为以 parameterskey 调用 解析单值数字读数 的结果。

      1. 如果 valueundefined

        1. 返回 undefined

    2. 设置 reading[key] 为 value[key]。

  5. 返回 reading

9. 磁力计传感器的局限性

本节为非规范性内容

地球磁场的方向和强度会因所在位置而变化,尤其是纬度。例如,磁场强度在赤道附近最低,极地附近最高。 一些硬铁干扰(即传感器附近存在永久磁体,如手机扬声器中的磁铁)也会影响读数的准确性。 电子设备、笔记本电脑、电池等的存在,也会带来软铁干扰。 手机上开启飞行模式可能有助于降低电磁干扰。

除了上述空间变化的磁场外,磁场还存在时间变化因素, 如太阳风或磁暴,也会扭曲地球的磁层或外部磁场。

10. 用例与需求

本节为非规范性内容

磁力计可用于多种场景,例如:

不同应用对数据粗糙度和采样频率的需求各异。例如,金属探测或磁按钮输入可用较粗的数据和较低的采样频率实现,而手势识别、室内导航、虚拟/增强现实等应用通常需要更高采样率。传感器融合场景中,最优采样频率还取决于算法类型及其它运动传感器的特性。

11. 利用磁力计测定罗盘方位

本节为非规范性内容

罗盘(可与地球磁极自动对齐的仪器)在导航中已有数百年历史。 地球自转轴定义了我们地图使用的地理南北极。但地理极点与磁极存在约 11.5°(约1000英里)的偏差。 需要对磁方向加上磁偏角做校正。

若设备始终与地球表面保持水平,则根据地球磁场 xy 分量(即沿地面方向)即可计算罗盘方位。 若要获得地理真北方位,需加上合适的磁偏角

地磁偏角磁偏角是在水平面上磁北到真北之间的夹角,取决于地表位置并随时间变化。 约定上,磁北东于真北为正,西于真北为负。可通过美国国家海洋和大气管理局(NOAA)磁偏角在线计算器实时获得地磁偏角

磁北的计算如下:

let sensor = new Magnetometer();
sensor.start();
let heading = Math.atan2(sensor.y, sensor.x) * (180 / Math.PI);
console.log('Heading in degrees: ' + heading);

某一点的地理真北可按下列方式计算:

// 获取纬度和经度,代码略。
let latitude = 0, longitude = 0;

// 获取对应位置的地磁偏角。
fetch('https://www.ngdc.noaa.gov/geomag-web/calculators/calculateDeclination' +
      '?lat1=' + latitude + '&lon1=' + longitude + '&resultFormat=csv')
  .then(response => response.text()).then(text => {
    let declination = parseFloat(text.replace(/^#.*$/gm, '').trim().split(',')[4]);

    // 用地磁偏角补偿以获得地理真北。
    console.log('True heading in degrees: ' + (heading + declination));
});

注: 如果设备未与地球表面水平,开发者需引入多种倾斜补偿技术,此时需要三轴加速度计。方向传感器(加速度计与磁力计融合所得)数据亦是实现此场景的前提。

12. 致谢

Tobie Langel 对 Generic Sensor API 的贡献。

13. 一致性

一致性要求用描述性断言和 RFC 2119 术语共同表达。规范性部分的 "MUST"、"MUST NOT"、"REQUIRED"、 "SHALL"、"SHALL NOT"、"SHOULD"、"SHOULD NOT"、"RECOMMENDED"、"MAY" 和 "OPTIONAL" 等关键词, 其释义参见 RFC 2119。但为便于阅读,本规范中不会全部采用全大写。

除非被明确标记为非规范性内容、示例或说明,否则本规范所有文本均为规范性内容。[RFC2119]

符合规范的用户代理必须实现本规范中适用于用户代理的全部要求。

本规范中的 IDL 片段须按 Web IDL 规范的相关要求进行解释。[WEBIDL]

索引

本规范定义的术语

外部引用定义的术语

参考文献

规范性引用

[ACCELEROMETER]
Anssi Kostiainen. 加速度计. 2024年10月9日. CRD. URL: https://www.w3.org/TR/accelerometer/
[DEVICE-ORIENTATION]
Reilly Grant; Marcos Caceres. 设备方向与运动. 2025年2月12日. CRD. URL: https://www.w3.org/TR/orientation-event/
[ECMASCRIPT]
ECMAScript 语言规范. URL: https://tc39.es/ecma262/multipage/
[GENERIC-SENSOR]
Rick Waldron. 通用传感器 API. 2024年2月22日. CRD. URL: https://www.w3.org/TR/generic-sensor/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准. Living Standard. URL: https://infra.spec.whatwg.org/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. 2024年12月20日. WD. URL: https://www.w3.org/TR/permissions/
[PERMISSIONS-POLICY-1]
Ian Clelland. 权限策略. 2025年2月10日. WD. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
S. Bradner. 在 RFC 中用于表示需求等级的关键词. 1997年3月. 最佳当前实践. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 标准. Living Standard. URL: https://webidl.spec.whatwg.org/

资料性引用

[MAGINDOORPOS]
Janne Haverinen, Anssi Kemppainen. 室内磁场自定位. 信息性. URL: https://doi.org/10.1016%2Fj.robot.2009.07.018
[MAGITACT]
Hamed Ketabdar, Kamer Ali Yüksel, Mehran Roshandel. Magitact. 信息性. URL: https://dl.acm.org/doi/10.1145/1719970.1720048
[MAGSPY]
Nikolay Matyunin, Yujue Wang, Tolga Arul, Kristian Kullmann, Jakub Szefer, Stefan Katzenbeisser. MagneticSpy:利用移动设备磁力计进行网站和应用指纹识别. 信息性. URL: https://dl.acm.org/doi/abs/10.1145/3338498.3358650
[MOTION-SENSORS]
Kenneth Christiansen; Alexander Shalamov. 运动传感器说明. 2017年8月30日. NOTE. URL: https://www.w3.org/TR/motion-sensors/
[VRBUTTON]
Boris Smus. Google Cardboard 的磁性输入. 信息性. URL: https://bugs.chromium.org/p/chromium/issues/detail?id=445926

IDL 索引

[SecureContext,
  Exposed=Window]
interface Magnetometer : Sensor {
  constructor(optional MagnetometerSensorOptions sensorOptions = {});
  readonly attribute double? x;
  readonly attribute double? y;
  readonly attribute double? z;
};

enum MagnetometerLocalCoordinateSystem { "device", "screen" };

dictionary MagnetometerSensorOptions : SensorOptions {
  MagnetometerLocalCoordinateSystem referenceFrame = "device";
};

[SecureContext,
  Exposed=Window]
interface UncalibratedMagnetometer : Sensor {
  constructor(optional MagnetometerSensorOptions sensorOptions = {});
  readonly attribute double? x;
  readonly attribute double? y;
  readonly attribute double? z;
  readonly attribute double? xBias;
  readonly attribute double? yBias;
  readonly attribute double? zBias;
};