jgeumlek / MoltenGamepad

Flexible Linux input device translator, geared for gamepads
MIT License
280 stars 42 forks source link

Trying to get it to work... #28

Closed gustavolinux closed 7 years ago

gustavolinux commented 7 years ago

Well, I'm trying to use MoltenGamepad to control my mouse pointer with my wiimote. I'm doing that cause I don't use keyboard and mouse to play some games cause my hands get pain over time. Well, it compiles fine, it runs like shown below:

loading /etc/xdg/moltengamepad/moltengamepad.cfg
driver: wiimote driver initialized.
hotplug: device wm1 added.
wiimote: wm1: added core
wiimote: wm1: added accelerometers
wiimote: wm1: added IR
wiimote: wm1: added motion+
slot: wm1 assigned to slot virtpad1

But it just doesn't work at all. No keyboard buttons are mapped, and my profile file looks ok, I have tryied to setup it for hours, but there is something wrong here. Can you anyone help me with that?... I want to do a tutorial on how to setup it after get it working.

(yeah, I have read all the documentation, but there is no step by step simple and direct page that could help me) (there is no forum, so here is the only place I found to get help, sorry for that)

jgeumlek commented 7 years ago

Hello. Yes, documentation is an issue for this project. I am glad to help get this working.

In this case, I believe the issue is that wm1 is being assigned to the output slot virtpad1, which is a virtual gamepad. It doesn't support keyboard and mouse events. Instead, wm1 must be placed on the keyboard slot.

Would you mind sharing just one of the mappings from your profile?

Does it look like

wiimote.wm_a = key_a

or

wiimote.wm_a = key(key_a)

?

I am guessing it looks like the former. If it is the latter, then this is a bug, as the latter should be working. (The second way uses a special event translator that forces it to be sent to the virtual keyboard).

You can change wm1's slot manually, via entering move wm1 to keyboard on MG's standard input.

There are also ways to get the wiimote to end up on the keyboard slot automatically. They include:

gustavolinux commented 7 years ago

That's how my profile looks like:

[wiimote]
wiimote.wm_a = key(key_a)
wiimote.wm_b = key(key_b)
wiimote.wm_1 = key(key_1)
wiimote.wm_2 = key(key_2)
wiimote.wm_up = key(key_up)
wiimote.wm_down = key(key_down)
wiimote.wm_left = key(key_left)
wiimote.wm_right = key(key_right)
wiimote.wm_plus = key(key_4)
wiimote.wm_minus = key(key_3)
wiimote.wm_ir_x mouse(rel_x)
wiimote.wm_ir_y mouse(rel_y)

it's saved as /home/me/.config/moltengamepad/profiles/mywiimote

my configuration file looks like this: load profiles from /home/gustavo/.config/moltengampad/profiles/mywiimote and it's saved as /etc/xdg/moltengamepad/moltengamepad.cfg

I'm executing moltengamepad as root, because when I try as a normal user I get this output: open subdevice:: Permission denied

I'm really interested in use it to control my mouse pointer. Cwiid works fine for that, but when trying to play fps like games it's impossible cause it's not getting relative inputs, but absolute ones. So, moltengamepad would solve my issue.

Any clue?

jgeumlek commented 7 years ago

That looks right, other than some missing = signs on the last two.

As for the opening subdevice, it sounds like your normal user wasn't give the right permissions for wiimote devices, but that is a separate issue.

Weird, that does sound like something is wrong. Things are still working on this end. Can you run evtest and verify that there is a virtual keyboard created? And do you see any events generated on that device while running MG?

As for that last bit, MG does support outputting relative events, but that won't magically make FPS games handle like Metroid Prime or whatnot, so you mileage may vary.

jgeumlek commented 7 years ago

Oh, and can you do print profiles wiimote into MG? I see output above that says your moltengamepad.cfg is being read, but I would expect to see a line about loading the profile file as well. It's possible the profile isn't being loaded.

gustavolinux commented 7 years ago

When running evtest, that's what I get

sudo evtest 
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:  HID 0b38:0010
/dev/input/event1:  HID 0b38:0010
/dev/input/event2:  USB Optical Mouse
/dev/input/event3:  Sony Navigation Controller
/dev/input/event4:  Power Button
/dev/input/event5:  Power Button
/dev/input/event6:  PC Speaker
/dev/input/event7:  HDA Intel PCH Rear Mic
/dev/input/event8:  HDA Intel PCH Front Mic
/dev/input/event9:  HDA Intel PCH Line
/dev/input/event10: HDA Intel PCH Line Out Front
/dev/input/event11: HDA Intel PCH Line Out Surround
/dev/input/event12: HDA Intel PCH Line Out CLFE
/dev/input/event13: HDA Intel PCH Line Out Side
/dev/input/event14: HDA NVidia HDMI/DP,pcm=3
/dev/input/event15: HDA NVidia HDMI/DP,pcm=7
/dev/input/event16: HDA NVidia HDMI/DP,pcm=8
/dev/input/event17: HDA NVidia HDMI/DP,pcm=9
/dev/input/event18: UVC Camera (046d:0825)
/dev/input/event19: Nintendo Wii Remote Accelerometer
/dev/input/event20: Nintendo Wii Remote IR
/dev/input/event21: Nintendo Wii Remote
/dev/input/event22: Nintendo Wii Remote Motion Plus
/dev/input/event23: Virtual Keyboard (MoltenGamepad)
/dev/input/event24: Virtual Mouse (MoltenGamepad)
/dev/input/event25: Virtual Gamepad (MoltenGamepad)
/dev/input/event26: Virtual Gamepad (MoltenGamepad)
/dev/input/event27: Virtual Gamepad (MoltenGamepad)
/dev/input/event28: Virtual Gamepad (MoltenGamepad)
Select the device event number [0-28]:

When running print profiles wiimote that's my output:


loading /etc/xdg/moltengamepad/moltengamepad.cfg
driver: wiimote driver initialized.
hotplug: device wm1 added.
wiimote: wm1: added core
wiimote: wm1: added accelerometers
wiimote: wm1: added IR
wiimote: wm1: added motion+
slot: wm1 assigned to slot virtpad1
print profiles wiimote
wiimote.cc_right_x = +right_x
wiimote.cc_y = fourth
wiimote.cc_minus = select
wiimote.cc_x = third
wiimote.cc_plus = start
wiimote.cc_up = up
wiimote.cc_down = down
wiimote.cc_home = mode
wiimote.cc_b = secondary
wiimote.cc_left_x = +left_x
wiimote.cc_zr = tr2
wiimote.cc_thumbl = thumbl
wiimote.cc_left = left
wiimote.cc_left_y = +left_y
wiimote.bal_x = nothing
wiimote.nk_stick_y = +left_y
wiimote.nk_accel_y = nothing
wiimote.nk_accel_x = nothing
wiimote.nk_ir_y = nothing
wiimote.nk_wm_accel_z = nothing
wiimote.nk_wm_accel_y = nothing
wiimote.nk_wm_accel_x = nothing
wiimote.wm_ir_y = nothing
wiimote.wm_accel_z = nothing
wiimote.nk_left = left
wiimote.nk_a = primary
wiimote.nk_b = secondary
wiimote.wm_down = right
wiimote.nk_minus = select
wiimote.wm_plus = start
wiimote.wm_2 = primary
wiimote.wm_a = third
wiimote.nk_1 = tl
wiimote.nk_home = mode
wiimote.wm_home = mode
wiimote.nk_accel_z = nothing
wiimote.nk_up = up
wiimote.wm_1 = secondary
wiimote.wm_left = down
wiimote.cc_right_y = +right_y
wiimote.bal_y = nothing
wiimote.nk_right = right
wiimote.nk_2 = tr
wiimote.wm_up = left
wiimote.nk_ir_x = nothing
wiimote.wm_right = up
wiimote.wm_accel_y = nothing
wiimote.nk_c = third
wiimote.nk_z = fourth
wiimote.cc_right = right
wiimote.cc_r = tr
wiimote.wm_b = fourth
wiimote.cc_l = tl
wiimote.nk_stick_x = +left_x
wiimote.cc_zl = tl2
wiimote.wm_minus = select
wiimote.cc_a = primary
wiimote.cc_thumbr = thumbr
wiimote.nk_down = down
wiimote.wm_ir_x = nothing
wiimote.nk_plus = start
wiimote.wm_accel_x = nothing
wiimote.?grab_permissions = false
   #  Grab device via blocking all read permissions
wiimote.?grab_exclusive = true
   #  Grab device events via ioctl EVIOCGRAB
wiimote.?nk_ir_active = false
   #  Enable IR data when nunchuk is present
wiimote.?nk_accel_active = false
   #  Enable accelerometers when nunchuk is present
wiimote.?wm_accel_active = false
   #  Enable accelerometers when no extension is present
wiimote.?wm_ir_active = false
   #  Enable IR data when no extension is present

Well, you are right, there is anything saying my profile is being loaded. So, maybe that's is the issue here, but what did I wrong?

some minutes later...

Well, I just figured out that if I type: load profiles from /home/gustavo/.config/moltengamepad/profiles/mywiimote when the MG is running, it works! Well, not for mouse relative input, but for keyboard ones... looks like we are almost solving the problem! :)

jgeumlek commented 7 years ago

Thanks for following up on all this. Sounds like there is a bug in the cfg loading. I will try to drill down on that this weekend.

As for the mouse stuff, please make sure you got

wiimote.?wm_ir_active = true

somewhere in your profile, since the IR sensor is left off by default.

gustavolinux commented 7 years ago

That's my profile after putting your suggestion:

[wiimote]
wiimote.?wm_ir_active = true
wiimote.?wm_accel_active = true
wiimote.wm_a = key(key_a)
wiimote.wm_b = key(key_b)
wiimote.wm_1 = key(key_1)
wiimote.wm_2 = key(key_2)
wiimote.wm_up = key(key_up)
wiimote.wm_down = key(key_down)
wiimote.wm_left = key(key_left)
wiimote.wm_right = key(key_right)
wiimote.wm_plus = key(key_4)
wiimote.wm_minus = key(key_3)
wiimote.wm_ir_x = mouse(rel_x)
wiimote.wm_ir_y = mouse(rel_y)

It makes my wii remote act as a mouse pointer, but there is an little issue: no matter where I point it, it keeps the mouse pointer going to down and to the left... when looking at the MG's output, I can see that the relative input is like this:

mouse(+rel_y)
mouse(+rel_x)

So, maybe that's something wrong here....

jgeumlek commented 7 years ago

The + just means non-inverted, and is the default. (similar to how positive numbers tend not to have a + in front of them, but still mean the same). That's not a problem, and your profile seems fine.

This constant drift is exactly what relative input promises to happen, assuming "down and to the left" is the last thing we get from the IR sensor. This IR processing is very basic, and when tracking is lost, MG just sticks with the last known value. (if you point just a little too far, such that the IR isn't seen anymore, it doesn't really make sense to zero-out the cursor)

So I'd need to know more about the IR values being seen to tell what is going on here, and that is likely too much info to be conveyed here.

Since you were using cwiid previously, I'll assume MG is at fault here and that you have your IR sources set well enough. I will try to look for any major bugs in the IR stuff this weekend as well.

gustavolinux commented 7 years ago

Please, take a look at this: https://www.youtube.com/watch?v=a1RyykpBO98

Looks like he has changed some of the original MG's code to get to work:

https://gist.github.com/Ryochan7/a288dcfe70445cb722207a1739541540

jgeumlek commented 7 years ago

Sorry for the late reply, things have been busy. It is still technically the weekend where I am sitting, though.

About auto-loading profiles: I duplicated the set up, and things worked fine over here. I was worried it was something going wrong in the parsing, such as expecting quotes or a newline, but neither were an issue.

However, I have since noticed you had moltengampad instead of moltengamepad in the path specified in your cfg. Perhaps that was the issue? I'll be sure to add some better reporting when files aren't found.

About IR functionality: it was bugged! MG wasn't centering the IR data, instead it was reporting it directly. This meant any value seen was reported as positive, hence the constant movement to the corner.

(while debugging, I found a minor bug affecting the accelerometer functionality. Woo!)

It still isn't very natural to move the mouse in this relative IR mode, but with the fix it is at least working as expected. It is very, very basic event processing.

I think this is worthy of a hotfix on the master branch, so I'll get to work on pushing that out.

About Ryochan7's code: I expect this handles pretty well, judging from the uploaded videos and the fact that Ryochan7 was the main author of Antimicro.

I am hesitant to borrow too heavily from the gist, given the unclear licensing situation. It appears they pierced through some layers of abstraction to get it working, but I think the interfaces can be extended a bit cleaner and get similar results. I don't fully understand all the logic, but I think one can learn a lot about how to make nice movements from wiimote data from there.

gustavolinux commented 7 years ago

About the "moltengampad", it was actually a typo when I was editing my post, my pc's path is correct. About the Ryochan7's code, I don't think he would mind about using it here, since he sent that link to me after I ask him on youtube. I'm really hoping your fixes will make the IR movement input, and I'm glad to know that, in some way, I'm contributing reporting bugs. This project is awesome and I want to help to keep it alive.

I can't wait to test your new fixes. :P

jgeumlek commented 7 years ago

Hmm. Then I am currently at a loss as to why the .cfg is being loaded, but the profile specified inside is not. Perhaps the new messages I added about profile loading can help see what is going on? I do want to get to the bottom of this issue, but I can't reproduce it over here.

You should see something about the profile either being loaded or failing to load after the list of initialized drivers, but before the message about stdin. If you see nothing about it, then we can also start to narrow down the situation.

The master branch now has the hotfix with the IR processing, give it a whirl. It just uses the left-most visible IR dot, so it can act a bit weird if using a sensor bar (with multiple IR dots) when the currently left-most dot goes out of view.

I am glad to hear that others are interested in this project. That's some good motivation to try to find time to work on this again. Your bug reports here are quite valued on my end.

(I am going to be away from my computer for the next few days, so it might be a while before my next reply.)

gustavolinux commented 7 years ago

Well, about the my profile loading issue, It was really my fault, I'm sorry about that, I was using a lot config files, and it was typo in one of them. About your fixes, it really worked!, of course it's not fluid as good as a mouse, but it's indeed a great progress to use the relative input to play games which require it. I have tried to play CS using it, and worked. I think with some tweaking on the code based on Ryochan's patch, would be really playable and get closer to a mouse. I have some experience in C, but not with low level programming, so, unfortunately, I can help being a tester here. Enjoy your weekend, I'm happy that you want to keep this project alive.

Ryochan7 commented 7 years ago

The changes that were made were based around commit 797d4efd721e0fd599d9086d4c0efc6277da9755 and I still have not gotten around to converting the code over to the current HEAD. I cleaned up the code and Git history from my local copy and made an archive of the source.

https://drive.google.com/file/d/0B6yGHDx0CFzDaWZyal9pUGxkVFU/view?usp=sharing

jgeumlek commented 7 years ago

Thanks!

I think I understand what you did a bit better now that I have tried it out. What is cursorHold doing in that code? I wasn't able to notice anything when pushing A or B.

I'll try writing a group translator that'll read the accels, gyros, and a ratchet button and see if I can emulate the behavior you wrote.

The only part I'm hesistant about is the calibration period, as it isn't guaranteed that the user will set down the controller at first, especially if it is freshly connected.

I wonder if there is a reasonable threshold where we could just keep sampling during the calibration period until things settle down.

Ryochan7 commented 7 years ago

When A or B is usually pressed, the Wiimote will be moved unintentionally which would normally cause the mouse cursor to move. holdCursor is being used to not take a certain amount of input into account in order to minimize any unintentional movement of the Wiimote from pressing A or B. The technique is similar to Mouse Dampening for the Steam Controller. Right now, only the first input is being zeroed out.

As for the calibration part, that is a big problem. Since calibration is being done at startup, it is assumed that the Wiimote will be set down or it will not work properly. Also, it takes some time for the gyro to warm up and stabilize so the input values will jitter more at startup. Calibration will have to be done after using the Wiimote for a period of time or you will have to fight with cursor drift. I have not thought of a way to combat this while using the Wiimote so I just end up restarting MoltenGamepad to re-calibrate the gyro.

Ryochan7 commented 7 years ago

Updated routine to version 0.3.4. I could have sworn that I performed a pull in the past couple of days. Smoothing factors have also been increased.

https://drive.google.com/file/d/0B6yGHDx0CFzDcEZrdGVwMmtkTU0/view?usp=sharing

Gist: https://gist.github.com/Ryochan7/a288dcfe70445cb722207a1739541540