Mit der Generic Sensor API können Sie auf On-Device-Sensoren wie Beschleunigungsmesser, Gyroskope und Magnetometer zugreifen.
Heutzutage werden Sensordaten in vielen plattformspezifischen Anwendungen eingesetzt, um Anwendungsfälle wie immersives Gaming, Fitness-Tracking und Augmented bzw. Virtual Reality. Wäre es nicht toll, die Lücke zwischen plattformspezifischen und Webanwendungen zu schließen? Geben Sie den Generic Sensor API für das Web.
Was ist die Generic Sensor API?
Die Generic Sensor API ist eine Reihe von Schnittstellen, die Sensorgeräte der Webplattform zur Verfügung stellen. Die API besteht aus der Basis
Sensor
-Schnittstelle und einer Reihe konkreter
auf Basis von Sensorklassen. Eine Basisschnittstelle vereinfacht die Implementierung und Spezifikation der einzelnen Sensorklassen. Sehen wir uns beispielsweise die Klasse Gyroscope
an. Es ist superklein! Die Hauptfunktionen werden durch die Basisoberfläche angegeben und Gyroscope
erweitert sie lediglich um drei Attribute, die die Winkelgeschwindigkeit darstellen.
Einige Sensorklassen arbeiten mit Hardwaresensoren wie dem Beschleunigungsmesser oder
Gyroskopkursen. Diese Sensoren werden auch als Low-Level-Sensoren bezeichnet. Andere Sensoren, sogenannte Fusionssensoren, kombinieren Daten aus mehreren Low-Level-Sensoren, um Informationen bereitzustellen, die sonst von einem Script berechnet werden müssten. Der AbsoluteOrientation
-Sensor bietet beispielsweise eine gebrauchsfertige 4 × 4-Rotationsmatrix, die auf den Daten des Beschleunigungsmessers, des Gyroskops und des Magnetometers basiert.
Sie denken vielleicht, dass die Webplattform bereits Sensordaten bereitstellt. Das ist richtig. Für
Instanz DeviceMotion
und
DeviceOrientation
Bewegungssensordaten verfügbar. Warum brauchen wir also eine neue API?
Im Vergleich zu den vorhandenen Schnittstellen bietet die Generic Sensor API zahlreiche Vorteile:
- Die Generic Sensor API ist ein Sensor-Framework, das einfach mit neuen Sensorklassen und behalten alle diese Klassen die generische Schnittstelle bei. Der für einen Sensortyp geschriebene Clientcode kann mit nur wenigen Änderungen für einen anderen Sensortyp wiederverwendet werden.
- Sie können den Sensor konfigurieren. Sie können beispielsweise die Abtastrate so festlegen, dass sie den Anforderungen Ihrer Anwendung entspricht.
- Sie können prüfen, ob ein Sensor auf der Plattform verfügbar ist.
- Sensormesswerte haben hochpräzise Zeitstempel, was eine bessere Synchronisierung mit anderen Aktivitäten in Ihrer Anwendung ermöglicht.
- Sensordatenmodelle und Koordinatensysteme sind klar definiert, sodass Browseranbieter interoperable Lösungen implementieren.
- Die generischen sensorbasierten Schnittstellen sind nicht an das DOM gebunden, d. h., sie sind weder
navigator
- nochwindow
-Objekte. Dies eröffnet in Zukunft Möglichkeiten, die API in Service Workers zu verwenden oder in headless JavaScript-Laufzeiten wie eingebetteten Geräten zu implementieren. - Sicherheit und Datenschutz haben für den generischen Sensor höchste Priorität. API und bieten im Vergleich zu älteren Sensor-APIs viel mehr Sicherheit. Es gibt die Integration mit der Permissions API.
- Die automatische Synchronisierung mit Bildschirmkoordinaten ist für
Accelerometer
,Gyroscope
,LinearAccelerationSensor
,AbsoluteOrientationSensor
,RelativeOrientationSensor
undMagnetometer
verfügbar.
Verfügbare generische Sensor-APIs
Zum Zeitpunkt der Erstellung dieses Dokuments gibt es mehrere Sensoren, mit denen Sie experimentieren können.
Bewegungssensoren:
Accelerometer
Gyroscope
LinearAccelerationSensor
AbsoluteOrientationSensor
RelativeOrientationSensor
GravitySensor
Umgebungssensoren:
AmbientLightSensor
(Hinter der#enable-generic-sensor-extra-classes
-Markierung in Chromium)Magnetometer
(Hinter der#enable-generic-sensor-extra-classes
-Markierung in Chromium)
Funktionserkennung
Die Funktionserkennung von Hardware-APIs ist schwierig, da sowohl erkannt werden muss, ob der Browser
die betreffende Schnittstelle unterstützt und ob das Gerät über den entsprechenden Sensor verfügt. Wird geprüft
ob der Browser eine Oberfläche unterstützt. Ersetzen Sie Accelerometer
durch eine der oben genannten Schnittstellen.
if ('Accelerometer' in window) {
// The `Accelerometer` interface is supported by the browser.
// Does the device have an accelerometer, though?
}
Für ein aussagekräftiges Ergebnis der Feature-Erkennung müssen Sie auch versuchen, eine Verbindung zum Sensor herzustellen. In diesem Beispiel wird gezeigt, wie das geht.
let accelerometer = null;
try {
accelerometer = new Accelerometer({ frequency: 10 });
accelerometer.onerror = (event) => {
// Handle runtime errors.
if (event.error.name === 'NotAllowedError') {
console.log('Permission to access sensor was denied.');
} else if (event.error.name === 'NotReadableError') {
console.log('Cannot connect to the sensor.');
}
};
accelerometer.onreading = (e) => {
console.log(e);
};
accelerometer.start();
} catch (error) {
// Handle construction errors.
if (error.name === 'SecurityError') {
console.log('Sensor construction was blocked by the Permissions Policy.');
} else if (error.name === 'ReferenceError') {
console.log('Sensor is not supported by the User Agent.');
} else {
throw error;
}
}
Polyfill
Für Browser, die die Generic Sensor API nicht unterstützen, wird ein Polyfill ist verfügbar. Mit der Polyfill-Funktion können Sie nur die Implementierungen der relevanten Sensoren laden.
// Import the objects you need.
import { Gyroscope, AbsoluteOrientationSensor } from './src/motion-sensors.js';
// And they're ready for use!
const gyroscope = new Gyroscope({ frequency: 15 });
const orientation = new AbsoluteOrientationSensor({ frequency: 60 });
Was sind das für Sensoren? Wie kann ich sie verwenden?
Sensoren ist ein Bereich, der möglicherweise einer kurzen Einführung bedarf. Wenn Sie mit Sensoren vertraut sind, können Sie direkt zum Abschnitt mit praktischen Programmieraufgaben springen. Sehen wir uns ansonsten die einzelnen des Sensors genauer an.
Beschleunigungsmesser und linearer Beschleunigungssensor
Accelerometer
-Sensor
misst die Beschleunigung eines Geräts, auf dem sich der Sensor auf drei Achsen (X, Y und Z) befindet. Dieser Sensor ist ein inertialer Sensor. Wenn sich das Gerät also im linearen freien Fall befindet, beträgt die gemessene Gesamtbeschleunigung 0 m/s2. Wenn das Gerät flach auf einem Tisch liegt, entspricht die Beschleunigung in Aufwärtsrichtung (Z-Achse) der Schwerkraft der Erde, also g ≈ +9,8 m/s2, da die Kraft des Tisches gemessen wird, die das Gerät nach oben drückt. Wenn Sie das Gerät nach rechts schieben, ist die Beschleunigung auf der X-Achse positiv. Ist die Beschleunigung von rechts nach links, ist sie negativ.
Beschleunigungsmesser können beispielsweise für die Schrittzählung, die Bewegungserkennung oder die einfache Geräteausrichtung verwendet werden. Häufig werden Beschleunigungsmessermessungen mit Daten aus anderen Quellen kombiniert, um Fusionssensoren wie Orientierungssensoren zu erstellen.
Der LinearAccelerationSensor
misst die Beschleunigung, die auf das Gerät mit dem Sensor ausgeübt wird, ohne den Beitrag der Schwerkraft. Wenn ein Gerät ruht, zum Beispiel flach auf dem Tisch liegt, misst der Sensor
≤ 0 m/s2-Beschleunigung auf drei Achsen.
Schwerkraftsensor
Nutzer können bereits manuell Messwerte ableiten, die denen eines Gravitationssensors nahekommen, indem sie die Accelerometer
- und LinearAccelerometer
-Messwerte manuell prüfen. Das kann jedoch mühsam sein und von der Genauigkeit der von diesen Sensoren bereitgestellten Werte abhängen. Plattformen wie Android können
Gravitationswerte als Teil des Betriebssystems bereitstellen, was in Bezug auf
Berechnung, liefern je nach Hardware des Nutzers genauere Werte und sind einfacher in
im Hinblick auf die API-Ergonomie. GravitySensor
gibt die Beschleunigung entlang der X-, Y- und Z-Achse des Geräts aufgrund der Schwerkraft zurück.
Gyroskop
Der Gyroscope
-Sensor misst
Winkelgeschwindigkeit in Radianten pro Sekunde um die lokale X-, Y- und Z-Achse des Geräts herum. Die meisten Nutzer
Geräte haben ein mechanisches Speicherverfahren (MEMS).
Gyroskope, Trägheitssensoren, die die Rotationsrate auf Grundlage von
inertiale Corioliskraft. MEMS-Gyroskope sind anfällig für
die durch die Gravitationsempfindlichkeit des Sensors verursacht wird, die die
internes mechanisches System. Gyroskope schwingen mit relativ hohen Frequenzen, z. B. 10 kHz und
und verbraucht daher im Vergleich zu anderen Sensoren
möglicherweise mehr Strom.
Ausrichtungssensoren
Der AbsoluteOrientationSensor
ist ein Fusionssensor, der die Drehung eines Geräts in Bezug auf das Erdkoordinatensystem misst. Der RelativeOrientationSensor
liefert Daten zur Drehung eines Geräts mit Bewegungssensoren in Bezug auf ein stationäres Referenzkoordinatensystem.
Alle modernen 3D-JavaScript-Frameworks unterstützen Quaternionen und Rotationsmatrizen zur Darstellung von Drehungen. Wenn Sie jedoch WebGL direkt verwenden, hat OrientationSensor
sowohl eine quaternion
-Eigenschaft als auch eine populateMatrix()
-Methode.
Hier einige Beispiele:
let torusGeometry = new THREE.TorusGeometry(7, 1.6, 4, 3, 6.3);
let material = new THREE.MeshBasicMaterial({ color: 0x0071c5 });
let torus = new THREE.Mesh(torusGeometry, material);
scene.add(torus);
// Update mesh rotation using quaternion.
const sensorAbs = new AbsoluteOrientationSensor();
sensorAbs.onreading = () => torus.quaternion.fromArray(sensorAbs.quaternion);
sensorAbs.start();
// Update mesh rotation using rotation matrix.
const sensorRel = new RelativeOrientationSensor();
let rotationMatrix = new Float32Array(16);
sensor_rel.onreading = () => {
sensorRel.populateMatrix(rotationMatrix);
torus.matrix.fromArray(rotationMatrix);
};
sensorRel.start();
const mesh = new BABYLON.Mesh.CreateCylinder('mesh', 0.9, 0.3, 0.6, 9, 1, scene);
const sensorRel = new RelativeOrientationSensor({ frequency: 30 });
sensorRel.onreading = () => mesh.rotationQuaternion.FromArray(sensorRel.quaternion);
sensorRel.start();
// Initialize sensor and update model matrix when new reading is available.
let modMatrix = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
const sensorAbs = new AbsoluteOrientationSensor({ frequency: 60 });
sensorAbs.onreading = () => sensorAbs.populateMatrix(modMatrix);
sensorAbs.start();
// Somewhere in rendering code, update vertex shader attribute for the model
gl.uniformMatrix4fv(modMatrixAttr, false, modMatrix);
Orientierungssensoren ermöglichen verschiedene Anwendungsfälle, z. B. immersive Spiele, Augmented Reality und virtuelle Realität.
Weitere Informationen zu Bewegungssensoren, erweiterten Anwendungsfällen und Anforderungen finden Sie im Dokument Erläuterung zu Bewegungssensoren.
Synchronisierung mit Bildschirmkoordinaten
Standardmäßig werden die Messwerte der räumlichen Sensoren in einem lokalen Koordinatensystem aufgelöst, das an das Gerät gebunden ist und die Bildschirmausrichtung nicht berücksichtigt.
Bei vielen Anwendungsfällen wie Spielen oder Augmented Reality und Virtual Reality müssen Sensordaten jedoch in einem Koordinatensystem aufgelöst werden, das an die Bildschirmausrichtung gebunden ist.
Bisher musste die Neuzuordnung der Sensorwerte zu Bildschirmkoordinaten in JavaScript implementiert werden. Dieser Ansatz ist ineffizient und erhöht auch die Komplexität des Webanwendungscodes erheblich. Die Webanwendung muss die Bildschirmausrichtung überwachen und Koordinatentransformationen für Sensordaten ausführen, was bei Eulerwinkeln oder Quaternionen nicht trivial ist.
Die Generic Sensor API bietet eine wesentlich einfachere und zuverlässige Lösung. Das lokale Koordinatensystem
konfigurierbar für alle definierten räumlichen Sensorklassen: Accelerometer
, Gyroscope
,
LinearAccelerationSensor
, AbsoluteOrientationSensor
, RelativeOrientationSensor
und
Magnetometer
Durch Übergabe der Option referenceFrame
an den Konstruktor des Sensorobjekts definiert der Nutzer, ob die zurückgegebenen Messwerte in Geräte- oder Bildschirmkoordinaten aufgelöst werden.
// Sensor readings are resolved in the Device coordinate system by default.
// Alternatively, could be RelativeOrientationSensor({referenceFrame: "device"}).
const sensorRelDevice = new RelativeOrientationSensor();
// Sensor readings are resolved in the Screen coordinate system. No manual remapping is required!
const sensorRelScreen = new RelativeOrientationSensor({ referenceFrame: 'screen' });
Los gehts!
Die Generic Sensor API ist sehr einfach und nutzerfreundlich. Die Sensor-Benutzeroberfläche bietet die Methoden start()
und stop()
zur Steuerung des Sensorstatus sowie mehrere Ereignis-Handler, um Benachrichtigungen über die Sensoraktivierung, Fehler und neu verfügbare Messwerte zu erhalten. Die konkreten Sensorklassen fügen in der Regel ihre spezifischen Leseattribute zur Basis hinzu.
.
Entwicklungsumgebung
Während der Entwicklung können Sie Sensoren über localhost
verwenden. Wenn Sie für Ihr Unternehmen
Mobilgeräte, Einrichtung
Portweiterleitung
für Ihren lokalen Server und Sie sind bereit durchstarten!
Wenn der Code fertig ist, stellen Sie ihn auf einem Server bereit, der HTTPS unterstützt. GitHub-Seiten werden über HTTPS bereitgestellt und eignen sich daher ideal zum Teilen für Ihre Demos.
3D-Modell drehen
In diesem einfachen Beispiel verwenden wir die Daten eines Sensors für die absolute Ausrichtung, um die Drehung zu ändern.
Quaternion eines 3D-Modells. model
ist ein 3.js-Script.
Object3D
-Klasseninstanz mit einem
quaternion
. Im folgenden Code-Snippet aus der Demo orientation phone wird veranschaulicht, wie der Sensor für die absolute Ausrichtung verwendet werden kann, um ein 3D‑Modell zu drehen.
function initSensor() {
sensor = new AbsoluteOrientationSensor({ frequency: 60 });
sensor.onreading = () => model.quaternion.fromArray(sensor.quaternion);
sensor.onerror = (event) => {
if (event.error.name == 'NotReadableError') {
console.log('Sensor is not available.');
}
};
sensor.start();
}
Die Ausrichtung des Geräts wird in der WebGL-Szene durch eine 3D-model
-Drehung widergespiegelt.
Lochzange
Das folgende Code-Snippet wird aus dem Punchmeter-Demo, zur Veranschaulichung, wie mit dem linearen Beschleunigungssensor die maximale Geschwindigkeit eines wird angenommen, dass es am Anfang still liegt.
this.maxSpeed = 0;
this.vx = 0;
this.ax = 0;
this.t = 0;
/* … */
this.accel.onreading = () => {
let dt = (this.accel.timestamp - this.t) * 0.001; // In seconds.
this.vx += ((this.accel.x + this.ax) / 2) * dt;
let speed = Math.abs(this.vx);
if (this.maxSpeed < speed) {
this.maxSpeed = speed;
}
this.t = this.accel.timestamp;
this.ax = this.accel.x;
};
Die aktuelle Geschwindigkeit wird als Annäherung an das Integral der Beschleunigungsfunktion berechnet.
Debugging und Überschreiben von Sensoren mit den Chrome-Entwicklertools
In einigen Fällen benötigen Sie kein physisches Gerät, um die Generic Sensor API zu testen. Chrome-Entwicklertools das Unternehmen sehr gut unterstützt, die Geräteausrichtung zu simulieren.
Datenschutz und Sicherheit
Sensordaten sind sensible Daten, die von schädlichen Webseiten angegriffen werden können. Bei der Implementierung von Generic Sensor APIs werden einige Einschränkungen erzwungen, um die möglichen Sicherheits- und Datenschutzrisiken zu minimieren. Diese Einschränkungen müssen von Entwicklern berücksichtigt werden, die die API erstellen. Lassen Sie uns diese kurz auflisten.
Nur HTTPS
Da die Generic Sensor API eine leistungsstarke Funktion ist, lässt der Browser sie nur in sicheren Kontexten zu. In bedeutet das, dass Sie über HTTPS auf Ihre Seite zugreifen müssen, um die Generic Sensor API verwenden zu können. Während der Entwicklung können Sie dies über http://localhost tun, für die Produktion jedoch muss HTTPS auf Ihrem Server installiert sein. Best Practices und Richtlinien finden Sie in der Sammlung Sicher und geschützt.
Integration der Richtlinie für Berechtigungen
Die Integration der Berechtigungsrichtlinie in der Generic Sensor API steuert den Zugriff auf Sensordaten für einen Frame.
Standardmäßig können Sensor
-Objekte nur innerhalb eines Hauptframes oder Subframes mit demselben Ursprung erstellt werden.
Dadurch wird verhindert, dass ursprungsübergreifende iFrames Sensordaten unangekündigt lesen. Dieses Standardverhalten kann geändert werden, indem Sie die entsprechenden richtliniengesteuerten Funktionen explizit aktivieren oder deaktivieren.
Im folgenden Snippet wird veranschaulicht, wie einem iframe mit unterschiedlicher Herkunft Zugriff auf Beschleunigungsmesserdaten gewährt wird. Das bedeutet, dass dort jetzt Accelerometer
- oder LinearAccelerationSensor
-Objekte erstellt werden können.
<iframe src="https://third-party.com" allow="accelerometer" />
Die Übermittlung von Sensordaten kann ausgesetzt werden
Auf Sensordaten kann nur über eine sichtbare Webseite zugegriffen werden, d. h., wenn der Nutzer tatsächlich mit der Seite interagiert. Außerdem werden die Sensordaten nicht für den übergeordneten Frame bereitgestellt, wenn der Nutzer auf einen ursprungsübergreifenden Subframe hin. Dadurch wird verhindert, dass der übergeordnete Frame Nutzereingaben ableiten kann.
Nächste Schritte
Es gibt bereits eine Reihe von Sensorklassen, die in naher Zukunft implementiert werden sollen, z. B. der Umgebungslichtsensor oder der Näherungssensor. Dank der großen Erweiterungsfähigkeit des Generic Sensor-Frameworks können wir jedoch davon ausgehen, dass noch mehr neue Klassen für verschiedene Sensortypen hinzukommen werden.
Ein weiterer wichtiger Bereich für zukünftige Arbeit ist die Verbesserung der Generic Sensor API selbst. Die Spezifikation für den generischen Sensor ist derzeit eine Empfehlung, was bedeutet, dass noch Zeit für Fehlerkorrekturen und neue Funktionen bleibt, die Entwickler benötigen.
Du kannst helfen!
Die Sensorspezifikationen haben den Reifegrad Empfohlene Kandidatur erreicht. Daher wird das Feedback von Web- und Browserentwicklern sehr geschätzt. Lass uns wissen, welche Funktionen du dir wünschen würdest oder ob du etwas an der aktuellen API ändern möchtest.
Sie können auch Probleme mit Spezifikationen einreichen. als Programmfehler für die Chrome-Implementierung.
Ressourcen
- Demoprojekte: https://intel.github.io/generic-sensor-demos/
- Spezifikation der Generic Sensor API: https://w3c.github.io/sensors/
- Probleme mit der Spezifikation: https://github.com/w3c/sensors/issues
- Mailingliste der W3C-Arbeitsgruppe: public-device-apis@w3.org
- Chrome-Funktionsstatus: https://www.chromestatus.com/feature/5698781827825664
- Fehler bei der Implementierung: http://crbug.com?q=component:Blink>Sensor
Danksagungen
Dieser Artikel wurde von Joe Medley und Kayce Basques geprüft. Hero-Image von Misko über Wikimedia Commons