ウェブ用センサー

Generic Sensor API を使用して、加速度計、ジャイロスコープ、磁力計などのデバイス上のセンサーにアクセスします。

現在、センサーデータは多くのプラットフォーム固有のアプリケーションで使用され、臨場感のあるゲーム、フィットネス トラッキング、拡張現実や仮想現実などのユースケースを実現しています。橋渡しをするのは面白くないでしょう。 プラットフォーム固有のアプリケーションとウェブ アプリケーションのギャップウェブ向けの Generic Sensor API をご紹介します。

Generic Sensor API とは

Generic Sensor API は、センサー デバイスをウェブ プラットフォームに公開する一連のインターフェースです。この API は、基盤となる Sensor インターフェースと、 センサークラスです。ベース インターフェースを使用することで実装と仕様を簡素化できる プロセスをご覧ください。たとえば、Gyroscope クラスをご覧ください。とても小さいです。コア機能はベース インターフェースで指定され、Gyroscope は角速度を表す 3 つの属性で拡張するだけです。

一部のセンサークラスは、実際のハードウェア センサー(加速度計や ジャイロスコープクラスですこれらは低レベル センサーと呼ばれます。他のセンサーは 融合センサー、複数の低レベルのデータを統合する センサーを使用して、スクリプトが計算する必要のある情報をエクスポーズします。たとえば、 AbsoluteOrientation センサー モデルは、モデルから取得したデータに基づいて、すぐに使える 4 行 4 列の回転行列を 加速度計、ジャイロスコープ、磁力計です。

ウェブ プラットフォームですでにセンサーデータが提供されていると思われるかもしれませんが、そのとおりです。たとえば、DeviceMotion イベントと DeviceOrientation イベントはモーション センサー データを公開します。では、新しい API が必要な理由は何でしょうか。

既存のインターフェースと比較すると、Generic Sensor API には次のような多くの利点があります。

  • Generic Sensor API は、新しいセンサークラスで簡単に拡張できるセンサー フレームワークです。これらのクラスはそれぞれ汎用インターフェースを保持します。1 つのセンサータイプ用に記述されたクライアント コードは、ほとんど変更せずに別のセンサータイプで再利用できます。
  • センサーを構成できます。たとえば、環境に適したサンプリング頻度を 対応できます。
  • プラットフォームでセンサーが使用可能かどうかを検出できます。
  • センサー測定値には高精度のタイムスタンプが付加されているため、アプリ内の他のアクティビティとの同期がより正確になります。
  • センサーのデータモデルと座標系が明確に定義されているため、ブラウザ ベンダーは 相互運用性のあるソリューションの実装です。
  • 汎用センサーベースのインターフェースは DOM にバインドされていない(つまり、navigator でもない) window オブジェクトも)保存されるため、今後サービス内で API を使用する機会が またはヘッドレス JavaScript ランタイム(埋め込みなど)に実装するか、 できます。
  • セキュリティとプライバシーは、汎用センサー API の最優先事項であり、以前のセンサー API と比較してセキュリティが大幅に強化されています。Permissions API との統合があります。
  • 画面座標との自動同期は、AccelerometerGyroscopeLinearAccelerationSensorAbsoluteOrientationSensorRelativeOrientationSensorMagnetometer で使用できます。

使用可能な汎用センサー API

本書の執筆時点では、試せるセンサーがいくつかあります。

モーション センサー:

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

環境センサー:

  • AmbientLightSensor(Chromium の #enable-generic-sensor-extra-classes フラグの背後にある)
  • Magnetometer(Chromium の #enable-generic-sensor-extra-classes フラグの背後にある)

特徴検出

ハードウェア API の機能検出は、ブラウザが該当するインターフェースをサポートしているかどうかと、デバイスに対応するセンサーが搭載されているかどうかの両方を検出する必要があるため、難しい作業です。ブラウザがインターフェースをサポートしているかどうかを確認するのは簡単です。(Accelerometer は次のいずれかに置き換えます) 上記のその他のインターフェース。)

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

実際に有意な特徴検出結果を得るには、センサーへの接続も試みる必要があります。この例は、その方法を示しています。

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

ポリフィル

Generic Sensor API をサポートしていないブラウザの場合は、ポリフィルを使用できます。ポリフィルを使うと 関連するセンサーのみをあります。

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

これらすべてのセンサーとは何ですか?使用方法

センサーは、簡単に説明する必要がある分野です。センサーに精通している場合は、実践的なコーディング セクションに直接進んでください。サポートされている各センサーについて詳しく見てみましょう。

加速度計と直線加速度センサー

加速度計センサーの測定

Accelerometer センサー は、センサーをホストするデバイスの加速度を 3 軸(X、Y、Z)で測定します。このセンサーは 慣性センサーです。つまり、デバイスが直線的自由落下にあるときに、 加速度は 0 m/s2 で、テーブルの上にデバイスを平らに置いたときの加速度は 上向き(Z 軸)は地球の重力に等しくなります。すなわち g 約 +9.8 m/s2 テーブルを上方に押す力を測定します。デバイスを 右から、X 軸の加速度は正になります。 作成します。

加速度計は歩数計測、モーション検知、シンプルなデバイスなどに使用可能 方向です。多くの場合、加速度計の測定値は他のソースのデータと組み合わせて、向きセンサーなどの融合センサーを作成します。

LinearAccelerationSensor センサーをホストしているデバイスに加えられる加速度を測定します。 重力ですテーブルの上に平らに置いてあるなど、デバイスが静止しているとき、センサーは 3 軸で約 0 m/s2 の加速度。

重力センサー

ユーザーは、AccelerometerLinearAccelerometer の測定値を手動で検査することで、重力センサーの測定値に近い測定値を手動で導出できますが、これは手間がかかり、これらのセンサーから提供される値の精度に依存します。Android などのプラットフォームでは、 重力測定値を提供するオペレーティング システムなので、 計算、ユーザーのハードウェアに応じたより正確な値の提供、 API エルゴノミクスについて学びました。「 GravitySensor は効果を返します。 重力によるデバイスの X、Y、Z 軸に沿った加速度。

ジャイロスコープ

ジャイロスコープ センサーの測定

Gyroscope センサーは、デバイスのローカル X、Y、Z 軸周りの角速度をラジアン / 秒単位で測定します。ほとんどの消費者 機械(MEMS)を持つデバイス ジャイロスコープは、さまざまなセンサーに起因して 慣性コリオリ力。MEMS ジャイロスコープは、センサーの重力感度によってセンサーの内部機械システムが変形し、ドリフトが発生しやすくなります。ジャイロスコープは、10 kHz に達することがあります。そのため、他のセンサーと比較して電力を消費する可能性があります。

方向センサー

絶対方向センサーの測定

AbsoluteOrientationSensor 地球の座標系を基準としてデバイスの回転を測定するフュージョン センサーです。 一方、 RelativeOrientationSensor モーション センサーをホストしているデバイスの静止状態からの回転を表すデータを提供します。 参照座標系です。

最新の 3D JavaScript フレームワークはすべて、回転を表す四元数回転行列をサポートしています。ただし、WebGL を直接使用する場合、OrientationSensor にはquaternion プロパティpopulateMatrix() メソッドの両方が用意されています。スニペットは次のとおりです。

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

向きセンサーは、没入型ゲーム、拡張現実、仮想現実などのさまざまなユースケースを可能にします。

モーション センサー、高度なユースケース、要件について詳しくは、 モーション センサーの説明 ドキュメント。

画面座標との同期

デフォルトでは、空間センサーの測定値は デバイスにバインドされ、画面の向きを考慮しないローカル座標系です。 あります。

デバイスの座標系
デバイスの座標系

ただし、ゲームや拡張現実、仮想現実などの多くのユースケースでは、画面の向きにバインドされた座標系でセンサーの読み取りを解決する必要があります。

画面座標系
画面座標系

これまで、センサー測定値を画面座標に再マッピングするには、JavaScript で実装する必要がありました。 この方法は非効率的で、ウェブの複雑さも著しく増大します。 アプリケーション コードウェブ アプリケーションは画面の向きの変化を監視し、座標を センサー測定値の変換も行いますが、オイラー角や 四元数。

Generic Sensor API は、はるかにシンプルで信頼性の高いソリューションです。ローカル座標系は、定義されたすべての空間センサークラス(AccelerometerGyroscopeLinearAccelerationSensorAbsoluteOrientationSensorRelativeOrientationSensorMagnetometer)で構成できます。センサー オブジェクトのコンストラクタに referenceFrame オプションを渡すことで、返される測定値をデバイス座標または画面座標で解決するかどうかを定義します。

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

コーディングを始めましょう。

Generic Sensor API はとてもシンプルで、簡単に使用できます。Sensor インターフェースには、センサーの状態を制御する start() メソッドと stop() メソッド、センサーの有効化、エラー、新たに利用可能な測定値に関する通知を受け取る複数のイベント ハンドラがあります。通常、具体的なセンサークラスは、固有の読み取り属性をベースに追加します。 クラスです。

開発環境

開発中は、localhost を使用してセンサーを使用できます。モバイル デバイス用に開発している場合は、ローカルサーバーのポート転送を設定して、準備完了です。

コードの準備ができたら、HTTPS をサポートするサーバーにデプロイします。GitHub ページは HTTPS で配信されるため、リソースを共有するのに最適な場所 できます。

3D モデルの回転

この簡単な例では、絶対方向センサーのデータを使用して、3D モデルの回転クォータニオンを変更します。model は、quaternion プロパティを持つ three.js Object3D クラスのインスタンスです。スマートフォンの向きのデモの次のコード スニペットは、絶対方向センサーを使用して 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();
}

デバイスの向きは、WebGL シーン内の 3D model の回転に反映されます。

センサーが 3D モデルの向きを更新する
センサーが 3D モデルの向きを更新する

パンチメーター

次のコード スニペットは、パンチメーターのデモから抜粋したものです。デバイスが最初は静止していると仮定して、リニア加速度センサーを使用してデバイスの最大速度を計算する方法を示しています。

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

現在の速度は、加速度関数の積分への近似として計算されます。

パンチ速度測定用のデモ ウェブ アプリケーション
パンチ速度の測定

Chrome DevTools を使用したデバッグとセンサー オーバーライド

場合によっては、Generic Sensor API を試すために実機は必要ありません。Chrome DevTools は、デバイスの向きのシミュレーションをサポートしています。

<ph type="x-smartling-placeholder">
</ph> 仮想スマートフォンのカスタム 画面の向きデータをオーバーライドするために使用される Chrome DevTools
Chrome DevTools を使用してデバイスの向きをシミュレートする

プライバシーとセキュリティ

センサーの測定値は機密データであり、悪意のあるウェブページからのさまざまな攻撃の対象となる可能性があります。汎用センサー API の実装では、セキュリティとプライバシーに関する潜在的なリスクを軽減するために、いくつかの制限が適用されます。これらの制限は、API を使用するデベロッパーが考慮する必要があります。以下に、その制限を簡単に示します。

HTTPS のみ

Generic Sensor API は高度な機能であるため、ブラウザでは安全なコンテキストでのみ許可されます。つまり、Generic Sensor API を使用するには、HTTPS 経由でページにアクセスする必要があります。開発中は http://localhost でアクセスできますが、本番環境ではサーバーで HTTPS を設定する必要があります。ベスト プラクティスとガイドラインについては、安全とセキュリティ コレクションをご覧ください。

権限ポリシーの統合

Generic Sensor API の権限ポリシーの統合は、フレームのセンサーデータへのアクセスを制御します。

デフォルトでは、Sensor オブジェクトはメインフレーム内または同一オリジン サブフレーム内でのみ作成できます。 これにより、クロスオリジンの iframe が無許可でセンサーデータを読み取ることを防止できます。このデフォルトの動作 これを変更するには、対応するエンドポイントを明示的に有効または無効に ポリシー制御機能

次のスニペットは、クロスオリジン iframe への加速度計データアクセスを許可する例を示しています。これにより、Accelerometer オブジェクトまたは LinearAccelerationSensor オブジェクトを iframe 内に作成できるようになります。

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

センサー測定値の配信は停止できます

センサーの測定値にアクセスできるのは、表示されているウェブページ(ユーザーが実際に操作しているページ)に限られます。さらに、ユーザーが操作を実行した場合、センサーデータは親フレームに提供されません。 クロスオリジン サブフレームにフォーカスが移ります。これにより、親フレームがユーザー入力を推測するのを防ぐことができます。

次のステップ

周囲光センサー近接センサーなど、近い将来実装される予定のセンサークラスがすでにいくつかあります。ただし、汎用センサー フレームワークの優れた拡張性により、さまざまなセンサータイプを表す新しいクラスがさらに増えることが予想されます。

今後の作業の重要な領域として、Generic Sensor API 自体の改善があります。Generic Sensor 仕様は現在候補推奨仕様です。つまり、デベロッパーが必要とする修正や新機能を追加する時間はまだあります。

ご協力いただけます。

センサーの仕様に達しました 候補への推奨事項 ウェブ デベロッパーやブラウザのデベロッパーからのフィードバックは大いに参考になります。Google に どの機能を追加すればよいか、 現在の API。

Chrome の実装に関する仕様に関する問題バグをお気軽に報告してください。

リソース

謝辞

この記事は Joe Medley によってレビューされ、 Kayce BasquesMisko によるヒーロー画像(ウィキメディア コモンズより)。