Giao thức HID của trình theo dõi đầu

Giao thức thiết bị theo dõi đầu người (HID), có sẵn cho các thiết bị chạy Android 13 trở lên, cho phép thiết bị theo dõi đầu được kết nối với thiết bị Android thông qua USB hoặc Bluetooth và được tiếp xúc với khuôn khổ và ứng dụng Android thông qua các cảm biến khuôn khổ. Giao thức này được sử dụng để điều khiển hiệu ứng ảo hóa âm thanh (âm thanh 3D). Trang này sử dụng thuật ngữ thiết bịmáy chủ lưu trữ theo nghĩa Bluetooth, trong đó thiết bị có nghĩa là thiết bị theo dõi đầu và máy chủ có nghĩa là máy chủ Android.

Các nhà sản xuất thiết bị phải định cấu hình thiết bị Android của họ để kích hoạt hỗ trợ giao thức HID của trình theo dõi đầu. Để biết thêm thông tin chi tiết về cấu hình, hãy xem Bộ cảm biến động README .

Trang này giả định rằng bạn đã quen với các tài nguyên sau:

Cấu trúc cấp cao nhất

Khung Android xác định thiết bị theo dõi đầu là thiết bị HID.

Để có ví dụ đầy đủ về bộ mô tả HID hợp lệ, hãy xem Phụ lục 1: Ví dụ về bộ mô tả HID .

Ở cấp cao nhất, thiết bị theo dõi đầu là một bộ sưu tập ứng dụng với trang Sensors ( 0x20 ) và Trang Other: Custom ( 0xE1 ). Bên trong bộ sưu tập này là một số trường dữ liệu ( đầu vào ) và thuộc tính ( tính năng ).

Thuộc tính và trường dữ liệu

Phần này mô tả các thuộc tính và trường dữ liệu trong bộ sưu tập ứng dụng của thiết bị theo dõi phần đầu.

Thuộc tính: Mô tả cảm biến ( 0x0308 )

Thuộc tính Mô tả cảm biến ( 0x0308 ) là thuộc tính chuỗi ASCII (8-bit) chỉ đọc, phải chứa giá trị sau:

#AndroidHeadTracker#1.0

Không có null-terminator được mong đợi, có nghĩa là tổng kích thước của thuộc tính này là 23 ký tự 8 bit.

Thuộc tính này đóng vai trò phân biệt đối xử để tránh va chạm với các cảm biến tùy chỉnh khác.

Thuộc tính: ID duy nhất liên tục ( 0x0302 )

Thuộc tính ID duy nhất liên tục ( 0x0302 ) là một mảng chỉ đọc gồm 16 phần tử, mỗi phần tử 8 bit (tổng số 128 bit). Không có dấu chấm dứt rỗng được mong đợi. Thuộc tính này là tùy chọn.

Thuộc tính này cho phép các thiết bị theo dõi đầu được tích hợp trong thiết bị âm thanh tham chiếu đến thiết bị âm thanh mà chúng được gắn vào. Các chương trình sau được hỗ trợ.

Trình theo dõi phần đầu độc lập

Nếu thuộc tính ID duy nhất liên tục ( 0x0302 ) không tồn tại hoặc được đặt thành tất cả các số không, điều đó có nghĩa là thiết bị theo dõi đầu không được gắn vĩnh viễn với thiết bị âm thanh và có thể được sử dụng riêng biệt, chẳng hạn như bằng cách cho phép người dùng theo cách thủ công kết hợp thiết bị theo dõi đầu với một thiết bị âm thanh riêng biệt.

Tham khảo sử dụng địa chỉ MAC Bluetooth

Octet 0 1 2 3 4 5 6 7 số 8 9 10 11 12 13 14 15
Giá trị 0 0 0 0 0 0 0 0 B T MAC Bluetooth

Trong sơ đồ này, 8 octet đầu tiên phải là 0 , octet 8 và 9 phải chứa các giá trị ASCII BT tương ứng, và 6 octet sau được hiểu là địa chỉ MAC Bluetooth, giả sử thiết bị theo dõi đầu áp dụng cho bất kỳ thiết bị âm thanh nào có địa chỉ MAC này.

Tham khảo sử dụng UUID

Bất cứ khi nào bit quan trọng nhất (MSB) của octet 8 được đặt ( ≥0x80 ), trường được hiểu là UUID, như được chỉ định trong RFC-4122 . Thiết bị âm thanh tương ứng cung cấp cùng một UUID, được đăng ký trên khuôn khổ Android, thông qua một cơ chế không xác định dành riêng cho loại phương tiện được sử dụng.

Thuộc tính: Trạng thái báo cáo ( 0x0316 )

Thuộc tính Trạng thái báo cáo ( 0x0316 ) là thuộc tính đọc / ghi có ngữ nghĩa tiêu chuẩn như được định nghĩa trong đặc tả HID. Máy chủ sử dụng thuộc tính này để cho thiết bị biết sự kiện nào cần báo cáo. Chỉ các giá trị Không có sự kiện ( 0x0840 ) và Tất cả sự kiện ( 0x0841 ) được sử dụng.

Giá trị ban đầu cho trường này phải là Không có Sự kiện và nó không bao giờ được sửa đổi bởi thiết bị, chỉ bởi máy chủ.

Thuộc tính: Trạng thái nguồn ( 0x0319 )

Thuộc tính Power State ( 0x0319 ) là thuộc tính đọc / ghi có ngữ nghĩa tiêu chuẩn như được định nghĩa trong đặc tả HID. Máy chủ sử dụng thuộc tính này để cho biết thiết bị phải ở trạng thái nguồn nào. Chỉ các giá trị Nguồn đầy đủ ( 0x0851 ) và Tắt nguồn ( 0x0855 ) mới được sử dụng.

Giá trị ban đầu cho trường này được xác định bởi thiết bị và không bao giờ được sửa đổi bởi thiết bị, chỉ bởi máy chủ.

Thuộc tính: Khoảng thời gian báo cáo ( 0x030E )

Thuộc tính Khoảng thời gian báo cáo ( 0x030E ) là thuộc tính đọc / ghi có ngữ nghĩa tiêu chuẩn như được định nghĩa trong đặc tả HID. Máy chủ sử dụng thuộc tính này để cho thiết bị biết tần suất báo cáo các lần đọc dữ liệu của nó. Đơn vị là giây. Phạm vi hợp lệ cho giá trị này được xác định bởi thiết bị và được mô tả bằng cách sử dụng cơ chế Tối thiểu / Tối đa vật lý. Tốc độ báo cáo ít nhất 50 Hz phải được hỗ trợ và tốc độ báo cáo tối đa được khuyến nghị là 100 Hz. Do đó, khoảng thời gian báo cáo tối thiểu phải nhỏ hơn hoặc bằng 20 ms và được khuyến nghị lớn hơn hoặc bằng 10 ms.

Trường dữ liệu: Giá trị tùy chỉnh 1 ( 0x0544 )

Trường Giá trị tùy chỉnh 1 ( 0x0544 ) là trường đầu vào được sử dụng để báo cáo thông tin theo dõi phần đầu thực tế. Đó là một mảng 3 phần tử, được diễn giải theo các quy tắc HID thông thường cho các giá trị vật lý như được chỉ định trong phần 6.2.2.7 của đặc tả HID. Khoảng giá trị của mỗi phần tử là [-π, π] rad. Đơn vị luôn là radian.

Các phần tử được hiểu là: [rx, ry, rz] , sao cho [rx, ry, rz] là một vectơ quay , biểu diễn sự biến đổi từ hệ quy chiếu sang hệ đầu. Độ lớn phải nằm trong khoảng [0..π].

Hệ quy chiếu là tùy ý, nhưng nói chung là cố định và phải thuận tay. Một số lượng nhỏ của sự trôi dạt là có thể chấp nhận được. Các trục đầu là:

  • X từ tai trái sang phải
  • Y từ sau đầu đến mũi (sau ra trước)
  • Z từ cổ đến đỉnh đầu

Trường dữ liệu: Giá trị tùy chỉnh 2 ( 0x0545 )

Trường Giá trị tùy chỉnh 2 ( 0x0545 ) là trường đầu vào được sử dụng để báo cáo thông tin theo dõi phần đầu thực tế. Đó là một mảng điểm cố định gồm 3 phần tử, được diễn giải theo các quy tắc HID thông thường cho các giá trị vật lý. Đơn vị luôn là radian / giây.

Các phần tử được hiểu là: [vx, vy, vz] , sao cho [vx, vy, vz] là một vectơ quay , đại diện cho vận tốc góc của khung đầu (so với chính nó).

Trường dữ liệu: Giá trị tùy chỉnh 3 ( 0x0546 )

Trường Giá trị tùy chỉnh 3 ( 0x0546 ) là trường đầu vào được sử dụng để theo dõi sự gián đoạn trong khung tham chiếu. Đó là một số nguyên vô hướng có kích thước 8 bit. Nó phải được thiết bị tăng lên (có bao bọc) mỗi khi hệ quy chiếu được thay đổi, ví dụ, nếu một thuật toán bộ lọc định hướng được sử dụng để xác định hướng đã đặt lại trạng thái của nó. Giá trị này được diễn giải theo các quy tắc HID thông thường cho các giá trị vật lý. Tuy nhiên, giá trị vật lý và đơn vị không quan trọng. Thông tin duy nhất có liên quan đến máy chủ lưu trữ là một giá trị đã thay đổi. Để tránh các vấn đề về số liên quan đến mất độ chính xác trong khi chuyển đổi từ đơn vị lôgic sang đơn vị vật lý, bạn nên đặt các giá trị cho vật lý tối thiểu, vật lý tối đa và số mũ đơn vị thành 0 cho trường này.

Cấu trúc báo cáo

Việc nhóm các thuộc tính thành báo cáo (bằng cách gán ID báo cáo) là linh hoạt. Để đạt hiệu quả, chúng tôi khuyên bạn nên tách các thuộc tính chỉ đọc khỏi các thuộc tính đọc / ghi.

Đối với các trường dữ liệu, các trường Giá trị tùy chỉnh 1, 2 và 3 phải nằm trong cùng một báo cáo và chỉ nằm trong một báo cáo cho một thiết bị nhất định (bộ sưu tập ứng dụng).

Gửi báo cáo đầu vào

Thiết bị phải định kỳ và không đồng bộ (thông qua tin nhắn HID INPUT) gửi báo cáo đầu vào khi tất cả các điều kiện dưới đây được đáp ứng:

  • Thuộc tính Power State được đặt thành Full Power.
  • Thuộc tính Trạng thái báo cáo được đặt thành Tất cả sự kiện.
  • Thuộc tính Khoảng thời gian báo cáo khác 0.

Thuộc tính Khoảng thời gian báo cáo xác định tần suất gửi báo cáo. Khi bất kỳ điều kiện nào ở trên không được đáp ứng, thiết bị không được gửi bất kỳ báo cáo nào.

Tương thích chuyển tiếp và ngược

Giao thức HID của trình theo dõi đầu sử dụng lược đồ lập phiên bản cho phép cập nhật, đồng thời cho phép khả năng tương tác giữa máy chủ và thiết bị sử dụng các phiên bản khác nhau của giao thức. Các phiên bản của giao thức được xác định bằng hai số, chính và phụ, có ngữ nghĩa riêng biệt như được mô tả trong các phần sau.

Các phiên bản được hỗ trợ bởi một thiết bị có thể được xác định bằng cách kiểm tra thuộc tính Mô tả cảm biến ( 0x0308 ) của nó.

Khả năng tương thích với phiên bản nhỏ

Các thay đổi đối với phiên bản nhỏ tương thích ngược với các phiên bản nhỏ trước đó dựa trên cùng một phiên bản chính. Trong các bản cập nhật cho phiên bản nhỏ, máy chủ lưu trữ bỏ qua các trường và thuộc tính dữ liệu bổ sung. Ví dụ: một thiết bị sử dụng phiên bản giao thức 1.6 tương thích với một máy chủ hỗ trợ phiên bản giao thức 1.x, bao gồm cả phiên bản 1.5.

Khả năng tương thích phiên bản chính

Các thay đổi không tương thích ngược được cho phép đối với các thay đổi đối với các phiên bản chính. Để hỗ trợ nhiều phiên bản chính cho khả năng tương tác với các máy chủ cũ và mới, các thiết bị có thể chỉ định nhiều bộ sưu tập ứng dụng trong bộ mô tả báo cáo của chúng. Ví dụ:

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

Trong trường hợp này, máy chủ có thể liệt kê tất cả các bộ sưu tập ứng dụng khác nhau được thiết bị quảng cáo, kiểm tra thuộc tính Mô tả cảm biến của chúng để xác định các phiên bản giao thức mà chúng triển khai, sau đó chọn phiên bản giao thức mới nhất mà máy chủ hỗ trợ. Khi được chọn, máy chủ sẽ hoạt động với một giao thức duy nhất đã được chọn cho thời gian tồn tại của kết nối thiết bị.

Phụ lục 1: Ví dụ về bộ mô tả HID

Ví dụ sau minh họa một bộ mô tả HID hợp lệ điển hình. Nó sử dụng macro C thường được sử dụng, được cung cấp trong Cách sử dụng cảm biến HID (phần 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,
};