ヘッドトラッカーHIDプロトコル

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

ヘッド トラッカー ヒューマン インターフェイス デバイス (HID) プロトコルは、Android 13 以降を実行するデバイスで使用でき、ヘッド トラッキング デバイスを USB または Bluetooth 経由で Android デバイスに接続し、センサーを介して Android フレームワークとアプリに公開することができます。フレームワーク。このプロトコルは、オーディオ バーチャライザー効果 (3D オーディオ) を制御するために使用されます。このページでは、デバイスホストという用語を Bluetooth の意味で使用しています。ここで、デバイスはヘッド トラッキング デバイスを意味し、ホストは Android ホストを意味します。

デバイス メーカーは、ヘッド トラッカー HID プロトコルのサポートを有効にするように Android デバイスを構成する必要があります。構成の詳細については、 Dynamic Sensors READMEを参照してください。

このページは、次のリソースに精通していることを前提としています。

トップレベルの構造

Android フレームワークは、ヘッド トラッカー デバイスを HID デバイスとして識別します。

有効な HID 記述子の完全な例については、「付録 1: HID 記述子の例」を参照してください。

最上位のヘッド トラッカー デバイスは、[ Sensors ] ページ ( 0x20 ) と [ Other: Customの使用法] ( 0xE1 ) を含むアプリ コレクションです。このコレクション内には、いくつかのデータ フィールド ( inputs ) とプロパティ ( features ) があります。

プロパティとデータ フィールド

このセクションでは、ヘッド トラッカー デバイスのアプリケーション コレクションのプロパティとデータ フィールドについて説明します。

プロパティ: センサーの説明 ( 0x0308 )

Sensor Description ( 0x0308 ) プロパティは、次の値を含む必要がある読み取り専用の ASCII (8 ビット) 文字列プロパティです。

#AndroidHeadTracker#1.0

null ターミネータは想定されていません。つまり、このプロパティの合計サイズは 23 個の 8 ビット文字です。

このプロパティは、他のカスタム センサーとの衝突を避けるための識別子として機能します。

プロパティ: 永続的な一意の ID ( 0x0302 )

Persistent Unique ID ( 0x0302 ) プロパティは、それぞれ 8 ビット (合計 128 ビット) の 16 要素の読み取り専用配列です。 null ターミネータは想定されていません。このプロパティはオプションです。

このプロパティを使用すると、オーディオ デバイスに統合されているヘッド トラッキング デバイスが、接続先のオーディオ デバイスを参照できます。次のスキームがサポートされています。

スタンドアロンのヘッド トラッカー

Persistent Unique ID ( 0x0302 ) プロパティが存在しないか、すべてゼロに設定されている場合は、ヘッド トラッカー デバイスがオーディオ デバイスに永続的に接続されておらず、個別に使用できることを意味します。ヘッド トラッカー デバイスを別のオーディオ デバイスに関連付けます。

Bluetooth MAC アドレスを使用した参照

オクテット0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
価値0 0 0 0 0 0 0 0 B Tブルートゥース MAC

このスキームでは、最初の 8 オクテットは0でなければならず、オクテット 8 と 9 にはそれぞれ ASCII 値BTが含まれていなければならず、次の 6 オクテットは Bluetooth MAC アドレスとして解釈されます。この MAC アドレス。

UUIDによる参照

オクテット 8 の最上位ビット (MSB) が設定されている ( ≥0x80 ) 場合は常に、 RFC-4122で指定されているように、フィールドは UUID として解釈されます。対応するオーディオ デバイスは、Android フレームワークに登録されている同じ UUID を、使用されるトランスポートのタイプに固有の不特定のメカニズムを介して提供します。

プロパティ: レポート状態 ( 0x0316 )

Reporting State ( 0x0316 ) プロパティは、HID 仕様で定義されている標準的なセマンティクスを持つ読み取り/書き込みプロパティです。ホストはこのプロパティを使用して、レポートするイベントをデバイスに示します。値 No Events ( 0x0840 ) と All Events ( 0x0841 ) のみが使用されます。

このフィールドの初期値は No Events である必要があり、デバイスによって変更されることはなく、ホストによってのみ変更されます。

プロパティ: 電源状態 ( 0x0319 )

Power State ( 0x0319 ) プロパティは、HID 仕様で定義されている標準的なセマンティクスを持つ読み取り/書き込みプロパティです。ホストは、このプロパティを使用して、どの電源状態にする必要があるかをデバイスに示します。フル パワー ( 0x0851 ) と電源オフ ( 0x0855 ) の値のみが使用されます。

このフィールドの初期値はデバイスによって決定され、デバイスによって変更されることはなく、ホストによってのみ変更されます。

プロパティ: レポート間隔 ( 0x030E )

レポート間隔 ( 0x030E ) プロパティは、HID 仕様で定義されている標準的なセマンティクスを持つ読み取り/書き込みプロパティです。ホストはこのプロパティを使用して、データの読み取り値を報告する頻度をデバイスに示します。単位は秒です。この値の有効範囲はデバイスによって決定され、物理最小/最大メカニズムを使用して記述されます。少なくとも 50 Hz のレポート レートをサポートする必要があり、推奨される最大レポート レートは 100 Hz です。したがって、最小レポート間隔は 20 ミリ秒以下にする必要があり、10 ミリ秒以上にすることをお勧めします。

データ フィールド: カスタム値 1 ( 0x0544 )

Custom Value 1 ( 0x0544 ) フィールドは、実際のヘッド トラッキング情報を報告するために使用される入力フィールドです。これは 3 要素の配列であり、HID 仕様のセクション 6.2.2.7 で指定されている物理値の通常の HID 規則に従って解釈されます。各要素の有効な範囲は [-π, π] rad です。単位は常にラジアンです。

要素は[rx, ry, rz]として解釈され、 [rx, ry, rz]は参照フレームからヘッド フレームへの変換を表す回転ベクトルです。マグニチュードは [0..π] の範囲内でなければなりません。

参照フレームは任意ですが、通常は固定されており、右利きでなければなりません。少量のドリフトは許容されます。頭の軸は次のとおりです。

  • X 左耳から右へ
  • Y 後頭部から鼻まで(後ろから前)
  • 首から頭頂部までのZ

データ フィールド: カスタム値 2 ( 0x0545 )

Custom Value 2 ( 0x0545 ) フィールドは、実際のヘッド トラッキング情報を報告するために使用される入力フィールドです。これは 3 要素の固定小数点配列であり、物理値の通常の HID ルールに従って解釈されます。単位は常にラジアン/秒です。

要素は次のように解釈されます: [vx, vy, vz][vx, vy, vz]回転ベクトルであり、ヘッド フレームの角速度 (それ自体に対する) を表します。

データ フィールド: カスタム値 3 ( 0x0546 )

カスタム値 3 ( 0x0546 ) フィールドは、参照フレームの不連続を追跡するために使用される入力フィールドです。これは、サイズが 8 ビットのスカラー整数です。たとえば、向きを決定するために使用される向きフィルタ アルゴリズムの状態がリセットされた場合など、基準フレームが変更されるたびに、デバイスによって (ラップアラウンドを使用して) インクリメントされる必要があります。この値は、物理値の通常の HID ルールに従って解釈されます。ただし、物理的な値と単位は関係ありません。ホストに関連する唯一の情報は、変更された値です。論理単位から物理単位への変換中に精度が失われることに関連する数値の問題を回避するには、このフィールドの物理最小値、物理最大値、および単位指数の値をゼロに設定することをお勧めします。

レポートの構造

レポートへのプロパティのグループ化 (レポート ID の割り当てによる) は柔軟です。効率のために、読み取り専用プロパティを読み取り/書き込みプロパティから分離することをお勧めします。

データ フィールドの場合、カスタム値 1、2、および 3 フィールドは同じレポート内に存在し、特定のデバイス (アプリ コレクション) に対して 1 つのレポート内にのみ存在する必要があります。

入力レポートの送信

以下のすべての条件が満たされた場合、デバイスは定期的かつ非同期的に (HID INPUT メッセージを介して) 入力レポートを送信する必要があります。

  • [電源状態] プロパティはフル パワーに設定されています。
  • レポートの状態プロパティは、すべてのイベントに設定されています。
  • レポート間隔プロパティがゼロ以外です。

レポート間隔プロパティは、レポートを送信する頻度を決定します。上記の条件のいずれかが満たされない場合、デバイスはレポートを送信してはなりません。

上位互換性と下位互換性

ヘッド トラッカー HID プロトコルは、異なるバージョンのプロトコルを使用するホストとデバイス間の相互運用性を可能にしながら、更新を可能にするバージョン管理スキームを使用します。プロトコルのバージョンは、次のセクションで説明するように、メジャーとマイナーの 2 つの番号で識別されます。

デバイスでサポートされているバージョンは、センサーの説明 ( 0x0308 ) プロパティを調べることで確認できます。

マイナー バージョンの互換性

マイナー バージョンへの変更は、同じメジャー バージョンに基づく以前のマイナー バージョンと下位互換性があります。マイナー バージョンへの更新では、ホストは追加のデータ フィールドとプロパティを無視します。たとえば、プロトコル バージョン 1.6 を使用するデバイスは、バージョン 1.5 を含むプロトコル バージョン 1.x をサポートするホストと互換性があります。

メジャー バージョンの互換性

メジャー バージョンへの変更では、下位互換性のない変更が許可されます。古いホストと新しいホストとの相互運用性のために複数のメジャー バージョンをサポートするために、デバイスはレポート記述子で複数のアプリ コレクションを指定できます。例えば:

const unsigned char ReportDescriptor[] = {
    HID_USAGE_PAGE_SENSOR,
    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,

    HID_COLLECTION(HID_APPLICATION),
        // Feature report 2 (read-only).
        HID_REPORT_ID(2),

        // Magic value: "#AndroidHeadTracker#1.5"
        HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(23),
        HID_FEATURE(HID_CONST_VAR_ABS),

      ...

    HID_END_COLLECTION,

    HID_COLLECTION(HID_APPLICATION),
        // Feature report 12 (read-only).
        HID_REPORT_ID(12),

        // Magic value: "#AndroidHeadTracker#2.4"
        HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(23),
        HID_FEATURE(HID_CONST_VAR_ABS),

      ...

    HID_END_COLLECTION,
};

この場合、ホストは、デバイスによってアドバタイズされたさまざまなアプリ コレクションをすべて列挙し、センサーの説明プロパティを調べて、それぞれが実装するプロトコル バージョンを特定し、ホストがサポートする最新のプロトコル バージョンを選択できます。選択した場合、ホストは、デバイス接続の存続期間中、選択された単一のプロトコルで動作します。

付録 1: HID 記述子の例

次の例は、典型的な有効な HID 記述子を示しています。 HID センサーの使用法 (セクション 4.1) で提供されている、一般的に使用される C マクロを使用します。

const unsigned char ReportDescriptor[] = {
    HID_USAGE_PAGE_SENSOR,
    HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
    HID_COLLECTION(HID_APPLICATION),
        // Feature report 2 (read-only).
        HID_REPORT_ID(2),

        // Magic value: "#AndroidHeadTracker#1.0"
        HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(23),
        HID_FEATURE(HID_CONST_VAR_ABS),

        // UUID.
        HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(16),
        HID_FEATURE(HID_CONST_VAR_ABS),

        // Feature report 1 (read/write).
        HID_REPORT_ID(1),

        // 1-bit on/off reporting state.
        HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(1),
        HID_REPORT_SIZE(1),
        HID_REPORT_COUNT(1),
        HID_COLLECTION(HID_LOGICAL),
            HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS,
            HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS,
            HID_FEATURE(HID_DATA_ARR_ABS),
        HID_END_COLLECTION,

        // 1-bit on/off power state.
        HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(1),
        HID_REPORT_SIZE(1),
        HID_REPORT_COUNT(1),
        HID_COLLECTION(HID_LOGICAL),
            HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF,
            HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER,
            HID_FEATURE(HID_DATA_ARR_ABS),
        HID_END_COLLECTION,

        // 6-bit reporting interval, with values [0x00..0x3F] corresponding to [10ms..100ms].
        HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
        HID_LOGICAL_MIN_8(0x00),
        HID_LOGICAL_MAX_8(0x3F),
        HID_PHYSICAL_MIN_8(10),
        HID_PHYSICAL_MAX_8(100),
        HID_REPORT_SIZE(6),
        HID_REPORT_COUNT(1),
        HID_USAGE_SENSOR_UNITS_SECOND,
        HID_UNIT_EXPONENT(0xD),  // 10^-3
        HID_FEATURE(HID_DATA_VAR_ABS),

        // Input report 1

        // Orientation as rotation vector (scaled to [-pi..pi] rad).
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
        HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
        HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
        HID_PHYSICAL_MIN_32(0x60, 0x4F, 0x46, 0xED),  // -314159265
        HID_PHYSICAL_MAX_32(0xA1, 0xB0, 0xB9, 0x12),  // 314159265
        HID_UNIT_EXPONENT(0x08),  // 10^-8
        HID_REPORT_SIZE(16),
        HID_REPORT_COUNT(3),
        HID_INPUT(HID_DATA_VAR_ABS),

        // Angular velocity as rotation vector (scaled to [-32..32] rad/sec).
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
        HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
        HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
        HID_PHYSICAL_MIN_8(0xE0),
        HID_PHYSICAL_MAX_8(0x20),
        HID_UNIT_EXPONENT(0x00),  // 10^0
        HID_REPORT_SIZE(16),
        HID_REPORT_COUNT(3),
        HID_INPUT(HID_DATA_VAR_ABS),

        // Reference frame reset counter.
        HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
        HID_LOGICAL_MIN_16(0x00, 0x00), // LOGICAL_MINIMUM (0)
        HID_LOGICAL_MAX_16(0xFF, 0x00), // LOGICAL_MAXIMUM (255)
        HID_PHYSICAL_MIN_8(0x00),
        HID_PHYSICAL_MAX_8(0x00),
        HID_UNIT_EXPONENT(0x00),  // 10^0
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(1),
        HID_INPUT(HID_DATA_VAR_ABS),

    HID_END_COLLECTION,
};