Use a API Generic Sensor para ter acesso a sensores no dispositivo, como acelerômetros, giroscópios e magnetômetros.
Atualmente, os dados do sensor são usados em muitos aplicativos específicos da plataforma para permitir casos de uso como jogos imersivos, monitoramento de atividades físicas e realidade aumentada ou virtual. Não seria legal unir a lacuna entre aplicativos específicos da plataforma e aplicativos da Web? Digite o API Generic Sensor, para a Web.
O que é a API Generic Sensor?
A API Generic Sensor é um conjunto de interfaces que expõem
de dispositivos com sensores para a plataforma da Web. A API é composta pelos
A interface Sensor
e um conjunto de modelos
classes de sensor
criadas acima dele. Ter uma interface base simplifica a implementação e a especificação
para as classes concretas do sensor. Por exemplo, dê uma olhada no
classe Gyroscope
. Ela é bem pequena! A
funcionalidade principal é especificada pela interface base, e Gyroscope
apenas a estende com três
atributos que representam a velocidade angular.
Algumas classes de sensores interagem com sensores de hardware reais, como o acelerômetro ou
classes de giroscópio. Eles são chamados de sensores de baixo nível. Outros sensores, chamados de
sensores de fusão, mesclar dados de vários níveis baixos
para expor informações que um script precisaria calcular. Por exemplo, o
Sensor AbsoluteOrientation
fornece uma matriz de rotação em quatro por quatro, pronta para uso, com base nos dados obtidos do
acelerômetro, giroscópio e magnetômetro.
Você pode pensar que a plataforma da Web já fornece dados do sensor e você está absolutamente certo! Para
instância, DeviceMotion
e
DeviceOrientation
expõem os dados do sensor de movimento. Por que precisamos de uma nova API?
Comparando com as interfaces existentes, a API Generic Sensor oferece diversas vantagens:
- A API Generic Sensor é um framework que pode ser estendido facilmente com novas classes de sensor e cada uma dessas classes manterá a interface genérica. O código do cliente escrito para um tipo de sensor pode ser reutilizado em outro com poucas modificações.
- Você pode configurar o sensor. Por exemplo, você pode definir a frequência de amostragem adequada para às necessidades do aplicativo.
- Você pode detectar se um sensor está disponível na plataforma.
- As leituras do sensor têm carimbos de data/hora de alta precisão, permitindo melhor sincronização com outros atividades em seu aplicativo.
- Os modelos de dados dos sensores e os sistemas de coordenadas são claramente definidos, permitindo que os fornecedores de navegadores implementar soluções interoperáveis.
- As interfaces baseadas em sensores genéricos não estão vinculadas ao DOM, ou seja, elas não são
navigator
. nem objetoswindow
), o que abre oportunidades futuras para usar a API no ambiente workers ou implementá-los em ambientes de execução JavaScript headless, como aplicativos dispositivos. - Os aspectos de segurança e privacidade são a prioridade do sensor genérico. e fornecem uma segurança muito melhor do que as APIs de sensores mais antigas. Há integração com a API Permissions.
- A sincronização automática com coordenadas de tela está
disponível para
Accelerometer
,Gyroscope
,LinearAccelerationSensor
eAbsoluteOrientationSensor
,RelativeOrientationSensor
eMagnetometer
.
APIs de sensores genéricos disponíveis
No momento em que este artigo foi escrito, existem vários sensores que você pode testar.
Sensores de movimento:
Accelerometer
Gyroscope
LinearAccelerationSensor
AbsoluteOrientationSensor
RelativeOrientationSensor
GravitySensor
Sensores ambientais:
AmbientLightSensor
(atrás da sinalização#enable-generic-sensor-extra-classes
no Chromium)Magnetometer
(atrás da sinalização#enable-generic-sensor-extra-classes
no Chromium)
Detecção de recursos
A detecção de recursos das APIs de hardware é complicada, porque é preciso detectar tanto se o navegador
oferece suporte à interface em questão e se o dispositivo tem o sensor correspondente. Verificando
se o navegador é compatível com uma interface é algo simples. (Substitua Accelerometer
por qualquer um dos
as outras interfaces mencionadas acima).
if ('Accelerometer' in window) {
// The `Accelerometer` interface is supported by the browser.
// Does the device have an accelerometer, though?
}
Para obter um resultado de detecção de atributos realmente significativo, você precisa tentar se conectar ao sensor também. Este exemplo mostra como fazer isso.
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 navegadores que não são compatíveis com a API Generic Sensor, um polyfill estiver disponível. O polyfill permite que você carregar apenas os sensores relevantes e implementações.
// 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 });
O que são todos esses sensores? Como posso usá-los?
"Sensores" é uma área que talvez precise de uma breve introdução. Se você já conhece os sensores, pode vá direto para a seção de programação prática. Caso contrário, vamos conferir cada modelo sensor em detalhes.
Acelerômetro e sensor de aceleração linear
O sensor Accelerometer
mede a aceleração de um dispositivo que hospeda o sensor em três eixos (X, Y e Z). Esse sensor é um
sensor de inércia. Isso significa que, quando o dispositivo está em queda livre linear, o total
a aceleração seria de 0 m/s2 e, quando um dispositivo estivesse nivelado com uma mesa, a aceleração
na direção para cima (eixo Z) será igual à gravidade da Terra, ou seja, g ✕ +9,8 m/s2 como
ela mede a força da mesa empurrando o dispositivo para cima. Se você empurrar o dispositivo para o
à direita, a aceleração no eixo X será positiva ou negativa se o dispositivo for acelerado a partir de
a direita para a esquerda.
Os acelerômetros podem ser usados para contagem de passos, detecção de movimento ou dispositivos simples orientação. Muitas vezes, as medições do acelerômetro são combinadas com dados de outras fontes para criar sensores de fusão, como os de orientação.
A
LinearAccelerationSensor
mede a aceleração aplicada ao dispositivo que hospeda o sensor, excluindo a contribuição
da gravidade. Quando um dispositivo está em repouso, por exemplo, deitado sobre uma mesa, o sensor mediria
Aceleração de 0 m/s2 em três eixos.
Sensor de gravidade
Os usuários já podem derivar leituras manualmente próximas das de um sensor de gravidade ao
inspecionar manualmente as leituras de Accelerometer
e LinearAccelerometer
, mas isso pode ser complicado.
e depender da precisão dos valores fornecidos por esses sensores. Plataformas como o Android podem
fornecem leituras de gravidade como parte do sistema operacional, que deve ser mais barato em termos de
computação em nuvem, fornecem valores mais precisos dependendo do hardware do usuário e são mais fáceis de usar
em termos de ergonomia das APIs. A
GravitySensor
retorna o efeito.
da aceleração ao longo dos eixos X, Y e Z do dispositivo devido à gravidade.
Giroscópio
O sensor Gyroscope
mede
velocidade angular em radianos por segundo ao redor dos eixos locais X, Y e Z do dispositivo. Maiores consumidores
têm dispositivos mecânicos (MEMS)
giroscópios, que são sensores de inércia que medem a taxa de rotação com base em
força inercial de Coriolis. Os giroscópios MEMS são suscetíveis
ao deslocamento, que é causado pela sensibilidade gravitacional do sensor, que deforma
sistema mecânico interno. Os giroscópios oscilam em altas frequências relativas, por exemplo, por dezenas de kHz e
portanto, pode consumir mais energia em comparação com outros sensores.
Sensores de orientação
A
AbsoluteOrientationSensor
é um sensor de fusão que mede a rotação de um dispositivo em relação ao sistema de coordenadas da Terra,
enquanto o
RelativeOrientationSensor
fornece dados que representam a rotação de um dispositivo que hospeda sensores de movimento em relação a um dispositivo estacionário
de coordenadas de referência.
Todas as estruturas modernas de JavaScript em 3D são compatíveis com quatérnios
e matrizes de rotação para representar a rotação.
No entanto, se você usar o WebGL diretamente, o OrientationSensor
, convenientemente, tem uma
Propriedade quaternion
e um
populateMatrix()
método.
Aqui estão alguns snippets:
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);
Os sensores de orientação permitem vários casos de uso, como jogos imersivos, aumentados e virtuais realidade.
Para mais informações sobre sensores de movimento, casos de uso avançados e requisitos, confira a documento de explicação dos sensores de movimento.
Sincronização com coordenadas de tela
Por padrão, as leituras dos sensores espaciais são resolvidas em um sistema de coordenadas local que é vinculado ao dispositivo e não usa a orientação da tela do Compute Engine.
No entanto, muitos casos de uso, como jogos ou realidade aumentada e virtual, exigem que as leituras dos sensores sejam resolvido em um sistema de coordenadas que está vinculado à orientação da tela.
Anteriormente, o remapeamento de leituras do sensor em coordenadas de tela precisava ser implementado em JavaScript. Essa abordagem é ineficiente e também aumenta significativamente a complexidade da Web código do aplicativo o aplicativo da Web precisa acompanhar as mudanças na orientação da tela e executar coordenadas transformações para leituras de sensores, o que não é algo trivial para ângulos de Euler ou quatérnios.
A API Generic Sensor oferece uma solução muito mais simples e confiável. O sistema de coordenadas local é
configurável para todas as classes de sensores espaciais definidas: Accelerometer
, Gyroscope
,
LinearAccelerationSensor
, AbsoluteOrientationSensor
, RelativeOrientationSensor
e
Magnetometer
. Ao transmitir a opção referenceFrame
para o construtor do objeto sensor, o usuário
define se as leituras retornadas serão resolvidas
device ou
screen.
// 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 programar!
A API Generic Sensor é muito simples e fácil de usar. A interface Sensor tem
start()
e
stop()
para controlar o estado do sensor e vários
manipuladores de eventos para receber notificações sobre ativação de sensores, erros e
e textos. As classes concretas do sensor geralmente adicionam seus atributos de leitura específicos à base
.
Ambiente de desenvolvimento
Durante o desenvolvimento, você poderá usar sensores com localhost
. Se você está desenvolvendo para
dispositivos móveis, configurar
encaminhamento de portas
para seu servidor local e está pronto para a ação.
Quando o código estiver pronto, implante-o em um servidor compatível com HTTPS. As páginas do GitHub são exibidas por HTTPS, o que as torna um ótimo local para compartilhar suas demonstrações.
Rotação do modelo 3D
Neste exemplo simples, usamos os dados de um sensor de orientação absoluta para modificar a rotação
quatérnio de um modelo 3D. O model
é um arquivo três.js.
instância da classe Object3D
que tem um
quaternion
. A
snippet de código da
smartphone com orientação
ilustra como o sensor de orientação absoluta pode ser usado para girar um 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();
}
A orientação do dispositivo vai ser refletida na rotação model
3D na cena WebGL.
Perfurador
O snippet de código a seguir é extraído da demonstração do punchmeter, ilustrando como o sensor de aceleração linear pode ser usado para calcular a velocidade máxima de um dispositivo com a suposição de que ele está inicialmente imóvel.
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;
};
A velocidade atual é calculada como uma aproximação da integral da função de aceleração.
Depuração e substituição de sensores com o Chrome DevTools
Em alguns casos, você não precisa de um dispositivo físico para brincar com a API Generic Sensor. Chrome DevTools oferece um ótimo suporte simular a orientação do dispositivo.
Privacidade e segurança
As leituras dos sensores são dados sensíveis que podem estar sujeitos a vários ataques de páginas da Web maliciosas. As implementações das APIs Generic Sensor aplicam algumas limitações para mitigar os possíveis efeitos riscos de segurança e privacidade. Essas limitações precisam ser consideradas pelos desenvolvedores que pretendem usar o API. Por isso, vamos listá-los rapidamente.
Somente HTTPS
Como a API Generic Sensor é um recurso avançado, o navegador só a permite em contextos seguros. Em Isso significa que, para usar a API Generic Sensor, você vai precisar acessar sua página pelo HTTPS. Durante o desenvolvimento, você pode fazer isso em http://localhost. No entanto, na produção, precisa ter HTTPS no seu servidor. Consulte a coleção Segurança e proteção para ver as práticas recomendadas e diretrizes de segurança.
Integração da política de permissões
A integração da política de permissões na página "Genérico" A API Sensor controla o acesso de um frame aos dados dos sensores.
Por padrão, os objetos Sensor
só podem ser criados dentro de um frame principal ou subframes de mesma origem.
impedindo, assim, que os iframes de origem cruzada leiam os dados do sensor não autorizados. Esse comportamento padrão
podem ser modificadas ativando ou desativando explicitamente os
recursos controlados por políticas.
O snippet abaixo ilustra como conceder ao acelerômetro acesso a um iframe de origem cruzada, ou seja,
que agora os objetos Accelerometer
ou LinearAccelerationSensor
podem ser criados lá.
<iframe src="https://third-party.com" allow="accelerometer" />
A entrega de leituras do sensor pode ser suspensa
As leituras do sensor só podem ser acessadas por uma página da Web visível, ou seja, quando o usuário está de fato interagir com ele. Além disso, os dados do sensor não seriam fornecidos ao frame principal se o usuário o foco muda para um subframe de origem cruzada. Isso impede que o frame pai infira a entrada do usuário.
A seguir
Há um conjunto de classes de sensores já especificadas para implementação em um futuro próximo, como Sensor de luz ambiente ou Sensor de proximidade; No entanto, graças à grande extensibilidade do um framework de sensor genérico, podemos antecipar o surgimento de ainda mais classes novas que representam vários diferentes de sensores.
Outra área importante para trabalhos futuros é melhorar a API Generic Sensor, a No momento, a especificação do sensor é uma recomendação candidata, o que significa que ainda há tempo para fazer correções e oferecer novas funcionalidades de que os desenvolvedores precisam.
Você pode ajudar!
As especificações do sensor foram alcançadas Candidato à recomendação nível de maturidade, portanto, o feedback de desenvolvedores de Web e navegadores é muito apreciado. Vamos saber quais recursos seriam ótimos para adicionar ou se há algo que você gostaria de modificar no API atual.
Você também pode informar problemas de especificação como bugs da implementação do Chrome.
Recursos
- Projetos de demonstração: https://intel.github.io/generic-sensor-demos/
- Especificação da API Generic Sensor: https://w3c.github.io/sensors/ (link em inglês)
- Problemas com a especificação: https://github.com/w3c/sensors/issues
- Lista de e-mails do grupo de trabalho do W3C: public-device-apis@w3.org
- Status do recurso do Chrome: https://www.chromestatus.com/feature/5698781827825664
- Bugs de implementação: http://crbug.com?q=component:Blink>Sensor
Agradecimentos
Este artigo foi revisado por Joe Medley e basco kayce. Imagem principal de Misko via Wikimedia Commons (link em inglês).