Gebruik de Generic Sensor API om toegang te krijgen tot sensoren op het apparaat, zoals accelerometers, gyroscopen en magnetometers.
Sensorgegevens worden tegenwoordig in veel platformspecifieke applicaties gebruikt voor toepassingen zoals meeslepende games, fitnessregistratie en augmented of virtual reality. 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 generieke sensor-API?
De Generic Sensor API is een set interfaces die sensoren beschikbaar maken voor 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 Gyroscope klasse. Die is superklein! De kernfunctionaliteit wordt gespecificeerd door de basisinterface en Gyroscope breidt deze slechts uit met drie attributen die de hoeksnelheid weergeven.
Sommige sensorklassen communiceren met daadwerkelijke hardware-sensoren, zoals bijvoorbeeld de accelerometer- of gyroscoopklassen. Deze worden laag-niveau sensoren genoemd. Andere sensoren, fusiesensoren genoemd, combineren gegevens van verschillende laag-niveau sensoren om informatie te tonen die een script anders zelf zou moeten berekenen. De AbsoluteOrientation sensor levert bijvoorbeeld een kant-en-klare vier-bij-vier rotatiematrix op basis van de gegevens van de accelerometer, gyroscoop en magnetometer.
Je zou kunnen denken dat het webplatform al sensorgegevens levert, en daar heb je helemaal gelijk in! Zo tonen de gebeurtenissen DeviceMotion en DeviceOrientation bijvoorbeeld gegevens van de bewegingssensor. Dus waarom hebben we een nieuwe API nodig?
Vergeleken met de bestaande interfaces biedt de Generic Sensor API een groot aantal voordelen:
- Generic Sensor API is een sensorframework dat eenvoudig kan worden uitgebreid met nieuwe sensorklassen, waarbij elke klasse de generieke interface behoudt. Clientcode die voor één sensortype is geschreven, kan met slechts minimale aanpassingen worden hergebruikt voor een ander sensortype!
- Je kunt de sensor configureren. Je kunt bijvoorbeeld de bemonsteringsfrequentie instellen die geschikt is voor jouw toepassing.
- Je kunt detecteren of er een sensor beschikbaar is op het platform.
- Sensorwaarden hebben zeer nauwkeurige tijdstempels, waardoor een betere synchronisatie met andere activiteiten in uw applicatie mogelijk is.
- Sensordatamodellen en coördinatensystemen zijn duidelijk gedefinieerd, waardoor browserleveranciers interoperabele oplossingen kunnen implementeren.
- De generieke, op sensoren gebaseerde interfaces zijn niet gebonden aan de DOM (wat betekent dat ze geen
navigatorofwindowobjecten zijn), en dit opent mogelijkheden voor toekomstig gebruik van de API binnen service workers of implementatie in headless JavaScript-runtimes, zoals ingebedde apparaten. - Beveiliging en privacy hebben de hoogste prioriteit bij de Generic Sensor API en bieden een veel betere beveiliging in vergelijking met oudere sensor-API's. Er is integratie met de Permissions API.
- Automatische synchronisatie met schermcoördinaten is beschikbaar voor
Accelerometer,Gyroscope,LinearAccelerationSensor,AbsoluteOrientationSensor,RelativeOrientationSensorenMagnetometer.
Beschikbare generieke sensor-API's
Op het moment van schrijven zijn er verschillende sensoren waarmee je kunt experimenteren.
Bewegingssensoren:
-
Accelerometer -
Gyroscope -
LinearAccelerationSensor -
AbsoluteOrientationSensor -
RelativeOrientationSensor -
GravitySensor
Omgevingssensoren:
-
AmbientLightSensor(Achter de vlag#enable-generic-sensor-extra-classesin Chromium.) -
Magnetometer(Achter de vlag#enable-generic-sensor-extra-classesin Chromium.)
Kenmerkdetectie
Het detecteren van hardware-API's is lastig, omdat je zowel moet vaststellen of de browser de betreffende interface ondersteunt als of het apparaat de bijbehorende sensor heeft. 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 echt zinvol resultaat bij het detecteren van kenmerken, moet je ook proberen verbinding te maken met de sensor. Dit voorbeeld laat zien hoe je 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 de polyfill kunt u alleen de implementaties van de relevante 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 });
Wat zijn al die sensoren? Hoe kan ik ze gebruiken?
Sensoren is een onderwerp dat wellicht een korte introductie nodig heeft. Als u al bekend bent met sensoren, kunt u direct doorgaan naar het gedeelte met praktische codeeropdrachten . Zo niet, dan bekijken we elke ondersteunde sensor in detail.
Versnellingsmeter en lineaire versnellingssensor
De Accelerometer meet de versnelling van een apparaat waarop de sensor is gemonteerd langs drie assen (X, Y en Z). Deze sensor is een inertiële sensor, wat betekent dat wanneer het apparaat zich in een lineaire vrije val bevindt, de totale gemeten versnelling 0 m/ s² is. Wanneer een apparaat plat op een tafel ligt, is de versnelling in opwaartse richting (Z-as) gelijk aan de zwaartekracht van de aarde, oftewel g ≈ +9,8 m/ s², omdat de sensor de kracht meet die de tafel uitoefent om het apparaat omhoog te duwen. Als je het apparaat naar rechts duwt, is de versnelling op de X-as positief, of negatief als het apparaat van rechts naar links wordt versneld.
Versnellingsmeters kunnen worden gebruikt voor zaken als: stappen tellen, beweging detecteren of simpelweg de oriëntatie van een apparaat bepalen. Vaak worden metingen van versnellingsmeters gecombineerd met gegevens uit andere bronnen om fusiesensoren te creëren, zoals oriëntatiesensoren.
De LinearAccelerationSensor meet de versnelling die wordt uitgeoefend op het apparaat waarop de sensor is gemonteerd, exclusief de bijdrage van de zwaartekracht. Wanneer een apparaat stilstaat, bijvoorbeeld plat op een tafel ligt, meet de sensor een versnelling van ongeveer 0 m/ s² in drie assen.
Zwaartekrachtsensor
Gebruikers kunnen al handmatig waarden afleiden die dicht bij die van een zwaartekrachtsensor liggen door handmatig de metingen van Accelerometer en LinearAccelerometer te inspecteren. Dit kan echter omslachtig zijn en is afhankelijk van de nauwkeurigheid van de waarden die door deze sensoren worden geleverd. Platformen zoals Android kunnen zwaartekrachtmetingen als onderdeel van het besturingssysteem leveren. Dit zou rekenkundig gezien minder belastend moeten zijn, nauwkeurigere waarden moeten opleveren (afhankelijk van de hardware van de gebruiker) en gebruiksvriendelijker moeten zijn qua API-ergonomie. De GravitySensor geeft het effect van de versnelling langs de X-, Y- en Z-as van het apparaat als gevolg van de zwaartekracht weer.
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 inertiële sensoren die de rotatiesnelheid meten op basis van de inertiële Coriolis-kracht . MEMS-gyroscopen zijn gevoelig voor drift, veroorzaakt door de zwaartekrachtgevoeligheid van de sensor, die het interne mechanische systeem van de sensor vervormt. Gyroscopen oscilleren met relatief hoge frequenties, bijvoorbeeld tientallen kHz, en verbruiken daardoor mogelijk meer energie 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 je echter rechtstreeks WebGL gebruikt, heeft de OrientationSensor handig genoeg zowel een quaternion eigenschap als een populateMatrix() methode . Hier zijn een paar codefragmenten:
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 diverse toepassingen mogelijk, zoals meeslepende games, augmented reality en virtual reality.
Voor meer informatie over bewegingssensoren, geavanceerde toepassingsmogelijkheden en vereisten, raadpleeg het toelichtingsdocument over bewegingssensoren .
Synchronisatie met schermcoördinaten
Standaard worden de metingen van ruimtelijke sensoren weergegeven in een lokaal coördinatensysteem dat aan het apparaat is gekoppeld en geen rekening houdt met de schermoriëntatie.

Veel toepassingen, zoals games of augmented en virtual reality, vereisen echter dat sensorwaarden worden weergegeven in een coördinatensysteem dat is gekoppeld aan de schermoriëntatie.

Voorheen moest het omzetten van sensorwaarden naar schermcoördinaten in JavaScript worden geïmplementeerd. Deze aanpak is inefficiënt en verhoogt bovendien de complexiteit van de webapplicatiecode aanzienlijk; de webapplicatie moet schermoriëntatieveranderingen in de gaten houden en coördinatentransformaties uitvoeren voor sensorwaarden, wat geen eenvoudige taak is voor Eulerhoeken of quaternionen.
De Generic 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 aan de constructor van het sensorobject door te geven, definieert de gebruiker of de geretourneerde metingen worden weergegeven 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 gaan programmeren!
De generieke sensor-API is erg eenvoudig en gebruiksvriendelijk! De sensorinterface heeft start() en stop() methoden om de sensorstatus te beheren en verschillende gebeurtenisafhandelaars voor het ontvangen van meldingen over sensoractivering, fouten en nieuwe meetwaarden. De concrete sensorklassen voegen doorgaans hun specifieke meetwaarden toe aan de basisklasse.
Ontwikkelingsomgeving
Tijdens de ontwikkeling kun je sensoren via localhost gebruiken. Als je ontwikkelt voor mobiele apparaten, stel dan poortforwarding in voor je lokale server en je bent klaar om aan de slag te gaan!
Zodra je code klaar is, kun je deze implementeren op een server die HTTPS ondersteunt. GitHub Pages wordt via HTTPS aangeboden, waardoor het een uitstekende 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 telefoon met oriëntatie laat zien 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 rotatie van het 3D- model binnen de WebGL-scène.

Punchmeter
Het volgende codefragment is afkomstig uit de punchmeter-demo en illustreert hoe de lineaire acceleratiesensor kan worden gebruikt om de maximale snelheid van een apparaat te berekenen, ervan uitgaande dat het apparaat aanvankelijk stil ligt.
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 het overschrijven van sensoren met Chrome DevTools
In sommige gevallen heb je geen fysiek apparaat nodig om met de Generic Sensor API te experimenteren. Chrome DevTools biedt uitstekende ondersteuning voor het simuleren van de oriëntatie van een apparaat .

Privacy en beveiliging
Sensorwaarden zijn gevoelige gegevens die het doelwit kunnen zijn van diverse aanvallen door kwaadwillende webpagina's. Implementaties van generieke sensor-API's hanteren een aantal beperkingen om mogelijke beveiligings- en privacyrisico's te beperken. Ontwikkelaars die de API willen gebruiken, moeten rekening houden met deze beperkingen. Laten we ze daarom kort op een rijtje zetten.
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, om de Generic Sensor API te gebruiken, uw pagina via HTTPS moet benaderen. Tijdens de ontwikkeling kunt u dit doen via http://localhost , maar voor productie moet uw server HTTPS hebben. Raadpleeg de ' Veilig en beveiligd'- collectie voor best practices en richtlijnen.
Integratie van het machtigingsbeleid
De integratie van het machtigingsbeleid in de generieke sensor-API regelt de toegang tot sensorgegevens voor een frame.
Standaard kunnen Sensor objecten alleen binnen een hoofdframe of subframes van dezelfde oorsprong worden aangemaakt, waardoor wordt voorkomen dat iframes van een andere oorsprong zonder toestemming sensorgegevens uitlezen. Dit standaardgedrag kan worden gewijzigd door de bijbehorende beleidsgestuurde functies expliciet in of uit te schakelen.
Het onderstaande codefragment illustreert hoe toegang tot accelerometergegevens kan worden verleend aan een iframe met een andere oorsprong, waardoor nu Accelerometer of LinearAccelerationSensor objecten daar kunnen worden aangemaakt.
<iframe src="https://third-party.com" allow="accelerometer" />
De levering van sensorwaarden kan worden onderbroken.
Sensorwaarden zijn alleen toegankelijk via een zichtbare webpagina, oftewel wanneer de gebruiker er daadwerkelijk mee interacteert. Bovendien worden sensorgegevens niet aan het bovenliggende frame doorgegeven als de focus van de gebruiker verschuift naar een subframe met een andere oorsprong. Dit voorkomt dat het bovenliggende frame gebruikersinvoer kan afleiden.
Wat volgt?
Er is een aantal reeds gespecificeerde sensorklassen die in de nabije toekomst geïmplementeerd zullen worden, zoals omgevingslichtsensoren en nabijheidssensoren . Dankzij de grote uitbreidbaarheid van het Generic Sensor-framework kunnen we echter de komst van nog meer nieuwe klassen verwachten die verschillende sensortypen vertegenwoordigen.
Een ander belangrijk aandachtspunt voor de toekomst is het verbeteren van de Generic Sensor API zelf. De Generic Sensor-specificatie is momenteel een Candidate Recommendation, wat betekent dat er nog tijd is om bugs te verhelpen en nieuwe functionaliteit toe te voegen waar ontwikkelaars behoefte aan hebben.
U kunt helpen!
De sensorspecificaties hebben het volwassenheidsniveau 'Kandidaat-aanbeveling' bereikt. Feedback van web- en browserontwikkelaars wordt daarom zeer op prijs gesteld. Laat ons weten welke functies we graag zouden toevoegen of welke wijzigingen u in de huidige API zou willen aanbrengen.
U kunt gerust specificatieproblemen en bugs melden voor de Chrome-implementatie.
Bronnen
- Demo-projecten: https://w3c.github.io/generic-sensor-demos/
- Algemene API-specificatie voor sensoren: https://w3c.github.io/sensors/
- Specificatieproblemen: https://github.com/w3c/sensors/issues
- Mailinglijst van de 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 .