Il protocollo HID (Human Interface Device) del tracker per la testa, disponibile per i dispositivi con Android 13 e versioni successive, consente di collegare un tracker per la testa a un dispositivo Android tramite USB o Bluetooth ed esporlo al framework e alle app Android tramite il framework sensori. Questo protocollo viene utilizzato per controllare un effetto di virtualizzazione 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 di dispositivi devono configurare i propri dispositivi Android per attivare il supporto del protocollo HID del tracker per la testa. Per informazioni più dettagliate su per la configurazione, consulta README dei sensori dinamici.
In questa pagina si presuppone che tu conosca le seguenti risorse:
- Definizione della classe di dispositivo per HID
- Tabelle di utilizzo HID per USB
- Utilizzi dei sensori HID
Struttura di primo livello
Il framework Android identifica il tracker per la testa come 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 sensore (0x0308
)
La proprietà Descrizione sensore (0x0308
) è una proprietà di stringa ASCII (8 bit) di sola lettura che deve contenere i seguenti valori:
Head tracker versione 1.0:
#AndroidHeadTracker#1.0
Tracker per il movimento della testa versione 2.0 (disponibile su Android 15 o versioni successive), che include il supporto dell'audio LE:
#AndroidHeadTracker#2.0#x
x
è un numero intero (1
, 2
, 3
) che indica il trasporto supportato:
- 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 persistente (0x0302
) è un array di sola lettura di 16 elementi, ciascuno di 8 bit (128 bit in totale). Non è previsto un terminatore null. Questa proprietà è facoltativa.
Questa proprietà consente ai dispositivi di monitoraggio della testa integrati nei dispositivi audio di fare riferimento al dispositivo audio a cui sono collegati. Sono supportati i seguenti schemi.
Tracker autonomo per la testa
Se la proprietà ID univoco persistente (0x0302
) non esiste o è impostata su tutti i zeri, significa che il tracker per la testa non è collegato in modo permanente a un dispositivo audio e può essere utilizzato separatamente, ad esempio consentendo all'utente di associarlo manualmente 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 | Indirizzo 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 l'indirizzo di identità, anche se il dispositivo utilizza un indirizzo MAC casuale per stabilire le connessioni. I dispositivi dual mode che si connettono tramite Bluetooth classico
(formato HID v1.0) e Bluetooth LE (formato HID v2.0) devono esporre due descrittori HID con lo stesso indirizzo di 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 utilizzando l'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. Il
dispositivo audio corrispondente fornisce lo stesso UUID, registrato sul
framework Android, tramite un meccanismo non specificato specifico per il
tipo di trasporto utilizzato.
Proprietà: Stato report (0x0316
)
La proprietà Stato report (0x0316
) è una proprietà di lettura/scrittura che ha la semantica standard come 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à Stato alimentazione (0x0319
) è una proprietà di lettura/scrittura che ha la semantica standard come definita nella specifica HID. L'organizzatore utilizza questo
per indicare al dispositivo lo stato di alimentazione. 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 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'host utilizza questa proprietà per indicare al dispositivo la frequenza con cui segnalare le letture dei dati.
Le unità di misura 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'host
utilizza questa proprietà per indicare il protocollo di 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à viene configurata prima degli stati di alimentazione o di generazione di report.
Campo dati: Valore personalizzato 1 (0x0544
)
Il campo Valore personalizzato 1 (0x0544
) è un campo di immissione utilizzato per registrare le informazioni effettive sul monitoraggio della testa. Si tratta di un array di 3 elementi, interpretato in base alle normali regole HID per i valori fisici come specificato nella sezione 6.2.2.7 della specifica HID. L'intervallo valido per ogni elemento è [-1, 1] 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.
L'intensità 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 quello destro
- Y dalla parte posteriore della testa al naso (dalla parte posteriore alla parte anteriore)
- Z dal collo alla sommità 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. Si tratta di un array a virgola fissa di 3 elementi, interpretato 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 monitorare le discontinuità nel frame di riferimento. Si tratta di un numero intero scalare di 8 bit. 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
utilizzata per determinare se l'orientamento è stato reimpostato. Questo valore viene interpretato in base alle normali regole HID per i valori fisici. Tuttavia, il valore fisico e le unità non sono importanti. L'unica informazione pertinente per l'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 di dati, i campi Valore personalizzato 1, 2 e 3 devono trovarsi nello stesso report e in un solo report per un determinato dispositivo (raccolta di app).
Inviare report sugli 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 report determina la frequenza di invio dei report. Se una delle condizioni sopra indicate non è soddisfatta, il dispositivo non deve inviare alcun report.
Compatibilità con le versioni precedenti e successive
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 come descritto nelle sezioni seguenti.
Le versioni supportate da un dispositivo possono essere determinate esaminando la proprietà Descrizione sensore (0x0308
).
Compatibilità con le versioni minori
Le modifiche alla versione minore sono compatibili con le versioni minori precedenti basate 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 la versione 1.6 del protocollo è compatibile con un host che supporta la versione 1.x del protocollo, inclusa la versione 1.5.
Compatibilità con le versioni principali
Le modifiche non compatibili con le versioni precedenti sono consentite 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ò enumerare tutte le diverse raccolte di app pubblicizzate dal dispositivo, esaminando la proprietà Sensor Description per determinare le versioni del protocollo implementate da ciascuna e poi scegliendo la versione più recente 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 descrittore HID valido tipico. 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 soltanto il trasporto ACL Bluetooth LE.
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,
};