@openhps/web-sensors
Version:
Open Hybrid Positioning System - Web Sensors API
175 lines • 7.58 kB
JavaScript
"use strict";
/// <reference types="web" />
Object.defineProperty(exports, "__esModule", { value: true });
exports.SensorSourceNode = void 0;
const core_1 = require("@openhps/core");
/**
* Sensor source node using Web Sensor API.
*/
class SensorSourceNode extends core_1.SourceNode {
constructor(options) {
super(options);
this._subscriptions = new Map();
this._values = new Map();
this._lastPush = 0;
this._running = false;
this.options.interval = this.options.interval || 100;
if (this.options.autoStart) {
this.once('build', this.start.bind(this));
}
this.once('destroy', this.stop.bind(this));
}
static checkPermissions(sensors) {
return this.requestPermissions(sensors);
}
static requestPermissions(sensors) {
return new Promise((resolve, reject) => {
if (navigator.permissions === undefined) {
return resolve(true);
}
Promise.all(sensors
.map((sensor) => this.getPermissions(sensor).map((permission) => navigator.permissions.query({ name: permission })))
.reduce((a, b) => [...a, ...b]))
.then((results) => {
if (results.every((result) => result.state === 'granted')) {
resolve(true);
}
else {
resolve(false);
}
})
.catch(reject);
});
}
requestPermissions() {
return SensorSourceNode.requestPermissions(this.options.sensors);
}
start() {
return new Promise((resolve) => {
this._running = true;
if (this._subscriptions.size > 0) {
return resolve();
}
this.options.sensors.forEach((sensor) => {
const SensorType = this.findSensor(sensor);
if (SensorType === undefined) {
// Not supported
return;
}
const sensorInstance = new SensorType({
frequency: Math.round(1000 / this.options.interval),
});
sensorInstance.addEventListener('reading', (event) => {
if (!this._running)
return;
this._values.set(sensor, event.target);
if (this._isUpdated()) {
this._lastPush = event.timeStamp;
this.createFrame().catch((ex) => {
this.logger('error', 'Unable to create sensor data frame!', ex);
});
}
});
sensorInstance.start();
this._subscriptions.set(sensor, sensorInstance);
});
resolve();
});
}
_isUpdated() {
return (Array.from(this._values.values()).filter((sensor) => sensor.timestamp > this._lastPush).length ===
Array.from(this._subscriptions.values()).filter((sensor) => sensor.activated).length);
}
stop() {
return new Promise((resolve) => {
if (this.options.softStop) {
this._running = false;
}
else {
this._subscriptions.forEach((value) => value.stop());
this._subscriptions = new Map();
this._values = new Map();
}
resolve();
});
}
createFrame() {
return new Promise((resolve) => {
const dataFrame = new core_1.DataFrame();
dataFrame.source = this.source;
const acceleration = this._values.get(core_1.Accelerometer);
const linearAcceleration = this._values.get(core_1.LinearAccelerationSensor);
const gyroscope = this._values.get(core_1.Gyroscope);
const orientation = this._values.get(core_1.AbsoluteOrientationSensor);
const relativeOrientation = this._values.get(core_1.RelativeOrientationSensor);
const magnetometer = this._values.get(core_1.Magnetometer);
const sourceUID = this.source ? this.source.uid : this.uid;
const frequency = 1000 / this.options.interval;
if (acceleration) {
dataFrame.addSensor(new core_1.Accelerometer(sourceUID + '_accel', new core_1.Acceleration(acceleration.x, acceleration.y, acceleration.z, core_1.AccelerationUnit.METER_PER_SECOND_SQUARE), frequency));
}
if (linearAcceleration) {
dataFrame.addSensor(new core_1.LinearAccelerationSensor(sourceUID + '_linearaccel', new core_1.Acceleration(linearAcceleration.x, linearAcceleration.y, linearAcceleration.z, core_1.AccelerationUnit.METER_PER_SECOND_SQUARE), frequency));
}
if (gyroscope) {
dataFrame.addSensor(new core_1.Gyroscope(sourceUID + '_gyro', new core_1.AngularVelocity(gyroscope.x, gyroscope.y, gyroscope.z, core_1.AngularVelocityUnit.RADIAN_PER_SECOND), frequency));
}
if (orientation) {
dataFrame.addSensor(new core_1.AbsoluteOrientationSensor(sourceUID + '_absoluteorientation', core_1.Orientation.fromQuaternion(new core_1.Quaternion(...orientation.quaternion)), frequency));
}
if (relativeOrientation) {
dataFrame.addSensor(new core_1.RelativeOrientationSensor(sourceUID + '_relativeorientation', core_1.Orientation.fromQuaternion(new core_1.Quaternion(...relativeOrientation.quaternion)), frequency));
}
if (magnetometer) {
dataFrame.addSensor(new core_1.Magnetometer(sourceUID + '_mag', new core_1.Magnetism(magnetometer.x, magnetometer.y, magnetometer.z, core_1.MagnetismUnit.MICROTESLA), frequency));
}
this.push(dataFrame);
resolve();
});
}
onPull() {
return new Promise((resolve) => {
resolve(undefined);
});
}
findSensor(sensor) {
switch (sensor) {
case core_1.RelativeOrientationSensor:
return RelativeOrientationSensor;
case core_1.AbsoluteOrientationSensor:
return AbsoluteOrientationSensor;
case core_1.LinearAccelerationSensor:
return LinearAccelerationSensor;
// case SensorType.AMBIENT_LIGHT:
// return AmbientLightSensor;
case core_1.Gyroscope:
return Gyroscope;
case core_1.Magnetometer:
return window.Magnetometer; // Experimental
case core_1.Accelerometer:
return Accelerometer;
default:
return undefined;
}
}
static getPermissions(sensor) {
switch (sensor) {
// case SensorType.AMBIENT_LIGHT:
// return ["ambient-light-sensor"];
case core_1.RelativeOrientationSensor:
case core_1.AbsoluteOrientationSensor:
return ['gyroscope', 'accelerometer', 'magnetometer'];
case core_1.Gyroscope:
return ['gyroscope'];
case core_1.Magnetometer:
return ['magnetometer'];
case core_1.LinearAccelerationSensor:
case core_1.Accelerometer:
return ['accelerometer'];
default:
return undefined;
}
}
}
exports.SensorSourceNode = SensorSourceNode;
//# sourceMappingURL=SensorSourceNode.js.map