Protocolo HID do rastreador de cabeça

O protocolo HID (dispositivo de interface humana) do rastreador de cabeça, disponível para dispositivos com Android 13 e superior, permite que um dispositivo de rastreamento de cabeça seja conectado a um dispositivo Android por meio de USB ou Bluetooth e seja exposto à estrutura e aos aplicativos Android por meio dos sensores estrutura. Este protocolo é usado para controlar um efeito virtualizador de áudio (áudio 3D). Esta página usa os termos dispositivo e host no sentido Bluetooth, onde dispositivo significa o dispositivo de rastreamento de cabeça e host significa o host Android.

Os fabricantes de dispositivos devem configurar seus dispositivos Android para ativar o suporte ao protocolo HID do rastreador de cabeça. Para obter informações mais detalhadas sobre configuração, consulte o README de Sensores Dinâmicos .

Esta página pressupõe familiaridade com os seguintes recursos:

Estrutura de nível superior

A estrutura Android identifica o dispositivo rastreador de cabeça como um dispositivo HID.

Para obter um exemplo completo de um descritor HID válido, consulte Apêndice 1: Exemplo de um descritor HID .

No nível superior, o dispositivo rastreador de cabeça é uma coleção de aplicativos com a página Sensors ( 0x20 ) e Other: Custom ( 0xE1 ). Dentro desta coleção estão vários campos de dados ( entradas ) e propriedades ( recursos ).

Propriedades e campos de dados

Esta seção descreve as propriedades e os campos de dados em uma coleção de aplicativos de um dispositivo rastreador de cabeça.

Propriedade: Descrição do Sensor ( 0x0308 )

A propriedade Sensor Description ( 0x0308 ) é uma propriedade de string ASCII (8 bits) somente leitura que deve conter o seguinte valor:

#AndroidHeadTracker#1.0

Nenhum terminador nulo é esperado, o que significa que o tamanho total dessa propriedade é de 23 caracteres de 8 bits.

Esta propriedade serve como discriminador para evitar colisões com outros sensores personalizados.

Propriedade: ID exclusivo persistente ( 0x0302 )

A propriedade Persistent Unique ID ( 0x0302 ) é uma matriz somente leitura de 16 elementos, 8 bits cada (total de 128 bits). Nenhum terminador nulo é esperado. Esta propriedade é opcional.

Esta propriedade permite que dispositivos de rastreamento de cabeça integrados em dispositivos de áudio façam referência ao dispositivo de áudio ao qual estão conectados. Os esquemas a seguir são suportados.

Rastreador de cabeça autônomo

Se a propriedade Persistent Unique ID ( 0x0302 ) não existir ou estiver definida como zeros, significa que o dispositivo rastreador de cabeça não está permanentemente conectado a um dispositivo de áudio e pode ser usado separadamente, por exemplo, permitindo que o usuário manualmente associar o dispositivo rastreador de cabeça a um dispositivo de áudio separado.

Referência usando endereço MAC 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 MAC Bluetooth

Neste esquema, os primeiros 8 octetos devem ser 0 , os octetos 8 e 9 devem conter os valores ASCII B e T respectivamente, e os 6 octetos seguintes são interpretados como um endereço MAC Bluetooth, assumindo que o dispositivo rastreador principal se aplica a qualquer dispositivo de áudio tendo este endereço MAC.

Referência usando UUID

Sempre que o bit mais significativo (MSB) do octeto 8 for definido ( ≥0x80 ), o campo será interpretado como um UUID, conforme especificado em RFC-4122 . O dispositivo de áudio correspondente fornece o mesmo UUID, que é registrado no framework Android, por meio de um mecanismo não especificado e específico do tipo de transporte utilizado.

Propriedade: Estado do Relatório ( 0x0316 )

A propriedade Reporting State ( 0x0316 ) é uma propriedade de leitura/gravação que possui a semântica padrão definida na especificação HID. O host usa essa propriedade para indicar ao dispositivo quais eventos relatar. Somente os valores No Events ( 0x0840 ) e All Events ( 0x0841 ) são usados.

O valor inicial deste campo deve ser No Events e nunca deve ser modificado pelo dispositivo, apenas pelo host.

Propriedade: Estado de energia ( 0x0319 )

A propriedade Power State ( 0x0319 ) é uma propriedade de leitura/gravação que possui a semântica padrão definida na especificação HID. O host utiliza esta propriedade para indicar ao dispositivo em qual estado de energia ele deve estar. Somente os valores Full Power ( 0x0851 ) e Power Off ( 0x0855 ) são utilizados.

O valor inicial deste campo é determinado pelo dispositivo e nunca deve ser modificado pelo dispositivo, apenas pelo host.

Propriedade: Intervalo de Relatório ( 0x030E )

A propriedade Report Interval ( 0x030E ) é uma propriedade de leitura/gravação que possui a semântica padrão definida na especificação HID. O host usa essa propriedade para indicar ao dispositivo com que frequência relatar suas leituras de dados. As unidades são segundos. A faixa válida para esse valor é determinada pelo dispositivo e descrita usando o mecanismo Físico Min/Max. Deve ser suportada uma taxa de transmissão de pelo menos 50 Hz e a taxa de transmissão máxima recomendada é de 100 Hz. Portanto, o intervalo mínimo de reporte deve ser menor ou igual a 20 ms, sendo recomendado que seja maior ou igual a 10 ms.

Campo de dados: Valor personalizado 1 ( 0x0544 )

O campo Valor personalizado 1 ( 0x0544 ) é um campo de entrada usado para relatar as informações reais de rastreamento de cabeça. É uma matriz de 3 elementos, interpretada de acordo com as regras normais do HID para valores físicos, conforme especificado na seção 6.2.2.7 da especificação HID. O intervalo válido para cada elemento é [-π, π] rad. As unidades são sempre radianos.

Os elementos são interpretados como: [rx, ry, rz] , de modo que [rx, ry, rz] é um vetor de rotação , representando a transformação do quadro de referência para o quadro principal. A magnitude deve estar no intervalo [0..π].

O referencial é arbitrário, mas geralmente é fixo e deve ser destro. Uma pequena quantidade de desvio é aceitável. Os eixos principais são:

  • X da orelha esquerda para a direita
  • Y da parte de trás da cabeça até o nariz (de trás para frente)
  • Z do pescoço ao topo da cabeça

Campo de dados: Valor personalizado 2 ( 0x0545 )

O campo Valor personalizado 2 ( 0x0545 ) é um campo de entrada usado para relatar as informações reais de rastreamento de cabeça. É uma matriz de ponto fixo de 3 elementos, interpretada de acordo com as regras HID normais para valores físicos. As unidades são sempre radianos/segundo.

Os elementos são interpretados como: [vx, vy, vz] , de modo que [vx, vy, vz] é um vetor de rotação , representando a velocidade angular da estrutura da cabeça (em relação a si mesma).

Campo de dados: Valor personalizado 3 ( 0x0546 )

O campo Valor personalizado 3 ( 0x0546 ) é um campo de entrada usado para rastrear descontinuidades no quadro de referência. É um número inteiro escalar de 8 bits de tamanho. Deve ser incrementado (com wraparound) pelo dispositivo toda vez que o quadro de referência for alterado, por exemplo, se um algoritmo de filtro de orientação usado para determinar a orientação tiver seu estado redefinido. Este valor é interpretado de acordo com as regras HID normais para valores físicos. No entanto, o valor físico e as unidades não importam. A única informação relevante para o host é um valor alterado. Para evitar problemas numéricos relacionados à perda de precisão durante a conversão de unidades lógicas para físicas, é recomendável definir os valores de mínimo físico, máximo físico e expoente da unidade como zero para este campo.

Estrutura do relatório

O agrupamento de propriedades em relatórios (por atribuição de IDs de relatório) é flexível. Para maior eficiência, recomendamos separar as propriedades somente leitura das propriedades de leitura/gravação.

Para os campos de dados, os campos de Valor Personalizado 1, 2 e 3 devem estar no mesmo relatório e em apenas um relatório para um determinado dispositivo (coleção de aplicativos).

Enviar relatórios de entrada

O dispositivo deve enviar relatórios de entrada periodicamente e de forma assíncrona (através de mensagens HID INPUT) quando todas estas condições forem atendidas:

  • A propriedade Power State está definida como Full Power.
  • A propriedade Estado do Relatório está definida como Todos os Eventos.
  • A propriedade Intervalo de Relatório é diferente de zero.

A propriedade Reporting Interval determina a frequência de envio dos relatórios. Quando alguma das condições acima não for atendida, o dispositivo não deverá enviar nenhum relatório.

Compatibilidade com versões anteriores e posteriores

O protocolo HID do rastreador principal usa um esquema de controle de versão que permite atualizações, ao mesmo tempo que permite a interoperabilidade entre um host e um dispositivo que usa versões diferentes do protocolo. As versões do protocolo são identificadas por dois números, maior e menor, que possuem semântica distinta conforme descrito nas seções a seguir.

As versões suportadas por um dispositivo podem ser determinadas examinando sua propriedade Sensor Description ( 0x0308 ).

Compatibilidade com versões secundárias

As alterações na versão secundária são compatíveis com versões anteriores baseadas na mesma versão principal. Nas atualizações da versão secundária, o host ignora campos de dados e propriedades adicionais. Por exemplo, um dispositivo que usa o protocolo versão 1.6 é compatível com um host que suporta o protocolo versão 1.x, incluindo a versão 1.5.

Compatibilidade de versão principal

Alterações não compatíveis com versões anteriores são permitidas para alterações em versões principais. Para oferecer suporte a diversas versões principais para interoperabilidade com hosts novos e antigos, os dispositivos podem especificar diversas coleções de aplicativos em seus descritores de relatório. Por exemplo:

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

Nesse caso, o host pode enumerar todas as diferentes coleções de aplicativos anunciadas pelo dispositivo, examinando sua propriedade Sensor Description para determinar as versões de protocolo que cada uma delas implementa e, em seguida, escolhendo a versão de protocolo mais recente compatível com o host. Quando escolhido, o host funciona com o protocolo único escolhido para o tempo de vida da conexão do dispositivo.

Apêndice: Exemplo de um descritor HID

O exemplo a seguir ilustra um descritor HID válido típico. Ele usa as macros C comumente usadas, fornecidas em Usos do sensor HID (seção 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,
};