Protocollo HID tracker della testa

Il protocollo HID (Human Interface Device), disponibile per i dispositivi con Android 13 e versioni successive, consente di tracciamento della testa da collegare a un dispositivo Android tramite USB oppure attivare il Bluetooth ed essere esposti al framework e alle app Android tramite sensori. Questo protocollo è utilizzato per controllo un effetto di virtualizzatore audio (audio 3D). In questa pagina vengono utilizzati i termini device e host nel senso che ha il Bluetooth, dove device indica il dispositivo di tracciamento della testa mentre host indica l'host Android.

I produttori devono configurare i propri dispositivi Android per abilitare il supporto per il protocollo HID del tracker della testa. Per informazioni più dettagliate su configurazione, consulta README dei sensori dinamici.

Questa pagina presuppone la conoscenza delle seguenti risorse:

Struttura di primo livello

Il framework Android identifica il tracker della testa come un dispositivo HID.

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

Al livello principale, il tracker della testa è una raccolta di app con Sensors (0x20) e l'utilizzo di Other: Custom (0xE1). All'interno sono presenti diversi campi di dati (input) e proprietà (caratteristiche).

Proprietà e campi di dati

Questa sezione descrive le proprietà e i campi di dati di un'applicazione un tracker per la testa.

Proprietà: descrizione del sensore (0x0308)

La proprietà Sensor Description (0x0308) è una stringa ASCII di sola lettura (8 bit) che deve contenere i seguenti valori:

Head tracker versione 1.0:

#AndroidHeadTracker#1.0

Tracker per la testa versione 2.0 (disponibile su Android 15 o superiore), che include il supporto per LE audio:

#AndroidHeadTracker#2.0#x

x è un numero intero (1, 2, 3) che indica il metodo di trasporto dell'assistenza:

  • 1: ACL
  • 2: ISO
  • 3: ACL + ISO

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

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

Proprietà: ID univoco permanente (0x0302)

La proprietà ID univoco permanente (0x0302) è un array di sola lettura di 16 a 8 bit ciascuno (per un totale di 128 bit). Non è previsto alcun carattere di terminazione nullo. Questo è facoltativa.

Questa proprietà consente i dispositivi di tracciamento della testa integrati nell'audio per fare riferimento al dispositivo audio a cui sono collegati. Sono supportati i seguenti schemi.

Tracker autonomo per la testa

Se la proprietà ID univoco permanente (0x0302) non esiste o è impostata su tutte zero, significa che il tracker per la testa non è collegato in modo permanente a un dispositivo audio e possono essere usati separatamente, ad esempio consentendo all'utente associare manualmente il tracker della testa a un dispositivo audio separato.

Riferimento tramite 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 seguenti 6 ottetti interpretabile come un indirizzo MAC Bluetooth, presupponendo che il dispositivo si applica a qualsiasi dispositivo audio con questo indirizzo MAC. Questo indirizzo deve essere il anche se il dispositivo usa un indirizzo MAC casuale per stabilire e connessioni a Internet. Dispositivi dual-mode che si connettono tramite Bluetooth Classic (formato HID v1.0) e Bluetooth LE (formato HID v2.0) devono esporre due HID descrittori con lo stesso indirizzo identità. Dispositivi dual-mode con i dispositivi sinistro e destro devono esporre Bluetooth LE HID utilizzando il dispositivo principale anziché il dispositivo secondario solo LE.

Riferimento tramite UUID

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

Proprietà: stato del report (0x0316)

La proprietà Stato dei report (0x0316) è una proprietà di lettura/scrittura con la semantica standard definita nella specifica HID. L'organizzatore utilizza questo per indicare al dispositivo gli eventi da segnalare. Solo i valori No Vengono utilizzati gli eventi (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 alimentazione (0x0319)

La proprietà Power State (0x0319) è una proprietà di lettura/scrittura con la semantica standard definita nella specifica HID. L'organizzatore utilizza questo per indicare al dispositivo lo stato di alimentazione. Solo il vengono utilizzati i valori Massima potenza (0x0851) e Spegnimento (0x0855).

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

Proprietà: intervallo di report (0x030E)

La proprietà Intervallo di report (0x030E) è una proprietà di lettura/scrittura con il valore la semantica standard definita nella specifica HID. L'organizzatore utilizza questo per indicare al dispositivo la frequenza con cui segnalare le letture dei dati. Le unità sono in secondi. L'intervallo valido per questo valore è determinato dal dispositivo e descritto utilizzando il meccanismo Min/Max fisico. Almeno 50 Hz la frequenza di reporting deve essere supportata e la frequenza massima consigliata è 100 Hz. Pertanto, l'intervallo minimo di report deve essere minore o uguale a a 20 ms ed è consigliato essere superiore o uguale a 10 ms.

Proprietà: LE Transport prenotato dal fornitore (0xF410)

La proprietà LE Transport (0xF410) prenotata dal fornitore è una proprietà di lettura/scrittura che ha la semantica standard definita nella specifica HID. L'organizzatore utilizza questa proprietà per indicare il trasporto selezionato (ACL o ISO). Solo il vengono utilizzati i valori ACL (0xF800) e ISO (0xF801) ed entrambi devono essere inclusi nella raccolta logica.

Questa proprietà è configurata prima dell'attivazione o degli stati dei report.

Campo dati: Valore personalizzato 1 (0x0544)

Il campo Valore personalizzato 1 (0x0544) è un campo di immissione utilizzato per generare report sul informazioni sull'head-tracking effettive. È un array di 3 elementi, interpretato come alle normali regole HID per i valori fisici, come specificato nella sezione 6.2.2.7 delle la specifica HID. L'intervallo valido per ogni elemento è [-1, 10] rad. Unità sono sempre radianti.

Gli elementi sono interpretati come: [rx, ry, rz], in modo che [rx, ry, rz] sia un vettore di rotazione, che rappresenta la trasformazione dal frame di riferimento al frame principale. La grandezza deve essere compresa nell'intervallo [0..")

Il frame di riferimento è arbitrario, ma in genere è fisso e deve essere mano destra. Una piccola deviazione è accettabile. Gli assi della testa sono:

  • X dall'orecchio sinistro a destra
  • Y dalla parte posteriore della testa al naso (dalla parte posteriore alla parte anteriore)
  • Z dal collo alla parte superiore della testa

Campo dati: Valore personalizzato 2 (0x0545)

Il campo Valore personalizzato 2 (0x0545) è un campo di immissione utilizzato per generare report sul informazioni sull'head-tracking effettive. È un array di 3 elementi a punto fisso, interpretati in base alle normali regole HID per i valori fisici. Le unità sono sempre radianti/secondo.

Gli elementi sono interpretati come: [vx, vy, vz], in modo che [vx, vy, vz] sia un vettore di rotazione, che rappresenta la velocità angolare del telaio della testa (relativa a se stessa).

Campo dati: valore personalizzato 3 (0x0546)

Il campo Valore personalizzato 3 (0x0546) è un campo di immissione utilizzato per il monitoraggio discontinuità nel quadro di riferimento. È un numero intero scalare a 8 bit in dimensioni. Deve essere incrementato (con il wraparound) dal dispositivo ogni volta che il frame di riferimento viene modificato, ad esempio se un algoritmo del filtro di orientamento utilizzato per determinare se l'orientamento è stato reimpostato. Questo valore è interpretati in base alle normali regole HID per i valori fisici. Tuttavia, il valore fisico e le unità non contano. Le uniche informazioni pertinenti host è un valore modificato. Per evitare problemi numerici legati alla perdita di precisione durante la conversione da unità logiche a unità fisiche, ti consigliamo di impostare valori per minimo fisico, massimo fisico ed esponente dell'unità a zero per questo campo.

Struttura del report

Il raggruppamento delle proprietà nei report (per assegnazione degli ID report) flessibile. Per maggiore efficienza, consigliamo di separare le proprietà di sola lettura dalle proprietà di lettura/scrittura.

Per i campi dei dati, i campi Valore personalizzato 1, 2 e 3 devono essere uguali ed essere inclusi in un solo report per un determinato dispositivo (raccolta di app).

Invia report di input

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

  • La proprietà Power State è impostata su Full Power.
  • La proprietà Stato dei report è impostata su Tutti gli eventi.
  • La proprietà Intervallo di report è diversa da zero.

La proprietà Intervallo dei report determina la frequenza di invio dei report. Quando se una delle condizioni di cui sopra non è soddisfatta, il dispositivo non deve inviare alcuna segnalazione.

Compatibilità avanti e indietro

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

Le versioni supportate da un dispositivo possono essere determinate esaminando relativa alla proprietà Descrizione del sensore (0x0308).

Compatibilità con le versioni minori

Le modifiche alla versione secondaria sono compatibili con le versioni precedenti che si basano sulla stessa versione principale. Negli aggiornamenti per il minorenne , l'host ignora i campi di dati e le proprietà aggiuntivi. Ad esempio: un dispositivo che utilizza il protocollo versione 1.6 sia compatibile con un host che supporta protocollo versione 1.x, inclusa la versione 1.5.

Compatibilità con le versioni principali

Sono consentite modifiche non compatibili con le versioni precedenti per le modifiche alle versioni principali. A supportare più versioni principali per l'interoperabilità con host vecchi e nuovi, I dispositivi possono specificare più raccolte di app nel proprio report descrittori. Ad 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ò elencare tutte le diverse raccolte di app pubblicizzato dal dispositivo, esaminando la proprietà Descrizione del sensore per determinare le versioni di protocollo implementate, quindi scegliere l'ultima versione del protocollo supportata dall'host. Quando viene scelto, l'organizzatore lavora con l'unico protocollo scelto per tutta la durata del dispositivo connessione.

Appendice: esempio di descrittore HID

L'esempio seguente illustra un tipico descrittore HID valido. Utilizza la classe le macro C di uso comune, fornite Utilizzi 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,
};

Appendice 2: Esempio di descrittore HID v2.0

L'esempio seguente illustra un descrittore HID v2.0 per un dispositivo che supporta solo il trasporto Bluetooth 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,
};