頭部追蹤器 HID 協定

頭部追蹤器人體介面裝置 (HID) 通訊協定,適用於裝置 搭載 Android 13 以上版本,可讓您 頭部追蹤裝置 (可透過 USB 或 藍牙並經由 sensors 架構。這個通訊協定用於控制音訊虛擬化效果 (3D 音訊)。本頁使用了「device」host 保持藍牙狀態,其中「device」是指頭部追蹤裝置 和 host 表示 Android 主機。

裝置製造商必須設定 Android 裝置,才能支援頭戴式追蹤器 HID 通訊協定。如要進一步瞭解 請參閱 動態感應器 README

本頁面假設您熟悉下列資源:

頂層結構

Android 架構會將頭戴式追蹤器裝置識別為 HID 裝置。

如需有效 HID 描述元資料的完整範例,請參閱「附錄 1:HID 描述元資料範例」。

在頂層,頭戴式追蹤裝置是應用程式集合,其中包含 Sensors 頁面 (0x20) 和 Other: Custom 用途 (0xE1)。這個集合內含多個資料欄 (輸入內容) 和資源 (功能)。

資源和資料欄位

本節說明頭戴式追蹤裝置應用程式集合中的屬性和資料欄位。

屬性:感應器說明 (0x0308)

感應器說明 (0x0308) 屬性是只讀 ASCII (8 位元) 字串屬性,必須包含下列值:

Head Tracker 1.0 版:

#AndroidHeadTracker#1.0

頭戴式追蹤器 2.0 版 (適用於 Android 15 以上版本),支援 LE 音訊:

#AndroidHeadTracker#2.0#x

x 是整數 (123),用於指出支援的傳輸方式:

  • 1:ACL
  • 2:ISO
  • 3:ACL + ISO

不應有空值結束字元,意指此屬性的總大小 在 1.0 版中,則有 23 個 8 位元字元。

這項屬性可做為區別器,避免與其他自訂感應器發生衝突。

屬性:永久專屬 ID (0x0302)

永久性專屬 ID (0x0302) 屬性是 16 個元素的唯讀陣列,每個元素為 8 位元 (總共 128 位元)。不應有空值的結束字元。這是選用屬性。

這個屬性允許使用音訊中整合的頭部追蹤裝置 裝置,以參照目前附加的音訊裝置。 支援下列機制。

獨立頭戴式追蹤器

如果永久專屬 ID (0x0302) 屬性不存在或設為全部 0,表示頭部追蹤器裝置不會永久連接至 音訊裝置,並可以單獨使用,例如 手動將頭部智慧手環裝置與個別音訊裝置建立關聯。

使用藍牙 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 藍牙 MAC

在這個配置中,前 8 個八位元必須是 0,八位元 8 和 9 必須包含 ASCII 值分別為 BT,以及以下 6 個八位元組 視為藍牙 MAC 位址,假設使用頭戴式追蹤器裝置 皆適用於具有此 MAC 位址的任何音訊裝置。這個地址必須是 身分位址,即使裝置使用隨機 MAC 位址建立 連線狀態。透過傳統藍牙 (v1.0 HID 格式) 和藍牙 LE (v2.0 HID 格式) 連線的雙模式裝置,必須公開兩個使用相同身分位址的 HID 描述項。分離的雙模式裝置 左右裝置都必須使用主要雙重公開藍牙 LE HID 模式裝置取代 LE 僅支援 LE 的次要裝置。

使用 UUID 的參照

只要 8 位元組的最高位元 (MSB) 已設為 ≥0x80,系統就會依 RFC-4122 的規定,將欄位解讀為 UUID。 對應的音訊裝置會提供相同的 UUID 還是透過專門用來 所用的交通方式

屬性:報表狀態 (0x0316)

回報狀態 (0x0316) 屬性是讀/寫屬性,具有 HID 規格中定義的標準語義。主機會使用這個屬性,向裝置指出要回報哪些事件。系統只會使用「No Events」(0x0840) 和「All Events」(0x0841) 的值。

這個欄位的初始值必須為「No Events」,且裝置不得修改該值,只能由主機修改。

屬性:電源狀態 (0x0319)

電源狀態 (0x0319) 屬性是讀/寫屬性,具有 HID 規格中定義的標準語意。主機會使用這個屬性,向裝置指出裝置必須處於哪種電源狀態。僅使用 Full Power (0x0851) 和 Power Off (0x0855) 值。

這個欄位的初始值是由裝置決定,一律不得 僅由裝置修改。

資源:報表間隔 (0x030E)

「Report Interval」(0x030E) 屬性是讀/寫屬性,具有 HID 規格中定義的標準語義。主機會使用這個屬性,向裝置指出要多久回報一次資料讀數。單位為秒。這個值的有效範圍由裝置決定,並使用 Physical Min/Max 機制說明。必須支援至少 50 Hz 的回報率,建議的最高回報率為 100 Hz。因此,最小回報間隔必須小於或等於 20 毫秒,建議為大於或等於 10 毫秒。

資源:供應商保留 LE Transport (0xF410)

供應商保留的 LE Transport (0xF410) 屬性為讀取/寫入屬性 而且具有 HID 規格中定義的標準語意主機會使用這項屬性,指出所選的傳輸方式 (ACL 或 ISO)。只會使用值 ACL (0xF800) 和 ISO (0xF801),且兩者都必須納入邏輯集合。

這項屬性會在電源或回報狀態之前設定。

資料欄位:自訂值 1 (0x0544)

「自訂值 1」(0x0544) 欄位則是用於回報 實際的頭部追蹤資訊這是 3 元素陣列,根據 適用於實體值的一般 HID 規則,如第 6.2.2.7 節 HID 規格每個元素的有效範圍為 [-π, π] 弧度。單位一律為弧度。

元素會解讀為:[rx, ry, rz],例如 [rx, ry, rz]旋轉向量、 代表從參考框架到標頭影格的轉換過程。 範圍必須在 [0..π] 範圍內。

參考框架是任意的,但一般是固定的,且必須 右手。允許少許漂移。頭部軸為:

  • 從左耳到右耳的 X 符號
  • Y 從頭後到鼻子 (從後往前)
  • 從頸部到頭頂的 Z 軸

資料欄位:自訂值 2 (0x0545)

「自訂值 2」(0x0545) 欄位是用於回報實際頭部追蹤資訊的輸入欄位。這是 3 個元素的固定點陣列 依據實體值的一般 HID 規則進行解讀。 單位一律為弧度/秒。

元素會解讀為:[vx, vy, vz],例如 [vx, vy, vz]旋轉向量、 代表車頭框架 (相對於自身) 的角速度。

資料欄位:自訂值 3 (0x0546)

「自訂值 3」(0x0546) 欄位是用於追蹤參考影格中的不連續性輸入欄位。這是 8 位元的純量整數值 大小每當系統呼叫 參考影格發生變化,例如螢幕方向篩選器演算法發生變化 用於判斷方向的狀態已重設。系統會根據物理值的一般 HID 規則解讀這個值。不過 實體價值和單位無關與主機相關的唯一資訊是變更的值。避免與精確度遺失相關的數值問題 如要從邏輯轉換為實體單位,建議您將 這個欄位的實際最小值、實體最大值及單位指數為零。

報表結構

報表的資源分組 (按報表 ID 的分配方式) 是 彈性。為提高效率,建議您區隔唯讀屬性 來自讀取/寫入屬性的資料

資料欄位的「自訂值 1」、「自訂值」和「3」欄位必須相同 並依特定裝置 (應用程式組合) 只用單一報表查看。

傳送輸入報告

裝置必須在符合下列所有條件時,以非同步方式 (透過 HID 輸入訊息) 定期傳送輸入報告:

  • Power State 屬性已設為 Full Power。
  • 「回報狀態」屬性已設為「所有事件」。
  • 報告間隔屬性不是零。

「報表間隔」資源會決定報表的傳送頻率。如果裝置未滿足上述任何條件,則不得傳送任何報表。

前瞻相容性

車用追蹤器 HID 通訊協定的版本管理架構 上的更新,同時使主機與使用 每個版本的通訊協定不同協定版本會以兩個數字 (主要和次要) 標示,這兩個數字具有不同的語意,請參閱下文。

您可以查看裝置的感應器說明 (0x0308) 屬性,判斷裝置支援哪些版本。

子版本相容性

次要版本的變更會與以相同主要版本為基礎的舊版次要版本回溯相容。未成年人更新 版本時,主機就會忽略其他資料欄位和屬性。例如: 使用通訊協定版本 1.6 的裝置與支援主機 包括 1.5 版在內

主要版本相容性

您可以對主要版本進行非回溯相容的變更。為了支援多個主要版本,以便與舊版和新版主機互通,裝置可以在報表描述符中指定多個應用程式集合。例如:

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

在這種情況下,主機可以列舉裝置宣傳的所有不同應用程式集合,檢查其「Sensor Description」屬性,判斷各個應用程式實作的通訊協定版本,然後挑選主機支援的最新通訊協定版本。如果選擇,主機即可運作 是您為裝置使用壽命所選的單一通訊協定 以獲得最佳效能和最安全的連線

附錄:HID 描述元範例

以下範例說明典型的有效 HID 描述元。該元件會使用 常用的 C 巨集, HID 感應器使用情形 (第 4.1 節)。

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

附錄 2:v2.0 HID 描述元範例

以下範例說明支援裝置的 v2.0 HID 描述元 只有藍牙 LE ACL 傳輸

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#2.0#1"
        HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
        HID_LOGICAL_MIN_8(0),
        HID_LOGICAL_MAX_8(0xFF),
        HID_REPORT_SIZE(8),
        HID_REPORT_COUNT(25),
        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),

        // 1-bit transport selection
        HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT,
        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_VENDOR_LE_TRANSPORT_ACL,
            HID_USAGE_SENSOR_PROPERTY_VENDOR_LE_TRANSPORT_ISO,
            HID_FEATURE(HID_DATA_ARR_ABS),
        HID_END_COLLECTION,

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