Protocollo HID del tracciatore della testa

Il protocollo HID (Head Tracker Human Interface Device), disponibile per dispositivi con Android 13 e versioni successive, consente di connettere un dispositivo di tracciamento della testa a un dispositivo Android tramite USB o Bluetooth e di essere esposto al framework e alle app Android attraverso i sensori struttura. Questo protocollo viene utilizzato per controllare un effetto di virtualizzazione audio (audio 3D). In questa pagina vengono utilizzati i termini dispositivo e host nel senso Bluetooth, dove dispositivo indica il dispositivo di tracciamento della testa e host indica l'host Android.

I produttori di dispositivi devono configurare i propri dispositivi Android per abilitare il supporto per il protocollo HID head tracker. Per informazioni più dettagliate sulla configurazione, consultare il README dei sensori dinamici .

Questa pagina presuppone la familiarità con le seguenti risorse:

Struttura di primo livello

Il framework Android identifica il dispositivo head tracker come dispositivo HID.

Per un esempio completo di descrittore HID valido, vedere Appendice 1: Esempio di descrittore HID .

Al livello più alto, il dispositivo head tracker è una raccolta di app con la pagina Sensors ( 0x20 ) e Other: Custom ( 0xE1 ). All'interno di questa raccolta sono presenti diversi campi dati ( input ) e proprietà ( funzionalità ).

Proprietà e campi dati

Questa sezione descrive le proprietà e i campi dati in una raccolta di applicazioni di un dispositivo head tracker.

Proprietà: Descrizione sensore ( 0x0308 )

La proprietà Descrizione sensore ( 0x0308 ) è una proprietà stringa ASCII (8 bit) di sola lettura che deve contenere il seguente valore:

#AndroidHeadTracker#1.0

Non è previsto alcun terminatore null, il che significa che la dimensione totale di questa proprietà è di 23 caratteri a 8 bit.

Questa proprietà funge da discriminatore per evitare collisioni con altri sensori personalizzati.

Proprietà: ID univoco persistente ( 0x0302 )

La proprietà ID univoco persistente ( 0x0302 ) è un array di sola lettura di 16 elementi, 8 bit ciascuno (totale 128 bit). Non è previsto alcun terminatore nullo. Questa proprietà è facoltativa.

Questa proprietà consente ai dispositivi di rilevamento della testa integrati nei dispositivi audio di fare riferimento al dispositivo audio a cui sono collegati. Sono supportati i seguenti schemi.

Tracciatore della testa autonomo

Se la proprietà ID univoco persistente ( 0x0302 ) non esiste o è impostata su tutti zeri, significa che il dispositivo head tracker non è permanentemente collegato a un dispositivo audio e può essere utilizzato separatamente, ad esempio, consentendo all'utente manualmente associare il dispositivo head tracker a un dispositivo audio separato.

Riferimento utilizzando l'indirizzo MAC Bluetooth

Ottetto 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Valore 0 0 0 0 0 0 0 0 B T MAC Bluetooth

In questo schema, i primi 8 ottetti devono essere 0 , gli ottetti 8 e 9 devono contenere rispettivamente i valori ASCII B e T e i successivi 6 ottetti vengono interpretati come un indirizzo MAC Bluetooth, presupponendo che il dispositivo head tracker si applichi a qualsiasi dispositivo audio avente questo indirizzo MAC.

Riferimento tramite UUID

Ogni volta che viene impostato il bit più significativo (MSB) dell'ottetto 8 ( ≥0x80 ), il campo viene interpretato come UUID, come specificato in RFC-4122 . Il dispositivo audio corrispondente fornisce lo stesso UUID, che viene registrato sul framework Android, attraverso un meccanismo non meglio specificato e specifico per il tipo di trasporto utilizzato.

Proprietà: Stato di segnalazione ( 0x0316 )

La proprietà Reporting State ( 0x0316 ) è una proprietà di lettura/scrittura con la semantica standard definita nella specifica HID. L'host utilizza questa proprietà per indicare al dispositivo quali eventi segnalare. Vengono utilizzati solo i valori Nessun evento ( 0x0840 ) e Tutti gli eventi ( 0x0841 ).

Il valore iniziale di questo campo deve essere Nessun evento e non deve mai essere modificato dal dispositivo, ma solo dall'host.

Proprietà: Stato di alimentazione ( 0x0319 )

La proprietà Power State ( 0x0319 ) è una proprietà di lettura/scrittura con la semantica standard definita nella specifica HID. L'host utilizza questa proprietà per indicare al dispositivo in quale stato di alimentazione deve trovarsi. Vengono utilizzati solo i valori Full Power ( 0x0851 ) e Power Off ( 0x0855 ).

Il valore iniziale di questo campo è determinato dal dispositivo e non deve mai essere modificato dal dispositivo, ma solo dall'host.

Proprietà: Intervallo report ( 0x030E )

La proprietà Report Interval ( 0x030E ) è una proprietà di lettura/scrittura con la semantica standard definita nella specifica HID. L'host utilizza questa proprietà per indicare al dispositivo la frequenza con cui segnalare le letture dei dati. Le unità sono secondi. L'intervallo valido per questo valore è determinato dal dispositivo e descritto utilizzando il meccanismo fisico Min/Max. Deve essere supportata una frequenza di segnalazione di almeno 50 Hz e la frequenza di segnalazione massima consigliata è 100 Hz. Pertanto, l'intervallo minimo di report deve essere inferiore o uguale a 20 ms e si consiglia che sia maggiore o uguale a 10 ms.

Campo dati: Valore personalizzato 1 ( 0x0544 )

Il campo Valore personalizzato 1 ( 0x0544 ) è un campo di input utilizzato per riportare le informazioni effettive sul tracciamento della testa. È un array di 3 elementi, interpretato secondo le normali regole HID per i valori fisici come specificato nella sezione 6.2.2.7 delle specifiche HID. L'intervallo valido per ciascun elemento è [-π, π] rad. Le unità sono sempre radianti.

Gli elementi sono interpretati come: [rx, ry, rz] , tale che [rx, ry, rz] è un vettore di rotazione , che rappresenta la trasformazione dal sistema di riferimento al fotogramma principale. La grandezza deve essere compresa nell'intervallo [0..π].

Il sistema di riferimento è arbitrario, ma generalmente è fisso e deve essere destrorso. Una piccola deriva è accettabile. Gli assi della testa sono:

  • X dall'orecchio sinistro a destro
  • Y dalla parte posteriore della testa al naso (da dietro in avanti)
  • Z dal collo alla sommità della testa

Campo dati: Valore personalizzato 2 ( 0x0545 )

Il campo Valore personalizzato 2 ( 0x0545 ) è un campo di input utilizzato per riportare le informazioni effettive sul tracciamento della testa. È un array a virgola fissa di 3 elementi, interpretato secondo le normali regole HID per i valori fisici. Le unità sono sempre radianti/secondo.

Gli elementi sono interpretati come: [vx, vy, vz] , tale che [vx, vy, vz] è un vettore di rotazione , che rappresenta la velocità angolare del telaio della testa (rispetto a se stesso).

Campo dati: Valore personalizzato 3 ( 0x0546 )

Il campo Valore personalizzato 3 ( 0x0546 ) è un campo di input utilizzato per tracciare le discontinuità nel quadro di riferimento. È un intero scalare di 8 bit. Deve essere incrementato (con wraparound) dal dispositivo ogni volta che il sistema di riferimento viene modificato, ad esempio, se un algoritmo di filtro di orientamento utilizzato per determinare l'orientamento ha subito il ripristino dello stato. Questo valore viene interpretato secondo le normali regole HID per i valori fisici. Tuttavia, il valore fisico e le unità non contano. L'unica informazione rilevante per l'host è un valore modificato. Per evitare problemi numerici legati alla perdita di precisione durante la conversione da unità logiche a unità fisiche, si consiglia di impostare i valori minimo fisico, massimo fisico ed esponente unitario su zero per questo campo.

Struttura del rapporto

Il raggruppamento delle proprietà nei report (mediante l'assegnazione degli ID report) è flessibile. Per motivi di efficienza, consigliamo di separare le proprietà di sola lettura dalle proprietà di lettura/scrittura.

Per i campi dati, i campi Valore personalizzato 1, 2 e 3 devono trovarsi nello stesso report ed essere presenti in un solo report per un determinato dispositivo (raccolta di app).

Invia report di input

Il dispositivo deve periodicamente e in modo asincrono (tramite messaggi HID INPUT) inviare report di input quando tutte queste condizioni sono soddisfatte:

  • La proprietà Power State è impostata su Piena potenza.
  • La proprietà Stato segnalazione è impostata su Tutti gli eventi.
  • La proprietà Intervallo di reporting è diversa da zero.

La proprietà Intervallo di reporting determina la frequenza con cui inviare i report. Quando una qualsiasi delle condizioni di cui sopra non è soddisfatta, il dispositivo non deve inviare alcun report.

Compatibilità avanti e indietro

Il protocollo HID head tracker utilizza uno schema di controllo delle versioni che consente gli aggiornamenti, consentendo al tempo stesso l'interoperabilità tra un host e un dispositivo che utilizzano versioni diverse del protocollo. Le versioni del protocollo sono identificate da due numeri, maggiore e minore, che hanno una semantica distinta come descritto nelle sezioni seguenti.

Le versioni supportate da un dispositivo possono essere determinate esaminando la sua proprietà Descrizione sensore ( 0x0308 ).

Compatibilità con versioni minori

Le modifiche alla versione secondaria sono retrocompatibili con le versioni minori precedenti basate sulla stessa versione principale. Negli aggiornamenti alla versione secondaria, l'host ignora campi dati e proprietà aggiuntivi. Ad esempio, un dispositivo che utilizza la versione del protocollo 1.6 è compatibile con un host che supporta la versione del protocollo 1.x, inclusa la versione 1.5.

Compatibilità delle versioni principali

Sono consentite modifiche non compatibili con le versioni precedenti per le modifiche alle versioni principali. Per supportare più versioni principali per l'interoperabilità con host vecchi e nuovi, i dispositivi possono specificare più raccolte di app nei descrittori di report. Per esempio:

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

In questo caso, l'host può enumerare tutte le diverse raccolte di app pubblicizzate dal dispositivo, esaminando la proprietà Descrizione sensore per determinare le versioni di protocollo implementate da ciascuna di esse, quindi selezionando la versione di protocollo più recente supportata dall'host. Quando selezionato, l'host funziona con il singolo protocollo scelto per tutta la durata della connessione del dispositivo.

Appendice: esempio di descrittore HID

L'esempio seguente illustra un tipico descrittore HID valido. Utilizza le macro C comunemente utilizzate, fornite in Utilizzo dei sensori HID (sezione 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,
};