頭部追蹤器 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 Audio:

#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 位址建立 連線狀態。透過藍牙連線的雙模式裝置 (1.0 HID 格式) 和藍牙 LE (v2.0 HID 格式) 必須公開兩組 HID 由同一個身分位址的描述元所導致。分離的雙模式裝置 左右裝置都必須使用主要雙重公開藍牙 LE HID 模式裝置取代 LE 僅支援 LE 的次要裝置。

使用 UUID

每當設定了八位元 8 中最重要的位元 (MSB) (≥0x80) 時,這個欄位 會解讀為 UUID RFC-4122。 對應的音訊裝置會提供相同的 UUID 還是透過專門用來 所用的交通方式

資源:報表狀態 (0x0316)

「報表狀態」(0x0316) 屬性是讀取/寫入屬性,具有 HID 規格中定義的標準語意主機會使用這個 屬性向裝置指明要回報哪些事件。僅限值 否 使用事件 (0x0840) 和所有事件 (0x0841)。

這個欄位的初始值必須是「No Event」,且不得為 僅由裝置修改。

屬性:電源狀態 (0x0319)

電源狀態 (0x0319) 屬性是讀取/寫入屬性, HID 規格中定義的標準語意主機會使用這個 屬性,指示裝置應處於電源狀態。只有 值為 Full Power (0x0851) 和關機 (0x0855)。

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

資源:報表間隔 (0x030E)

「報表間隔」(0x030E) 屬性是讀取/寫入屬性, HID 規格中定義的標準語意主機會使用這個 屬性,指定裝置回報資料讀取的頻率。 單位為秒。這個值的有效範圍由裝置決定 並使用實體最低/最大數量機制描述。至少 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 INPUT 訊息) 滿足下列所有條件時,才傳送輸入報告:

  • 電源狀態屬性已設為「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,
};

在這種情況下,主機可以列舉所有不同的應用程式集合 由裝置通告的感應器說明屬性 決定每個版本導入的通訊協定版本 主機支援的最新通訊協定版本。如果選擇,主機即可運作 是您為裝置使用壽命所選的單一通訊協定 以獲得最佳效能和最安全的連線

附錄: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,
};