Sensores para la Web

Usa la API de Generic Sensor para acceder a sensores integrados en el dispositivo, como acelerómetros, giroscopios y magnetómetros.

Alex Shalamov
Alex Shalamov
Mikhail Pozdnyakov
Mikhail Pozdnyakov

Hoy en día, los datos de sensores se usan en muchas aplicaciones específicas de la plataforma para habilitar videojuegos envolventes, seguimiento del estado físico y realidad virtual o aumentada. ¿No sería genial conectar los dos la brecha entre las aplicaciones específicas de la plataforma y las aplicaciones web? Ingresa el API de Sensor genérico para la Web

¿Qué es la API de Generic Sensor?

La API de Generic Sensor es un conjunto de interfaces que exponen sensores a la plataforma web. La API consiste en la base Sensor y un conjunto de elementos concretos de sensores compiladas sobre la base. Tener una interfaz base simplifica la implementación y la especificación para las clases de sensores concretos. Por ejemplo, echa un vistazo a Gyroscope. ¡Es muy diminuta! El la funcionalidad principal se especifica con la interfaz base y Gyroscope simplemente la extiende con tres atributos que representan la velocidad angular.

Algunas clases de sensores interactúan con sensores de hardware reales, como, por ejemplo, el acelerómetro o de giroscopio. Estos se denominan sensores de bajo nivel. Otros sensores, denominados sensores de fusión, combina datos de varios niveles sensores para exponer información que una secuencia de comandos, de otro modo, tendría que calcular. Por ejemplo, el Sensor AbsoluteOrientation proporciona una matriz de rotación de cuatro por cuatro lista para usar basada en los datos obtenidos del acelerómetro, giroscopio y magnetómetro.

Podrías pensar que la plataforma web ya proporciona datos de sensores, ¡y tienes toda la razón! Para instancia, DeviceMotion y DeviceOrientation exponen los datos del sensor de movimiento. ¿Por qué necesitamos una API nueva?

En comparación con las interfaces existentes, la API de Generic Sensor proporciona una gran cantidad de ventajas:

  • La API genérica de Sensor es un marco de trabajo de sensores que se puede extender fácilmente con nuevas clases de sensores y cada una de estas clases mantendrá la interfaz genérica. El código del cliente escrito para un tipo de sensor puede reutilizarse en otro con muy pocas modificaciones.
  • Puedes configurar el sensor. Por ejemplo, puedes configurar la frecuencia de muestreo adecuada para tu las necesidades de la aplicación.
  • Puedes detectar si hay un sensor disponible en la plataforma.
  • Las lecturas de los sensores tienen marcas de tiempo de alta precisión, lo que permite una mejor sincronización con otros las actividades en tu aplicación.
  • Los modelos de datos de sensores y los sistemas de coordinación están claramente definidos, lo que permite a los proveedores de navegadores para implementar soluciones interoperables.
  • Las interfaces genéricas basadas en sensores no están vinculadas al DOM (lo que significa que no están navigator ni objetos window), lo que abre oportunidades futuras para usar la API dentro del servicio o impleméntalos en entornos de ejecución de JavaScript sin interfaz gráfica, como dispositivos.
  • Los aspectos de seguridad y privacidad son la prioridad principal para el sensor genérico y brinda una seguridad mucho mejor en comparación con las APIs de sensores más antiguas. Existe integración con la API de Permissions.
  • La sincronización automática con coordenadas en pantalla es disponible para Accelerometer, Gyroscope, LinearAccelerationSensor, AbsoluteOrientationSensor, RelativeOrientationSensor y Magnetometer.

APIs de sensores genéricos disponibles

Al momento de escribir este documento, hay varios sensores con los que puedes experimentar.

Sensores de movimiento:

  • Accelerometer
  • Gyroscope
  • LinearAccelerationSensor
  • AbsoluteOrientationSensor
  • RelativeOrientationSensor
  • GravitySensor

Sensores ambientales:

  • AmbientLightSensor (detrás de la marca #enable-generic-sensor-extra-classes en Chromium).
  • Magnetometer (detrás de la marca #enable-generic-sensor-extra-classes en Chromium).

Detección de funciones

La detección de funciones de las APIs de hardware es complicada, ya que debes detectar si el navegador admita la interfaz en cuestión y si el dispositivo cuenta con el sensor correspondiente. En proceso de verificación si el navegador admite una interfaz es sencillo. (Reemplaza Accelerometer por cualquiera de las otras interfaces mencionadas anteriormente).

if ('Accelerometer' in window) {
  // The `Accelerometer` interface is supported by the browser.
  // Does the device have an accelerometer, though?
}

Para obtener un resultado de detección de características realmente significativo, también debes intentar conectarte al sensor. Este ejemplo ilustra cómo hacerlo.

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

Para los navegadores que no admiten la API de Generic Sensor, una polyfill está disponible. El polyfill te permite cargar solo los sensores relevantes de Google Cloud.

// 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 });

¿Qué son todos esos sensores? ¿Cómo puedo usarlas?

Los sensores son un área que podría necesitar una breve introducción. Si estás familiarizado con los sensores, puedes ve directamente a la sección práctica de programación. De lo contrario, del sensor de movimiento en detalle.

Acelerómetro y sensor de aceleración lineal

. Mediciones del sensor del acelerómetro
.

El sensor Accelerometer mide la aceleración de un dispositivo que aloja el sensor en tres ejes (X, Y y Z). Este sensor es un es decir, cuando el dispositivo está en caída libre lineal, el total medido sería de 0 m/s2 y, cuando un dispositivo se ubica sobre una mesa, la aceleración en dirección hacia arriba (eje Z) será igual a la gravedad de la Tierra, es decir, g ≈ +9.8 m/s2 como mide la fuerza de la mesa que empuja el dispositivo hacia arriba. Si insertas el dispositivo en el derecha, la aceleración en el eje X sería positiva o negativa si el dispositivo se acelera desde la derecha hacia la izquierda.

Los acelerómetros se pueden usar para cosas como recuentos de pasos, detección de movimiento o dispositivos simples. orientación. Muy a menudo, las mediciones del acelerómetro se combinan con datos de otras fuentes para crear sensores de fusión, como sensores de orientación.

El LinearAccelerationSensor mide la aceleración que se aplica al dispositivo que aloja el sensor, sin incluir la contribución de la gravedad. Cuando un dispositivo está en reposo, por ejemplo, apoyado sobre una mesa, el sensor medirá ≈ 0 m/s2 de aceleración en tres ejes

Sensor de gravedad

Los usuarios ya pueden derivar manualmente lecturas cercanas a las de un sensor de gravedad mediante Inspeccionar manualmente las lecturas de Accelerometer y LinearAccelerometer, pero esto puede ser complicado y dependen de la exactitud de los valores proporcionados por esos sensores. Las plataformas como Android pueden proporcionan lecturas de gravedad como parte del sistema operativo, lo que debería ser más económico en términos de datos, proporcionan valores más exactos en función del hardware del usuario y son más fáciles de usar en en términos de ergonomía de las APIs. El GravitySensor muestra el efecto de aceleración en los ejes X, Y y Z del dispositivo debido a la gravedad.

Giroscopio

. Mediciones del sensor del giroscopio
.

El sensor Gyroscope mide de velocidad angular en radianes por segundo alrededor de los ejes X, Y y Z locales del dispositivo. Mayoría del consumidor Los dispositivos tienen sistemas mecánicos (MEMS). giroscopios, que son sensores inerciales que miden la velocidad de rotación según fuerza de Coriolis inercial. Los giroscopios MEMS son propensos a la deriva causada por la sensibilidad gravitacional del sensor que deforma la sistema mecánico interno. Los giroscopios oscilan a frecuencias relativas altas, p.ej., 10 s de kHz y por lo que podrían consumir más energía en comparación con otros sensores.

Sensores de orientación

. Mediciones del sensor de orientación absoluta
.

El AbsoluteOrientationSensor es un sensor de fusión que mide la rotación de un dispositivo en relación con el sistema de coordenadas de la Tierra, mientras que RelativeOrientationSensor proporciona datos que representan la rotación de un dispositivo que aloja sensores de movimiento en relación con una estación de coordenadas de referencia.

Todos los frameworks 3D modernos de JavaScript son compatibles con cuaterniones. y matrices de rotación para representar la rotación; Sin embargo, si usas WebGL directamente, el OrientationSensor convenientemente tiene un Propiedad quaternion y un populateMatrix(). Estos son algunos fragmentos:

three.js

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();

BABYLON

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();

WebGL

// 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);

Los sensores de orientación permiten varios casos de uso, como los videojuegos envolventes, aumentados y virtuales la realidad.

Para obtener más información sobre sensores de movimiento, casos de uso avanzados y requisitos, consulta la explicación sobre los sensores de movimiento.

Sincronización con coordenadas de pantalla

De forma predeterminada, las lecturas de los sensores espaciales se resuelven en un sistema de coordenadas local que está vinculado al dispositivo y que no toma la orientación de la pantalla de servicio predeterminada.

Sistema de coordenadas del dispositivo
Sistema de coordenadas del dispositivo

Sin embargo, muchos casos de uso, como los juegos o la realidad aumentada y virtual, requieren que las lecturas de los sensores se resuelven en un sistema de coordenadas que, en cambio, está vinculado a la orientación de la pantalla.

Sistema de coordenadas de pantalla
Sistema de coordenadas de pantalla

Anteriormente, era necesario implementar en JavaScript la reasignación de las lecturas del sensor a las coordenadas de la pantalla. Este enfoque es ineficiente y aumenta de manera significativa la complejidad de la Web. el código de la aplicación; la aplicación web debe observar los cambios de orientación de la pantalla y realizar coordenadas en las lecturas de los sensores, lo cual no es algo trivial para los ángulos de Euler o cuaterniones.

La API de Generic Sensor proporciona una solución mucho más simple y confiable. El sistema de coordenadas local es se puede configurar para todas las clases de sensores espaciales definidas: Accelerometer, Gyroscope, LinearAccelerationSensor, AbsoluteOrientationSensor, RelativeOrientationSensor y Magnetometer Cuando pasas la opción referenceFrame al constructor de objetos del sensor, el usuario define si las lecturas devueltas se resolverán en device o coordenadas de la pantalla.

// 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' });

Vamos a programar.

La API de Generic Sensor es muy simple y fácil de usar. La interfaz del sensor start() y métodos stop() para controlar el estado del sensor y varias controladores de eventos para recibir notificaciones sobre la activación de sensores, los errores y las actualizaciones de lectura. Las clases de sensores concretas suelen agregar sus atributos de lectura específicos a la base. .

Entorno de desarrollo

Durante el desarrollo, podrás usar sensores a través de localhost. Si estás desarrollando dispositivos móviles, configurar redirección de puertos para tu servidor local, ¡y estás listo para roquear!

Cuando tu código esté listo, impleméntalo en un servidor que admita HTTPS. Las páginas de GitHub se publican a través de HTTPS, por lo que es un excelente lugar para compartir tus demostraciones.

Rotación de modelos 3D

En este ejemplo sencillo, usamos los datos de un sensor de orientación absoluta para modificar la rotación. cuaternión de un modelo 3D. El elemento model es un elemento Three.js Object3D que tiene una propiedad quaternion. El siguiente fragmento de código de la teléfono de orientación muestra cómo se puede usar el sensor de orientación absoluta para rotar un modelo 3D.

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();
}

La orientación del dispositivo se reflejará en la rotación 3D model dentro de la escena de WebGL.

El sensor actualiza la orientación del modelo 3D
El sensor actualiza la orientación de un modelo 3D

Punchador

El siguiente fragmento de código se extrajo del demostración de Punchmeter ilustrar cómo se puede usar el sensor de aceleración lineal para calcular la velocidad máxima de un suponiendo que inicialmente está quieto.

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;
};

La velocidad actual se calcula como una aproximación a la integral de la función de aceleración.

Aplicación web de demostración para medir la velocidad de perforación
Medición de la velocidad de perforación

Depuración y anulación de sensores con las Herramientas para desarrolladores de Chrome

En algunos casos, no necesitas un dispositivo físico para jugar con la API de Generic Sensor. Herramientas para desarrolladores de Chrome tiene un gran apoyo simulación de la orientación del dispositivo.

Las herramientas para desarrolladores de Chrome se usan para anular los datos de orientación personalizada de un teléfono virtual.
Simula la orientación del dispositivo con las Herramientas para desarrolladores de Chrome

Privacidad y seguridad

Las lecturas de los sensores son datos sensibles que pueden estar sujetos a diversos ataques de páginas web maliciosas. Las implementaciones de las APIs de sensores genéricos imponen algunas limitaciones para mitigar los posibles efectos y riesgos de privacidad. Los desarrolladores que deseen utilizar las enumeremos brevemente esta API.

Solo HTTPS

Debido a que la API de Generic Sensor es una función potente, el navegador solo la permite en contextos seguros. En significa que, para usar la API de Generic Sensor, tendrás que acceder a tu página a través de HTTPS. Durante el desarrollo, puedes hacerlo a través de http://localhost pero, para la producción, debe tener HTTPS en su servidor. Consulta la colección Seguridad y protección para conocer las prácticas recomendadas y lineamientos.

Integración de la política de permisos

La integración de la política de permisos en genérico La API de Sensor controla el acceso a los datos de los sensores de una trama.

De forma predeterminada, los objetos Sensor solo se pueden crear dentro de un marco principal o submarcos del mismo origen. lo que evita que los iframes de origen cruzado realicen lecturas no autorizadas de datos de sensores. Este comportamiento predeterminado se pueden modificar habilitando o inhabilitando explícitamente el servicio correspondiente funciones controladas por políticas.

El siguiente fragmento ilustra cómo otorgar acceso a los datos del acelerómetro a un iframe de origen cruzado, lo que significa que ahora se pueden crear objetos Accelerometer o LinearAccelerationSensor allí.

<iframe src="https://third-party.com" allow="accelerometer" />

Se puede suspender la entrega de lecturas de sensores

Solo se puede acceder a las lecturas de los sensores desde una página web visible, es decir, cuando el usuario que estás interactuando con él. Además, los datos del sensor no se proporcionarán a la trama superior si el usuario cambia el enfoque a un submarco de origen cruzado. Esto evita que el marco superior infiera la entrada del usuario.

Próximos pasos

Hay un conjunto de clases de sensores ya especificadas que se implementarán en un futuro cercano, como Sensor de luz ambiente o Sensor de proximidad; sin embargo, gracias a la gran extensibilidad El marco de trabajo genérico del sensor permite anticipar la aparición de incluso más clases nuevas que representan varios de sensores.

Otra área importante para el trabajo futuro es mejorar la propia API de Generic Sensor, la API de Generic La especificación del sensor actualmente es una recomendación candidata, lo que significa que aún hay tiempo para hacer correcciones y aportar nuevas funcionalidades que los desarrolladores necesiten.

¡Puedes ayudar!

Se alcanzaron las especificaciones del sensor Recomendación de candidato y, por lo tanto, los comentarios de los desarrolladores web y de navegadores son muy bienvenidos. Permítenos sabrás qué atributos serían geniales agregar o si hay algo que quisieras modificar en la API actual.

No dudes en informar también problemas de especificaciones como errores en la implementación de Chrome.

Recursos

Agradecimientos

Joe Medley revisó este artículo, y Kayce Basques. Hero image de Misko mediante Wikimedia Commons.