ardaku / stick

Rust library for platform-agnostic asynchronous gamepad, joystick, and flightstick interaction
https://crates.io/crates/stick
Apache License 2.0
73 stars 14 forks source link

Nintendo Joycon gyro/accelerometer support #39

Open medakk opened 2 years ago

medakk commented 2 years ago

Thanks for creating this library! Is there a way to access gyroscope and accelerometer data from Joycons currently? On Ubuntu 20.04 with the dkms-hid-nintendo, there are two input sources I can see:

/dev/input/js0
/dev/input/js1

js0 corresponds to buttons/analog stick and that works fine in stick. The gyro and accelerometer readings seem to be a part of js1. Is there a way I can use the "second" controller via stick?

I'm using the haptics example to test

AldaronLau commented 2 years ago

@medakk Thanks for opening this issue! /dev/input/js0 and /dev/input/js1 are the old Linux API for joysticks, and stick depends on the new Linux api, evdev. I believe there should be an equivalent for gyroscope and accelerometer for evdev - but I don't know what that would be. Have you tested it with the stick example program to see if it prints anything out?

edit: sorry, just realized you said you are using the haptic example program. But just verifying it doesn't print anything out for those events?

medakk commented 2 years ago

correct. the haptic example doesn't print out anything for those events. I modified the example slightly to print out all events:

        match event {
            Event::Disconnect => {
                self.controllers.swap_remove(id);
            }
            Event::MenuR(true) => return Ready(player),
            Event::ActionA(pressed) => {
                self.controllers[id].rumble(f32::from(u8::from(pressed)));
            }
            Event::ActionB(pressed) => {
                self.controllers[id].rumble(0.5 * f32::from(u8::from(pressed)));
            }
            Event::BumperL(pressed) => {
                self.rumble.0 = f32::from(u8::from(pressed));
                self.controllers[id].rumble(self.rumble);
            }
            Event::BumperR(pressed) => {
                self.rumble.1 = f32::from(u8::from(pressed));
                self.controllers[id].rumble(self.rumble);
            }
            other => {
                dbg!(other);
            }
        }

but there is no events for the gyroscope and accelerometer. EDIT: Button presses are detected and rumble works

I wasn't aware that js is the old API. I can confirm that the gyro works in the jstest-gtk app.

According to dmesg, it might be showing up as two different controllers:

[ 7139.066010] input: Nintendo Switch Right Joy-Con as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/bluetooth/hci0/hci0:256/0005:057E:2007.0008/input/input34
[ 7139.066620] input: Nintendo Switch Right Joy-Con IMU as /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/bluetooth/hci0/hci0:256/0005:057E:2007.0008/input/input35

I'm unfamiliar with async in rust, but does the haptic example iterate through all available gamepads? Or stop at the first?

medakk commented 2 years ago

EDIT: Disregard my previous message here. The bluetooth connection had died. I can see a single evdev device listed for the joycon:

/dev/input/event20 Nintendo Switch Right Joy-Con

EDIT 2: there also exists /dev/input/event21 for the IMU

medakk commented 2 years ago

I think there's an unrelated permission issue involved. If I run as root :fearful: I can see the IMU device. But stick isn't too happy about it.

Connected p1, id: 05007E0507200180, name: Nintendo Switch Right Joy-Con IMU
Connected p2, id: 05007E0507200180, name: Nintendo Switch Right Joy-Con
thread 'main' panicked at 'assertion failed: `(left != right)`
  left: `-1`,
 right: `-1`', /home/karthik/.cargo/registry/src/github.com-1ecc6299db9ec823/stick-0.12.2/src/raw/linux.rs:567:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panicking.rs:517:5
   1: core::panicking::panic_fmt
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/core/src/panicking.rs:101:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
   4: stick::raw::ffi::Listener::controller
   5: <stick::raw::ffi::Listener as stick::raw::Listener>::poll
   6: <stick::listener::Listener as core::future::future::Future>::poll
   7: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   8: pasts::exec::block_on
   9: test_rpi_rs::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
medakk commented 2 years ago

Okay so I'm able to get some readings out by disabling that assert and hardcoding a random number for minimum and maximum. It now picks up on the gyro events! (JoyZ)

Unknown Linux Button 29
Report at https://github.com/libcala/stick/issues
Unknown Linux Misc Code: 5, Value: 1073556594
Report at https://github.com/libcala/stick/issues
Reading: 0.1239661854915006
Unknown Linux Misc Code: 5, Value: 1073561260
Report at https://github.com/libcala/stick/issues
Reading: 0.12335581530198066
Unknown Linux Misc Code: 5, Value: 1073565926
Report at https://github.com/libcala/stick/issues
Reading: 0.12411877803888058
Unknown Linux Misc Code: 5, Value: 1073584592
Report at https://github.com/libcala/stick/issues
Unknown Linux Misc Code: 5, Value: 1073589258
Report at https://github.com/libcala/stick/issues
Reading: 0.12335581530198066
Unknown Linux Misc Code: 5, Value: 1073593924
Report at https://github.com/libcala/stick/issues
Reading: 0.12341685232093265
Unknown Linux Misc Code: 5, Value: 1073612590
Report at https://github.com/libcala/stick/issues
Reading: 0.12448500015259255
Unknown Linux Misc Code: 5, Value: 1073617256
Report at https://github.com/libcala/stick/issues
Unknown Linux Misc Code: 5, Value: 1073621922
Report at https://github.com/libcala/stick/issues
Reading: 0.12430188909573657
Unknown Linux Misc Code: 5, Value: 1073640588
Report at https://github.com/libcala/stick/issues
Reading: 0.1271095919675283
Unknown Linux Misc Code: 5, Value: 1073645254
Report at https://github.com/libcala/stick/issues
Reading: 0.12567522202215645
Unknown Linux Misc Code: 5, Value: 1073649920
Report at https://github.com/libcala/stick/issues
Reading: 0.12439344462416456
Unknown Linux Button 46

so I need to figure out:

AldaronLau commented 2 years ago

@medakk Thanks for investigating further! ioctl failure looks like it's related to #38. Currently a work-in-progress to fix it. It's weird that the permissions are wrong for joycons, not sure what I can do about that. "Unknown Linux Misc Code" should be trivial enough to fix, should just be an extra branch arm for the match statement.

aspanoz commented 2 years ago

I had the same problem. Everything was working fine. I changed the linux. A lot of packages were updated. Started to build the project and the bugs started. I use "054c:09cc Sony Corp. DualShock 4 [CUH-ZCT2x]"

AldaronLau commented 2 years ago

@aspanoz It should be fixed on my fork here: https://github.com/AldaronLau/stick/tree/deps-update - The reason I haven't merged it and released a new version is that the changes broke Windows compilation and I haven't had time to fix yet. I'll try to get back to it soon.

ImUrX commented 1 year ago

Is there any progress on this?

AldaronLau commented 1 year ago

@ImUrX I was getting close to getting the Windows port fixed on that branch a couple months ago and finally merging, but got distracted by issues in other projects I'm maintaining. Sorry I'm so slow to resolve this one. I'm hoping to prioritize it in the next few months, and finally get this resolved - then try to get more maintainers on this crate, so issues like this aren't outstanding for so long in the future.

ImUrX commented 1 year ago

I made some code based on evdev with tokio if interested. link