Protokół HID (ludzki interfejs urządzenia śledzącego) dostępny na urządzeniach z Androidem 13 lub nowszym, śledzące ruchy głowy, które należy podłączyć do urządzenia z Androidem przez USB lub Bluetooth oraz dostęp do platformy i aplikacji Androida za pomocą sensors. Protokół ten służy do kontrolowania efekt wirtualizacji dźwięku (dźwięk 3D). Na tej stronie używamy haseł urządzenie i hosta w technologii Bluetooth, gdzie urządzenie oznacza urządzenie śledzące ruch głowy a host oznacza hosta Androida.
Producenci urządzeń muszą skonfigurować swoje urządzenia z Androidem, aby umożliwić obsługę dla protokołu HID trackera. Aby uzyskać bardziej szczegółowe informacje: konfiguracji, zapoznaj się z Plik README dotyczący czujników dynamicznych.
Zakładamy, że znasz te zasoby:
Struktura najwyższego poziomu
Platforma Androida identyfikuje urządzenie śledzące na głowie jako urządzenie HID.
Pełny przykład prawidłowego deskryptora HID znajdziesz w sekcji Załącznik 1. Przykład deskryptora HID
Najwyższy poziom trackera to kolekcja aplikacji z
Sensors
(0x20
) i użycie usługi Other: Custom
(0xE1
). Wewnątrz
zbiór danych obejmuje różne pola danych (dane wejściowe) i właściwości (funkcje).
Właściwości i pola danych
W tej sekcji opisano właściwości i pola danych w aplikacji kolekcji trackerów na głowie.
Właściwość: opis czujnika (0x0308
)
Właściwość Sensor Opis (0x0308
) jest ciągiem 8-bitowym (tylko do odczytu) ASCII.
właściwość, która musi zawierać tę wartość:
#AndroidHeadTracker#1.0
Nie oczekuje się wartości null-terminator, co oznacza, że całkowity rozmiar tej usługi ma 23 znaki 8-bitowe.
Ta właściwość służy jako dyskryminator, aby uniknąć kolizji z innymi za pomocą niestandardowych czujników.
Usługa: stały unikalny identyfikator (0x0302
)
Właściwość stałego unikalnego identyfikatora (0x0302
) to tablica tylko do odczytu zawierająca 16 elementów
elementów, po 8 bitów (łącznie 128 bitów). Nie oczekuje się zakończenia o wartości null. Ten
jest opcjonalna.
Ta właściwość zezwala na urządzenia śledzące ruchy głowy, które są zintegrowane z dźwiękiem. urządzeń, aby wskazać urządzenie audio, do którego są podłączone. Obsługiwane są poniższe schematy.
Samodzielny tracker na głowę
Jeśli właściwość Persistent Unique ID (0x0302
) nie istnieje lub została ustawiona na wszystkie
oznacza to, że tracker nie jest na stałe podłączony do
urządzenia audio i można jej używać oddzielnie, np. umożliwiając
ręcznie powiązać go z osobnym urządzeniem audio.
Odniesienie z użyciem adresu MAC Bluetootha
Oktet | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Wartość | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | B | T | Adres MAC Bluetooth |
W tym schemacie pierwsze 8 oktetów musi zawierać ciąg 0
, oktety 8 i 9 muszą zawierać
wartości ASCII odpowiednio B
i T
, a następujących 6 oktetów jest
interpretowane jako adres MAC Bluetootha przy założeniu, że urządzenie śledzące
dotyczy wszystkich urządzeń audio z tym adresem MAC.
Odwołanie z użyciem identyfikatora UUID
Gdy ustawiony jest najbardziej znaczący bit (MSB) oktetu 8 (≥0x80
), pole
jest interpretowany jako identyfikator UUID, jak określono w
RFC-4122.
odpowiednie urządzenie audio udostępnia ten sam identyfikator UUID zarejestrowany na
platformy Androida za pomocą nieokreślonego mechanizmu charakterystycznego dla
z jakiegoś rodzaju transportu.
Usługa: stan raportowania (0x0316
)
Właściwość Stan raportowania (0x0316
) to właściwość do odczytu/zapisu, w której występuje wartość
standardowej semantyki zdefiniowanej w specyfikacji HID. Używany przez gospodarza
aby wskazać urządzeniu, które zdarzenia mają być zgłaszane. Tylko wartości Nie
Użyto Zdarzenia (0x0840
) i Wszystkie zdarzenia (0x0841
).
Początkowa wartość tego pola musi wynosić Brak zdarzeń i nigdy nie może modyfikowane przez urządzenie, tylko przez gospodarza.
Usługa: stan zasilania (0x0319
)
Właściwość Power State (0x0319
) to właściwość do odczytu/zapisu, która zawiera atrybut
standardowej semantyki zdefiniowanej w specyfikacji HID. Używany przez gospodarza
we właściwości, aby wskazać urządzeniu, w jakim musi być ono stanie zasilania. Tylko
używane są wartości Pełne zasilanie (0x0851
) i Wyłącz (0x0855
).
Początkowa wartość tego pola zależy od urządzenia i nie można jej nigdy modyfikowane przez urządzenie, tylko przez gospodarza.
Usługa: interwał raportów (0x030E
)
Właściwość Interwał raportów (0x030E
) to właściwość do odczytu/zapisu, w której parametr
standardowej semantyki zdefiniowanej w specyfikacji HID. Używany przez gospodarza
właściwość wskazującą urządzenie, jak często ma ono raportować odczyty danych.
Jednostki są wyrażone w sekundach. Prawidłowy zakres tej wartości jest określany przez urządzenie
i opisane z użyciem mechanizmu
minimalne/maksymalnej wartości fizycznej. Co najmniej 50 Hz
częstotliwość raportowania musi być obsługiwana, a zalecana maksymalna częstotliwość raportowania to
100 Hz. W związku z tym minimalny odstęp czasu między raportem musi być mniejszy niż lub równy
do 20 ms, a zalecana wartość to co najmniej 10 ms.
Pole danych: wartość niestandardowa 1 (0x0544
)
Pole Wartość niestandardowa 1 (0x0544
) to pole do wprowadzania danych służące do raportowania wartości
prawdziwych danych
na temat śledzenia ruchów głowy. Jest to 3-elementowa tablica interpretowana jako
do normalnych reguł HID dla wartości fizycznych, zgodnie z sekcją 6.2.2.7
ze specyfikacją HID. Prawidłowy zakres dla każdego elementu to [-π, π] rad. Jednostki
zawsze są radiany.
Elementy są interpretowane w taki sposób: [rx, ry, rz]
, więc [rx, ry, rz]
to
wektor obrotu,
reprezentujący przekształcenie z ramki referencyjnej w ramkę nagłówka.
Magnituda musi należeć do zakresu [0..π].
Układ odniesienia jest dowolny, ale zwykle jest stały i musi być dla prawej ręki. Dopuszczalna jest niewielka wartość dryfu. Osie głowy:
- X od lewego ucha do prawej
- Y od tylnej części głowy do nosa (od tyłu do przodu)
- Z od szyi do góry głowy
Pole danych: wartość niestandardowa 2 (0x0545
)
Pole Wartość niestandardowa 2 (0x0545
) to pole do wprowadzania danych służące do raportowania wartości
prawdziwych danych
na temat śledzenia ruchów głowy. Jest to 3-elementowa macierz punktowa
interpretowane zgodnie ze normalnymi regułami HID dla wartości fizycznych.
Jednostki to zawsze radiany na sekundę.
Elementy są interpretowane w taki sposób: [vx, vy, vz]
, więc [vx, vy, vz]
to
wektor obrotu,
reprezentujący prędkość kątową ramy głowy (względem siebie).
Pole danych: wartość niestandardowa 3 (0x0546
)
Pole Wartość niestandardowa 3 (0x0546
) to pole do wprowadzania danych używane do śledzenia
nieciągłości w ramce referencyjnej. Jest to skalarna liczba całkowita 8-bitowa
rozmiaru. Musi zostać zwiększona (z zawijaniem) za każdym razem, gdy
obszar odniesienia ulegnie zmianie, np. gdy algorytm filtra orientacji zostanie zmieniony.
służy do określenia, że stan orientacji został zresetowany. Ta wartość to
interpretowane zgodnie ze normalnymi regułami HID dla wartości fizycznych. Pamiętaj jednak:
wartość fizyczna i jednostki nie mają znaczenia. Jedyne istotne informacje
host to zmieniona wartość. Aby uniknąć problemów liczbowych związanych z utratą dokładności
przy konwertowaniu jednostek logicznych na fizyczne zalecamy ustawienie
dla fizycznego minimum, fizycznego maksimum i wykładnika jednostki do zera dla tego pola.
Struktura raportu
Grupowanie usług w raporty (przez przypisanie identyfikatorów raportów) to i elastyczności. Aby zwiększyć wydajność, najlepiej oddzielić właściwości tylko do odczytu z właściwości do odczytu/zapisu.
W przypadku pól danych pola Wartość niestandardowa 1, 2 i 3 muszą być w tym samym widoku i wyświetlać tylko jeden raport dla danego urządzenia (kolekcja aplikacji).
Wysyłaj raporty wejściowe
Urządzenie musi okresowo i asynchronicznie (za pomocą komunikatów HID INPUT) wysyłaj raporty wejściowe, gdy są spełnione wszystkie poniższe warunki:
- Właściwość stanu zasilania ma wartość Pełne zasilanie.
- Właściwość Stan raportowania jest ustawiona na Wszystkie zdarzenia.
- Właściwość Interwał raportowania ma wartość różną od zera.
Właściwość Interwał raportowania określa, jak często mają być wysyłane raporty. Kiedy żaden z powyższych warunków nie jest spełniony, urządzenie nie może wysyłać żadnych raportów.
Zgodność do przodu i do tyłu
Protokół HID trackera korzysta ze schematu obsługi wersji, który umożliwia aktualizacji przy jednoczesnym umożliwieniu współdziałania hosta i urządzenia korzystającego różnych wersji protokołu. Zidentyfikowano wersje protokołu dzielone na dwie liczby, większe i mniejsze. Mają one odmienne semantyki: opisane w dalszej części tego artykułu.
Wersje obsługiwane przez urządzenie można określić, analizując
jego właściwość „Opis czujnika” (0x0308
).
Zgodność wersji podrzędnych
Zmiany w wersji podrzędnej są zgodne wstecznie z wcześniejszymi wersjami podrzędnymi opartych na tej samej wersji głównej. Informacje dotyczące osoby nieletniej wersji, host ignoruje dodatkowe pola danych i właściwości. Przykład: urządzenie korzystające z protokołu w wersji 1.6 jest zgodne z hostem obsługującym protokołu w wersji 1.x, w tym wersji 1.5.
Zgodność wersji głównej
Zmiany niekompatybilne wstecznie są dozwolone w przypadku zmian w wersjach głównych. Do obsługują wiele wersji głównych w celu interoperacyjności ze starymi i nowymi hostami, urządzeń mogą określać w raporcie wiele kolekcji aplikacji deskryptory. Na przykład:
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,
};
W tym przypadku host może wyliczyć wszystkie różne kolekcje aplikacji które są reklamowane przez urządzenie, sprawdzając właściwość „Opis czujnika”, aby określić wersje protokołów wdrażane przez każdy z nich, a następnie wybrać Najnowsza wersja protokołu obsługiwana przez hosta. Po jej wybraniu host będzie działać korzystając z pojedynczego protokołu wybranego przez cały okres użytkowania urządzenia połączenia.
Dodatek: przykład deskryptora HID
Przykład poniżej pokazuje typowy prawidłowy deskryptor HID. Wykorzystuje często używane makra C, udostępniane w Wykorzystanie czujników HID (art. 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,
};