Web için sensörler

İvme ölçer, jiroskop ve manyetometre gibi cihaz üzerindeki sensörlere erişmek için Generic Sensor API'yi kullanın.

Alex Shalamov
Alex Shalamov
Mikhail Pozdnyakov
Mikhail Pozdnyakov

Günümüzde sensör verileri, platforma özel birçok uygulamada sürükleyici oyun, fitness takibi ve artırılmış veya sanal gerçeklik gibi kullanım alanlarını etkinleştirmek için kullanılır. Platforma özel uygulamalar ile web uygulamaları arasındaki boşluğu doldurmak harika olmaz mıydı? Web için Generic Sensor API'yi kullanıma sunuyoruz.

Generic Sensor API nedir?

Generic Sensor API, sensör cihazlarını web platformuna sunan bir arayüz grubudur. API, temel Sensor arayüzünden ve bunun üzerine oluşturulmuş bir dizi somut sensör sınıfından oluşur. Temel bir arayüz, somut sensör sınıfları için uygulama ve belirtme sürecini basitleştirir. Örneğin, Gyroscope sınıfına göz atın. Çok küçük! Temel işlevsellik, temel arayüz tarafından belirtilir ve Gyroscope, bunu yalnızca açısal hızı temsil eden üç özellikle genişletir.

Bazı sensör sınıfları, örneğin ivme ölçer veya jiroskop sınıfları gibi gerçek donanım sensörleriyle arayüz oluşturur. Bunlara düşük seviyeli sensörler denir. Birleştirme sensörleri olarak adlandırılan diğer sensörler, bir komut dosyasının aksi takdirde hesaplaması gereken bilgileri göstermek için çeşitli düşük seviyeli sensörlerden gelen verileri birleştirir. Örneğin, AbsoluteOrientation sensörü, ivme ölçer, jiroskop ve manyetometreden elde edilen verilere dayalı, kullanıma hazır dört çarpı dört boyutlu bir dönüş matrisi sağlar.

Web platformunun zaten sensör verileri sağladığını düşünüyor olabilirsiniz ve bu konuda kesinlikle haklısınız. Örneğin, DeviceMotion ve DeviceOrientation etkinlikleri, hareket sensörü verilerini gösterir. Peki neden yeni bir API'ye ihtiyacımız var?

Generic Sensor API, mevcut arayüzlere kıyasla çok sayıda avantaj sunar:

  • Generic Sensor API, yeni sensör sınıflarıyla kolayca genişletilebilen bir sensör çerçevesidir ve bu sınıfların her biri genel arayüzü korur. Bir sensör türü için yazılan istemci kodu, çok az değişiklikle başka bir sensör türü için yeniden kullanılabilir.
  • Sensörü yapılandırabilirsiniz. Örneğin, örnekleme sıklığını uygulama ihtiyaçlarınıza uygun şekilde ayarlayabilirsiniz.
  • Platformda bir sensörün olup olmadığını algılayabilirsiniz.
  • Sensör okumaları, yüksek hassasiyetli zaman damgalarına sahiptir. Bu sayede, uygulamanızdaki diğer etkinliklerle daha iyi senkronizasyon sağlanır.
  • Sensör veri modelleri ve koordinat sistemleri net bir şekilde tanımlanır. Böylece tarayıcı satıcıları birlikte çalışabilir çözümler uygulayabilir.
  • Genel sensöre dayalı arayüzler DOM'a bağlı değildir (yani navigator veya window nesneleri değildir). Bu da API'nin hizmet çalışanlarında kullanılabilmesi veya yerleştirilmiş cihazlar gibi başsız JavaScript çalışma zamanlarında uygulanabilmesi için gelecekte fırsatlar sunar.
  • Güvenlik ve gizlilik, Generic Sensor API'nin en önemli önceliğidir ve eski sensör API'lerine kıyasla çok daha iyi güvenlik sağlar. İzin API'si ile entegrasyon vardır.
  • Accelerometer, Gyroscope, LinearAccelerationSensor, AbsoluteOrientationSensor, RelativeOrientationSensor ve Magnetometer için ekran koordinatlarıyla otomatik senkronizasyon özelliği kullanılabilir.

Kullanılabilen genel sensör API'leri

Bu makalenin yazıldığı sırada, deneme yapabileceğiniz çeşitli sensörler bulunmaktadır.

Hareket sensörleri:

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

Çevre sensörleri:

  • AmbientLightSensor (Chromium'daki #enable-generic-sensor-extra-classes flag'inin arkasında)
  • Magnetometer (Chromium'daki #enable-generic-sensor-extra-classes flag'inin arkasında)

Özellik algılama

Donanım API'lerinin özellik algılaması zordur. Çünkü hem tarayıcının söz konusu arayüzü destekleyip desteklemediğini hem de cihazda ilgili sensörün olup olmadığını algılamanız gerekir. Tarayıcının bir arayüzü destekleyip desteklemediğini kontrol etmek kolaydır. (Accelerometer yerine yukarıda belirtilen diğer arayüzlerden herhangi birini kullanın.)

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

Gerçekten anlamlı bir özellik algılama sonucu için sensöre de bağlanmayı denemeniz gerekir. Bu örnekte, bu işlemin nasıl yapılacağı gösterilmektedir.

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

Generic Sensor API'yi desteklemeyen tarayıcılar için polyfill kullanılabilir. Polyfill, yalnızca ilgili sensör uygulamalarını yüklemenize olanak tanır.

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

Bu sensörler nelerdir? Bunları nasıl kullanabilirim?

Sensörler, kısa bir giriş yapılması gereken bir alandır. Sensörler hakkında bilginiz varsa doğrudan uygulamalı kodlama bölümüne geçebilirsiniz. Aksi takdirde, desteklenen her sensörü ayrıntılı olarak inceleyelim.

İvme ölçer ve doğrusal hızlanma sensörü

İvmeölçer sensör ölçümleri

Accelerometer sensörü, sensörü barındıran bir cihazın üç eksende (X, Y ve Z) ivmesini ölçer. Bu sensör bir atalet sensörüdür.Bu nedenle, cihaz doğrusal serbest düşme durumundayken ölçülen toplam ivme 0 m/s2 olur. Bir masanın üzerinde düz bir şekilde duran cihazda ise yukarı yöndeki (Z ekseni) ivme, Dünya'nın yer çekimine eşit olur.Yani, masanın cihazı yukarı itme kuvvetini ölçtüğü için g ≈ +9,8 m/s2 olur. Cihazı sağa iterseniz X eksenindeki ivme pozitif olur. Cihaz sağdan sola doğru hızlandırılırsa ivme negatif olur.

İvme ölçerler; adım sayma, hareket algılama veya basit cihaz yönlendirme gibi işlemler için kullanılabilir. Çok sık olmamakla birlikte, ivmeölçer ölçümleri, yön sensörleri gibi birleştirilmiş sensörler oluşturmak için diğer kaynaklardan alınan verilerle birleştirilir.

LinearAccelerationSensor, yer çekiminin katkısı hariç olmak üzere sensöre ev sahipliği yapan cihaza uygulanan ivmeyi ölçer. Bir cihaz dinlenirken (ör. masanın üzerinde düz bir şekilde dururken) sensör, üç eksende ≈ 0 m/sn2 ivme ölçer.

Yer çekimi sensörü

Kullanıcılar, Accelerometer ve LinearAccelerometer değerlerini manuel olarak inceleyerek yerçekimi sensörünün değerlerine yakın değerler elde edebilir. Ancak bu işlem zahmetli olabilir ve bu sensörlerin sağladığı değerlerin doğruluğuna bağlıdır. Android gibi platformlar, işletim sisteminin bir parçası olarak yer çekimi okumaları sağlayabilir. Bu okumalar, hesaplama açısından daha ucuz olmalı, kullanıcının donanımına bağlı olarak daha doğru değerler sağlamalı ve API ergonomisi açısından daha kolay kullanılmalıdır. GravitySensor, yer çekimi nedeniyle cihazın X, Y ve Z eksenleri boyunca ivmenin etkisini döndürür.

Jiroskop

Jiroskop sensörü ölçümleri

Gyroscope sensörü, cihazın yerel X, Y ve Z eksenleri etrafındaki açısal hızı saniyede radyan cinsinden ölçer. Çoğu tüketici cihazında, ataletsel Coriolis kuvvetine dayalı olarak dönüş hızını ölçen ataletsel sensörler olan mekanik (MEMS) jiroskoplar bulunur. MEMS jiroskoplar, sensörün yerçekimi hassasiyetinden kaynaklanan kaymaya eğilimlidir. Bu durum, sensörün iç mekanik sistemini deforme eder. Jiroskoplar nispeten yüksek frekanslarda salınır. Örneğin, 10 kHz'dir ve bu nedenle diğer sensörlere kıyasla daha fazla güç tüketebilir.

Yön sensörleri

Mutlak yön sensörü ölçümleri

AbsoluteOrientationSensor, bir cihazın Dünya'nın koordinat sistemine göre dönüşünü ölçen bir füzyon sensörüdür. RelativeOrientationSensor ise hareket sensörlerine sahip bir cihazın sabit bir referans koordinat sistemine göre dönüşünü temsil eden veriler sağlar.

Tüm modern 3B JavaScript çerçeveleri, döndürmeyi temsil etmek için kuaterniyonları ve döndürme matrislerini destekler. Ancak WebGL'yi doğrudan kullanıyorsanız OrientationSensor, hem quaternion özelliğine hem de populateMatrix() yöntemine sahiptir. Aşağıda birkaç snippet verilmiştir:

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

Yön sensörleri, sürükleyici oyun deneyimi, artırılmış gerçeklik ve sanal gerçeklik gibi çeşitli kullanım alanlarına olanak tanır.

Hareket sensörleri, gelişmiş kullanım alanları ve gereksinimler hakkında daha fazla bilgi için hareket sensörleri açıklama belgesine göz atın.

Ekran koordinatlarıyla senkronizasyon

Uzamsal sensörlerin okumaları varsayılan olarak cihaza bağlı olan ve ekran yönünü dikkate almayan yerel bir koordinat sisteminde çözümlenir.

Cihaz koordinat sistemi
Cihaz koordinat sistemi

Ancak oyunlar veya artırılmış ve sanal gerçeklik gibi birçok kullanım alanında, sensör okumalarının ekran yönüne bağlı bir koordinat sisteminde çözümlenmesi gerekir.

Ekran koordinat sistemi
Ekran koordinat sistemi

Daha önce, sensör okumalarının ekran koordinatlarıyla yeniden eşlenmesi JavaScript'te uygulanmak zorundaydı. Bu yaklaşım verimsizdir ve web uygulaması kodunun karmaşıklığını da önemli ölçüde artırır. Web uygulaması, ekran yönü değişikliklerini izlemeli ve sensör okumaları için koordinat dönüşümleri gerçekleştirmelidir. Bu, Euler açıları veya kuaterniyonlar için kolay bir işlem değildir.

Generic Sensor API, çok daha basit ve güvenilir bir çözüm sunar. Yerel koordinat sistemi, tanımlanan tüm uzamsal sensör sınıfları (Accelerometer, Gyroscope, LinearAccelerationSensor, AbsoluteOrientationSensor, RelativeOrientationSensor ve Magnetometer) için yapılandırılabilir. Kullanıcı, referenceFrame seçeneğini sensör nesnesi oluşturucusuna ileterek döndürülen okumaların cihaz veya ekran koordinatlarında çözümlenip çözümlenmeyeceğini tanımlar.

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

Haydi kodlayalım!

Generic Sensor API çok basit ve kullanımı kolaydır. Sensör arayüzünde, sensör durumunu kontrol etmek için start() ve stop() yöntemleri, sensör etkinleştirme, hatalar ve yeni kullanılabilir okumalar hakkında bildirim almak için de çeşitli olay işleyiciler bulunur. Somut sensör sınıfları genellikle kendi okuma özelliklerini temel sınıfa ekler.

Geliştirme ortamı

Geliştirme sırasında localhost üzerinden sensörleri kullanabilirsiniz. Mobil cihazlar için geliştirme yapıyorsanız yerel sunucunuzda bağlantı noktası yönlendirmeyi ayarlayın. Artık geliştirme yapmaya hazırsınız.

Kodunuz hazır olduğunda HTTPS'yi destekleyen bir sunucuya dağıtın. GitHub Pages, HTTPS üzerinden sunulduğu için demolarınızı paylaşmak için harika bir yerdir.

3D model döndürme

Bu basit örnekte, 3D modelin dönüş kuaterniyonunu değiştirmek için mutlak yön sensöründen gelen verileri kullanıyoruz. model, quaternion özelliği olan bir three.js Object3D sınıf örneğidir. orientation phone demosundaki aşağıdaki kod snippet'inde, mutlak yön sensörünün 3D modeli döndürmek için nasıl kullanılabileceği gösterilmektedir.

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

Cihazın yönü, WebGL sahnesindeki 3D model döndürme işlemine yansıtılır.

Sensör, 3D modelin yönünü günceller
Sensör, 3D modelin yönünü günceller

Punchmeter

Aşağıdaki kod snippet'i, punchmeter demosundan alınmıştır. Bu snippet'te, doğrusal ivme sensörünün başlangıçta hareketsiz olduğu varsayılan bir cihazın maksimum hızını hesaplamak için nasıl kullanılabileceği gösterilmektedir.

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

Mevcut hız, ivme fonksiyonunun integralinin yaklaşık değeri olarak hesaplanır.

Yumruk hızı ölçümü için demo web uygulaması
Yumruk hızının ölçülmesi

Chrome Geliştirici Araçları ile hata ayıklama ve sensör geçersiz kılma

Bazı durumlarda, Generic Sensor API ile oynamak için fiziksel bir cihaza ihtiyacınız yoktur. Chrome Geliştirici Araçları, cihaz yönünü simüle etme konusunda mükemmel destek sunar.

Sanal telefonun özel yönlendirme verilerini geçersiz kılmak için kullanılan Chrome Geliştirici Araçları
Chrome Geliştirici Araçları ile cihaz yönünü simüle etme

Gizlilik ve güvenlik

Sensör okumaları, kötü amaçlı web sayfalarının çeşitli saldırılarına maruz kalabilecek hassas verilerdir. Genel Sensör API'lerinin uygulamaları, olası güvenlik ve gizlilik risklerini azaltmak için birkaç sınırlama uygular. API'yi kullanmak isteyen geliştiricilerin bu sınırlamaları dikkate alması gerekir. Bu nedenle, sınırlamaları kısaca listeleyelim.

Yalnızca HTTPS

Generic Sensor API güçlü bir özellik olduğundan tarayıcı yalnızca güvenli bağlamlarda kullanılmasına izin verir. Bu, pratikte Generic Sensor API'yi kullanmak için sayfanıza HTTPS üzerinden erişmeniz gerektiği anlamına gelir. Geliştirme sırasında bunu http://localhost üzerinden yapabilirsiniz ancak üretim için sunucunuzda HTTPS olması gerekir. En iyi uygulamalar ve yönergeler için Güvenli ve güvenli koleksiyonuna göz atın.

İzin politikası entegrasyonu

Generic Sensor API'deki izin politikası entegrasyonu, bir çerçeve için sensör verilerine erişimi kontrol eder.

Varsayılan olarak Sensor nesneleri yalnızca ana çerçeve veya aynı kaynaklı alt çerçeveler içinde oluşturulabilir. Bu sayede, kaynaklar arası iFrame'lerin sensör verilerini yetkisiz bir şekilde okuması engellenir. Bu varsayılan davranış, ilgili politika kontrollü özelliklerin açıkça etkinleştirilmesi veya devre dışı bırakılmasıyla değiştirilebilir.

Aşağıdaki snippet, kaynaklar arası bir iFrame'e ivmeölçer verilerine erişim izni verilmesini gösterir. Bu, artık orada Accelerometer veya LinearAccelerationSensor nesnelerinin oluşturulabileceği anlamına gelir.

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

Sensör okumalarının iletilmesi askıya alınabilir

Sensör okumalarına yalnızca görünür bir web sayfası üzerinden erişilebilir. Yani, kullanıcı sayfayla etkileşimde bulunurken erişilebilir. Ayrıca, kullanıcı odağı kaynaklar arası bir alt çerçeveye değişirse sensör verileri üst çerçeveye sağlanmaz. Bu, üst çerçevenin kullanıcı girişini tahmin etmesini engeller.

Sırada ne var?

Yakın gelecekte uygulanacak, önceden belirtilmiş bir dizi sensör sınıfı vardır. Örneğin, ortam ışığı sensörü veya yakınlık sensörü. Ancak, Generic Sensor Framework'ün büyük ölçekli genişletilebilirliği sayesinde, çeşitli sensör türlerini temsil eden daha da fazla yeni sınıfın ortaya çıkmasını bekleyebiliriz.

Gelecekteki çalışmalar için bir diğer önemli alan, Generic Sensor API'nin kendisini iyileştirmektir. Generic Sensor spesifikasyonu şu anda Aday Öneri durumundadır. Bu da düzeltmeler yapmak ve geliştiricilerin ihtiyaç duyduğu yeni işlevleri eklemek için hâlâ zaman olduğu anlamına gelir.

Yardım edebilirsiniz.

Sensör spesifikasyonları Aday Önerisi olgunluk düzeyine ulaştı. Bu nedenle, web ve tarayıcı geliştiricilerden gelen geri bildirimler çok değerlidir. Eklenmesi gereken harika özellikler veya mevcut API'de değiştirmek istediğiniz bir şey varsa bize bildirin.

Lütfen Chrome uygulamasıyla ilgili spesifikasyon sorunlarını ve hataları bildirin.

Kaynaklar

Teşekkür

Bu makale Joe Medley ve Kayce Basques tarafından incelenmiştir.