Gebruik de Generic Sensor API om toegang te krijgen tot sensoren op het apparaat, zoals accelerometers, gyroscopen en magnetometers.
Tegenwoordig worden sensordata gebruikt in veel platformspecifieke toepassingen om toepassingen zoals immersieve gaming, fitnesstracking en augmented reality of virtual reality mogelijk te maken. Zou het niet geweldig zijn om de kloof tussen platformspecifieke en webapplicaties te overbruggen? Maak kennis met de Generic Sensor API , voor het web!
Wat is de Generic Sensor API?
De Generic Sensor API is een set interfaces die sensorapparaten blootstelt aan het webplatform. De API bestaat uit de basisinterface Sensor
en een set concrete sensorklassen die daarop zijn gebouwd. Een basisinterface vereenvoudigt het implementatie- en specificatieproces voor de concrete sensorklassen. Neem bijvoorbeeld de klasse Gyroscope
. Deze is superklein! De kernfunctionaliteit wordt gespecificeerd door de basisinterface, en Gyroscope
breidt deze simpelweg uit met drie attributen die de hoeksnelheid vertegenwoordigen.
Sommige sensorklassen koppelen aan daadwerkelijke hardwaresensoren, zoals bijvoorbeeld de accelerometer- of gyroscoopklassen. Deze worden low-level sensoren genoemd. Andere sensoren, fusiesensoren genoemd, voegen data van verschillende low-level sensoren samen om informatie bloot te leggen die een script anders zou moeten berekenen. De AbsoluteOrientation
-sensor biedt bijvoorbeeld een gebruiksklare rotatiematrix van vier bij vier, gebaseerd op de data verkregen van de accelerometer, gyroscoop en magnetometer.
Je zou denken dat het webplatform al sensordata levert, en je hebt helemaal gelijk! Zo maken DeviceMotion
en DeviceOrientation
-gebeurtenissen bewegingssensordata openbaar. Waarom hebben we dan een nieuwe API nodig?
Vergeleken met de bestaande interfaces biedt Generic Sensor API een groot aantal voordelen:
- De Generic Sensor API is een sensorframework dat eenvoudig kan worden uitgebreid met nieuwe sensorklassen. Elk van deze klassen behoudt de generieke interface. De clientcode die voor het ene sensortype is geschreven, kan met minimale aanpassingen voor een ander type worden hergebruikt!
- U kunt de sensor configureren. U kunt bijvoorbeeld de bemonsteringsfrequentie instellen die het beste past bij uw toepassingsbehoeften.
- U kunt detecteren of een sensor op het platform beschikbaar is.
- Sensormetingen beschikken over zeer nauwkeurige tijdstempels, waardoor betere synchronisatie met andere activiteiten in uw toepassing mogelijk is.
- Sensordatamodellen en coördinatensystemen zijn duidelijk gedefinieerd, waardoor browserleveranciers interoperabele oplossingen kunnen implementeren.
- De op generieke sensoren gebaseerde interfaces zijn niet gebonden aan de DOM (wat betekent dat het geen
navigator
ofwindow
zijn). Dit biedt in de toekomst mogelijkheden voor het gebruik van de API in service workers of voor de implementatie ervan in headless JavaScript-runtimes, zoals embedded apparaten. - Beveiliging en privacy staan voorop bij de Generic Sensor API en bieden een veel betere beveiliging dan oudere sensor-API's. Er is integratie met de Permissions API.
- Automatische synchronisatie met schermcoördinaten is beschikbaar voor
Accelerometer
,Gyroscope
,LinearAccelerationSensor
,AbsoluteOrientationSensor
,RelativeOrientationSensor
enMagnetometer
.
Beschikbare generieke sensor-API's
Er zijn op dit moment verschillende sensoren waarmee u kunt experimenteren.
Bewegingssensoren:
-
Accelerometer
-
Gyroscope
-
LinearAccelerationSensor
-
AbsoluteOrientationSensor
-
RelativeOrientationSensor
-
GravitySensor
Omgevingssensoren:
-
AmbientLightSensor
(achter de#enable-generic-sensor-extra-classes
vlag in Chromium.) -
Magnetometer
(achter de#enable-generic-sensor-extra-classes
vlag in Chromium.)
Functiedetectie
Het detecteren van functies van hardware-API's is lastig, omdat je zowel moet vaststellen of de browser de betreffende interface ondersteunt als of het apparaat over de bijbehorende sensor beschikt. Controleren of de browser een interface ondersteunt, is eenvoudig. (Vervang Accelerometer
door een van de andere hierboven genoemde interfaces.)
if ('Accelerometer' in window) {
// The `Accelerometer` interface is supported by the browser.
// Does the device have an accelerometer, though?
}
Voor een daadwerkelijk zinvol resultaat van kenmerkdetectie moet u ook verbinding maken met de sensor. Dit voorbeeld illustreert hoe u dat doet.
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
Voor browsers die de Generic Sensor API niet ondersteunen, is een polyfill beschikbaar. Met deze polyfill kunt u alleen de relevante sensorimplementaties 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 });
Wat zijn al deze sensoren? Hoe kan ik ze gebruiken?
Sensoren zijn een gebied dat wellicht een korte introductie nodig heeft. Als je bekend bent met sensoren, kun je direct naar het praktische gedeelte over coderen gaan. Anders bekijken we elke ondersteunde sensor in detail.
Accelerometer en lineaire versnellingssensor
De Accelerometer
meet de versnelling van een apparaat waarop de sensor is gemonteerd op drie assen (X, Y en Z). Deze sensor is een traagheidssensor, wat betekent dat wanneer het apparaat in lineaire vrije val is, de totale gemeten versnelling 0 m/ s² is. Wanneer het apparaat plat op een tafel ligt, is de versnelling in opwaartse richting (Z-as) gelijk aan de zwaartekracht van de aarde, d.w.z. g ≈ +9,8 m/ s², aangezien de kracht van de tafel die het apparaat omhoog duwt, wordt gemeten. Als u het apparaat naar rechts duwt, is de versnelling op de X-as positief, of negatief als het apparaat van rechts naar links wordt versneld.
Accelerometers kunnen worden gebruikt voor zaken als stappentelling, bewegingsdetectie of eenvoudige apparaatoriëntatie. Vaak worden accelerometermetingen gecombineerd met gegevens uit andere bronnen om fusiesensoren te creëren, zoals oriëntatiesensoren.
De LinearAccelerationSensor
meet de versnelling die wordt toegepast op het apparaat waarin de sensor zich bevindt, exclusief de bijdrage van de zwaartekracht. Wanneer een apparaat in rust is, bijvoorbeeld plat op tafel, meet de sensor een versnelling van ≈ 0 m/ s² op drie assen.
zwaartekrachtsensor
Het is al mogelijk voor gebruikers om handmatig waarden af te leiden die dicht bij die van een zwaartekrachtsensor liggen door handmatig de waarden Accelerometer
en LinearAccelerometer
te inspecteren, maar dit kan omslachtig zijn en afhangen van de nauwkeurigheid van de waarden die door deze sensoren worden geleverd. Platforms zoals Android kunnen zwaartekrachtmetingen leveren als onderdeel van het besturingssysteem, wat rekenkundig goedkoper zou moeten zijn, nauwkeurigere waarden zou moeten opleveren, afhankelijk van de hardware van de gebruiker, en gebruiksvriendelijker zou moeten zijn qua API-ergonomie. De GravitySensor
geeft het effect weer van de versnelling langs de X-, Y- en Z-as van het apparaat als gevolg van de zwaartekracht.
Gyroscoop
De Gyroscope
meet de hoeksnelheid in radialen per seconde rond de lokale X-, Y- en Z-as van het apparaat. De meeste consumentenapparaten hebben mechanische ( MEMS ) gyroscopen, dit zijn traagheidssensoren die de rotatiesnelheid meten op basis van de traagheids-corioliskracht . MEMS-gyroscopen zijn gevoelig voor drift, veroorzaakt door de zwaartekrachtgevoeligheid van de sensor, waardoor het interne mechanische systeem vervormt. Gyroscopen oscilleren met relatief hoge frequenties, bijvoorbeeld 10 seconden kHz, en kunnen daardoor meer stroom verbruiken dan andere sensoren.
Oriëntatiesensoren
De AbsoluteOrientationSensor
is een fusiesensor die de rotatie van een apparaat meet ten opzichte van het coördinatensysteem van de aarde, terwijl de RelativeOrientationSensor
gegevens levert die de rotatie van een apparaat met bewegingssensoren weergeven ten opzichte van een stationair referentiecoördinatensysteem.
Alle moderne 3D JavaScript-frameworks ondersteunen quaternionen en rotatiematrices om rotatie weer te geven; als u echter rechtstreeks WebGL gebruikt, beschikt de OrientationSensor
handig genoeg over zowel een quaternion
-eigenschap als een populateMatrix()
methode . Hier zijn enkele fragmenten:
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);
Oriëntatiesensoren maken verschillende toepassingen mogelijk, zoals meeslepende games en augmented en virtual reality.
Raadpleeg het document met uitleg over bewegingssensoren voor meer informatie over bewegingssensoren, geavanceerde use cases en vereisten.
Synchronisatie met schermcoördinaten
Standaard worden de metingen van ruimtelijke sensoren opgelost in een lokaal coördinatensysteem dat aan het apparaat is gekoppeld en waarbij geen rekening wordt gehouden met de schermoriëntatie.

In veel toepassingen, zoals games of augmented en virtual reality, moeten sensormetingen worden omgezet in een coördinatensysteem dat gekoppeld is aan de schermoriëntatie.

Voorheen moest het opnieuw toewijzen van sensorwaarden aan schermcoördinaten in JavaScript worden geïmplementeerd. Deze aanpak is inefficiënt en verhoogt bovendien de complexiteit van de webapplicatiecode aanzienlijk; de webapplicatie moet veranderingen in de schermoriëntatie in de gaten houden en coördinatentransformaties uitvoeren voor sensorwaarden, wat niet eenvoudig is voor Euler-hoeken of quaternionen.
De generieke sensor-API biedt een veel eenvoudigere en betrouwbaardere oplossing! Het lokale coördinatensysteem is configureerbaar voor alle gedefinieerde ruimtelijke sensorklassen: Accelerometer
, Gyroscope
, LinearAccelerationSensor
, AbsoluteOrientationSensor
, RelativeOrientationSensor
en Magnetometer
. Door de optie referenceFrame
door te geven aan de sensorobjectconstructor, definieert de gebruiker of de geretourneerde meetwaarden worden omgezet in apparaat- of schermcoördinaten .
// 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' });
Laten we programmeren!
De generieke sensor-API is zeer eenvoudig en gebruiksvriendelijk! De sensorinterface heeft start()
en stop()
methoden om de sensorstatus te regelen en diverse event handlers voor het ontvangen van meldingen over sensoractivering, fouten en nieuwe beschikbare meetwaarden. De concrete sensorklassen voegen meestal hun specifieke meetwaarden toe aan de basisklasse.
Ontwikkelomgeving
Tijdens de ontwikkeling kun je sensoren gebruiken via localhost
. Ontwikkel je voor mobiele apparaten? Stel dan poortdoorschakeling in voor je lokale server en je bent klaar om te knallen!
Zodra je code klaar is, implementeer je deze op een server die HTTPS ondersteunt. GitHub-pagina's worden via HTTPS aangeboden, waardoor het een geweldige plek is om je demo's te delen.
3D-modelrotatie
In dit eenvoudige voorbeeld gebruiken we de gegevens van een absolute oriëntatiesensor om de rotatiequaternion van een 3D-model aan te passen. Het model
is een instantie van de three.js Object3D
klasse met een quaternion
eigenschap. Het volgende codefragment uit de demo van de oriëntatietelefoon illustreert hoe de absolute oriëntatiesensor kan worden gebruikt om een 3D-model te roteren.
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();
}
De oriëntatie van het apparaat wordt weerspiegeld in de 3D- model
in de WebGL-scène.

Punchmeter
Het volgende codefragment is afkomstig uit de punchmeter-demo en illustreert hoe de lineaire versnellingssensor kan worden gebruikt om de maximale snelheid van een apparaat te berekenen, ervan uitgaande dat het apparaat aanvankelijk stilstaat.
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;
};
De huidige snelheid wordt berekend als een benadering van de integraal van de versnellingsfunctie.

Foutopsporing en sensoroverschrijving met Chrome DevTools
In sommige gevallen heb je geen fysiek apparaat nodig om met de Generic Sensor API te spelen. Chrome DevTools biedt uitstekende ondersteuning voor het simuleren van apparaatoriëntatie .

Privacy en veiligheid
Sensorgegevens zijn gevoelige gegevens die vatbaar zijn voor diverse aanvallen van kwaadaardige webpagina's. Implementaties van generieke sensor-API's leggen een aantal beperkingen op om mogelijke beveiligings- en privacyrisico's te beperken. Ontwikkelaars die de API willen gebruiken, moeten rekening houden met deze beperkingen. Daarom sommen we ze kort op.
Alleen HTTPS
Omdat de Generic Sensor API een krachtige functie is, staat de browser deze alleen toe in beveiligde contexten. In de praktijk betekent dit dat u uw pagina via HTTPS moet openen om de Generic Sensor API te kunnen gebruiken. Tijdens de ontwikkeling kunt u dit doen via http://localhost, maar voor de productie moet u HTTPS op uw server hebben. Zie de collectie Veilig en beveiligd voor best practices en richtlijnen.
Integratie van machtigingenbeleid
Met de integratie van het machtigingsbeleid in de Generic Sensor API wordt de toegang tot sensorgegevens voor een frame beheerd.
Standaard kunnen Sensor
alleen binnen een hoofdframe of subframes met dezelfde oorsprong worden aangemaakt, waardoor wordt voorkomen dat iframes van verschillende oorsprong sensorgegevens onbevoegd kunnen lezen. Dit standaardgedrag kan worden aangepast door de bijbehorende, door beleid aangestuurde functies expliciet in of uit te schakelen.
Het onderstaande fragment illustreert het verlenen van toegang tot accelerometergegevens aan een cross-origin iframe. Dit betekent dat er nu Accelerometer
of LinearAccelerationSensor
-objecten in kunnen worden gemaakt.
<iframe src="https://third-party.com" allow="accelerometer" />
De levering van sensormetingen kan worden opgeschort
Sensorgegevens zijn alleen toegankelijk via een zichtbare webpagina, d.w.z. wanneer de gebruiker er daadwerkelijk mee interageert. Bovendien worden sensorgegevens niet aan het bovenliggende frame verstrekt als de focus van de gebruiker verandert naar een cross-origin subframe. Dit voorkomt dat het bovenliggende frame gebruikersinvoer afleidt.
Wat nu?
Er is een reeks reeds gespecificeerde sensorklassen die in de nabije toekomst zullen worden geïmplementeerd, zoals Ambient Light Sensor en Proximity Sensor . Dankzij de grote uitbreidbaarheid van het Generic Sensor-framework kunnen we echter verwachten dat er nog meer nieuwe klassen zullen verschijnen die verschillende sensortypen vertegenwoordigen.
Een ander belangrijk gebied voor toekomstig werk is het verbeteren van de Generic Sensor API zelf. De Generic Sensor-specificatie is op dit moment een Candidate Recommendation. Dit betekent dat er nog tijd is om oplossingen door te voeren en nieuwe functionaliteit te bieden die ontwikkelaars nodig hebben.
Jij kan helpen!
De sensorspecificaties hebben het niveau 'Aanbeveling kandidaat' bereikt, daarom stellen we de feedback van web- en browserontwikkelaars zeer op prijs. Laat ons weten welke functies we graag zouden toevoegen of wat u wilt aanpassen aan de huidige API.
U kunt gerust specificatieproblemen en bugs in de Chrome-implementatie melden.
Bronnen
- Demoprojecten: https://intel.github.io/generic-sensor-demos/
- Algemene sensor-API-specificatie: https://w3c.github.io/sensors/
- Specificatieproblemen: https://github.com/w3c/sensors/issues
- Mailinglijst W3C-werkgroep: public-device-apis@w3.org
- Status van Chrome-functies: https://www.chromestatus.com/feature/5698781827825664
- Implementatiefouten: http://crbug.com?q=component:Blink>Sensor
Dankbetuigingen
Dit artikel is beoordeeld door Joe Medley en Kayce Basques .