Mengakses sensor gerak DualShock 4 di Windows (idealnya Unity)

10

Saya mencoba menggunakan IMU DualShock 4 sebagai pengontrol gerakan di Unity, di bawah Windows 7.

Sejauh ini saya sudah mencoba:

  • DS4Windows (1.5.11): membaca data sensor gerak, tetapi tidak mengeksposnya ke Unity sebagai sumbu kecuali jika saya memetakannya ke batang kiri & kanan. Ini tidak cukup karena saya kehilangan penggunaan tongkat, saya hanya bisa memasukkan 4 dari 6 saluran data, dan nilai-nilai yang masuk terpotong dalam kisaran yang sempit.
  • Motioninjoy (0.7.1001): tampaknya tidak mendeteksi DS4 sebagai pengontrol (dokumen terbaru hanya merujuk ke DS3 dan sebelumnya)
  • GlovePIE (0.43): setelah mengikuti instruksi untuk menggunakan DualShock 3 dengan LibUSB-Win32 (tembakan panjang), properti SixAxis semuanya kosong.

Di masa lalu saya telah menggunakan program eksternal seperti GlovePIE untuk menangkap data sensor gerak jarak jauh Wii dan meneruskannya ke Unity melalui pesan OSC , jadi saya akan terbuka untuk pendekatan seperti ini jika saya tidak bisa membuat Unity membaca sensor pengontrol langsung melalui sistem Input -nya .

Adakah yang beruntung dengan ini?

DMGregory
sumber

Jawaban:

8

Saya telah menemukan pendekatan yang bisa diterapkan. Saya mengambil sumber DS4Tool dan menyalin bit yang saya butuhkan ke proyek Unity saya sehingga saya bisa membaca laporan dari perangkat secara langsung.

(Itu kelas NativeMethods untuk berinteraksi dengan Kernel32.dll, enumerasi perangkat dari HidDevices , dan membaca laporan dari kelas HidDevice . Saya memotong sisanya untuk menjaga hal-hal sesederhana mungkin - Saya baru saja mendapat polling thread untuk yang baru data secepat mungkin.)

Panduan ini memberi tahu saya di mana menemukan data sensor gerak dalam laporan 64-byte. Pengujian empiris kecil dan sepertinya ini mendapatkan data menjadi gs dan radian / detik:

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;

Ini adalah sistem koordinat tangan kanan dengan x + kanan, y + atas, dan z + mengarah ke pemain.

Mengambil data dengan cara ini tidak mengganggu InputManager Unity, yang masih akan mengambil tombol & tongkat seperti yang diharapkan, tanpa perlu mengunduh driver non-standar atau menjalankan perangkat lunak tambahan di latar belakang.


Pembaruan: Nirkabel (Bluetooth)

Saya menemukan dua masalah dalam memperpanjang ini untuk bekerja secara nirkabel (dan dua solusi):

  1. DualShock 4s tidak suka dipasangkan dengan Windows (sebelum Windows 8). Prosedur konyol ini sepertinya berhasil di Windows 7.

  2. Tidak ada data sensor gerak saat terhubung melalui Bluetooth . Saya menemukan Anda perlu menulis Laporan Output ke perangkat (lihat HidDevice untuk metode ini dan DS4Device untuk angka ajaib) untuk membujuknya mengirim data gerak. Setelah ini selesai, laporan input yang Anda dapatkan kembali akan digeser oleh 2 byte.

DMGregory
sumber
Apakah mungkin bagi Anda untuk mengklarifikasi jawaban ini per postingan ini ?
Saya bepergian sekarang, tapi saya akan mengambilnya ketika saya punya waktu luang dengan wifi. Terima kasih @JoshPetrie!
DMGregory
Menggali ini, saya tidak lagi memiliki kode sumber untuk proyek sensor gerak yang sedang saya kerjakan, dan kembali ke DS4Tool mengingatkan saya mengapa saya hanya merobek bit yang saya butuhkan! Ini mendapat super verbose dan mungkin melampaui panjang yang wajar untuk jawaban StackExchange. Saya akan mencoba menyederhanakan sebanyak yang saya bisa, tetapi itu akan memakan waktu.
DMGregory
1
@DMGregory - Lembar data ini, saya pikir, untuk IMU yang menggunakan DualShock 4: mouser.com/ds/2/783/BST-BMI055-DS000-08-786482.pdf - dan dikatakan Short.MaxValue sesuai hingga 2000 derajat per detik. Dengan perhitungan saya, Anda mendapatkan sekitar 1833 derajat per detik, yang dekat (dan masuk akal untuk hasil pengujian), tetapi mungkin menyesuaikan perhitungan Anda akan memberi Anda sedikit lebih akurat?
Jibb Smart
(Saya sendiri sedang mengerjakan hal-hal gyro, dan akan mencoba mencari tahu konversi unit standar dengan menguji diri saya, dan kemudian seorang teman menemukan tautan itu untuk saya)
Jibb Smart
1

Saya telah membuat solusi untuk ini sendiri. Ini disebut JoyShockLibrary , dan membaca dari DualShock 4, Switch Pro Controller, dan Joy-Cons. Ini open source, lisensi MIT, dan berfungsi dengan baik, meskipun dukungan Bluetooth untuk DS4 baru ditambahkan baru-baru ini dan masih membaik.

Ini digunakan di JoyShockMapper , yang merupakan alat pemetaan input, dan JoyShockOverlay, yang belum dipublikasikan, tetapi Anda dapat melihatnya beraksi di sini (Gfycat) dan di sini (YouTube).

JoyShockLibrary melengkapi XInput dengan baik - selain laporan IMU, tampilannya sangat mirip dengan XInput - sehingga Anda dapat dengan mudah mencakup semua pengontrol konsol gen saat ini dengan mudah, dengan manfaat input gyro dan akselerometer dari mereka yang mendukungnya.

Ini cukup mudah digunakan dengan Unity, meskipun saya harus memasang file .cs untuk membuatnya lebih mudah bagi orang lain.

Jibb Smart
sumber
0

Semua itu tampak sebagai alat yang membungkus DirectInput ke XInput. Unity memiliki dukungan untuk DirectInput dan karenanya Anda harus berusaha membuatnya tanpa alat pihak ke-3. Kuncinya adalah jika IMU dipetakan ke apa pun di DirectInput dan jika sudah dalam keadaan dapat digunakan. Jika tidak, Anda mungkin harus menulis handler DirectInput Anda sendiri untuk menangani data mentah.

Anda dapat berterima kasih kepada xbox untuk semua kesengsaraan pengontrol ini.

pengguna54892
sumber
Sayangnya IMU tampaknya tidak dipetakan ke salah satu dari 20 "sumbu joystick" yang dibaca Unity, atau ke Input.gyro dll. Saya akhirnya menggali data mentah; menambahkan jawaban dengan detail solusinya.
DMGregory