New class for Logitech Dual Action Gamepad

Wildstang is using the Logitech Dual Action Gamepad for our manipulator this year so I “borrowed” the gamepad class that 1114 released as part of the beta project (thanks guys :slight_smile: ) for some early testing. I quickly realized that it didn’t give access to the D-pad and the left analog stick at the same time since the joystick class they derived from only gives access to four controller axes at once. You have to press the “Mode” button to swap between the D-pad and the left analog stick. Since we want to use both at the same time, I wrote my own class that interfaces directly with the DriverStation class, just like the provided Joystick class does. I didn’t bother to add GetLeftTrigger() or similar methods because we won’t be using those, but they should be simple for you to add if you need them.

I figured that since most of the code in the new class was pieced together from code in the WPILib Joystick class and the Simbot’s LogitechGamepad class, the fair thing to do is release it to everyone. I wouldn’t have been able to create this class as quickly and easily without using both of those classes as references.

The code is fairly well tested and it should work fine since it’s very simple stuff, but if you find any bugs or make improvements, please post them here.

Gamepad.zip (1.61 KB)


Gamepad.zip (1.61 KB)

Thanks!

For some reason I was under the impression that it wasn’t physically possible to access both the D-pad and the left stick at the same time when I wrote that class, so thanks for clearing that up.

Thanks from us here as well!

We’re using these exact gamepads for both driver and operator. We haven’t gotten around to using the D-Pad portion of it, but we know will need to soon enough.

We’re planning on using the Logitech gamepad to control our arm, and just for the sake of time I’ve been using the FRC Joystick class. It actually provides all the functionality you need (axes, buttons, etc), but this should make the code more user-friendly, thanks!

Regarding the actual class:
The D-pad is made from a standard x and a y axis (as you know), but each only return either 1 or -1. The if statements (ex: x < -0.5) would more simply be written like if(x = -1).
EDIT: this is not good practice, see below.

I hope you don’t mind, attached is a modification of your Gamepad class that adds an enum for button type (top, bottom-left-trigger, etc) and a Get function that uses the new enum. Hopefully that should make the code more user-friendly.

EDIT: Updated attachment to use the original d-pad code (which, as pointed out below, is more portable and better follows convention).
Also, this particular class assumes the Logitech Dual-Action gamepad with its button enumeration. This should be easy enough to reorder for other gamepads.

Gamepad.zip (1.71 KB)


Gamepad.zip (1.71 KB)

I think Mike did that intentionally because the values that are being used are floats. Because of this, you shouldn’t perform equality checks on them, but rather check a range. This page provides a good explanation on why this is the case. While the equality works most of the time, using .5 as the comparison point works all the time.

I think Mike did that intentionally because the values that are being used are floats. Because of this, you shouldn’t perform equality checks on them, but rather check a range.

In general, you’re absolutely right. But in this case, I’ve done pretty extensive testing (outputting the raw axis value to the console), and the gamepad will always output -1 or 1.

Edit 1: You’ll notice the article is talking about testing floats when doing floating point math. Since we’re doing no math, only testing a returned value, it’s safe.
Edit 2: Furthermore, it talks about how the binary representation is not 100% precise for some numbers. The binary representation of floating points is implementation-specific, but lets assume the first bit is for the sign, the next 24 bits are for the significant figures, and the last 7 bits are for the base (IEEE 754 defines 24 bits as standard for 32-bit - single precision - floating point numbers). OK, a d1 (a 1 in decimal) looks like:

11000000000000000000000000000000

or, a 1 for the sign, a “100000000000000000000000” (a 1 followed by 23 0s) for the significant figures, and 7 0s (base = 0).
This is precisely 1.

We’re using a Logitech gamepad that outputs analog values on the D-Pad. The buttons under the dpad on that stick are pressure sensitive and CAN output a value less than 1 if you press them lightly. And, most people follow the “don’t test an exact value of a float” as a rule-of-thumb (so as not to get into trouble) rather than considering the exact implementation and whether it’s safe for a particular case. We tend to write code with portability in mind, even if we’re not likely to port it, just as a good habit to have.

The buttons under the dpad on that stick are pressure sensitive and CAN output a value less than 1 if you press them lightly.

Ah, I hadn’t considered that. I’d only seen 1 or -1.

You’re absolutely right on all counts. I got a bit too into the argument xD

I updated the code I posted above to the original d-pad code.
Not a huge improvement over the original code, but worthwhile, I think.

Thanks to all of those that have worked on this and released it to everybody! I’m really looking forward to the forthcoming “open source project” for the WPILib robot code, where hopefully lots of teams will be able to work together to publish generically useful capabilities like this!

Thanks again!