Czujniki internetu

Interfejs Generative Sensor API pozwala uzyskać dostęp do czujników urządzenia, takich jak akcelerometry, żyroskopy i magnetometry.

Alex Shalamov
Alex Shalamov
Mikhail Pozdnyakov
Mikhail Pozdnyakov

Obecnie dane z czujników są wykorzystywane w wielu aplikacjach działających na konkretnych platformach, na przykład wciągające gry, śledzenie aktywności fizycznej oraz rzeczywistość rozszerzoną lub wirtualną. Czy nie byłoby wspaniale przejść przez most między aplikacjami zależnymi od platformy a aplikacjami internetowymi? Wpisz wartość Ogólny Sensor API do użytku w internecie.

Czym jest interfejs Generative Sensor API?

Ogólny Sensor API to zestaw interfejsów, które udostępniają czujniki do platformy internetowej. Interfejs API składa się z elementów Interfejs Sensor i zestaw konkretnych i klasy czujników. Posiadanie podstawowego interfejsu upraszcza implementację i specyfikację dla konkretnych klas czujników. Spójrz na przykład na Gyroscope. Jest bardzo malutki! główna funkcjonalność jest określana przez interfejs podstawowy, a Gyroscope rozszerza ją o trzy atrybutów reprezentujących prędkość kątową.

Niektóre klasy czujników łączą się z rzeczywistymi czujnikami sprzętowymi, takimi jak akcelerometr lub lekcji żyroskopu. Są to tzw. czujniki niskopoziomowe. Inne czujniki, nazywane też czujniki Fusion, scalają dane z kilku źródeł niskiego poziomu. do ujawniania informacji, które skrypt musiałby inaczej obliczać. Na przykład parametr Czujnik AbsoluteOrientation zapewnia gotową do użycia macierz obrotu w zakresie 4:4, opartą na danych uzyskanych akcelerometr, żyroskop i magnetometr.

Może Ci się wydawać, że platforma internetowa już dostarcza dane z czujników, a masz absolutną rację. Dla: instancja DeviceMotion oraz DeviceOrientation zdarzeń ujawniają dane z czujnika ruchu. Dlaczego potrzebujemy nowego interfejsu API?

W porównaniu z dotychczasowymi interfejsami interfejs Generative Sensor API ma wiele zalet:

  • Interfejs General Sensor API to platforma czujników, którą można łatwo rozszerzyć za pomocą nowych klas czujników i każda z nich zachowa ogólny interfejs. Kod klienta zapisany dla jednego typu czujnika Można je ponownie wykorzystać w innym, w niewielkich ilościach!
  • Możesz skonfigurować czujnik. Możesz np. ustawić częstotliwość próbkowania do aplikacji.
  • Możesz sprawdzić, czy na platformie jest dostępny czujnik.
  • Odczyty z czujników mają bardzo precyzyjne sygnatury czasowe, co umożliwia lepszą synchronizację z innymi aktywności w aplikacji.
  • Modele danych czujników i układy współrzędnych są jasno zdefiniowane, dzięki czemu dostawcy przeglądarek mogą wdrażania rozwiązań interoperacyjnych.
  • Interfejsy oparte na czujnikach ogólnych nie są powiązane z DOM (co oznacza, że nie są navigator ani obiektów window), co otwiera możliwości korzystania z interfejsu API w usłudze w przyszłości. lub implementować w środowiskach wykonawczych JavaScript bez interfejsu graficznego, takich jak urządzenia.
  • Aspekty bezpieczeństwa i prywatności mają najwyższy priorytet. API i zapewniają znacznie lepsze zabezpieczenia w porównaniu ze starszymi interfejsami API czujników. Integracja z usługą przy użyciu interfejsu Permissions API.
  • Automatyczna synchronizacja ze współrzędnymi ekranu jest dostępny w okresach: Accelerometer, Gyroscope, LinearAccelerationSensor, AbsoluteOrientationSensor, RelativeOrientationSensor i Magnetometer.

Dostępne ogólne interfejsy API czujników

W momencie pisania masz kilka czujników, z którymi możesz poeksperymentować.

Czujniki ruchu:

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

Czujniki środowiskowe:

  • AmbientLightSensor (za flagą #enable-generic-sensor-extra-classes w Chromium).
  • Magnetometer (za flagą #enable-generic-sensor-extra-classes w Chromium).

Wykrywanie cech

Wykrywanie cech sprzętowych interfejsów API jest trudne, ponieważ trzeba określić, czy przeglądarka obsługuje dany interfejs, oraz czy urządzenie ma odpowiedni czujnik. Konto rozliczeniowe czy przeglądarka obsługuje odpowiedni interfejs. (Zastąp Accelerometer dowolnym z tych elementów innych interfejsów wymienionych powyżej).

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

Aby wykryć właściwy wynik, musisz też spróbować połączyć się z czujnikiem. Ten przykład pokazuje, jak to zrobić.

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

Watolina

W przypadku przeglądarek, które nie obsługują interfejsu Generative Sensor API, parametr polyfill jest dostępny. Polyfill umożliwia uwzględniaj tylko odpowiednie czujniki implementacji.

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

Co to za wszystkie te czujniki? Jak mogę z nich korzystać?

Czujniki to zagadnienie, o którym warto wspomnieć. Jeśli potrafisz obsługiwać czujniki, przejdź od razu do sekcji praktycznego kodowania. Przyjrzyjmy się teraz każdemu z nich z czujnika.

Akcelerometr i czujnik przyspieszenia liniowego

Pomiary z czujników akcelerometru
.

Czujnik Accelerometer mierzy przyspieszenie urządzenia hostującego czujnik na 3 osiach (X, Y i Z). Ten czujnik jest czujnika bezwładnego, co oznacza, że gdy urządzenie znajduje się w liniowym swobodnym spadaniu, całkowita liczba przyspieszenie wyniesie 0 m/s2, a gdy urządzenie leży płasko na stole, przyspieszenie w kierunku do góry (oś Z) będzie równa grawitacji Ziemi, tj. g ≈ +9,8 m/s2 Wskazuje on siłę, na jaką stół pcha urządzenie w górę. Jeśli umieścisz urządzenie w do prawej, przyspieszenie na osi X będzie dodatnie lub ujemne, jeśli przyspieszenie w prawo, w lewo.

Akcelerometr może służyć np. do liczenia kroków, wykrywania ruchu lub prostych urządzeń. orientacji ekranu. Pomiary z akcelerometru są często łączone z danymi z innych źródeł, czujniki Fusion, takie jak czujniki orientacji.

LinearAccelerationSensor mierzy przyspieszenie, które jest stosowane do urządzenia hostującego czujnik, z wyłączeniem danych grawitacji. Gdy urządzenie jest w spoczynku, np. leży płasko na stole, czujnik mierzy Przyspieszenie 0 m/s2 na 3 osiach.

Czujnik grawitacji

Użytkownicy mogą już ręcznie uzyskiwać odczyty zbliżone do odczytów z czujnika grawitacji, ręcznie sprawdzam odczyty Accelerometer i LinearAccelerometer, ale może to być uciążliwe i zależą od dokładności wartości dostarczanych przez te czujniki. Takie platformy jak Android udostępniają odczyty grawitacji w ramach systemu operacyjnego, co powinno być tańsze pod względem pozwala na generowanie dokładniejszych wartości w zależności od sprzętu użytkownika i łatwiejsze korzystanie pod kątem ergonomii interfejsów API. GravitySensor zwraca efekt. przyspieszenia wzdłuż osi X, Y i Z urządzenia z powodu grawitacji.

Żyroskop

Pomiary z czujników żyroskopowych
.

Czujnik Gyroscope mierzy prędkość kątowa w radianach na sekundę wokół lokalnej osi X, Y i Z urządzenia. Większość konsumentów urządzenia są wyposażone w mechanizm (MEMS) żyroskopy, które są czujnikami bezwładnymi mierzącymi prędkość obrotu na podstawie siły wewnętrznej Coriolisa. Żyroskopy MEMS są podatne na ataki. które jest spowodowane czułością grawitacyjną czujnika, która odkształca wewnętrznego systemu mechanicznego. Żyroskopy oscylują z względnie wysokimi częstotliwościami, np. 10 s kHz oraz dlatego może zużywać więcej energii w porównaniu z innymi czujnikami.

Czujniki orientacji

Pomiary z czujników orientacji bezwzględnej
.

AbsoluteOrientationSensor to czujnik fuzji, który mierzy obrót urządzenia w odniesieniu do układu współrzędnych Ziemi, podczas gdy RelativeOrientationSensor dostarcza dane przedstawiające obrót urządzenia z czujnikami ruchu w odniesieniu do miejsca nieruchomego wsadowy układ współrzędnych.

Wszystkie nowoczesne platformy JavaScript 3D obsługują kwantyny i macierze obrotu reprezentujące rotację; ale przy bezpośrednim korzystaniu z WebGL, OrientationSensor ma wygodne i dobrze Usługa quaternion i populateMatrix(). Oto kilka fragmentów:

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

Czujniki orientacji umożliwiają różne zastosowania, np. wciągające gry, rozszerzone i wirtualne. rzeczywistości.

Więcej informacji o czujnikach ruchu, zaawansowanych przypadkach użycia i wymaganiach znajdziesz w wyjaśnienie dotyczącym czujników ruchu.

Synchronizacja ze współrzędnymi ekranu

Domyślnie odczyty z czujników przestrzennych są rozpoznawane. w lokalnym układzie współrzędnych, który jest powiązany z urządzeniem i nie uwzględnia orientacji ekranu koncie.

Układ współrzędnych urządzenia
Układ współrzędnych urządzenia

Jednak w wielu przypadkach użycia, takich jak gry czy rzeczywistość rozszerzona i wirtualna, odczyty z czujników muszą być w układzie współrzędnych, który jest powiązany z orientacją ekranu.

Układ współrzędnych ekranu
Układ współrzędnych ekranu

Wcześniej mapowanie odczytów z czujników do współrzędnych ekranu trzeba było wdrażać w JavaScripcie. Takie podejście jest nieskuteczne i znacznie zwiększa złożoność sieci kod aplikacji; aplikacja internetowa musi obserwować zmiany orientacji ekranu i wykonywać współrzędne przekształcenia odczytów czujników, co nie jest banalne dla kątów Eulera ani kterniny.

Interfejs General Sensor API zapewnia znacznie prostsze i niezawodne rozwiązanie. Lokalny układ współrzędnych to konfigurowalny dla wszystkich zdefiniowanych klas czujnika przestrzennego: Accelerometer, Gyroscope, LinearAccelerationSensor, AbsoluteOrientationSensor, RelativeOrientationSensor i Magnetometer. Przekazując opcję referenceFrame do konstruktora obiektów czujnika, użytkownik określa, czy zwrócone odczyty zostaną rozwiązane w device lub Współrzędne ekranu.

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

Kodujmy!

Interfejs Generative Sensor API jest bardzo prosty i łatwy w użyciu. Interfejs czujnika start() i Metody stop() do kontrolowania stanu czujnika oraz kilku moduły obsługi zdarzeń do otrzymywania powiadomień o aktywowaniu czujników, błędach i nowo dostępnych odczyty. Klasy betonowych czujników dodają do podstawy zazwyczaj swoje określone atrybuty odczytu zajęcia.

Środowisko programistyczne

Podczas programowania będzie można używać czujników w programie localhost. Jeśli tworzysz aplikacje z myślą o urządzenia mobilne, konfiguracja przekierowanie portów dla lokalnego serwera.

Gdy kod będzie gotowy, wdróż go na serwerze obsługującym HTTPS. Strony GitHub są wyświetlane przez HTTPS, dzięki czemu warto je udostępniać w Twoich wersjach demonstracyjnych.

Obrót modelu 3D

W tym prostym przykładzie używamy danych z czujnika orientacji bezwzględnej, aby zmodyfikować obrót kwartion modelu 3D. model to tryl.js instancję klasy Object3D, która ma usłudze quaternion. ten fragment kodu z telefon w orientacji poziomej ilustruje sposób użycia czujnika orientacji bezwzględnej do obracania modelu 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();
}

Orientacja urządzenia zostanie odzwierciedlona w 3D model w scenie WebGL.

Czujnik aktualizuje orientację modelu 3D
Czujnik aktualizuje orientację modelu 3D

Pięść do miernika

Następujący fragment kodu jest wyodrębniony z pliku prezentacja Punchmeter, przedstawia sposób użycia czujnika przyspieszenia liniowego do obliczania maksymalnej prędkości przy założeniu, że początkowo leży nieruchomo.

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

Prędkość bieżąca jest obliczana w przybliżeniu do całki z funkcji przyspieszania.

Wersja demonstracyjna aplikacji internetowej do pomiaru szybkości przebijania
Pomiar prędkości uderzenia

Debugowanie i zastępowanie czujników w Narzędziach deweloperskich w Chrome

W niektórych przypadkach do korzystania z interfejsu General Sensor API nie potrzebujesz fizycznego urządzenia. Narzędzia deweloperskie w Chrome ma świetne poparcie symulowanie orientacji urządzenia.

Narzędzia deweloperskie w Chrome służące do zastępowania danych dotyczących niestandardowej orientacji telefonu wirtualnego
Symulowanie orientacji urządzenia za pomocą Narzędzi deweloperskich w Chrome

Prywatność i bezpieczeństwo

Odczyty z czujników to dane wrażliwe, które mogą być celem różnych ataków ze złośliwych stron internetowych. Implementacje interfejsów Generative Sensor API wymuszają kilka ograniczeń, aby zniwelować możliwe bezpieczeństwo i zagrożeniami dla prywatności. Deweloperzy, którzy zamierzają korzystać z API, więc omówimy je pokrótce.

Tylko HTTPS

Interfejs Generative Sensor API jest zaawansowanymi funkcjami, więc przeglądarka zezwala na niego tylko w bezpiecznych kontekstach. W oznacza to, że aby korzystać z interfejsu Generative Sensor API, musisz uzyskiwać dostęp do strony przez HTTPS. W trakcie programowania możesz to zrobić przez http://localhost, ale w wersji produkcyjnej niezbędny jest protokół HTTPS na Twoim serwerze. Sprawdzone metody znajdziesz w kolekcji Bezpieczeństwo i ochrona. i wytycznych.

Integracja z zasadami dotyczącymi uprawnień

Integracja z zasadami dotyczącymi uprawnień w sekcji Ogólna Interfejs Sensor API kontroluje dostęp do danych z czujników klatki.

Domyślnie obiekty Sensor można tworzyć tylko w ramce głównej lub ramkach podrzędnych z tej samej domeny. w ten sposób zapobiega nieupoważnionemu odczytowi danych z czujników w elementach iframe z innych domen. To działanie domyślne można zmodyfikować, włączając lub wyłączając odpowiednie funkcjach kontrolowanych przez zasady.

Fragment kodu poniżej pokazuje przyznawanie dostępu do danych z akcelerometru do elementu iframe z innej domeny, co oznacza, że że teraz można w niej tworzyć obiekty Accelerometer lub LinearAccelerationSensor.

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

Dostarczanie odczytów z czujników można zawiesić

Odczyty z czujników są dostępne tylko dla widocznej strony internetowej, tj. gdy użytkownik wchodzenia z nią w interakcję. Ponadto dane z czujnika nie będą przekazywane do ramki nadrzędnej, jeśli użytkownik i zaznacz zmiany na ramce podrzędnej z innej domeny. Zapobiega to wnioskowaniu o dane wejściowe użytkownika przez ramkę nadrzędną.

Co dalej?

W najbliższej przyszłości zostanie wdrożony zestaw określonych klas czujnika, takich jak Czujnik jasności otoczenia lub Czujnik zbliżeniowy jednak dzięki uniwersalności możemy przewidzieć pojawienie się jeszcze większej liczby nowych klas reprezentujących różne typu czujnika.

W przyszłości warto też udoskonalać interfejs Generative Sensor API, Specyfikacja czujnika jest obecnie rekomendowaną rekomendacją, co oznacza, że jest jeszcze mniej czasu aby wprowadzić poprawki i udostępnić nowe funkcje, których potrzebują programiści.

Możesz pomóc.

Specyfikacja czujnika Rekomendacja kandydatów dojrzałości cyfrowej, dlatego opinie programistów internetu i przeglądarek są dla nas bardzo ważne. Pozwól nam wiesz, które funkcje warto dodać, lub czy jest coś, co chcesz zmodyfikować w obecnego interfejsu API.

Możesz też zgłaszać problemy ze specyfikacją. jako błędy w implementacji Chrome.

Zasoby

Podziękowania

Ten artykuł został zrecenzowany przez Joe Medley i Kayce Basques Baner powitalny: Misko przez Wikimedia Commons