ardaku / stick

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

Thrustmaster Warthog support #8

Closed theunkn0wn1 closed 4 years ago

theunkn0wn1 commented 4 years ago

Describe the bug Ran the example code provided on the docs' homepage, and plugged my Warthog into the machine.

Connected p1, id: 44F0404, name: Thrustmaster Throttle - HOTAS Warthog
[/home/orion/.cargo/registry/src/github.com-1ecc6299db9ec823/stick-0.9.0/src/ffi/linux.rs:560] id = 422
Button 422 is Unknown, report at https://github.com/libcala/stick/issues
[/home/orion/.cargo/registry/src/github.com-1ecc6299db9ec823/stick-0.9.0/src/ffi/linux.rs:560] id = 422
Button 422 is Unknown, report at https://github.com/libcala/stick/issues
^C

The above spams the STDOUT.

To Reproduce Steps to reproduce the behavior:

  1. cargo init rustpad
  2. cd rustpad
  3. cargo add stick pasts
  4. copy example program into src/main.rs
  5. cargo run Expected behavior

Expected Connected p1, id: 44F0404, name: Thrustmaster Throttle - HOTAS Warthog and for the program to read joystick events, not spew errors over STDOUT.

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

   Compiling smelling_salts v0.1.0
   Compiling pasts v0.4.0
   Compiling stick v0.9.0
   Compiling rustpad v0.1.0 (/home/orion/projects/skool/rover/movement/rustpad/rustpad)
theunkn0wn1 commented 4 years ago

Just noticed #5 , il see if i can come up with a more useful contribution...

theunkn0wn1 commented 4 years ago

Axies 2,3 (left,right thrust) incorrectly read. only reads 0-1 at the forward extreme. None of the buttons read correctly. (all spew the above OP error message) Attempted to write a patch by creating file stick/src/controllers/s044F0404.txt and matching the format of other files in that directory, using values from https://html5gamepad.com/ and the library appears to have ignored it.

I would like to contribute to this library, but its unclear what needs to be done here, can i get some pointers? :confused:

AldaronLau commented 4 years ago

@theunkn0wn1 Thank you for being interested in contributing! Sorry about it not being super clear how stuff works. From the comments on #5, there was a suggestion to use https://github.com/gabomdq/gamecontrollerdb.git, which I wanted to look into, which might fix your issue. The text files as they exist now are notes to myself on what maps to what for each joystick.

I'm curious, though, is it always button 422 for this controller (or is it constant)? It also appears as though I accidentally left the dbg!() prints in the newest version (oof, that should be fixed)!

At the moment, src/ffi/linux.rs is where the work needs to be done. I would start by adding the joystick id as a constant at the top of the file with the other joystick id. I would make HardwareId::is_thrustmaster() return true if it matches that id (that's probably a good place to start to get some things working). Since 422 is not currently recognized as a possible button, it can be added in the match statement on line 696:

match self.remapping(ev.ev_code - 0x120) {

I wouldn't use the numbers from https://html5gamepad.com/, there's some remapping that web browsers do, so they probably wouldn't match the ids from /dev/input on linux.

Anyway, if you want to make a patch, I can give you more pointers if you get stuck. And, if you're feeling really ambitious you could look into parsing the gamecontrollerdb repository mentioned above. Hopefully the information I gave is helpful!

theunkn0wn1 commented 4 years ago

@AldaronLau I did actually come across game controller db when i was investigating alternate joystick libraries, but unfortunately it doesn't cover my use case as the Warthog controller does NOT match that particular standard.

The button ID appears to be constant, however is different from the IDs im getting out of gilrs. For instance, gilrs reports the switch labeled EAC on the controller as EvCode 711 kind 1.

ButtonPressed, code: Code(EvCode(EvCode { kind: 1, code: 711 }))
ButtonReleased, code: Code(EvCode(EvCode { kind: 1, code: 711 }))

this library, on the other hand, reports it as id 423 if i am reading this output correctly.

[src/ffi/linux.rs:560] id = 423
Button 423 is Unknown, report at https://github.com/libcala/stick/issues

EDIT: adding 0x120 to the output matches the evcode from gilrs

AldaronLau commented 4 years ago

@theunkn0wn1 I'm wondering if there's another file in /dev that would make this controller usable with stick. I'm thinking stick will definitely have to patch gamecontrollerdb to support more controllers. I'm not sure how to fix it if evdev always returns the same value. Here's some file locations which might be able to be tried out (from my xbox controller):

/dev/input/event15
/dev/input/js0
/dev/input/by-id/usb-Performance_Designed_Products_Wired_Controller_for_Xbox_360_069CAAEF-event-joystick
/dev/input/by-id/usb-Performance_Designed_Products_Wired_Controller_for_Xbox_360_069CAAEF-joystick
/dev/input/by-path/pci-0000:00:14.0-usb-0:2.1:1.0-event-joystick
/dev/input/by-path/pci-0000:00:14.0-usb-0:2.1:1.0-joystick

I'm wondering if some controllers work better with files ending in -joystick rather than -event-joystick (stick currently uses /by-id/*-event-joystick)? I believe gilrs uses the /dev/input/event15, but I might be mistaken. Maybe by-path makes a difference? I would prefer not to use /dev/input/js0, because that's the older Linux joystick API, but it would be interesting to see if that works with your controller if none of the other ones do, it might need to be implemented as a fall-back.

theunkn0wn1 commented 4 years ago

@AldaronLau , my previous experience with handling this joystick in other languages (python via pygame, a wrapper aroundlibsdl2 and Golang using a wrapper around libsdl2) is that the button IDs are always constant. Im not sure why you perceive this as a problem?

Being able to parse gamecontrollerdb will certainly help this library support more hardware and is a step in the right direction, but it unfortunately won't do me any good for this particular controller as its not yet another general-purpose controller. IT just doesn't match that database's schema.

As for the discrepancy between what stick and gilrs reports, i think that has to do with that remapping you pointed out, where it subtracts the ev_code by 0x120. Why is stick doing this?

What i think would be a good thing to do here is come up with decoders from a neutral file format like json or, better yet, toml describing the inputs of a given HID. E.g. IDs of the hat(s), axies, and buttons. This is the path that gobot takes for implementing unknown joysticks. gobot's joystick constructor accepts a file path argument to a well-formated JSON file that contains the stick description.

AldaronLau commented 4 years ago

@theunkn0wn1 I thought you meant different buttons were returning the same id, glad that's not the case!

Yeah, I'll have to expand the schema for sure.

The subtraction of 0x120 was something I kept from a C evdev example that I used in order to learn how to use evdev. I'm not sure why it was in there (there wasn't a comment or anything), but I kept it just for that reason. It may not be necessary.

I'd rather not have stick look for specific files on the system to parse at start-up (since file system structures vary across distributions, and requires that binary programs using stick include a format parser). I think there should be GUI and TUI interfaces for calibrating them, and then the interface exports to some format like toml or MuON, which can then be added to stick and parsed in a build script or something at compile time. I haven't yet had time to develop these interfaces, but it has been a plan of mine for a while.

theunkn0wn1 commented 4 years ago

@AldaronLau Oh no, each switch state has a unique ID*.

The subtraction of 0x120 im not seeing a use for, you may want to consider refactoring that out.

I agree that file systems are a pita to handle, doing code gen from a neutral format might not be a terrible idea. To this end, the approach i would take is to produce a rust module per joystick, which at minimum will contain a struct that implements some trait that defines an event decoder.

something to the effect of

use stick::devices::thrustmaster_warthog_throttle; // Thrustmaster Warthog Throttle HID
use stick::devices::xbox_360; // Xbox 360 game controller HID
// ...

thrustmaster_warthog_throttle would implement some trait that allows it to decode the raw event codes, allowing it to plug into the Gamepad type somehow.

What are your thoughts?

AldaronLau commented 4 years ago

I'm going to look into why that subtraction was there, and either add a comment or remove it. It is very odd.

I foresee this being a lot of manual code writing to support each controller. There's going to be a lot of modules with that approach. I think it will be a lot less maintenance work to have the build script generate a function for each joystick, as well as a function that matches on the joystick ID to call a device-specific function. And that can be generated as one file and included as it's own module. Then there's just one pub(super) fn that the linux.rs module in stick can call and the rest are private. This approach wouldn't add a trait or even structs, and would require a specific EvdevEvent enum (or maybe stick's code generation can use one that already exists).

The generated module would look something like this:

fn thrustmaster_warthog_throttle_remap(event: super::EvdevEvent) -> stick::Event {
    match event.axis_or_button_etc { ... }
}

// Other controllers
...

pub(super) fn remap(id: u32, event: super::EvdevEvent) -> stick::Event {
    match id {
        0x044F_0404 => thrustmaster_warthog_throttle_remap(event),
        ...
    }
}
AldaronLau commented 4 years ago

It also looks like at least adding an ExtSwitch variant to the Event enum might be necessary. Probably two (one for 2-way and one for 3-way).

theunkn0wn1 commented 4 years ago

Ah, i had intended the codegen to generate the modules at build time, sorta the same way prost does it; one way or another I think each joystick should generate into their own files for the sake of organization. Having to sort through a 2k + line file looking for one specific function definition is, i imagine, less maintainable than files that are named after the devices in question that are only a couple lines long.

Looking at your stick::Event type, its again doesn't quite match up with the inputs on this specific controller, for general purpose joysticks this may work, but for this case it might be a good idea to generate controller-specific enums to go with. The codegen could read the names of the inputs and generate something like:

pub enum ThrustmasterWarthogThrottleEvent {
    EacOn,
    EacOff,
    RadarAltimeterOn,
    RadarAltimeterOff,
// ...
}

Either that, or the existing stick::Event should be generalized to something applicable to all devices and let the downstream users differentiate the exact button/axis/input that was fired. This would eliminate a lot of codegen.

pub enum Event{

    ButtonDown(u32),
    ButtonUp(u32),
    AxisMotion(u32),
    HatMotion(u32),
    // ...
}

In fact, doing it the latter method means all this library would need to do is tell what differentiate what kind of input its recv'ed from the underlying interface, it might not need to do anything terribly device-specific

AldaronLau commented 4 years ago

The idea is you don't look for functions in the generated code. You look at the source files. And that should probably be separated into different files, at least based on operating system.

There are actually quite a few of the general events that match up with your controller. The goal of sticks remappings is to use the "meaning" rather than the "position". Some meanings are specific to your controller. I think having the same Event structure for all controllers makes it easier to do something like: Have a game that would usually require your specific controller, and then a 3-way switch for some game mechanic and then someone doesn't own your specific controller but still wants to play the game; Then they can use Lt and Rt to move the 3-way switch up and down. My main goal with this crate is maximum compatibility, and I feel like having multiple event enums goes against that. The second option also makes this difficult.

Extra buttons, switches, hats that don't fit in the standard gamepad model can use Ext event variants, and I think constants could be available in the public API:

// probably in a `devices` module.
pub mod thrustmaster_warthog {
    pub const SWITCH_EAC: u32 = 0;
    pub const SWITCH_RADAR_ALTIMETER: u32 = 1;
}

enum Event {
    // ...
    ExtSwitch(u32, bool),
}

Although, I would also like if some other controller had an Radar Altimeter switch, that it would be matched to the same id. I'm not sure what a good solution would be to that. Maybe use something similar to what you suggested, but only for the events that don't fit into the standard gamepad model as a #[non_exhaustive] enum?

#[non_exhaustive]
pub enum ExtTwoWaySwitchEvent {
    Eac,
    RadarAltimeter,
    // ...
}

enum Event {
    // ...
    ExtTwoWaySwitch(ExtTwoWaySwitchEvent, bool),
}

Would you be O.K with this kind of an API for your use case?

AldaronLau commented 4 years ago

Note: I'm renaming it switch because throttle makes me think continuous, switch makes me think discrete.

theunkn0wn1 commented 4 years ago

Yep, they are two way and three way switches. Having built-in support in this library would be a welcome addition, it sure would make programming against this device easier in downstreams.

You are absolutely right about not generating device-specific enums; the intended use of an input might not even be whats on the label. My specific use case i use eac as a master enable switch for instance.

All stick really needs to do is receive and decode incoming hardware events into some form of Event enum which a downstream could then interpret. Having the two/three-way switch implemented at the library level would be a welcome bonus.

As a side note, I am not planning on building a video game with all this, I am controlling physical hardware with this HID as part of a robotics project. There is more than one application for a joystick library. I fully expect extra work downstream if I need to support a second kind of controller.

AldaronLau commented 4 years ago

@theunkn0wn1 I was just using a video game as an example use case. It's cool to see stick be used for something else!

I think I can try to develop some sort of a schema and code generation this week. If you want to make a PR adding ExtTwoWaySwitchEvent, ExtThreeWaySwitchEvent, ExtButtonEvent and ExtHatEvent? etc. enums, with the unique input labels from your controller that would be very helpful first step to supporting this controller.

theunkn0wn1 commented 4 years ago

Sounds like a plan, Il see what i can come up with. I know you floated the idea of Muon, but could you please support more widely used formats such as toml? A quick search indicates a lack of library support for your file format in other languages (either that or picking a relatively common word is throwing my search off completely).

AldaronLau commented 4 years ago

Is there a reason to worry about supporting other languages for an issue specific to stick? The reason I suggested MuON, is because it was designed to be easy to learn for non-programmers or beginning programmers. This would (hopefully) make it so anyone could make and contribute a remapping file. I also may be biased because I was involved in MuON's design. IMO, TOML is not as easy to learn, and it still trips me up sometimes.

theunkn0wn1 commented 4 years ago

I actually find TOML to be quite intuitive, and has excellent library support in both rust, python, and a variety of languages. Further, if you are concerned about toml being easy to learn for non-programmers, then your issue is superseded by rust itself not being particularly easy to learn. It took a lot of hand-holding from existing rust developers for me to get to the point where I am comfortable with the language, and that was with existing programming experience in other languages. I strongly suspect it would be as hard for non-programmers to pick enough rust up to apply it such as to use stick to begin with. As a secondary, new users are likely to expect stick to "just work", and optimally wouldn't need to be creating these files themselves. You suggested the idea of creating some form of GUI for creating these files, you can make that tool intuitive and leave the schema well documented for advanced users that want to create these files themselves.

I come from a python background, so i tend to reach for that first for tasks that involve generating structured data. I already have a bit of a headache from handling postcard's encoding format, which doesn't have appear to have other language support.

AldaronLau commented 4 years ago

I suppose, at least until MuON gets more support in other languages, that TOML would be a better option, even though it's not my favorite, personally. I was talking more of users of programs that depend on stick rather than actual programmers depending on stick. I agree that people will expect stick to "just work", but it's not quite there yet, and that GUI isn't even started yet. I think postcard falls under a different category since it's format can't even be typed out as text.

But for now, I suppose TOML is the way to go (definitely simpler than YAML, at least, and for this use case should be simpler than JSON or RON).

theunkn0wn1 commented 4 years ago

I started work towards a possible toml-based schema for my specific device, though its presently unclear how the codegen would work to tie this into stick. My current idea is to generate a function that accepts a general EvCode object and decodes it into an device-specific enum. This aims to be supplemental to some generalized stick::Event type using an ExtEvent or something. Not sure yet.

[axies]
0 = "POV_X"
1 = "POV_Y"
2 = "THROTTLE_R"
3 = "UNKNOWN_AX0"  # can't find on device?
4 = "UNKNOWN_AX1"  # can't find on device?
5 = "THROTTLE_L"
6 = "SLEW" # ?

[triggers]
# triggers being unsigned axies, such as that of an Xbox controller
# no triggers for this specific device

[buttons]
# buttons, digital signals
713 = "AUTOPILOT_TOGGLE"
708 = "LANDING_GEAR_SILENCE"

[two_way]
# two way switches, have a single "on" state
711 = "EAC"
712 = "RADAR_ALTIMETER"

[three_way.autopilot]
# three way switches have two "on" states, so they get their own object defining the two "on" states and the neutral 
# state
714 = "PATH"
715 = "ALT"
neutral = "ALTITUDE_HEADING"

[three_way.flaps]
709 = "UP"
710 = "DOWN"
neutral = "MANEUVER"
AldaronLau commented 4 years ago

I actually don't think a device-specific enum is necessary at all. I think the controller schema could specify which events are made available directly to the user.

I think doing something like this would make the codegen trivial:

[axes]
0 = "CameraH"
1 = "CameraV"
2 = "ExtAxis/ThrottleR"
# don't worry about unused axis ids
5 = "ExtAxis/ThrottleL"
6 = "ExtAxis/Slew"

[triggers]
# triggers being unsigned axes, such as that of an Xbox controller
# no triggers for this specific device

[buttons]
# buttons, digital signals
713 = "ExtButton/AutopilotToggle"
708 = "ExtButton/LandingGearSilence"
# There's more buttons, right?

[switch.two_way]
# two way switches, have a single "on" state
711 = "ExtTwoWaySwitch/Eac"
712 = "ExtTwoWaySwitch/RadarAltimeter"

[switch.three_way]
# I'd rather keep it consistent with the rest of the file, if possible.
709 = "ExtThreeWaySwitch/Flaps(Up)"
710 = "ExtThreeWaySwitch/Flaps(Down)"
714 = "ExtThreeWaySwitch/Autopilot(Path)"
715 = "ExtThreeWaySwitch/Autopilot(Alt)"
theunkn0wn1 commented 4 years ago

Update, successfully implemented a code generator for my device-specific enum approach. This is the path I will be using using moving forward in my application, as it makes pattern-matching in user code much more straight-forward.

With your approach, the user code would need to match something like

match event{
    EventType::ExtThreeWaySwitch(name) => {
        match name{
            //  handle specific event here ...

With device-specific enums it can be simplified to

match event{
    DeviceEventType::DeviceSpecificEnum => {
        // handle specific event here ...

Since consistency is prefered, the two-way switch schema is now identical to the three way schema, and the two-way schema is a logical extension of the button / axis schema.

You can find my work at https://github.com/theunkn0wn1/rustpad/ as im presently unsure whether you would accept this approach. The prototype is implemented in python, leveraging jinja templates for code generation. Im sure with further effort i can implement this in rust natively so it could be stuck into a build.rs or something

theunkn0wn1 commented 4 years ago

And yes, there are a grand total of 3 actual "button" inputs on the Warthog throttle. the rest are switches, hats, and axies.

AldaronLau commented 4 years ago

Your code appears to use gilrs?

If you make a PR, I will accept it - but I will likely modify it to my approach. I'm thinking realistically it might actually be simpler, let me show an example:

With both device-agnostic Event and specific Event

match event {
    Event::DeviceSpecific(DeviceSpecificEvents::Warthog(WarthogEvent::Autopilot(state)) => {
    }
    _ => {}
}

With device-specific Event from device-agnostic Event

match event.unwrap_warthog() {
    WarthogEvent::Autopilot(state) => {
    }
    _ => {}
}

With device-agnostic Event only

match event {
    Event::ExtThreeWay(ExtThreeWayEvent::Autopilot(state)) => {
    }
    _ => {}
}

Aside from what I wrote as some kind of unwrap_warthog(), you approach is slightly prettier. But, I think what I did is a simplification of what would actually need to be done, as I probably wouldn't want to implement a public unwrap() / try_unwrap() for each device (even if it is auto-generated). I do think otherwise this would require multiple public device types, all implementing a trait - so a Box<trait> can be returned for Gamepad, which might be cool, but also sounds like a lot of extra complication for this library (and probably requires some kind of downcasting). Nested match statements will not be necessary, as I've shown above.

I've never learned jinja, so from a quick look over it I don't understand your code very much. I will look at the code in more detail tomorrow or Thursday, if you'd like. I'm also going to work on converting the gamecontrollerdb to TOML on those days, which will eventually require code generation, and I don't want us to do the same work, so let me know whether or not you're going to convert your Python code generation to Rust. Otherwise, I'll try to base it off the work you did.

theunkn0wn1 commented 4 years ago

My code used gilrs as it was easier to tie into for development purposes; I didn't need to patch the library to get at the raw event IDs and types.

Jinja isn't strictly necessary, but did simplify the process of creating the necessary text. There are rough equivalents in rust which i am presently evaluating, Il let you know if i have any success with them. I am certain the generator can be implemented without them, it would just be less readable (to the trained eye).

Currently investigating the practicality of converting this to rust in the next couple days, if i succeed il file a pull request.

theunkn0wn1 commented 4 years ago

Successfully generated valid modules in rust, I ended up overhauling the prototype toml because it turned out to be quite difficult to parse in a static language. The only reason it worked properly in the previous revision is the dynamic nature of python which allowed me to do magical things.

Current trouble is finding a binding point in stick, as it's current output just doesn't expose enough information. From what i can tell, the only place the relevant data (crate::linux::EvdevEv objects) exist is within the crate::linux::Gamepad::poll method. Given the size of the file this resides in, generating code into this one method is a terrible idea. Any added code / refactor to this method directly would need to call into generated code in another module. The best idea I can come up with this evening is to have a crate::controllers module, which can be generated (via a build.rs). This module would have one job: map raw EvdevEv / platform specific equivalent to generated device-specific event decoders (generated).

At any rate, i managed to hack in preliminary support For my controller by modifying poll to call my functions, its still a WIP.

I copy/pasted the README example into examples/readme.rs and here is proof of life:

    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/examples/readme`
Connected p1, id: 44F0404, name: Thrustmaster Throttle - HOTAS Warthog
p1: WarthogThrottle AutopilotTogglePressed
p1: WarthogThrottle AutopilotToggleReleased
p1: WarthogThrottle AutopilotTogglePressed
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle Unknown(1, 713, 2)
p1: WarthogThrottle AutopilotToggleReleased
p1: WarthogThrottle LtbPressed
p1: WarthogThrottle Unknown(1, 302, 2)
p1: WarthogThrottle Unknown(1, 302, 2)
p1: WarthogThrottle Unknown(1, 302, 2)
p1: WarthogThrottle LtbReleased

Funnily enough, the unknown events here are actually "input held" events; something i was not expecting. Alas its getting late, so il pick this back up again sometime later this week.

AldaronLau commented 4 years ago

@theunkn0wn1 I think your idea of the generated controllers module is exactly what I want. Input held events can be safely ignored since it's easy to get state from press/release. Looks great!

theunkn0wn1 commented 4 years ago

Sounds good, I have some cleanup and generalization left to do, I will open a draft PR shortly so you can see the end-result of my work.

AldaronLau commented 4 years ago

@theunkn0wn1 I have now incorporated a code generator and made a folder for a database of controllers. Would you mind testing the Warthog controller on the version of stick that's on crates.io? I believe it should work now, but I want to make sure I didn't break anything before closing this issue and releasing stick 0.10.

AldaronLau commented 4 years ago

Edit: I meant on GitHub (new changes are NOT on crates.io yet)

theunkn0wn1 commented 4 years ago

@AldaronLau Test unsuccessful to satisfy OP.

appears the library code is continuing to be extremely noisy, and the library still appears to not correctly handle this gamepad.

$ cargo run --example readme
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/examples/readme`
Connected p1, id: 0300_5E04_8E02_1001, name: X360 Controller (Microsoft X-Box 360 pad)
Connected p2, id: 0300_4F04_0404_1101, name: Unknown Pad (Thrustmaster Throttle - HOTAS Warthog)
*Evdev* Unknown Button Code: 421, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 421, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 421, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 421, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 421, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 421, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 421, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 421, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 422, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 422, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 422, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 422, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 422, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 422, report at https://github.com/libcala/stick/issues
AldaronLau commented 4 years ago

@theunkn0wn1 Thanks! Just pushed a change. I think I just needed to rename the file. It should work now, I think.

theunkn0wn1 commented 4 years ago

@AldaronLau seems to do better, however two major issues come up. Firstly, I believe we agreed to ignore ButtonHeld style events? at the very least it should be made unique so users can filter them out easily

~/projects/unknown/stick on  master! ⌚ 18:09:51
$ cargo run --example readme
   Compiling stick v0.10.0 (/home/orion/projects/unknown/stick)
    Finished dev [unoptimized + debuginfo] target(s) in 8.93s
     Running `target/debug/examples/readme`
Connected p1, id: 0300_4F04_0404_1101, name: Thrustmaster Warthog Throttle (Thrustmaster Throttle - HOTAS Warthog)
p1: Eac Forward
p1: Eac Forward
p1: Eac Forward
p1: Eac Forward
p1: Eac Forward

Secondly, and more importantly, it appears the axies do NOT read correctly. Left and right axies only output non-1 values at the forward extremes, and output 1 during 98% of the axis's movement. Almost as if they are reading the wrong thing?

AldaronLau commented 4 years ago

@theunkn0wn1 Yes, I agree those should be ignored. I don't know which events are being repeated, since I don't have the controller. Is it just the three-way switches, some of them, or something else? I think I have an idea about the axes, so it might be fixed now.

theunkn0wn1 commented 4 years ago

@AldaronLau All digital inputs on this controller; When i was working on #9 I noticed buttons have three states: 0x00 (off), 0x01, (on), and 0x02 (held). This information is held in stick::ffi::EvdevEv::ev_value field.

AS for your later commit, you made the axis unsigned; but did NOT fix the underlying issue of it only reading non-1 at the forward extreme

AldaronLau commented 4 years ago

@theunkn0wn1 Thanks! I temporarily commented out the Left and Right axes on the Warthog, so now it will print unknown events. Can you tell me what it prints out at maximum (backward) and minimum (forward) values? I'll work on fixing the held events.

theunkn0wn1 commented 4 years ago

Your latest commit doesn't produce useful data, rolled back a commit and used debugging tools to get requested data.

Forward extreme: 0 Backwards extreme 16339

Breakpoint reached: linux.rs:243
ev.ev_value = (i32) 16339
... Noise ...
Breakpoint reached: linux.rs:243
ev.ev_value = (i32) 32
AldaronLau commented 4 years ago

@theunkn0wn1 Thanks, I added the useful data back into the prints, and used the range to hopefully fix the bug.

And, also the repeating buttons should be fixed now, if you want to check that too.

theunkn0wn1 commented 4 years ago

@AldaronLau Range is flipped; MAX reads 0 and OFF reads 1, otherwise the axies read reasonably. Event duplicity appears to be mostly resolved, it now only occurs for unknown events.

Only remaining issue for this gamepad, it seems, is one unimplemented HAT

*Evdev* Unknown Button Code: 2, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 2, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 4, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 4, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 3, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 3, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 4, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 4, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 5, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 5, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 2, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 3, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 3, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 4, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 4, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 1, Value: 1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Button Code: 1, Value: 0, report at https://github.com/libcala/stick/issues

North: code 2 South: Code 4 West: code 3 East: code 3 Pressed: code 1

Event repetition occurs for these inputs (most probably because they are unknown).

AldaronLau commented 4 years ago

@theunkn0wn1 I inverted the left and right throttles by adding an "invert" option to the TOML schema, I think the hat should work now too.

theunkn0wn1 commented 4 years ago

@AldaronLau that broke the POV hat somehow Both the axis and the hat on the back of right throttle are now broken (both previously working)

*Evdev* Unknown Absolute Axis Code: 0, Value: 518, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 520, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 518, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 512, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 533, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 397, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 510, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 512, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 593, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 370, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 525, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 505, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 512, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 512, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 247, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 574, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 168, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 587, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 306, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 599, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 725, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 166, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 240, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 18, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 696, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 0, Value: 512, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 1, Value: 512, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 16, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 17, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 16, Value: -1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 17, Value: -1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 16, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 17, Value: 0, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 16, Value: -1, report at https://github.com/libcala/stick/issues
*Evdev* Unknown Absolute Axis Code: 16, Value: 0, report at https://github.com/libcala/stick/issues
AldaronLau commented 4 years ago

Looking at the controller online, it looks like there's three 2 dimensional hats. The "Mouse Hat with a push button", The "8-Way POV Hat", and The "4-Way Mic Hat with a push button".

I'm guessing that the Mouse Hat is axis 0 and 1 which I don't believe were ever actually working, because it looks like it's actually a Mouse Hat X and Mouse Hat Y unsigned axes (0 thru 1024, that rest at 512). I don't think the Mouse Hat Push button works (since it's not in the TOML file).

I'm going to guess that axis 16 and 17 are the POV hat.

I also don't think Mic hat Push button event is getting covered either.

I am uncertain which hat buttons 1, 2, 3, 4, and 5 correspond to. It could be the mic hat, but 256, 257, 258 and 259 are currently mapped to the Mic hat (which maybe is wrong I'm guessing?).

I'm very confused, so any help on how many hats are actually on the controller and what events are returned from each hat would be very much appreciated.

AldaronLau commented 4 years ago

By the way, the Warthog TOML mapping is located at stick/pad_db/pad/mapping/03004F0404041101.toml. If you remove it you can see all the raw events (Now repeat events are filtered out). If that's helpful.

AldaronLau commented 4 years ago

It might sort of work now from what I can guess?

AldaronLau commented 4 years ago

@theunkn0wn1 I believe I have made all of the necessary changes if you would like to check it again.

theunkn0wn1 commented 4 years ago

@AldaronLau latest changes seem good. Beyond one unexpected input the remaining controls appear to be reported in a logical manor.

Apparently the mouse hat as your events call it has a button attached to it. Not sure how i missed that during my initial rounds of testing, It just didn't occur to me there would be a button there.

p1: MouseY -1
*Evdev* Unknown Button Code: 0, Value: 1, report at https://github.com/libcala/stick/issues
p1: MouseX 0.0390625
*Evdev* Unknown Button Code: 0, Value: 0, report at https://github.com/libcala/stick/issues

To keep naming similar, this can be appended to the relevant pad descriptor file

[[button]]
code = 0
event = "MousePush"

I tested this change locally and it appears to handle all inputs in a sensible manor. Expect a PR shortly for the fix..

AldaronLau commented 4 years ago

Thanks! Now, would you say this issue can be closed? That is, this controller works correctly on master?

theunkn0wn1 commented 4 years ago

@AldaronLau Affirmative, it can be closed via #14 .

AldaronLau commented 4 years ago

Closing, will release stick 0.10 today with the changes.

AldaronLau commented 4 years ago

Stick 0.10 released!