Accesso al sensore di movimento DualShock 4 in Windows (idealmente Unity)


10

Sto cercando di utilizzare una IMU di DualShock 4 come controller di movimento in Unity, sotto Windows 7.

Finora ho provato:

  • DS4Windows (1.5.11): legge i dati del sensore di movimento, ma non li espone a Unity come assi a meno che non li associ alle levette sinistra e destra. Questo non è abbastanza poiché perdo l'uso degli stick, posso solo inserire 4 dei 6 canali di dati e i valori che arrivano vengono troncati in un intervallo ristretto.
  • Motioninjoy (0.7.1001): non sembra rilevare DS4 come controller (i documenti più recenti si riferiscono solo a DS3 e precedenti)
  • GlovePIE (0.43): dopo aver seguito le istruzioni per l'uso del DualShock 3 con LibUSB-Win32 (un colpo lungo), le proprietà SixAxis sono tutte vuote.

In passato ho usato programmi esterni come GlovePIE per acquisire i dati del sensore di movimento remoto Wii e trasmetterli a Unity tramite messaggi OSC , quindi sarei aperto a un approccio come questo se non riuscissi a Unity a leggere i sensori del controller direttamente attraverso il suo sistema di input .

Qualcuno ha avuto fortuna con questo?

Risposte:


8

Ho trovato un approccio praticabile. Ho preso la fonte DS4Tool e copiato i bit necessari nel mio progetto Unity in modo da poter leggere direttamente i rapporti dal dispositivo.

(Questa è la classe NativeMethods per l'interfaccia con Kernel32.dll, l'enumerazione del dispositivo da HidDevices e la lettura del rapporto da HidDevice classe . Ho tagliato il resto per rendere le cose il più semplice possibile - Ho appena ricevuto un polling di thread per il nuovo dati il ​​più velocemente possibile.)

Questa guida mi ha spiegato dove trovare i dati del sensore di movimento all'interno del rapporto a 64 byte. Un piccolo test empirico e sembra che questo porti i dati in gs e radianti / sec:

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;

È un sistema di coordinate destrorso con x + destra, y + su e z + che punta verso il giocatore.

Il recupero dei dati in questo modo non interferisce con InputManager di Unity, che raccoglierà comunque i pulsanti e le levette come previsto, senza la necessità di scaricare driver non standard o eseguire software extra in background.


Aggiornamento: wireless (Bluetooth)

Ho riscontrato due problemi estendendolo per funzionare in modalità wireless (e due soluzioni):

  1. A DualShock 4s non piace rimanere associato a Windows (prima di Windows 8). Questa sciocca procedura sembra aggirare quella su Windows 7.

  2. Nessun dato del sensore di movimento quando connesso tramite Bluetooth . Ho scoperto che devi scrivere un rapporto di output sul dispositivo (vedi HidDevice per il metodo e DS4Device per i numeri magici) al fine di convincerlo a inviare dati di movimento. Fatto ciò, i rapporti di input che si ottengono saranno spostati di 2 byte.


Puoi chiarire questa risposta per questo post ?

Sto viaggiando proprio ora, ma lo accetterò quando avrò dei tempi di inattività con il wifi. Grazie @JoshPetrie!
DMGregory

Scavando in questo, non ho più il codice sorgente per il progetto di rilevamento del movimento su cui stavo lavorando, e tornando a DS4Tool mi ha ricordato perché ho strappato solo i bit di cui avevo bisogno! Questo diventa super dettagliato e potrebbe andare oltre una lunghezza ragionevole per una risposta StackExchange. Proverò a semplificare il più possibile ma ci vorrà del tempo.
DMGregory

1
@DMGregory - Questa scheda tecnica è, credo, per l'IMU utilizzata da DualShock 4: mouser.com/ds/2/783/BST-BMI055-DS000-08-786482.pdf - e dice Short.MaxValue corrisponde a 2000 gradi al secondo. Secondo il mio calcolo, stai ottenendo circa 1833 gradi al secondo, il che è vicino (e ragionevole per il risultato del test), ma forse aggiustare il calcolo di conseguenza ti darà un po 'più di precisione?
Jibb Smart

(Sto facendo roba da giroscopio da solo in questo momento, e stavo cercando di capire le conversioni di unità standard testandomi, e poi un amico ha trovato quel link per me)
Jibb Smart

1

Ho creato una soluzione per questo me stesso. Si chiama JoyShockLibrary e legge da DualShock 4, Switch Pro Controller e Joy-Contro. È open source, licenza MIT e funziona bene, anche se il supporto Bluetooth per DS4 è stato aggiunto solo di recente e continua a migliorare.

È utilizzato in JoyShockMapper , che è uno strumento di mappatura dell'input, e JoyShockOverlay, che non è ancora pubblico, ma puoi vederlo in azione qui (Gfycat) e qui (YouTube).

JoyShockLibrary integra perfettamente XInput - oltre ai suoi rapporti IMU, sembra molto simile a XInput - in modo da poter coprire facilmente tutti i controller di console gen attuali, con il vantaggio di input giroscopio e accelerometro da quelli che lo supportano.

È abbastanza facile da usare con Unity, anche se dovrei creare un file .cs per renderlo più facile per gli altri.


0

Questi sembrano essere tutti strumenti che racchiudono DirectInput in XInput. Unity ha il supporto per DirectInput e quindi dovresti cercare di farlo funzionare senza strumenti di terze parti. La chiave è se l'IMU è mappata su qualcosa in DirectInput e se è già in uno stato utilizzabile. In caso contrario, potrebbe essere necessario scrivere il proprio gestore DirectInput per gestire i dati non elaborati.

Puoi ringraziare xbox per tutti questi problemi del controller.


Sfortunatamente l'IMU non sembra essere mappata su nessuno dei 20 "assi del joystick" letti da Unity, né su Input.gyro ecc. Ho finito per scavare nei dati grezzi; aggiunta una risposta con i dettagli della soluzione.
DMGregory
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.