Web için sensörler

İvme ölçer, jiroskop ve manyetometre gibi cihaz üzerindeki sensörlere erişmek için Genel Sensör API'sini kullanın.

Alex Shalamov
Alex Shalamov
Mikhail Pozdnyakov
Mikhail Pozdnyakov

Günümüzde sensör verileri, sürükleyici oyun, fitness takibi ve artırılmış ya da sanal gerçeklik gibi kullanım alanlarını desteklemek için platforma özel birçok uygulamada kullanılmaktadır. Platforma özgü uygulamalarla web uygulamaları arasında bir köprü kurmak güzel olmaz mıydı? Web için Genel Sensör API'sini girin.

Genel Sensör API'si, sensör cihazlarını web platformuna gösteren bir arayüz grubudur. API, temel Sensor arayüzünden ve bunun üzerine inşa edilmiş bir dizi somut sensör sınıfından oluşur. Temel bir arayüze sahip olmak, beton sensör sınıfları için uygulama ve spesifikasyon sürecini basitleştirir. Örneğin, Gyroscope sınıfına göz atın. Çok küçük. Temel işlev, temel arayüzle belirtilir ve Gyroscope yalnızca açısal hızı temsil eden üç özellikle genişletilir.

Bazı sensör sınıfları, ivme ölçer veya jiroskop sınıfları gibi gerçek donanım sensörleriyle arayüz oluşturur. Bunlara düşük seviye sensörler denir. Füzyon sensörleri olarak adlandırılan diğer sensörler, komut dosyasının 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 bir dörde dört dönüş matrisi sağlar.

Web platformunun zaten sensör verisi sağladığını düşünebilirsiniz ve 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?

Mevcut arayüzlere kıyasla Generic Sensor API birçok avantaj sunar:

  • Genel Sensör API'si, 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 kullanılıp kullanılamadığını algılayabilirsiniz.
  • Sensör okumaları, yüksek hassasiyetli zaman damgaları içerir. 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. Bu sayede tarayıcı tedarikçileri birlikte çalışabilir çözümler uygulayabilir.
  • Genel sensör tabanlı arayüzler DOM'a bağlı değildir (yani navigator veya window nesnesi değildir). Bu, API'yi hizmet işçileri içinde kullanma veya yerleşik cihazlar gibi başlıksız JavaScript çalışma zamanlarında uygulama fırsatları sunar.
  • Güvenlik ve gizlilik, Genel Sensör API'si için en büyük önceliktir ve eski sensör API'lerine kıyasla çok daha iyi güvenlik sağlar. Permissions API ile entegrasyon vardır.
  • Accelerometer, Gyroscope, LinearAccelerationSensor, AbsoluteOrientationSensor, RelativeOrientationSensor ve Magnetometer modellerinde ekran koordinatlarıyla otomatik senkronizasyon kullanılabilir.

Kullanılabilir genel sensör API'leri

Bu makalenin yazıldığı sırada, deneyebilirsiniz birkaç sensör vardır.

Hareket sensörleri:

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

Ortam sensörleri:

  • AmbientLightSensor (Chromium'da #enable-generic-sensor-extra-classes işaretinin arkasında.)
  • Magnetometer (Chromium'daki #enable-generic-sensor-extra-classes işaretinin 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 arayüzü destekleyip desteklemediğini kolayca kontrol edebilirsiniz. (Accelerometer yerine yukarıda belirtilen diğer arayüzlerden 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 elde etmek için sensöre de bağlanmayı denemeniz gerekir. Bu örnekte bunun 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;
  }
}

Çoklu Dolgu

Genel Sensör API'sini desteklemeyen tarayıcılarda polyfill kullanılabilir. Polifill, yalnızca alakalı 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ş gerektirebilecek bir alandır. Sensörler hakkında bilginiz varsa doğrudan pratik kodlama bölümüne atlayabilirsiniz. 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 eylemsizlik sensörüdür. Yani cihaz doğrusal serbest düşüşteyken ölçülen toplam ivme 0 m/s2 olur. Cihaz bir masanın üzerinde düz bir şekilde yatarken yukarı yöndeki ivme (Z ekseni), masanın cihazı yukarı doğru iten kuvvetini ölçtüğü için Dünya'nın yer çekimine (g ≈ +9,8 m/s2) eşit olur. Cihazı sağa iterseniz X eksenindeki hızlanma pozitif, cihaz sağdan sola doğru hızlandırılıyorsa negatif olur.

İvme ölçerler adım sayma, hareket algılama veya basit cihaz yönü gibi işlemler için kullanılabilir. İvmeölçer ölçümleri, oryantasyon sensörleri gibi birleştirme sensörleri oluşturmak için genellikle diğer kaynaklardan alınan verilerle birleştirilir.

LinearAccelerationSensor, yer çekiminin katkısı hariç olmak üzere sensörü barındıran cihaza uygulanan ivmeyi ölçer. Bir cihaz hareketsizken, örneğin masa üzerinde düz bir şekilde durduğunda, sensör üç eksende ≈ 0 m/sn2 ivme ölçer.

Yerçekimi sensörü

Kullanıcıların Accelerometer ve LinearAccelerometer ölçümlerini manuel olarak inceleyerek yerçekimi sensörüne yakın ölçümler elde etmesi zaten mümkün olsa da bu işlem zahmetli olabilir ve bu sensörler tarafından sağlanan değerlerin doğruluğuna bağlıdır. Android gibi platformlar, işletim sisteminin bir parçası olarak yer çekimi ölçümleri sağlayabilir. Bu da hesaplama açısından daha ucuz olmalıdır, kullanıcının donanımına bağlı olarak daha doğru değerler sağlar ve API ergonomisi açısından kullanımı daha kolay olur. GravitySensor, yer çekimi nedeniyle cihazın X, Y ve Z eksenlerinde 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 olarak ölçer. Tüketici cihazlarının çoğunda, inertial Coriolis kuvvetine göre dönme hızını ölçen eylemsiz sensörler olan mekanik (MEMS) jiroskoplar bulunur. MEMS jiroskopları, sensörün yerçekimi hassasiyetinden kaynaklanan ve sensörün iç mekanik sistemini deforme eden yer çekimi hassasiyetinden kaynaklanan kaymaya açıktır. Jiroskoplar nispeten yüksek frekanslarda salınır (ör. 10 kHz'e kadar çalışabilir 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önüşünü Dünya'nın koordinat sistemine göre ölçen bir füzyon sensörüdür. RelativeOrientationSensor ise hareket sensörleri barındıran bir cihazın sabit bir referans koordinat sistemine göre dönüşünü gösteren veriler sağlar.

Tüm modern 3D JavaScript çerçeveleri, rotasyonu temsil etmek için kuaterniyonları ve döndürme matrislerini destekler. Ancak, doğrudan WebGL'yi kullanırsanız OrientationSensor, hem quaternion özelliğine hem de populateMatrix() yöntemine kolayca sahip olur. Birkaç snippet:

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önlendirme sensörleri, sürükleyici oyun, artırılmış ve sanal gerçeklik gibi çeşitli kullanım alanlarına olanak tanır.

Hareket sensörleri, gelişmiş kullanım alanları ve koşullar hakkında daha fazla bilgi edinmek için Hareket Sensörleri Açıklayıcı belgesine göz atın.

Ekran koordinatlarıyla senkronizasyon

Varsayılan olarak, uzamsal sensörlerin okumaları, cihaza bağlı olan ve ekran yönünü dikkate almayan yerel bir koordinat sisteminde çözülür.

Cihaz koordinat sistemi
Cihaz koordinat sistemi

Bununla birlikte, 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ı olan bir koordinat sisteminde yapılması gerekir.

Ekran koordinat sistemi
Ekran koordinat sistemi

Daha önce, sensör okumalarının ekran koordinatlarına yeniden eşlenmesi JavaScript'te uygulanmak zorundaydı. Bu yaklaşım verimsizdir ve web uygulaması kodunun karmaşıklığını önemli ölçüde artırır. Web uygulaması, ekran yönelimindeki değişiklikleri izlemeli ve sensör okumaları için koordinat dönüşümleri yapmalıdır. Bu, Öklid açıları veya dört boyutlu vektörler için yapılması kolay bir işlem değildir.

Genel Sensör API, çok daha basit ve güvenilir bir çözüm sunar. Yerel koordinat sistemi, tanımlanmış tüm uzamsal sensör sınıfları için yapılandırılabilir: Accelerometer, Gyroscope, LinearAccelerationSensor, AbsoluteOrientationSensor, RelativeOrientationSensor ve Magnetometer. Kullanıcı, referenceFrame seçeneğini sensör nesnesi oluşturucuya ileterek döndürülen ölçümlerin cihaz koordinatlarında mı yoksa ekran koordinatlarında mı çözüleceğ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' });

Kod yazalım.

Genel Sensör API'si çok basit ve kullanımı kolaydır. Sensör arayüzünde, sensör durumunu kontrol etmek için start() ve stop() yöntemleri ve sensör etkinleştirme, hatalar ve yeni kullanıma sunulan okumalar hakkında bildirim almak için çeşitli etkinlik işleyicileri bulunur. Somut sensör sınıfları genellikle kendi özel 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 sunucunuz için bağlantı noktası yönlendirmeyi kurduğunuzda harika bir başlangıç yapabilirsiniz.

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

3D model döndürme

Bu basit örnekte, bir 3D modelin dönme dörtlüsünü değiştirmek için mutlak yön sensöründen gelen verileri kullanıyoruz. model, three.js Object3D sınıf örneğidir ve quaternion özelliğine sahiptir. Yönlendirme telefonu demosundaki aşağıdaki kod snippet'i, mutlak yön sensörünün bir 3D modeli döndürmek için nasıl kullanılabileceğini gösterir.

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 rotasyonuna 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 hızlanma sensörünün, başlangıçta sabit durduğ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;
};

Geçerli hız, ivme fonksiyonunun integraline yaklaşım olarak hesaplanır.

Delik hızı ölçümü için demo web uygulaması
Delme hızı ölçümü

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

Bazı durumlarda, Genel Sensör API'yi kullanmak için fiziksel bir cihaza ihtiyacınız yoktur. Chrome DevTools, cihaz yönünü taklit etme için mükemmel destek sunar.

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

Gizlilik ve güvenlik

Sensör ölçümleri, kötü amaçlı web sayfalarından çeşitli saldırılara maruz kalabilen hassas verilerdir. Genel sensör API'lerinin uygulamaları, olası güvenlik ve gizlilik risklerini azaltmak için birkaç sınırlama uygular. API'yi kullanmayı düşünen geliştiriciler bu sınırlamaları dikkate almalıdır. Bu nedenle, bu sınırlamaları kısaca listeleyelim.

Yalnızca HTTPS

Genel Sensör API'si güçlü bir özellik olduğundan tarayıcı yalnızca güvenli bağlamlarda buna izin verir. Pratikte bu, Genel Sensör 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'nin etkin olması gerekir. En iyi uygulamalar ve yönergeler için Güvenli koleksiyonuna göz atın.

İzin Politikası entegrasyonu

Generic Sensor API'deki İzin Politikası entegrasyonu, bir karenin sensör verilerine erişimi kontrol eder.

Varsayılan olarak Sensor nesneleri yalnızca ana çerçeve veya aynı kaynaklı alt çerçevelerin içinde oluşturulabilir. Böylece, kaynaklar arası iframe'lerin sensör verilerini yaptırımsız bir şekilde okuması önlenir. 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'te, çapraz kaynak iframe'lere ivme ölçer verilerine erişim izni verilmekte, yani artık Accelerometer veya LinearAccelerationSensor nesnelerinin burada oluşturulabileceği gösterilmektedir.

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

Sensör ölçümlerinin teslimatı askıya alınabilir

Sensör ölçümlerine yalnızca görünür bir web sayfası tarafından (kullanıcı gerçekten etkileşim kurduğunda) erişilebilir. Ayrıca, kullanıcı odağı kaynaklar arası bir alt çerçeveye geçerse sensör verileri üst çerçeveye sağlanmaz. Bu sayede üst çerçeve, kullanıcı girişini tahmin edemez.

Sırada ne var?

Yakın gelecekte uygulanacak ortam ışığı sensörü veya yakınlık sensörü gibi önceden tanımlanmış bir dizi sensör sınıfı vardır. Ancak Genel Sensör çerçevesinin geniş 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 önemli bir diğer alan da Genel Sensör API'nin kendisidir. Genel Sensör spesifikasyonu şu anda aday öneri olarak kabul edilmektedir. Bu, düzeltmeler yapmak ve geliştiricilerin ihtiyaç duyduğu yeni işlevleri sunmak için hâlâ zaman olduğu anlamına gelir.

Siz de yardım edebilirsiniz.

Sensör özellikleri Önerilen Aday olgunluk düzeyine ulaştı. Bu nedenle, web ve tarayıcı geliştiricilerinden gelecek geri bildirimler çok değerlidir. Hangi özelliklerin eklenmesi gerektiğini veya geçerli API'de değiştirmek istediğiniz bir şeyler olup olmadığını bize bildirin.

Chrome uygulamasıyla ilgili özellik sorunlarını ve hataları bildirebilirsiniz.

Kaynaklar

Teşekkür ederiz

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