El protocolo de dispositivo de interfaz humana (HID) con seguimiento de cabeza, disponible para dispositivos que ejecutan Android 13 y versiones posteriores, permite que un dispositivo de seguimiento de cabeza se conecte a uno Android mediante USB o Bluetooth y que se exponga al framework y las apps de Android a través del framework de sensores. Este protocolo se usa para controlando un efecto de virtualización de audio (audio en 3D). En esta página, se usan los términos dispositivo y host en el sentido de Bluetooth, en el que device se refiere al dispositivo de seguimiento de cabeza. y host se refiere al host de Android.
Los fabricantes de dispositivos deben configurar sus dispositivos Android para habilitar la compatibilidad con el protocolo HID para seguimiento de cabeza. Para obtener información más detallada sobre configuración, consulta la Archivos dinámicos README.
En esta página, se asume que conoces los siguientes recursos:
Estructura de nivel superior
El framework de Android identifica el dispositivo de seguimiento de cabeza como un dispositivo HID.
Para obtener un ejemplo completo de un descriptor HID válido, consulta el Apéndice 1: Ejemplo de un descriptor HID.
En el nivel superior, el dispositivo de seguimiento de cabeza es una colección de apps con la
Página Sensors
(0x20
) y el uso de Other: Custom
(0xE1
). Dentro de este
colección son varios campos de datos (entradas) y propiedades (atributos).
Propiedades y campos de datos
En esta sección, se describen las propiedades y los campos de datos de una aplicación. colección de un dispositivo de seguimiento de cabeza.
Propiedad: Descripción del sensor (0x0308
)
La propiedad de descripción del sensor (0x0308
) es una cadena ASCII (de 8 bits) de solo lectura
que debe contener los siguientes valores:
Monitor de cabeza 1.0:
#AndroidHeadTracker#1.0
Monitor de cabeza 2.0 (disponible en Android 15 o superior), que incluye compatibilidad con LE Audio:
#AndroidHeadTracker#2.0#x
x
es un número entero (1
, 2
, 3
) que indica el transporte de compatibilidad:
- 1: LCA
- 2: ISO
- 3: LCA + ISO
No se espera un terminador nulo, lo que significa que el tamaño total de esta propiedad es de 23 caracteres de 8 bits para la versión 1.0.
Esta propiedad funciona como discriminador para evitar colisiones con otras personalizados.
Propiedad: ID único persistente (0x0302
)
La propiedad de ID único persistente (0x0302
) es un array de solo lectura de 16 elementos, cada uno de 8 bits (128 bits en total). No se espera un terminador nulo. Esta propiedad es opcional.
Esta propiedad permite usar dispositivos de seguimiento de cabeza que están integrados en audio para hacer referencia al dispositivo de audio al que están conectados. Se admiten los siguientes esquemas.
Monitor de cabeza independiente
Si la propiedad de ID único persistente (0x0302
) no existe o se establece en toda
ceros, significa que el dispositivo de seguimiento de cabeza no está conectado permanentemente a una
dispositivo de audio y se pueden usar de forma independiente, por ejemplo, permitiendo que el usuario
asociar manualmente el dispositivo de rastreo de cabeza con otro dispositivo de audio.
Referencia con dirección MAC de Bluetooth
Octeto | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Valor | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | B | T | Bluetooth MAC |
En este esquema, los primeros 8 octetos deben ser 0
, y los octetos 8 y 9 deben contener
los valores ASCII B
y T
respectivamente, y los siguientes 6 octetos se
interpretado como una dirección MAC de Bluetooth, suponiendo que el dispositivo de seguimiento de cabeza
se aplica a cualquier dispositivo de audio con esta dirección MAC. Esta dirección debe ser la dirección de identidad, incluso si el dispositivo usa una dirección MAC aleatoria para establecer conexiones. Dispositivos en modo dual que se conectan por Bluetooth clásico
(formato HID v1.0) y Bluetooth LE (formato HID v2.0) deben exponer dos HID
descriptores de archivo con la misma dirección de identidad. Los dispositivos de modo doble con espacios
Los dispositivos izquierdo y derecho deben exponer el Bluetooth LE HID mediante el módulo de
en lugar del dispositivo secundario solo de LE.
Referencia con UUID
Cada vez que se establece el bit más significativo (MSB) del octeto 8 (≥0x80
), el campo se interpreta como un UUID, como se especifica en RFC-4122. El dispositivo de audio correspondiente proporciona el mismo UUID, que se registra en el framework de Android, a través de un mecanismo no especificado que es específico del tipo de transporte utilizado.
Propiedad: Estado de los informes (0x0316
)
La propiedad Estado de informes (0x0316
) es una propiedad de lectura y escritura que tiene la semántica estándar como se define en la especificación HID. El host usa esta propiedad para indicarle al dispositivo qué eventos informar. Solo los valores No
Se usan Eventos (0x0840
) y Todos los eventos (0x0841
).
El valor inicial de este campo debe ser No Events y el dispositivo nunca debe modificarlo, solo el host.
Propiedad: Estado de energía (0x0319
)
La propiedad de estado de la batería (0x0319
) es una propiedad de lectura y escritura que tiene la semántica estándar como se define en la especificación de HID. El host usa esta propiedad para indicarle al dispositivo en qué estado de energía debe estar. Solo se usan los valores Full Power (0x0851
) y Power Off (0x0855
).
El dispositivo determina el valor inicial de este campo y nunca debe modificarlo, solo el host.
Propiedad: Intervalo de informes (0x030E
)
La propiedad Intervalo de informes (0x030E
) es una propiedad de lectura y escritura que tiene la semántica estándar como se define en la especificación de HID. El host usa esta propiedad para indicarle al dispositivo con qué frecuencia informar sus lecturas de datos.
Las unidades son segundos. El dispositivo determina el rango válido para este valor
y se describe con el mecanismo de Mínimo/Máximo físico. Al menos 50 Hz
tasa de generación de informes debe ser compatible, y la tasa máxima recomendada de estos debe ser
100 Hz. Por lo tanto, el intervalo mínimo del informe debe ser menor o igual que
a 20 ms y se recomienda que sea mayor o igual que 10 ms.
Propiedad: LE Transport reservado por el proveedor (0xF410
)
La propiedad de LE Transport reservada por el proveedor (0xF410
) es una propiedad de lectura/escritura
que tenga la semántica estándar tal como se define en la especificación HID. El host usa esta propiedad para indicar el transporte seleccionado (ACL o ISO). Solo se usan los valores de ACL (0xF800
) e ISO (0xF801
), y ambos deben incluirse en la colección lógica.
Esta propiedad se configura antes de los estados de energía o informes.
Campo de datos: Valor personalizado 1 (0x0544
)
El campo Custom Value 1 (0x0544
) es un campo de entrada que se usa para informar la información real del seguimiento de la cabeza. Es un array de 3 elementos que se interpreta de acuerdo
a las reglas HID normales para valores físicos, como se especifica en la sección 6.2.2.7 de
la especificación HID. El rango válido para cada elemento es [-π, π] rad. Las unidades siempre son radianes.
Los elementos se interpretan como [rx, ry, rz]
, de modo que [rx, ry, rz]
es un vector de rotación que representa la transformación del marco de referencia al marco principal.
La magnitud debe estar dentro del rango [0..π].
El marco de referencia es arbitrario, pero generalmente es fijo y debe ser para diestros. Se acepta una pequeña cantidad de deriva. Los ejes principales son los siguientes:
- X de la oreja izquierda a la derecha
- Y desde la parte posterior de la cabeza hasta la nariz (de atrás hacia adelante)
- Z desde el cuello hasta la parte superior de la cabeza
Campo de datos: valor personalizado 2 (0x0545
)
El campo Valor personalizado 2 (0x0545
) es un campo de entrada que se utiliza para informar el
información real sobre el seguimiento de la cabeza. Es un array de 3 elementos de punto fijo,
interpretarse de acuerdo con las reglas normales de HID para valores físicos.
Las unidades siempre son radianes por segundo.
Los elementos se interpretan como [vx, vy, vz]
, de modo que [vx, vy, vz]
es un vector de rotación que representa la velocidad angular del marco de la cabeza (en relación con sí mismo).
Campo de datos: valor personalizado 3 (0x0546
)
El campo Valor personalizado 3 (0x0546
) es un campo de entrada que se usa para hacer un seguimiento de las discontinuidades en el marco de referencia. Es un número entero escalar de 8 bits de tamaño. El dispositivo debe incrementarlo (con unión) cada vez que se cambia el marco de referencia, por ejemplo, si se restablece el estado de un algoritmo de filtro de orientación que se usa para determinar la orientación. Este valor se interpreta según las reglas normales de HID para los valores físicos. Sin embargo, el valor físico y las unidades no importan. La única información relevante para el host es un valor modificado. Para evitar problemas numéricos relacionados con la pérdida de precisión
mientras conviertes de unidades lógicas a físicas, se recomienda establecer la
valores para el mínimo físico, el máximo físico y el exponente unitario en cero en este campo.
Estructura del informe
La agrupación de propiedades en informes (a través de la asignación de IDs de informes) es flexible. Para mayor eficiencia, te recomendamos separar las propiedades de solo lectura. de las propiedades de lectura y escritura.
En los campos de datos, los campos Valor personalizado 1, 2 y 3 deben estar en el mismo y estar en un solo informe para un dispositivo determinado (colección de aplicaciones).
Cómo enviar informes de entradas
El dispositivo debe enviar de forma periódica y asíncrona (a través de mensajes HID INPUT). enviar informes de entrada cuando se cumplan todas estas condiciones:
- La propiedad Estado de energía se establece en Alimentación completa.
- La propiedad Estado de los informes está configurada en Todos los eventos.
- La propiedad Reporting Interval no es igual a cero.
La propiedad Intervalo de informes determina la frecuencia con la que se envían los informes. Cuándo no se cumple alguna de las condiciones anteriores, el dispositivo no debe enviar ningún informe.
Compatibilidad con versiones anteriores y posteriores
El protocolo HID del dispositivo de seguimiento de cabeza usa un esquema de control de versiones que permite actualizaciones y, al mismo tiempo, interoperabilidad entre un host y un dispositivo que usan diferentes versiones del protocolo. Las versiones del protocolo se identifican con dos números, principales y secundarios, que tienen semánticas distintas, como se describe en las siguientes secciones.
Para determinar las versiones admitidas por un dispositivo, puedes examinar
su propiedad de descripción del sensor (0x0308
).
Compatibilidad con versiones secundarias
Los cambios en la versión secundaria son retrocompatibles con versiones secundarias anteriores que se basan en la misma versión principal. En actualizaciones del menor , el host ignora los campos de datos y propiedades adicionales. Por ejemplo: un dispositivo que usa la versión 1.6 de protocolo es compatible con un host que admite protocolo versión 1.x, incluida la versión 1.5.
Compatibilidad con versiones principales
Se permiten los cambios no retrocompatibles para las modificaciones en versiones principales. Para admitir varias versiones principales para la interoperabilidad con hosts nuevos y antiguos, los dispositivos pueden especificar varias colecciones de apps en sus descriptores de informes. Por ejemplo:
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,
};
En este caso, el host puede enumerar todas las diferentes colecciones de apps que anuncia el dispositivo, examinar su propiedad Sensor Description para determinar las versiones de protocolo que implementa cada una y, luego, elegir la versión de protocolo más reciente que admite el host. Cuando se elige, el host funciona con el único protocolo que se eligió para toda la vida útil de la conexión del dispositivo.
Apéndice: Ejemplo de un descriptor HID
En el siguiente ejemplo, se muestra un descriptor HID válido típico. Usa las macros C de uso general, que se proporcionan en Usos del sensor HID (secció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,
};
Apéndice 2: Ejemplo de un descriptor HID v2.0
En el siguiente ejemplo, se muestra un descriptor HID v2.0 para un dispositivo que admite solo el transporte de LCA de Bluetooth de bajo consumo.
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,
};