Magnetometer Sensor

W3C First Public Working Draft,

This version:
https://www.w3.org/TR/2016/WD-magnetometer-20160913/
Latest published version:
https://www.w3.org/TR/magnetometer/
Editor's Draft:
https://w3c.github.io/magnetometer/
Version History:
https://github.com/w3c/magnetometer/commits/gh-pages/index.bs
Feedback:
public-device-apis@w3.org with subject line “[magnetometer] … message topic …” (archives)
Issue Tracking:
GitHub
Editors:
Anssi Kostiainen (Intel Corporation)
Rijubrata Bhaumik (Intel Corporation)
Bug Reports:
via the w3c/magnetometer repository on GitHub
Test Suite:
web-platform-tests on GitHub

Abstract

This specification defines a concrete sensor interface to measure magnetic field in the X, Y and Z axis.

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 Device 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 “magnetometer” in the subject, preferably like this: “[magnetometer] …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 5 February 2004 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 September 2015 W3C Process Document.

1. Introduction

The Magnetometer Sensor extends the Generic Sensor API [GENERIC-SENSOR] to provide information about the geomagnetic field as detected by the device’s primary magnetometer sensor. The magnetometer sensor measures the ambient geomagnetic field for all three physical axes (x, y, z) in μT (micro Tesla).

Geomagnetic field is defined as the magnetic force field that surrounds the Earth. It is attributed to the combined effects of the planetary rotation and the movement of molten iron in the Earth’s core.

A magnetoresistive component (permalloy) is one which changes resistance in proportion to the strength of a magnetic field along its axis. The 3 axis magnetometer usually found in mobile phones, have 3 such components oriented such that each one is orthogonal to the other two, one each in the X, Y and Z directions in the device’s local coordinate system. Each individual magnetoresistive element senses only the component of the magnetic field parallel to the element axis and ignores field components orthogonal to the element axis.

2. Examples

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

sensor.onchange = function(event) {
    console.log("Magnetic field along the X-axis " + event.reading.magneticFieldX);
    console.log("Magnetic field along the Y-axis " + event.reading.magneticFieldY);
    console.log("Magnetic field along the Z-axis " + event.reading.magneticFieldZ);
};

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

3. Security and Privacy Considerations

There are no specific security and privacy considerations beyond those described in the Generic Sensor API [GENERIC-SENSOR].

4. Model

The Magnetometer Sensor’s associated Sensor subclass is the MagnetometerSensor class.

The Magnetometer Sensor’s associated SensorReading subclass is the MagnetometerSensorReading class.

The Magnetometer Sensor has a default sensor, which is the device’s main magnetometer sensor.

The Magnetometer Sensor has a single supported reporting mode which is "auto".

The Magnetometer Sensor’s permission name is "magnetometer". It has no associated PermissionDescriptor.

The Magnetometer Sensor has an associated abstract operation to retrieve the sensor permission which must simply return a permission whose name is "magnetometer".

The Magnetometer Sensor has an associated abstract operation to construct a SensorReading object which creates a new MagnetometerSensorReading object and sets each of its magneticFieldX, magneticFieldY and magneticFieldZ attributes to zero.

The MagnetometerSensorReading's attribute values must be in μT (micro Tesla), expressed in a three-dimentional Cartesian local coordinate system defined by the device.

The sign of the geomagnetic field values must be according to the right-hand convention in a local coordinate system defined by the device.

Note: The local coordinate system of a mobile device is usually defined relative to the device’s screen when the device in its default orientation (see figure below).

Magnetometer coordinate system.

5. API

5.1. The MagnetometerSensor Interface

[Constructor(optional SensorOptions sensorOptions)]
interface MagnetometerSensor : Sensor {
  readonly attribute MagnetometerSensorReading? reading;
};

To Construct an MagnetometerSensor Object the user agent must invoke the construct a Sensor object abstract operation.

5.2. The MagnetometerSensorReading Interface

[Constructor(MagnetometerSensorReadingInit magnetometerSensorReadingInit)]
interface MagnetometerSensorReading : SensorReading {
    readonly attribute double magneticFieldX;
    readonly attribute double magneticFieldY;
    readonly attribute double magneticFieldZ;
};

dictionary MagnetometerSensorReadingInit {
  double magneticFieldX = 0;
  double magneticFieldY = 0;
  double magneticFieldZ = 0;
};

5.2.1. The MagnetometerSensorReading constructor

The MagnetometerSensorReading constructor accepts MagnetometerSensorReadingInit dictionary that is used for initialization of MagnetometerSensorReading attributes.

5.2.2. The MagnetometerSensorReading attributes

The magneticFieldX attribute of the MagnetometerSensorReading interface represents represents the geomagnetic field around X-axis.

The magneticFieldY attribute of the MagnetometerSensorReading interface represents represents the geomagnetic field around Y-axis.

The magneticFieldZ attribute of the MagnetometerSensorReading interface represents represents the geomagnetic field around Z-axis.

6. Limitations of Magnetometer Sensors

This section is non-normative.

The direction and magnitude of the Earth’s field changes with location, latitude in particular. For example, the magnitude is lowest near the equator and highest near the poles. Some hard-iron interference, meaning presence of permanent magnets (e.g. magnets in the speaker of a phone) in the vicinity of the sensor also affects the accuracy of the reading. Presence of electronic items, laptops, batteries, etc also contribute to the soft-iron interference. Flight Mode option in mobile phones might help in decreasing the electro magnetic interference.

In addition to the above spatial variations of the geomagnetic field, time based variations, like solar winds or magnetic storms, also distort the magnetosphere or external magnetic field of the earth.

7. Compass Heading Using Magnetometers

Compasses, instruments that align themselves with the magnetic poles of the Earth, have been used in navigation for centuries. The earth’s rotational axis defines the geographic north and south poles that we use for map references. It turns out that there is a discrepancy of around 11.5 degrees (around 1000 miles) between the geographic poles and the magnetic poles. Declination angle is applied to the magnetic direction to correct for this situation.

If the device is always level to the earth’s surface, compass heading can be determined by using just the magneticFieldX and magneticFieldY component of the earth’s magnetic field, that is, the directions planar with the earth’s surface. To determine geographic north (or true north) heading, add the appropriate declination angle.

Magnetic declination or declination angle is the angle on the horizontal plane between magnetic north and the true north and depends on the position on the Earth’s surface, and changes over time. By convention, declination is positive when magnetic north is east of true north, and negative when it is to the west. You can get real time value for magnetic declination e.g. using the Magnetic declination calculator provided by the National Oceanic and Atmospheric Administration (NOAA).

Magnetic north calculation is simple:

var headingDegrees = Math.atan2(event.reading.magneticFieldY,
                                event.reading.magneticFieldX) * (180 / Math.PI);

console.log('Heading in degrees: ' + headingDegrees);

To get geographic north (or true north) that considers the magnetic declination at the given latitude and longitude, further work is required:

// First, get the latitude and longitude (omitted for brevity).
var latitude = 0, longitude = 0;

// Then, get the magnetic declination using your favorite web service.
var base = 'http://www.ngdc.noaa.gov/geomag-web/calculators/calculateDeclination';
fetch(base + '?lat1=' + latitude + '&lon1=' + longitude + '&resultFormat=csv')
  .then(response => response.text()).then(text => { 
    var declinationDegrees =
        parseFloat(text.replace(/^#.*$/gm, '').trim().split(',')[4]);
    // Compensate for the magnetic declination to get the true north.
    console.log('True heading in degrees: ' + (headingDegrees + declinationDegrees));
});

If the device is not level to the Earth’s surface, we need to apply various tilt compensation techniques for which we need a 3-axis accelerometer. A specification for orientation sensor, which is a fusion of the accelerometer and magnetometer sensors, is required to implement this particular use case.

8. Acknowledgements

Tobie Langel for the work on Generic Sensor API.

9. 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

Terms defined by reference

References

Normative References

[GENERIC-SENSOR]
Tobie Langel; Rick Waldron. Generic Sensor API. 24 March 2016. WD. URL: https://www.w3.org/TR/generic-sensor/
[PERMISSIONS]
Mounir Lamouri; Marcos Caceres. The Permissions API. 7 April 2015. WD. URL: https://www.w3.org/TR/permissions/
[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]
Cameron McCormack; Boris Zbarsky. WebIDL Level 1. 8 March 2016. CR. URL: https://www.w3.org/TR/WebIDL-1/

IDL Index

[Constructor(optional SensorOptions sensorOptions)]
interface MagnetometerSensor : Sensor {
  readonly attribute MagnetometerSensorReading? reading;
};

[Constructor(MagnetometerSensorReadingInit magnetometerSensorReadingInit)]
interface MagnetometerSensorReading : SensorReading {
    readonly attribute double magneticFieldX;
    readonly attribute double magneticFieldY;
    readonly attribute double magneticFieldZ;
};

dictionary MagnetometerSensorReadingInit {
  double magneticFieldX = 0;
  double magneticFieldY = 0;
  double magneticFieldZ = 0;
};