Dostęp do czujnika ruchu DualShock 4 w systemie Windows (najlepiej Unity)

10

Próbuję użyć IMU DualShock 4 jako kontrolera ruchu w Unity pod Windows 7.

Do tej pory próbowałem:

  • DS4Windows (1.5.11): odczytuje dane czujnika ruchu, ale nie wystawia ich na Unity jako osie, chyba że odwzoruję je na lewy i prawy drążek. To nie wystarczy, ponieważ tracę użycie drążków, mogę zmieścić tylko 4 z 6 kanałów danych, a nadchodzące wartości są przycięte w wąskim zakresie.
  • Motioninjoy (0.7.1001): nie wydaje się wykryć DS4 jako kontroler (ostatnie docs odnoszą się tylko do DS3 i przed)
  • GlovePIE (0.43): po wykonaniu instrukcji używania DualShock 3 z LibUSB-Win32 (długie ujęcie), wszystkie właściwości SixAxis są puste.

W przeszłości korzystałem z zewnętrznych programów, takich jak GlovePIE, aby przechwytywać dane zdalnego czujnika ruchu Wii i przekazywać je do Unity za pośrednictwem komunikatów OSC , więc byłbym otwarty na takie podejście, jeśli nie mogę zmusić Unity do odczytania czujników kontrolera bezpośrednio przez system wprowadzania danych .

Czy ktoś miał z tym szczęście?

DMGregory
źródło

Odpowiedzi:

8

Znalazłem wykonalne podejście. Chwyciłem źródło DS4Tool i skopiowałem potrzebne mi fragmenty do projektu Unity, aby bezpośrednio odczytać raporty z urządzenia.

(To klasa NativeMethods do interfejsu z Kernel32.dll, wyliczenie urządzenia z HidDevices i czytanie raportu z klasy HidDevice . Wycięłam resztę, aby wszystko było tak proste, jak to tylko możliwe - Właśnie mam sondowanie wątku dla nowego dane tak szybko, jak to możliwe).

Ten przewodnik powiedział mi, gdzie znaleźć dane czujnika ruchu w 64-bajtowym raporcie. Trochę testów empirycznych i wygląda na to, że przenosi dane do gs i radian / s:

accel = new Vector3(
            System.BitConverter.ToInt16(_inputBuffer, 19),
            System.BitConverter.ToInt16(_inputBuffer, 21),
            System.BitConverter.ToInt16(_inputBuffer, 23)
            )/8192f;

gyro = new Vector3(
            System.BitConverter.ToInt16(_inputBuffer, 13),
            System.BitConverter.ToInt16(_inputBuffer, 15),
            System.BitConverter.ToInt16(_inputBuffer, 17)
            )/1024f;

Jest to prawy układ współrzędnych z x + prawy, y + w górę i z + skierowanymi w stronę gracza.

Pobieranie danych w ten sposób nie koliduje z InputManagerem Unity, który nadal wybiera przyciski i drążki zgodnie z oczekiwaniami, bez konieczności pobierania niestandardowych sterowników lub uruchamiania dodatkowego oprogramowania w tle.


Aktualizacja: bezprzewodowy (Bluetooth)

Znalazłem dwa problemy z rozszerzeniem tego działania na działanie bezprzewodowe (i dwa rozwiązania):

  1. DualShock 4s nie lubią być sparowane z systemem Windows (wcześniejszym niż Windows 8). Ta głupia procedura wydaje się obejść tę w Windows 7.

  2. Brak danych czujnika ruchu po połączeniu przez Bluetooth . Odkryłem, że musisz napisać Raport Wyjściowy do urządzenia (zobacz HidDevice dla metody i DS4Device dla magicznych liczb), aby nakłonić go do wysyłania danych o ruchu. Gdy to zrobisz, raporty wejściowe, które otrzymasz, zostaną przesunięte o 2 bajty.

DMGregory
źródło
Czy możesz wyjaśnić tę odpowiedź dla tego postu ?
Podróżuję teraz, ale wezmę to na siebie, gdy mam trochę przestoju z Wi-Fi. Dzięki @JoshPetrie!
DMGregory
Wnikając w to, nie mam już kodu źródłowego dla projektu z czujnikiem ruchu, nad którym pracowałem, a powrót do DS4Tool przypomniał mi, dlaczego wyszarpałem tylko te bity, których potrzebuję! To staje się bardzo szczegółowe i może przekraczać rozsądną długość dla odpowiedzi StackExchange. Spróbuję maksymalnie uprościć, ale zajmie to trochę czasu.
DMGregory
1
@DMGregory - Myślę, że ten arkusz danych jest dla IMU, którego używa DualShock 4: mouser.com/ds/2/783/BST-BMI055-DS000-08-786482.pdf - i mówi Short.MaxValue odpowiada do 2000 stopni na sekundę. Według moich obliczeń otrzymujesz około 1833 stopni na sekundę, co jest bliskie (i rozsądne dla wyniku testu), ale może odpowiednie dostosowanie obliczeń da ci nieco większą dokładność?
Jibb Smart
(Sam robię teraz żyroskop i zamierzam wypróbować standardowe konwersje jednostek, testując siebie, a potem znajomy znalazł dla mnie ten link)
Jibb Smart
1

Sam stworzyłem rozwiązanie tego problemu. Nazywa się JoyShockLibrary i czyta z DualShock 4, Switch Pro Controller i Joy-Cons. Jest to oprogramowanie typu open source, licencja MIT i działa dobrze, chociaż obsługa DS4 przez Bluetooth została dodana dopiero niedawno i wciąż się poprawia.

Jest używany w JoyShockMapper , który jest narzędziem do mapowania danych wejściowych, oraz w JoyShockOverlay, która nie jest jeszcze publiczna, ale można to zobaczyć w akcji tutaj (Gfycat) i tutaj (YouTube).

JoyShockLibrary ładnie uzupełnia XInput - poza raportami IMU, wygląda bardzo podobnie do XInput - dzięki czemu można łatwo objąć wszystkie obecne kontrolery konsoli genowej, korzystając z żyroskopu i akcelerometru od tych, które go obsługują.

Jest dość łatwy w użyciu z Unity, chociaż powinienem umieścić plik .cs, aby ułatwić innym.

Jibb Smart
źródło
0

Wydaje się, że wszystkie są narzędziami, które zawijają DirectInput na XInput. Unity ma wsparcie dla DirectInput, więc powinieneś zastanowić się, jak to działa bez narzędzi innych firm. Kluczem jest to, czy IMU jest mapowane na cokolwiek w DirectInput i czy jest już w stanie użytkowym. Jeśli nie, być może będziesz musiał napisać własną procedurę obsługi DirectInput, aby poradzić sobie z surowymi danymi.

Możesz podziękować xbox za wszystkie te problemy z kontrolerem.

użytkownik54892
źródło
Niestety IMU nie wydaje się być zmapowane do żadnej z 20 „osi joysticka”, które czyta Unity, ani do Input.gyro itp. Skończyło się na tym, że zagłębiłem się w surowe dane; dodano odpowiedź ze szczegółami rozwiązania.
DMGregory