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 との統合があります。
- 画面座標との自動同期は、
Accelerometer
、Gyroscope
、LinearAccelerationSensor
、AbsoluteOrientationSensor
、RelativeOrientationSensor
、Magnetometer
で使用できます。
使用可能な汎用センサー 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 の加速度。
重力センサー
ユーザーは、Accelerometer
と LinearAccelerometer
の測定値を手動で検査することで、重力センサーの測定値に近い測定値を手動で導出できますが、これは手間がかかり、これらのセンサーから提供される値の精度に依存します。Android などのプラットフォームでは、
重力測定値を提供するオペレーティング システムなので、
計算、ユーザーのハードウェアに応じたより正確な値の提供、
API エルゴノミクスについて学びました。「
GravitySensor
は効果を返します。
重力によるデバイスの X、Y、Z 軸に沿った加速度。
ジャイロスコープ
Gyroscope
センサーは、デバイスのローカル X、Y、Z 軸周りの角速度をラジアン / 秒単位で測定します。ほとんどの消費者
機械(MEMS)を持つデバイス
ジャイロスコープは、さまざまなセンサーに起因して
慣性コリオリ力。MEMS ジャイロスコープは、センサーの重力感度によってセンサーの内部機械システムが変形し、ドリフトが発生しやすくなります。ジャイロスコープは、10 kHz に達することがあります。そのため、他のセンサーと比較して電力を消費する可能性があります。
方向センサー
「
AbsoluteOrientationSensor
地球の座標系を基準としてデバイスの回転を測定するフュージョン センサーです。
一方、
RelativeOrientationSensor
モーション センサーをホストしているデバイスの静止状態からの回転を表すデータを提供します。
参照座標系です。
最新の 3D JavaScript フレームワークはすべて、回転を表す四元数と回転行列をサポートしています。ただし、WebGL を直接使用する場合、OrientationSensor
にはquaternion
プロパティと populateMatrix()
メソッドの両方が用意されています。スニペットは次のとおりです。
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);
向きセンサーは、没入型ゲーム、拡張現実、仮想現実などのさまざまなユースケースを可能にします。
モーション センサー、高度なユースケース、要件について詳しくは、 モーション センサーの説明 ドキュメント。
画面座標との同期
デフォルトでは、空間センサーの測定値は デバイスにバインドされ、画面の向きを考慮しないローカル座標系です。 あります。
ただし、ゲームや拡張現実、仮想現実などの多くのユースケースでは、画面の向きにバインドされた座標系でセンサーの読み取りを解決する必要があります。
これまで、センサー測定値を画面座標に再マッピングするには、JavaScript で実装する必要がありました。 この方法は非効率的で、ウェブの複雑さも著しく増大します。 アプリケーション コードウェブ アプリケーションは画面の向きの変化を監視し、座標を センサー測定値の変換も行いますが、オイラー角や 四元数。
Generic Sensor API は、はるかにシンプルで信頼性の高いソリューションです。ローカル座標系は、定義されたすべての空間センサークラス(Accelerometer
、Gyroscope
、LinearAccelerationSensor
、AbsoluteOrientationSensor
、RelativeOrientationSensor
、Magnetometer
)で構成できます。センサー オブジェクトのコンストラクタに 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
の回転に反映されます。
パンチメーター
次のコード スニペットは、パンチメーターのデモから抜粋したものです。デバイスが最初は静止していると仮定して、リニア加速度センサーを使用してデバイスの最大速度を計算する方法を示しています。
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">プライバシーとセキュリティ
センサーの測定値は機密データであり、悪意のあるウェブページからのさまざまな攻撃の対象となる可能性があります。汎用センサー 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 の実装に関する仕様に関する問題やバグをお気軽に報告してください。
リソース
- デモ プロジェクト: https://intel.github.io/generic-sensor-demos/
- Generic Sensor API 仕様: https://w3c.github.io/sensors/
- 仕様に関する問題: https://github.com/w3c/sensors/issues
- W3C ワーキング グループのメーリング リスト: public-device-apis@w3.org
- Chrome 機能のステータス: https://www.chromestatus.com/feature/5698781827825664
- 実装のバグ: http://crbug.com?q=component:Blink>Sensor
謝辞
この記事は Joe Medley によってレビューされ、 Kayce Basques。Misko によるヒーロー画像(ウィキメディア コモンズより)。