[hal,wpilib] Add support for joystick outputs (#8385)

Support joystick outputs, including Rumble and LEDs.

Also requires an update to Joystick descriptors, as that has also
changed in mrccomm to support showing what outputs are supported.
This commit is contained in:
Thad House
2025-11-17 14:36:14 -08:00
committed by GitHub
parent 5db6d2f500
commit ce6fd225a6
54 changed files with 1607 additions and 854 deletions

View File

@@ -977,17 +977,31 @@ public final class DriverStation {
}
/**
* Gets the value of type on a joystick.
* Gets the value of type on a gamepad.
*
* @param stick The joystick port number
* @return The value of type
*/
public static int getJoystickType(int stick) {
public static int getJoystickGamepadType(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
return DriverStationJNI.getJoystickType((byte) stick);
return DriverStationJNI.getJoystickGamepadType((byte) stick);
}
/**
* Gets the value of supported outputs on a joystick.
*
* @param stick The joystick port number
* @return The value of supported outputs
*/
public static int getJoystickSupportedOutputs(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
return DriverStationJNI.getJoystickSupportedOutputs((byte) stick);
}
/**

View File

@@ -26,46 +26,36 @@ public class GenericHID {
kLeftRumble,
/** Right rumble motor. */
kRightRumble,
/** Both left and right rumble motors. */
kBothRumble
/** Left trigger rumble motor. */
kLeftTriggerRumble,
/** Right trigger rumble motor. */
kRightTriggerRumble,
}
/** USB HID interface type. */
public enum HIDType {
/** Unknown. */
kUnknown(-1),
/** XInputUnknown. */
kXInputUnknown(0),
/** XInputGamepad. */
kXInputGamepad(1),
/** XInputWheel. */
kXInputWheel(2),
/** XInputArcadeStick. */
kXInputArcadeStick(3),
/** XInputFlightStick. */
kXInputFlightStick(4),
/** XInputDancePad. */
kXInputDancePad(5),
/** XInputGuitar. */
kXInputGuitar(6),
/** XInputGuitar2. */
kXInputGuitar2(7),
/** XInputDrumKit. */
kXInputDrumKit(8),
/** XInputGuitar3. */
kXInputGuitar3(11),
/** XInputArcadePad. */
kXInputArcadePad(19),
/** HIDJoystick. */
kHIDJoystick(20),
/** HIDGamepad. */
kHIDGamepad(21),
/** HIDDriving. */
kHIDDriving(22),
/** HIDFlight. */
kHIDFlight(23),
/** HID1stPerson. */
kHID1stPerson(24);
kUnknown(0),
/** Standard. */
kStandard(1),
/** Xbox 360. */
kXbox360(2),
/** Xbox One. */
kXboxOne(3),
/** PS3. */
kPS3(4),
/** PS4. */
kPS4(5),
/** PS5. */
kPS5(6),
/** Switch Pro. */
kSwitchPro(7),
/** Switch Joycon Left. */
kSwitchJoyconLeft(8),
/** Switch Joycon Right. */
kSwitchJoyconRight(9),
/** Switch Joycon Pair. */
kSwitchJoyconPair(10);
/** HIDType value. */
public final int value;
@@ -94,9 +84,10 @@ public class GenericHID {
}
private final int m_port;
private int m_outputs;
private int m_leftRumble;
private int m_rightRumble;
private int m_leftTriggerRumble;
private int m_rightTriggerRumble;
private final Map<EventLoop, Map<Integer, BooleanEvent>> m_buttonCache = new HashMap<>();
private final Map<EventLoop, Map<Pair<Integer, Double>, BooleanEvent>> m_axisLessThanCache =
new HashMap<>();
@@ -432,8 +423,17 @@ public class GenericHID {
*
* @return the type of the HID.
*/
public HIDType getType() {
return HIDType.of(DriverStation.getJoystickType(m_port));
public HIDType getGamepadType() {
return HIDType.of(DriverStation.getJoystickGamepadType(m_port));
}
/**
* Get the supported outputs for the HID.
*
* @return the supported outputs for the HID.
*/
public int getSupportedOutputs() {
return DriverStation.getJoystickSupportedOutputs(m_port);
}
/**
@@ -455,24 +455,16 @@ public class GenericHID {
}
/**
* Set a single HID output value for the HID.
* Set leds on the controller. If only mono is supported, the system will use the highest value
* passed in.
*
* @param outputNumber The index of the output to set (1-32)
* @param value The value to set the output to
* @param r Red value from 0-255
* @param g Green value from 0-255
* @param b Blue value from 0-255
*/
public void setOutput(int outputNumber, boolean value) {
m_outputs = (m_outputs & ~(1 << (outputNumber - 1))) | ((value ? 1 : 0) << (outputNumber - 1));
DriverStationJNI.setJoystickOutputs((byte) m_port, m_outputs, m_leftRumble, m_rightRumble);
}
/**
* Set all HID output values for the HID.
*
* @param value The 32 bit output value (1 bit for each output)
*/
public void setOutputs(int value) {
m_outputs = value;
DriverStationJNI.setJoystickOutputs((byte) m_port, m_outputs, m_leftRumble, m_rightRumble);
public void setLeds(int r, int g, int b) {
int value = ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF);
DriverStationJNI.setJoystickLeds((byte) m_port, value);
}
/**
@@ -486,15 +478,27 @@ public class GenericHID {
value = Math.clamp(value, 0, 1);
int rumbleValue = (int) (value * 65535);
switch (type) {
case kLeftRumble -> this.m_leftRumble = rumbleValue;
case kRightRumble -> this.m_rightRumble = rumbleValue;
default -> {
case kLeftRumble:
this.m_leftRumble = rumbleValue;
break;
case kRightRumble:
this.m_rightRumble = rumbleValue;
}
break;
case kLeftTriggerRumble:
this.m_leftTriggerRumble = rumbleValue;
break;
case kRightTriggerRumble:
this.m_rightTriggerRumble = rumbleValue;
break;
default:
break;
}
DriverStationJNI.setJoystickOutputs(
(byte) this.m_port, this.m_outputs, this.m_leftRumble, this.m_rightRumble);
DriverStationJNI.setJoystickRumble(
(byte) this.m_port,
this.m_leftRumble,
this.m_rightRumble,
this.m_leftTriggerRumble,
this.m_rightTriggerRumble);
}
}

View File

@@ -322,15 +322,15 @@ public final class DriverStationSim {
* @param stick The joystick number
* @return The joystick outputs
*/
public static long getJoystickOutputs(int stick) {
return DriverStationDataJNI.getJoystickOutputs(stick);
public static int getJoystickLeds(int stick) {
return DriverStationDataJNI.getJoystickLeds(stick);
}
/**
* Gets the joystick rumble.
*
* @param stick The joystick number
* @param rumbleNum Rumble to get (0=left, 1=right)
* @param rumbleNum Rumble to get (0=left, 1=right, 2=left trigger, 3=right trigger)
* @return The joystick rumble value
*/
public static int getJoystickRumble(int stick, int rumbleNum) {
@@ -450,8 +450,18 @@ public final class DriverStationSim {
* @param stick The joystick number
* @param type The value of type
*/
public static void setJoystickType(int stick, int type) {
DriverStationDataJNI.setJoystickType(stick, type);
public static void setJoystickGamepadType(int stick, int type) {
DriverStationDataJNI.setJoystickGamepadType(stick, type);
}
/**
* Sets the value of supported outputs for a joystick.
*
* @param stick The joystick number
* @param supportedOutputs The value of supported outputs
*/
public static void setJoystickSupportedOutputs(int stick, int supportedOutputs) {
DriverStationDataJNI.setJoystickSupportedOutputs(stick, supportedOutputs);
}
/**

View File

@@ -133,8 +133,17 @@ public class GenericHIDSim {
*
* @param type the new device type
*/
public void setType(GenericHID.HIDType type) {
DriverStationSim.setJoystickType(m_port, type.value);
public void setGamepadType(GenericHID.HIDType type) {
DriverStationSim.setJoystickGamepadType(m_port, type.value);
}
/**
* Set the supported outputs of this device.
*
* @param supportedOutputs the new supported outputs
*/
public void setSupportedOutputs(int supportedOutputs) {
DriverStationSim.setJoystickSupportedOutputs(m_port, supportedOutputs);
}
/**
@@ -147,23 +156,12 @@ public class GenericHIDSim {
}
/**
* Read the output of a button.
* Get the led color set.
*
* @param outputNumber the button number
* @return the value of the button (true = pressed)
* @return the led color set
*/
public boolean getOutput(int outputNumber) {
long outputs = getOutputs();
return (outputs & (1L << (outputNumber - 1))) != 0;
}
/**
* Get the encoded 16-bit integer that passes button values.
*
* @return the button values
*/
public long getOutputs() {
return DriverStationSim.getJoystickOutputs(m_port);
public int getLeds() {
return DriverStationSim.getJoystickLeds(m_port);
}
/**
@@ -173,9 +171,24 @@ public class GenericHIDSim {
* @return the rumble value
*/
public double getRumble(GenericHID.RumbleType type) {
int value =
DriverStationSim.getJoystickRumble(
m_port, type == GenericHID.RumbleType.kLeftRumble ? 0 : 1);
int intType = 0;
switch (type) {
case kLeftRumble:
intType = 0;
break;
case kRightRumble:
intType = 1;
break;
case kLeftTriggerRumble:
intType = 2;
break;
case kRightTriggerRumble:
intType = 3;
break;
default:
return 0.0;
}
int value = DriverStationSim.getJoystickRumble(m_port, intType);
return value / 65535.0;
}
}