[hal,wpilib] Use new DS available API from mrccomm (#8302)

Instead of just having a max count for joystick values, there's an available mask of values. This is because in the future we're expecting there to be holes in the list of available buttons and axes. This updates everything to support that scenario.

Also, Joystick buttons, axes, and POVs all now start at 0 instead of 1.
This commit is contained in:
Thad House
2025-10-25 23:03:50 -07:00
committed by GitHub
parent 429698f508
commit 2e10f91e07
62 changed files with 6101 additions and 1066 deletions

View File

@@ -4,8 +4,6 @@
package edu.wpi.first.hal;
import java.nio.ByteBuffer;
/**
* Driver Station JNI Functions.
*
@@ -142,55 +140,18 @@ public class DriverStationJNI extends JNIWrapper {
/** The maximum number of axes. */
public static final int kMaxJoystickAxes = 12;
public static final int kMaxJoystickButtons = 64;
/** The maximum number of POVs. */
public static final int kMaxJoystickPOVs = 8;
/** The maximum number of joysticks. */
public static final int kMaxJoysticks = 6;
/**
* Gets the axes of a specific joystick.
*
* @param joystickNum the joystick number
* @param axesArray the axes values
* @return number of joystick axes, or 0 for error
* @see "HAL_GetJoystickAxes"
*/
public static native int getJoystickAxes(byte joystickNum, float[] axesArray);
/**
* Gets the axes of a specific joystick.
*
* @param joystickNum the joystick number
* @param rawAxesArray the raw int axes values (-32767-32768)
* @return number of joystick axes, or 0 for error
* @see "HAL_GetJoystickAxes"
*/
public static native int getJoystickAxesRaw(byte joystickNum, short[] rawAxesArray);
/**
* Gets the POVs of a specific joystick.
*
* @param joystickNum the joystick number
* @param povsArray the POV values
* @return number of POVs, or 0 for error
* @see "HAL_GetJoystickPOVs"
*/
public static native int getJoystickPOVs(byte joystickNum, byte[] povsArray);
/**
* Gets the buttons of a specific joystick.
*
* @param joystickNum the joystick number
* @param count the count of buttons
* @return The joystick button values
* @see "HAL_GetJoystickButtons"
*/
public static native int getJoystickButtons(byte joystickNum, ByteBuffer count);
/**
* Get all joystick data.
*
* @param stick the joystick to grab
* @param axesArray all joystick axes
* @param rawAxesArray all joystick axes as int
* @param povsArray all povs
@@ -199,7 +160,11 @@ public class DriverStationJNI extends JNIWrapper {
* @see "HAL_GetAllJoystickData"
*/
public static native void getAllJoystickData(
float[] axesArray, short[] rawAxesArray, byte[] povsArray, long[] buttonsAndMetadata);
int stick,
float[] axesArray,
short[] rawAxesArray,
byte[] povsArray,
long[] buttonsAndMetadata);
/**
* Set joystick outputs.
@@ -246,19 +211,6 @@ public class DriverStationJNI extends JNIWrapper {
*/
public static native String getJoystickName(byte joystickNum);
/**
* Gets the type of a specific joystick axis.
*
* <p>This is device specific, and different depending on what system input type the joystick
* uses.
*
* @param joystickNum the joystick number
* @param axis the axis number
* @return the enumerated axis type
* @see "HAL_GetJoystickAxisType"
*/
public static native int getJoystickAxisType(byte joystickNum, byte axis);
/**
* Returns the approximate match time.
*

View File

@@ -77,11 +77,14 @@ public class DriverStationDataJNI extends JNIWrapper {
public static native void setMatchTime(double matchTime);
public static native void setJoystickAxes(byte joystickNum, float[] axesArray);
public static native void setJoystickAxes(
byte joystickNum, float[] axesArray, short availableAxes);
public static native void setJoystickPOVs(byte joystickNum, byte[] povsArray);
public static native void setJoystickPOVs(
byte joystickNum, byte[] povsArray, short availablePovs);
public static native void setJoystickButtons(byte joystickNum, int buttons, int count);
public static native void setJoystickButtons(
byte joystickNum, long buttons, long availableButtons);
public static native long getJoystickOutputs(int stick);
@@ -108,13 +111,13 @@ public class DriverStationDataJNI extends JNIWrapper {
public static native void setJoystickPOV(int stick, int pov, byte value);
public static native void setJoystickButtonsValue(int stick, int buttons);
public static native void setJoystickButtonsValue(int stick, long buttons);
public static native void setJoystickAxisCount(int stick, int count);
public static native void setJoystickAxesAvailable(int stick, int available);
public static native void setJoystickPOVCount(int stick, int count);
public static native void setJoystickPOVsAvailable(int stick, int available);
public static native void setJoystickButtonCount(int stick, int count);
public static native void setJoystickButtonsAvailable(int stick, long available);
public static native void setJoystickIsGamepad(int stick, boolean isGamepad);
@@ -122,8 +125,6 @@ public class DriverStationDataJNI extends JNIWrapper {
public static native void setJoystickName(int stick, String name);
public static native void setJoystickAxisType(int stick, int axis, int type);
public static native void setGameSpecificMessage(String message);
public static native void setEventName(String name);

View File

@@ -133,142 +133,39 @@ Java_edu_wpi_first_hal_DriverStationJNI_nativeGetAllianceStation
return static_cast<jint>(allianceStation);
}
/*
* Class: edu_wpi_first_hal_DriverStationJNI
* Method: getJoystickAxesRaw
* Signature: (B[S)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_DriverStationJNI_getJoystickAxesRaw
(JNIEnv* env, jclass, jbyte joystickNum, jshortArray axesRawArray)
{
HAL_JoystickAxes axes;
HAL_GetJoystickAxes(joystickNum, &axes);
jsize javaSize = env->GetArrayLength(axesRawArray);
if (axes.count > javaSize) {
ThrowIllegalArgumentException(
env,
fmt::format("Native array size larger then passed in java array "
"size\nNative Size: {} Java Size: {}",
static_cast<int>(axes.count), static_cast<int>(javaSize)));
return 0;
}
env->SetShortArrayRegion(axesRawArray, 0, axes.count, axes.raw);
return axes.count;
}
/*
* Class: edu_wpi_first_hal_DriverStationJNI
* Method: getJoystickAxes
* Signature: (B[F)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_DriverStationJNI_getJoystickAxes
(JNIEnv* env, jclass, jbyte joystickNum, jfloatArray axesArray)
{
HAL_JoystickAxes axes;
HAL_GetJoystickAxes(joystickNum, &axes);
jsize javaSize = env->GetArrayLength(axesArray);
if (axes.count > javaSize) {
ThrowIllegalArgumentException(
env,
fmt::format("Native array size larger then passed in java array "
"size\nNative Size: {} Java Size: {}",
static_cast<int>(axes.count), static_cast<int>(javaSize)));
return 0;
}
env->SetFloatArrayRegion(axesArray, 0, axes.count, axes.axes);
return axes.count;
}
/*
* Class: edu_wpi_first_hal_DriverStationJNI
* Method: getJoystickPOVs
* Signature: (B[B)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_DriverStationJNI_getJoystickPOVs
(JNIEnv* env, jclass, jbyte joystickNum, jbyteArray povsArray)
{
HAL_JoystickPOVs povs;
HAL_GetJoystickPOVs(joystickNum, &povs);
jsize javaSize = env->GetArrayLength(povsArray);
if (povs.count > javaSize) {
ThrowIllegalArgumentException(
env,
fmt::format("Native array size larger then passed in java array "
"size\nNative Size: {} Java Size: {}",
static_cast<int>(povs.count), static_cast<int>(javaSize)));
return 0;
}
env->SetByteArrayRegion(povsArray, 0, povs.count,
reinterpret_cast<const jbyte*>(povs.povs));
return povs.count;
}
/*
* Class: edu_wpi_first_hal_DriverStationJNI
* Method: getAllJoystickData
* Signature: ([F[S[B[J)V
* Signature: (I[F[S[B[J)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_DriverStationJNI_getAllJoystickData
(JNIEnv* env, jclass cls, jfloatArray axesArray, jshortArray rawAxesArray,
jbyteArray povsArray, jlongArray buttonsAndMetadataArray)
(JNIEnv* env, jclass cls, jint stick, jfloatArray axesArray,
jshortArray rawAxesArray, jbyteArray povsArray,
jlongArray buttonsAndMetadataArray)
{
HAL_JoystickAxes axes[HAL_kMaxJoysticks];
HAL_JoystickPOVs povs[HAL_kMaxJoysticks];
HAL_JoystickButtons buttons[HAL_kMaxJoysticks];
HAL_JoystickAxes axes;
HAL_JoystickPOVs povs;
HAL_JoystickButtons buttons;
HAL_GetAllJoystickData(axes, povs, buttons);
HAL_GetAllJoystickData(stick, &axes, &povs, &buttons);
CriticalJSpan<jfloat> jAxes(env, axesArray);
CriticalJSpan<jshort> jRawAxes(env, rawAxesArray);
CriticalJSpan<jbyte> jPovs(env, povsArray);
CriticalJSpan<jlong> jButtons(env, buttonsAndMetadataArray);
static_assert(sizeof(jAxes[0]) == sizeof(axes[0].axes[0]));
static_assert(sizeof(jRawAxes[0]) == sizeof(axes[0].raw[0]));
static_assert(sizeof(jPovs[0]) == sizeof(povs[0].povs[0]));
static_assert(sizeof(jAxes[0]) == sizeof(axes.axes[0]));
static_assert(sizeof(jRawAxes[0]) == sizeof(axes.raw[0]));
static_assert(sizeof(jPovs[0]) == sizeof(povs.povs[0]));
for (size_t i = 0; i < HAL_kMaxJoysticks; i++) {
std::memcpy(&jAxes[i * HAL_kMaxJoystickAxes], axes[i].axes,
sizeof(axes[i].axes));
std::memcpy(&jRawAxes[i * HAL_kMaxJoystickAxes], axes[i].raw,
sizeof(axes[i].raw));
std::memcpy(&jPovs[i * HAL_kMaxJoystickPOVs], povs[i].povs,
sizeof(povs[i].povs));
jButtons[i * 4] = axes[i].count;
jButtons[(i * 4) + 1] = povs[i].count;
jButtons[(i * 4) + 2] = buttons[i].count;
jButtons[(i * 4) + 3] = buttons[i].buttons;
}
}
/*
* Class: edu_wpi_first_hal_DriverStationJNI
* Method: getJoystickButtons
* Signature: (BLjava/lang/Object;)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_DriverStationJNI_getJoystickButtons
(JNIEnv* env, jclass, jbyte joystickNum, jobject count)
{
HAL_JoystickButtons joystickButtons;
HAL_GetJoystickButtons(joystickNum, &joystickButtons);
jbyte* countPtr =
reinterpret_cast<jbyte*>(env->GetDirectBufferAddress(count));
*countPtr = joystickButtons.count;
return joystickButtons.buttons;
std::memcpy(&jAxes[0], axes.axes, sizeof(axes.axes));
std::memcpy(&jRawAxes[0], axes.raw, sizeof(axes.raw));
std::memcpy(&jPovs[0], povs.povs, sizeof(povs.povs));
jButtons[0] = axes.available;
jButtons[1] = povs.available;
jButtons[2] = buttons.available;
jButtons[3] = buttons.buttons;
}
/*
@@ -323,18 +220,6 @@ Java_edu_wpi_first_hal_DriverStationJNI_getJoystickName
return str;
}
/*
* Class: edu_wpi_first_hal_DriverStationJNI
* Method: getJoystickAxisType
* Signature: (BB)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_DriverStationJNI_getJoystickAxisType
(JNIEnv*, jclass, jbyte joystickNum, jbyte axis)
{
return HAL_GetJoystickAxisType(joystickNum, axis);
}
/*
* Class: edu_wpi_first_hal_DriverStationJNI
* Method: getMatchTime

View File

@@ -427,11 +427,12 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setMatchTime
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setJoystickAxes
* Signature: (B[F)V
* Signature: (B[FS)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickAxes
(JNIEnv* env, jclass, jbyte joystickNum, jfloatArray axesArray)
(JNIEnv* env, jclass, jbyte joystickNum, jfloatArray axesArray,
jshort availableAxes)
{
HAL_JoystickAxes axes;
{
@@ -440,7 +441,7 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickAxes
auto arraySize = arrayRef.size();
int maxCount =
arraySize < HAL_kMaxJoystickAxes ? arraySize : HAL_kMaxJoystickAxes;
axes.count = maxCount;
axes.available = availableAxes;
for (int i = 0; i < maxCount; i++) {
axes.axes[i] = arrayRef[i];
}
@@ -452,11 +453,12 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickAxes
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setJoystickPOVs
* Signature: (B[B)V
* Signature: (B[BS)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickPOVs
(JNIEnv* env, jclass, jbyte joystickNum, jbyteArray povsArray)
(JNIEnv* env, jclass, jbyte joystickNum, jbyteArray povsArray,
jshort availablePovs)
{
HAL_JoystickPOVs povs;
{
@@ -465,7 +467,7 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickPOVs
auto arraySize = arrayRef.size();
int maxCount =
arraySize < HAL_kMaxJoystickPOVs ? arraySize : HAL_kMaxJoystickPOVs;
povs.count = maxCount;
povs.available = availablePovs;
for (int i = 0; i < maxCount; i++) {
povs.povs[i] = static_cast<HAL_JoystickPOV>(arrayRef[i]);
}
@@ -477,17 +479,15 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickPOVs
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setJoystickButtons
* Signature: (BII)V
* Signature: (BJJ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickButtons
(JNIEnv* env, jclass, jbyte joystickNum, jint buttons, jint count)
(JNIEnv* env, jclass, jbyte joystickNum, jlong buttons,
jlong availableButtons)
{
if (count > 32) {
count = 32;
}
HAL_JoystickButtons joystickButtons;
joystickButtons.count = count;
joystickButtons.available = availableButtons;
joystickButtons.buttons = buttons;
HALSIM_SetJoystickButtons(joystickNum, &joystickButtons);
}
@@ -654,49 +654,49 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickPOV
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setJoystickButtonsValue
* Signature: (II)V
* Signature: (IJ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickButtonsValue
(JNIEnv*, jclass, jint stick, jint buttons)
(JNIEnv*, jclass, jint stick, jlong buttons)
{
HALSIM_SetJoystickButtonsValue(stick, buttons);
}
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setJoystickAxisCount
* Method: setJoystickAxesAvailable
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickAxisCount
(JNIEnv*, jclass, jint stick, jint count)
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickAxesAvailable
(JNIEnv*, jclass, jint stick, jint available)
{
HALSIM_SetJoystickAxisCount(stick, count);
HALSIM_SetJoystickAxesAvailable(stick, available);
}
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setJoystickPOVCount
* Method: setJoystickPOVsAvailable
* Signature: (II)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickPOVCount
(JNIEnv*, jclass, jint stick, jint count)
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickPOVsAvailable
(JNIEnv*, jclass, jint stick, jint available)
{
HALSIM_SetJoystickPOVCount(stick, count);
HALSIM_SetJoystickPOVsAvailable(stick, available);
}
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setJoystickButtonCount
* Signature: (II)V
* Method: setJoystickButtonsAvailable
* Signature: (IJ)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickButtonCount
(JNIEnv*, jclass, jint stick, jint count)
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickButtonsAvailable
(JNIEnv*, jclass, jint stick, jlong available)
{
HALSIM_SetJoystickButtonCount(stick, count);
HALSIM_SetJoystickButtonsAvailable(stick, available);
}
/*
@@ -737,18 +737,6 @@ Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickName
HALSIM_SetJoystickName(stick, &str);
}
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setJoystickAxisType
* Signature: (III)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_DriverStationDataJNI_setJoystickAxisType
(JNIEnv*, jclass, jint stick, jint axis, jint type)
{
HALSIM_SetJoystickAxisType(stick, axis, type);
}
/*
* Class: edu_wpi_first_hal_simulation_DriverStationDataJNI
* Method: setGameSpecificMessage

View File

@@ -102,7 +102,8 @@ int32_t HAL_GetJoystickPOVs(int32_t joystickNum, HAL_JoystickPOVs* povs);
int32_t HAL_GetJoystickButtons(int32_t joystickNum,
HAL_JoystickButtons* buttons);
void HAL_GetAllJoystickData(HAL_JoystickAxes* axes, HAL_JoystickPOVs* povs,
void HAL_GetAllJoystickData(int32_t joystickNum, HAL_JoystickAxes* axes,
HAL_JoystickPOVs* povs,
HAL_JoystickButtons* buttons);
/**
@@ -150,18 +151,6 @@ int32_t HAL_GetJoystickType(int32_t joystickNum);
*/
void HAL_GetJoystickName(struct WPI_String* name, int32_t joystickNum);
/**
* Gets the type of a specific joystick axis.
*
* This is device specific, and different depending on what system input type
* the joystick uses.
*
* @param joystickNum the joystick number
* @param axis the axis number
* @return the enumerated axis type
*/
int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis);
/**
* Set joystick outputs.
*

View File

@@ -21,7 +21,8 @@ struct HAL_ControlWord {
uint32_t eStop : 1;
uint32_t fmsAttached : 1;
uint32_t dsAttached : 1;
uint32_t control_reserved : 26;
uint32_t watchdogEnabled : 1;
uint32_t control_reserved : 25;
};
typedef struct HAL_ControlWord HAL_ControlWord;
@@ -67,7 +68,7 @@ HAL_ENUM(HAL_MatchType) {
#define HAL_kMaxJoysticks 6
struct HAL_JoystickAxes {
int16_t count;
uint16_t available;
float axes[HAL_kMaxJoystickAxes];
int16_t raw[HAL_kMaxJoystickAxes];
};
@@ -95,14 +96,14 @@ HAL_ENUM_WITH_UNDERLYING_TYPE(HAL_JoystickPOV, uint8_t){
};
struct HAL_JoystickPOVs {
int16_t count;
uint8_t available;
HAL_JoystickPOV povs[HAL_kMaxJoystickPOVs];
};
typedef struct HAL_JoystickPOVs HAL_JoystickPOVs;
struct HAL_JoystickButtons {
uint32_t buttons;
uint8_t count;
uint64_t buttons;
uint64_t available;
};
typedef struct HAL_JoystickButtons HAL_JoystickButtons;
@@ -110,10 +111,6 @@ struct HAL_JoystickDescriptor {
uint8_t isGamepad;
uint8_t type;
char name[256];
uint8_t axisCount;
uint8_t axisTypes[HAL_kMaxJoystickAxes];
uint8_t buttonCount;
uint8_t povCount;
};
typedef struct HAL_JoystickDescriptor HAL_JoystickDescriptor;

View File

@@ -140,17 +140,17 @@ void HALSIM_SetMatchInfo(const HAL_MatchInfo* info);
void HALSIM_SetJoystickButton(int32_t stick, int32_t button, HAL_Bool state);
void HALSIM_SetJoystickAxis(int32_t stick, int32_t axis, double value);
void HALSIM_SetJoystickPOV(int32_t stick, int32_t pov, HAL_JoystickPOV value);
void HALSIM_SetJoystickButtonsValue(int32_t stick, uint32_t buttons);
void HALSIM_SetJoystickAxisCount(int32_t stick, int32_t count);
void HALSIM_SetJoystickPOVCount(int32_t stick, int32_t count);
void HALSIM_SetJoystickButtonCount(int32_t stick, int32_t count);
void HALSIM_GetJoystickCounts(int32_t stick, int32_t* axisCount,
int32_t* buttonCount, int32_t* povCount);
void HALSIM_SetJoystickButtonsValue(int32_t stick, uint64_t buttons);
void HALSIM_SetJoystickAxesAvailable(int32_t stick, uint16_t available);
void HALSIM_SetJoystickPOVsAvailable(int32_t stick, uint8_t available);
void HALSIM_SetJoystickButtonsAvailable(int32_t stick, uint64_t available);
void HALSIM_GetJoystickAvailables(int32_t stick, uint16_t* axesAvailable,
uint64_t* buttonsAvailable,
uint8_t* povsAvailable);
void HALSIM_SetJoystickIsGamepad(int32_t stick, HAL_Bool isGamepad);
void HALSIM_SetJoystickType(int32_t stick, int32_t type);
void HALSIM_SetJoystickName(int32_t stick, const struct WPI_String* name);
void HALSIM_SetJoystickAxisType(int32_t stick, int32_t axis, int32_t type);
void HALSIM_SetGameSpecificMessage(const struct WPI_String* message);
void HALSIM_SetEventName(const struct WPI_String* name);

View File

@@ -266,15 +266,16 @@ int32_t HAL_GetJoystickButtons(int32_t joystickNum,
return 0;
}
void HAL_GetAllJoystickData(HAL_JoystickAxes* axes, HAL_JoystickPOVs* povs,
void HAL_GetAllJoystickData(int32_t joystickNum, HAL_JoystickAxes* axes,
HAL_JoystickPOVs* povs,
HAL_JoystickButtons* buttons) {
if (gShutdown) {
return;
}
std::scoped_lock lock{driverStation->cacheMutex};
std::memcpy(axes, currentRead->axes, sizeof(currentRead->axes));
std::memcpy(povs, currentRead->povs, sizeof(currentRead->povs));
std::memcpy(buttons, currentRead->buttons, sizeof(currentRead->buttons));
*axes = currentRead->axes[joystickNum];
*povs = currentRead->povs[joystickNum];
*buttons = currentRead->buttons[joystickNum];
}
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
@@ -314,15 +315,6 @@ void HAL_GetJoystickName(struct WPI_String* name, int32_t joystickNum) {
std::memcpy(write, cName, len);
}
int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis) {
HAL_JoystickDescriptor joystickDesc;
if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
return -1;
} else {
return joystickDesc.axisTypes[axis];
}
}
int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble) {
SimDriverStationData->SetJoystickOutputs(joystickNum, outputs, leftRumble,

View File

@@ -230,9 +230,9 @@ void DriverStationData::SetJoystickButton(int32_t stick, int32_t button,
}
std::scoped_lock lock(m_joystickDataMutex);
if (state) {
m_joystickData[stick].buttons.buttons |= 1 << (button - 1);
m_joystickData[stick].buttons.buttons |= 1llu << button;
} else {
m_joystickData[stick].buttons.buttons &= ~(1 << (button - 1));
m_joystickData[stick].buttons.buttons &= ~(1llu << button);
}
m_joystickButtonsCallbacks(stick, &m_joystickData[stick].buttons);
}
@@ -263,7 +263,7 @@ void DriverStationData::SetJoystickPOV(int32_t stick, int32_t pov,
m_joystickPOVsCallbacks(stick, &m_joystickData[stick].povs);
}
void DriverStationData::SetJoystickButtons(int32_t stick, uint32_t buttons) {
void DriverStationData::SetJoystickButtons(int32_t stick, uint64_t buttons) {
if (stick < 0 || stick >= kNumJoysticks) {
return;
}
@@ -272,52 +272,50 @@ void DriverStationData::SetJoystickButtons(int32_t stick, uint32_t buttons) {
m_joystickButtonsCallbacks(stick, &m_joystickData[stick].buttons);
}
void DriverStationData::SetJoystickAxisCount(int32_t stick, int32_t count) {
void DriverStationData::SetJoystickAxesAvailable(int32_t stick,
uint16_t available) {
if (stick < 0 || stick >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
m_joystickData[stick].axes.count = count;
m_joystickData[stick].descriptor.axisCount = count;
m_joystickData[stick].axes.available = available;
m_joystickAxesCallbacks(stick, &m_joystickData[stick].axes);
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
void DriverStationData::SetJoystickPOVCount(int32_t stick, int32_t count) {
void DriverStationData::SetJoystickPOVsAvailable(int32_t stick,
uint8_t available) {
if (stick < 0 || stick >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
m_joystickData[stick].povs.count = count;
m_joystickData[stick].descriptor.povCount = count;
m_joystickData[stick].povs.available = available;
m_joystickPOVsCallbacks(stick, &m_joystickData[stick].povs);
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
void DriverStationData::SetJoystickButtonCount(int32_t stick, int32_t count) {
void DriverStationData::SetJoystickButtonsAvailable(int32_t stick,
uint64_t available) {
if (stick < 0 || stick >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
m_joystickData[stick].buttons.count = count;
m_joystickData[stick].descriptor.buttonCount = count;
m_joystickData[stick].buttons.available = available;
m_joystickButtonsCallbacks(stick, &m_joystickData[stick].buttons);
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
void DriverStationData::GetJoystickCounts(int32_t stick, int32_t* axisCount,
int32_t* buttonCount,
int32_t* povCount) {
void DriverStationData::GetJoystickAvailables(int32_t stick,
uint16_t* axesAvailable,
uint64_t* buttonsAvailable,
uint8_t* povsAvailable) {
if (stick < 0 || stick >= kNumJoysticks) {
*axisCount = 0;
*buttonCount = 0;
*povCount = 0;
*axesAvailable = 0;
*buttonsAvailable = 0;
*povsAvailable = 0;
return;
}
std::scoped_lock lock(m_joystickDataMutex);
*axisCount = m_joystickData[stick].axes.count;
*buttonCount = m_joystickData[stick].buttons.count;
*povCount = m_joystickData[stick].povs.count;
*axesAvailable = m_joystickData[stick].axes.available;
*buttonsAvailable = m_joystickData[stick].buttons.available;
*povsAvailable = m_joystickData[stick].povs.available;
}
void DriverStationData::SetJoystickIsGamepad(int32_t stick,
@@ -350,19 +348,6 @@ void DriverStationData::SetJoystickName(int32_t stick, std::string_view name) {
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
void DriverStationData::SetJoystickAxisType(int32_t stick, int32_t axis,
int32_t type) {
if (stick < 0 || stick >= kNumJoysticks) {
return;
}
if (axis < 0 || axis >= HAL_kMaxJoystickAxes) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
m_joystickData[stick].descriptor.axisTypes[axis] = type;
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
void DriverStationData::SetGameSpecificMessage(std::string_view message) {
std::scoped_lock lock(m_matchInfoMutex);
auto copied =
@@ -511,26 +496,27 @@ void HALSIM_SetJoystickPOV(int32_t stick, int32_t pov, HAL_JoystickPOV value) {
SimDriverStationData->SetJoystickPOV(stick, pov, value);
}
void HALSIM_SetJoystickButtonsValue(int32_t stick, uint32_t buttons) {
void HALSIM_SetJoystickButtonsValue(int32_t stick, uint64_t buttons) {
SimDriverStationData->SetJoystickButtons(stick, buttons);
}
void HALSIM_SetJoystickAxisCount(int32_t stick, int32_t count) {
SimDriverStationData->SetJoystickAxisCount(stick, count);
void HALSIM_SetJoystickAxesAvailable(int32_t stick, uint16_t available) {
SimDriverStationData->SetJoystickAxesAvailable(stick, available);
}
void HALSIM_SetJoystickPOVCount(int32_t stick, int32_t count) {
SimDriverStationData->SetJoystickPOVCount(stick, count);
void HALSIM_SetJoystickPOVsAvailable(int32_t stick, uint8_t available) {
SimDriverStationData->SetJoystickPOVsAvailable(stick, available);
}
void HALSIM_SetJoystickButtonCount(int32_t stick, int32_t count) {
SimDriverStationData->SetJoystickButtonCount(stick, count);
void HALSIM_SetJoystickButtonsAvailable(int32_t stick, uint64_t available) {
SimDriverStationData->SetJoystickButtonsAvailable(stick, available);
}
void HALSIM_GetJoystickCounts(int32_t stick, int32_t* axisCount,
int32_t* buttonCount, int32_t* povCount) {
SimDriverStationData->GetJoystickCounts(stick, axisCount, buttonCount,
povCount);
void HALSIM_GetJoystickAvailables(int32_t stick, uint16_t* axesAvailable,
uint64_t* buttonsAvailable,
uint8_t* povsAvailable) {
SimDriverStationData->GetJoystickAvailables(stick, axesAvailable,
buttonsAvailable, povsAvailable);
}
void HALSIM_SetJoystickIsGamepad(int32_t stick, HAL_Bool isGamepad) {
@@ -545,10 +531,6 @@ void HALSIM_SetJoystickName(int32_t stick, const WPI_String* name) {
SimDriverStationData->SetJoystickName(stick, wpi::to_string_view(name));
}
void HALSIM_SetJoystickAxisType(int32_t stick, int32_t axis, int32_t type) {
SimDriverStationData->SetJoystickAxisType(stick, axis, type);
}
void HALSIM_SetGameSpecificMessage(const WPI_String* message) {
SimDriverStationData->SetGameSpecificMessage(wpi::to_string_view(message));
}

View File

@@ -98,17 +98,17 @@ class DriverStationData {
void SetJoystickButton(int32_t stick, int32_t button, HAL_Bool state);
void SetJoystickAxis(int32_t stick, int32_t axis, double value);
void SetJoystickPOV(int32_t stick, int32_t pov, HAL_JoystickPOV value);
void SetJoystickButtons(int32_t stick, uint32_t buttons);
void SetJoystickAxisCount(int32_t stick, int32_t count);
void SetJoystickPOVCount(int32_t stick, int32_t count);
void SetJoystickButtonCount(int32_t stick, int32_t count);
void GetJoystickCounts(int32_t stick, int32_t* axisCount,
int32_t* buttonCount, int32_t* povCount);
void SetJoystickButtons(int32_t stick, uint64_t buttons);
void SetJoystickAxesAvailable(int32_t stick, uint16_t available);
void SetJoystickPOVsAvailable(int32_t stick, uint8_t available);
void SetJoystickButtonsAvailable(int32_t stick, uint64_t available);
void GetJoystickAvailables(int32_t stick, uint16_t* axesAvailable,
uint64_t* buttonsAvailable,
uint8_t* povsAvailable);
void SetJoystickIsGamepad(int32_t stick, HAL_Bool isGamepad);
void SetJoystickType(int32_t stick, int32_t type);
void SetJoystickName(int32_t stick, std::string_view message);
void SetJoystickAxisType(int32_t stick, int32_t axis, int32_t type);
void SetGameSpecificMessage(std::string_view message);
void SetEventName(std::string_view name);

View File

@@ -256,7 +256,8 @@ void JoystickDataCache::Update(const mrc::ControlData& data) {
auto newAxes = newStick.Axes.Axes();
auto newPovs = newStick.Povs.Povs();
axes[count].count = newAxes.size();
axes[count].available = newStick.Axes.GetAvailable();
for (size_t i = 0; i < newAxes.size(); i++) {
axes[count].raw[i] = newAxes[i];
int16_t axisValue = newAxes[i];
@@ -267,12 +268,13 @@ void JoystickDataCache::Update(const mrc::ControlData& data) {
}
}
povs[count].count = newPovs.size();
// When mrccomm switches this to available, move to available
povs[count].available = (1lu << newPovs.size()) - 1;
for (size_t i = 0; i < newPovs.size(); i++) {
povs[count].povs[i] = static_cast<HAL_JoystickPOV>(newPovs[i]);
}
buttons[count].count = newStick.Buttons.GetMaxAvailableCount();
buttons[count].available = newStick.Buttons.GetAvailable();
buttons[count].buttons = newStick.Buttons.Buttons;
}
}
@@ -339,8 +341,6 @@ void TcpCache::Update() {
desc.isGamepad = newDesc.IsGamepad;
desc.type = newDesc.Type;
desc.buttonCount = newDesc.GetButtonsCount();
desc.povCount = newDesc.GetPovsCount();
auto joystickName = newDesc.GetName();
auto joystickNameLen =
@@ -350,14 +350,6 @@ void TcpCache::Update() {
std::memcpy(desc.name, joystickName.data(), joystickNameLen);
}
desc.name[joystickNameLen] = '\0';
auto sticks = newDesc.AxesTypes();
desc.axisCount = sticks.size();
for (size_t i = 0; i < sticks.size(); i++) {
desc.axisTypes[i] = sticks[i];
}
}
}
@@ -490,12 +482,13 @@ int32_t HAL_GetJoystickButtons(int32_t joystickNum,
return 0;
}
void HAL_GetAllJoystickData(HAL_JoystickAxes* axes, HAL_JoystickPOVs* povs,
void HAL_GetAllJoystickData(int32_t joystickNum, HAL_JoystickAxes* axes,
HAL_JoystickPOVs* povs,
HAL_JoystickButtons* buttons) {
std::scoped_lock lock{cacheMutex};
std::memcpy(axes, currentRead->axes, sizeof(currentRead->axes));
std::memcpy(povs, currentRead->povs, sizeof(currentRead->povs));
std::memcpy(buttons, currentRead->buttons, sizeof(currentRead->buttons));
*axes = currentRead->axes[joystickNum];
*povs = currentRead->povs[joystickNum];
*buttons = currentRead->buttons[joystickNum];
}
int32_t HAL_GetJoystickDescriptor(int32_t joystickNum,
@@ -546,15 +539,6 @@ void HAL_GetJoystickName(struct WPI_String* name, int32_t joystickNum) {
std::memcpy(write, cName, len);
}
int32_t HAL_GetJoystickAxisType(int32_t joystickNum, int32_t axis) {
HAL_JoystickDescriptor joystickDesc;
if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {
return -1;
} else {
return joystickDesc.axisTypes[axis];
}
}
int32_t HAL_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble) {
CHECK_JOYSTICK_NUMBER(joystickNum);

View File

@@ -84,19 +84,20 @@ void HALSIM_SetJoystickAxis(int32_t stick, int32_t axis, double value) {}
void HALSIM_SetJoystickPOV(int32_t stick, int32_t pov, HAL_JoystickPOV value) {}
void HALSIM_SetJoystickButtonsValue(int32_t stick, uint32_t buttons) {}
void HALSIM_SetJoystickButtonsValue(int32_t stick, uint64_t buttons) {}
void HALSIM_SetJoystickAxisCount(int32_t stick, int32_t count) {}
void HALSIM_SetJoystickAxesAvailable(int32_t stick, uint16_t available) {}
void HALSIM_SetJoystickPOVCount(int32_t stick, int32_t count) {}
void HALSIM_SetJoystickPOVsAvailable(int32_t stick, uint8_t available) {}
void HALSIM_SetJoystickButtonCount(int32_t stick, int32_t count) {}
void HALSIM_SetJoystickButtonsAvailable(int32_t stick, uint64_t available) {}
void HALSIM_GetJoystickCounts(int32_t stick, int32_t* axisCount,
int32_t* buttonCount, int32_t* povCount) {
*axisCount = 0;
*buttonCount = 0;
*povCount = 0;
void HALSIM_GetJoystickAvailables(int32_t stick, uint16_t* axesAvailable,
uint64_t* buttonsAvailable,
uint8_t* povsAvailable) {
*axesAvailable = 0;
*buttonsAvailable = 0;
*povsAvailable = 0;
}
void HALSIM_SetJoystickIsGamepad(int32_t stick, HAL_Bool isGamepad) {}
@@ -105,8 +106,6 @@ void HALSIM_SetJoystickType(int32_t stick, int32_t type) {}
void HALSIM_SetJoystickName(int32_t stick, const struct WPI_String* name) {}
void HALSIM_SetJoystickAxisType(int32_t stick, int32_t axis, int32_t type) {}
void HALSIM_SetGameSpecificMessage(const struct WPI_String* message) {}
void HALSIM_SetEventName(const struct WPI_String* name) {}

View File

@@ -24,18 +24,18 @@ TEST(DriverStationTest, Joystick) {
HAL_GetJoystickPOVs(joystickNum, &povs);
HAL_GetJoystickButtons(joystickNum, &buttons);
EXPECT_EQ(0, axes.count);
EXPECT_EQ(0, axes.available);
for (int i = 0; i < HAL_kMaxJoystickAxes; ++i) {
EXPECT_EQ(0, axes.axes[i]);
}
EXPECT_EQ(0, povs.count);
EXPECT_EQ(0, povs.available);
for (int i = 0; i < HAL_kMaxJoystickPOVs; ++i) {
EXPECT_EQ(0, povs.povs[i]);
}
EXPECT_EQ(0, buttons.count);
EXPECT_EQ(0u, buttons.buttons);
EXPECT_EQ(0llu, buttons.available);
EXPECT_EQ(0llu, buttons.buttons);
}
HAL_JoystickAxes set_axes;
@@ -47,17 +47,17 @@ TEST(DriverStationTest, Joystick) {
// Set values
int joystickUnderTest = 4;
set_axes.count = 5;
for (int i = 0; i < set_axes.count; ++i) {
set_axes.available = 0x1F;
for (int i = 0; i < 5; ++i) {
set_axes.axes[i] = i * 0.125;
}
set_povs.count = 3;
set_povs.available = 0x7;
set_povs.povs[0] = HAL_JoystickPOV_kUp;
set_povs.povs[1] = HAL_JoystickPOV_kRight;
set_povs.povs[2] = HAL_JoystickPOV_kDown;
set_buttons.count = 8;
set_buttons.available = 0xFF;
set_buttons.buttons = 0xDEADBEEF;
HALSIM_SetJoystickAxes(joystickUnderTest, &set_axes);
@@ -72,7 +72,7 @@ TEST(DriverStationTest, Joystick) {
HAL_GetJoystickPOVs(joystickUnderTest, &povs);
HAL_GetJoystickButtons(joystickUnderTest, &buttons);
EXPECT_EQ(5, axes.count);
EXPECT_EQ(0x1F, axes.available);
EXPECT_NEAR(0.000, axes.axes[0], 0.000001);
EXPECT_NEAR(0.125, axes.axes[1], 0.000001);
EXPECT_NEAR(0.250, axes.axes[2], 0.000001);
@@ -81,7 +81,7 @@ TEST(DriverStationTest, Joystick) {
EXPECT_NEAR(0, axes.axes[5], 0.000001); // Should not have been set, still 0
EXPECT_NEAR(0, axes.axes[6], 0.000001); // Should not have been set, still 0
EXPECT_EQ(3, povs.count);
EXPECT_EQ(0x7, povs.available);
EXPECT_EQ(HAL_JoystickPOV_kUp, povs.povs[0]);
EXPECT_EQ(HAL_JoystickPOV_kRight, povs.povs[1]);
EXPECT_EQ(HAL_JoystickPOV_kDown, povs.povs[2]);
@@ -90,8 +90,8 @@ TEST(DriverStationTest, Joystick) {
EXPECT_EQ(0, povs.povs[5]); // Should not have been set, still 0
EXPECT_EQ(0, povs.povs[6]); // Should not have been set, still 0
EXPECT_EQ(8, buttons.count);
EXPECT_EQ(0xDEADBEEFu, buttons.buttons);
EXPECT_EQ(0xFFllu, buttons.available);
EXPECT_EQ(0xDEADBEEFllu, buttons.buttons);
// Reset
HALSIM_ResetDriverStationData();
@@ -103,18 +103,18 @@ TEST(DriverStationTest, Joystick) {
HAL_GetJoystickPOVs(joystickNum, &povs);
HAL_GetJoystickButtons(joystickNum, &buttons);
EXPECT_EQ(0, axes.count);
EXPECT_EQ(0, axes.available);
for (int i = 0; i < HAL_kMaxJoystickAxes; ++i) {
EXPECT_EQ(0, axes.axes[i]);
}
EXPECT_EQ(0, povs.count);
EXPECT_EQ(0, povs.available);
for (int i = 0; i < HAL_kMaxJoystickPOVs; ++i) {
EXPECT_EQ(0, povs.povs[i]);
}
EXPECT_EQ(0, buttons.count);
EXPECT_EQ(0u, buttons.buttons);
EXPECT_EQ(0llu, buttons.available);
EXPECT_EQ(0llu, buttons.buttons);
}
}

View File

@@ -108,7 +108,7 @@ void DSCommPacket::ReadJoystickTag(std::span<const uint8_t> dataInput,
stick.axes.axes[i] = value / 127.0;
}
}
stick.axes.count = axesLength;
stick.axes.available = (1 << axesLength) - 1;
dataInput = dataInput.subspan(1 + axesLength);
@@ -119,7 +119,12 @@ void DSCommPacket::ReadJoystickTag(std::span<const uint8_t> dataInput,
for (int i = 0; i < numBytes; i++) {
stick.buttons.buttons |= dataInput[numBytes - i] << (8 * (i));
}
stick.buttons.count = buttonCount;
if (buttonCount < 64) {
stick.buttons.available = (1ULL << buttonCount) - 1;
} else {
stick.buttons.available = (std::numeric_limits<uint64_t>::max)();
}
dataInput = dataInput.subspan(1 + numBytes);
@@ -129,7 +134,7 @@ void DSCommPacket::ReadJoystickTag(std::span<const uint8_t> dataInput,
DegreesToPOV((dataInput[1 + i] << 8) | dataInput[2 + i]);
}
stick.povs.count = povsLength;
stick.povs.available = (1 << povsLength) - 1;
return;
}
@@ -264,17 +269,6 @@ void DSCommPacket::ReadJoystickDescriptionTag(std::span<const uint8_t> data) {
}
data = data.subspan(4 + nameLength);
packet.descriptor.name[nameLength] = '\0';
int axesCount = data[0];
packet.descriptor.axisCount = axesCount;
for (int i = 0,
len = std::min<int>(axesCount, sizeof(packet.descriptor.axisTypes));
i < len; i++) {
packet.descriptor.axisTypes[i] = data[1 + i];
}
data = data.subspan(1 + axesCount);
packet.descriptor.buttonCount = data[0];
packet.descriptor.povCount = data[1];
}
void DSCommPacket::SendJoysticks(void) {

View File

@@ -42,9 +42,9 @@ TEST_F(DSCommPacketTest, EmptyJoystickTag) {
for (int i = 0; i < HAL_kMaxJoysticks; i++) {
uint8_t arr[2];
auto& data = ReadJoystickTag(arr, 0);
ASSERT_EQ(data.axes.count, 0);
ASSERT_EQ(data.povs.count, 0);
ASSERT_EQ(data.buttons.count, 0);
ASSERT_EQ(data.axes.available, 0);
ASSERT_EQ(data.povs.available, 0);
ASSERT_EQ(data.buttons.available, 0llu);
}
}
@@ -57,9 +57,9 @@ TEST_F(DSCommPacketTest, BlankJoystickTag) {
arr[3] = 0;
arr[4] = 0;
auto& data = ReadJoystickTag(arr, 0);
ASSERT_EQ(data.axes.count, 0);
ASSERT_EQ(data.povs.count, 0);
ASSERT_EQ(data.buttons.count, 0);
ASSERT_EQ(data.axes.available, 0);
ASSERT_EQ(data.povs.available, 0);
ASSERT_EQ(data.buttons.available, 0llu);
}
}
@@ -87,12 +87,12 @@ TEST_F(DSCommPacketTest, MainJoystickTag) {
3, 0, 50, 0, 100, 0x0F, 0x00};
auto& data = ReadJoystickTag(arr, 0);
ASSERT_EQ(data.axes.count, 4);
ASSERT_EQ(data.povs.count, 3);
ASSERT_EQ(data.buttons.count, 12);
ASSERT_EQ(data.axes.available, 0xF);
ASSERT_EQ(data.povs.available, 0x7);
ASSERT_EQ(data.buttons.available, 0xFFFllu);
for (int btn = 0; btn < 12; btn++) {
ASSERT_EQ((data.buttons.buttons & (1 << btn)) != 0, _buttons[btn] != 0)
ASSERT_EQ((data.buttons.buttons & (1llu << btn)) != 0, _buttons[btn] != 0)
<< "Button " << btn;
}
}
@@ -115,12 +115,6 @@ TEST_F(DSCommPacketTest, DescriptorTag) {
ASSERT_EQ(data.descriptor.isGamepad, 1);
ASSERT_EQ(data.descriptor.type, 0);
ASSERT_STREQ(data.descriptor.name, "Hello World");
ASSERT_EQ(data.descriptor.axisCount, 4);
for (int i = 0; i < 4; i++) {
ASSERT_EQ(data.descriptor.axisTypes[i], i + 1);
}
ASSERT_EQ(data.descriptor.buttonCount, 12);
ASSERT_EQ(data.descriptor.povCount, 3);
}
}

View File

@@ -178,7 +178,7 @@ struct RobotJoystick {
void SetHAL(int i);
void GetHAL(int i);
bool IsButtonPressed(int i) {
return (data.buttons.buttons & (1u << i)) != 0;
return (data.buttons.buttons & (1llu << i)) != 0;
}
};
@@ -294,7 +294,7 @@ static inline bool IsDSDisabled() {
JoystickModel::JoystickModel(int index) : m_index{index} {
HAL_JoystickAxes halAxes;
HALSIM_GetJoystickAxes(index, &halAxes);
axisCount = halAxes.count;
axisCount = static_cast<uint8_t>(16 - std::countl_zero(halAxes.available));
for (int i = 0; i < axisCount; ++i) {
axes[i] = std::make_unique<glass::DoubleSource>(
fmt::format("Joystick[{}] Axis[{}]", index, i));
@@ -302,18 +302,19 @@ JoystickModel::JoystickModel(int index) : m_index{index} {
HAL_JoystickButtons halButtons;
HALSIM_GetJoystickButtons(index, &halButtons);
buttonCount = halButtons.count;
buttonCount =
static_cast<uint8_t>(64 - std::countl_zero(halButtons.available));
for (int i = 0; i < buttonCount; ++i) {
buttons[i] = new glass::BooleanSource(
fmt::format("Joystick[{}] Button[{}]", index, i + 1));
}
for (int i = buttonCount; i < 32; ++i) {
for (int i = buttonCount; i < 64; ++i) {
buttons[i] = nullptr;
}
HAL_JoystickPOVs halPOVs;
HALSIM_GetJoystickPOVs(index, &halPOVs);
povCount = halPOVs.count;
povCount = static_cast<uint8_t>(8 - std::countl_zero(halPOVs.available));
for (int i = 0; i < povCount; ++i) {
povs[i] = std::make_unique<glass::IntegerSource>(
fmt::format("Joystick[{}] POV [{}]", index, i));
@@ -328,7 +329,8 @@ void JoystickModel::CallbackFunc(const char*, void* param, const HAL_Value*) {
HAL_JoystickAxes halAxes;
HALSIM_GetJoystickAxes(self->m_index, &halAxes);
for (int i = 0; i < halAxes.count; ++i) {
int halAxesCount = 16 - std::countl_zero(halAxes.available);
for (int i = 0; i < halAxesCount; ++i) {
if (auto axis = self->axes[i].get()) {
axis->SetValue(halAxes.axes[i]);
}
@@ -336,15 +338,17 @@ void JoystickModel::CallbackFunc(const char*, void* param, const HAL_Value*) {
HAL_JoystickButtons halButtons;
HALSIM_GetJoystickButtons(self->m_index, &halButtons);
for (int i = 0; i < halButtons.count; ++i) {
int halButtonCount = 64 - std::countl_zero(halButtons.available);
for (int i = 0; i < halButtonCount; ++i) {
if (auto button = self->buttons[i]) {
button->SetValue((halButtons.buttons & (1u << i)) != 0 ? 1 : 0);
button->SetValue((halButtons.buttons & (1llu << i)) != 0 ? 1 : 0);
}
}
HAL_JoystickPOVs halPOVs;
HALSIM_GetJoystickPOVs(self->m_index, &halPOVs);
for (int i = 0; i < halPOVs.count; ++i) {
int halPovCount = 8 - std::countl_zero(halPOVs.available);
for (int i = 0; i < halPovCount; ++i) {
if (auto pov = self->povs[i].get()) {
pov->SetValue(halPOVs.povs[i]);
}
@@ -419,17 +423,22 @@ void GlfwSystemJoystick::GetData(HALJoystickData* data, bool mapGamepad) const {
data->desc.type = m_isGamepad ? 21 : 20;
std::strncpy(data->desc.name, m_name, sizeof(data->desc.name) - 1);
data->desc.name[sizeof(data->desc.name) - 1] = '\0';
data->desc.axisCount = (std::min)(m_axisCount, HAL_kMaxJoystickAxes);
// desc.axisTypes ???
data->desc.buttonCount = (std::min)(m_buttonCount, 32);
data->desc.povCount = (std::min)(m_hatCount, HAL_kMaxJoystickPOVs);
int axesCount = (std::min)(m_axisCount, HAL_kMaxJoystickAxes);
int buttonCount = (std::min)(m_buttonCount, 64);
int povsCount = (std::min)(m_hatCount, HAL_kMaxJoystickPOVs);
data->buttons.count = data->desc.buttonCount;
for (int j = 0; j < data->buttons.count; ++j) {
if (buttonCount < 64) {
data->buttons.available = (1ULL << buttonCount) - 1;
} else {
data->buttons.available = (std::numeric_limits<uint64_t>::max)();
}
data->axes.available = (1 << axesCount) - 1;
data->povs.available = (1 << povsCount) - 1;
for (int j = 0; j < buttonCount; ++j) {
data->buttons.buttons |= (sysButtons[j] ? 1u : 0u) << j;
}
data->axes.count = data->desc.axisCount;
if (m_isGamepad && mapGamepad) {
// the FRC DriverStation maps gamepad (XInput) trigger values to 0-1 range
// on axis 2 and 3.
@@ -440,21 +449,12 @@ void GlfwSystemJoystick::GetData(HALJoystickData* data, bool mapGamepad) const {
data->axes.axes[4] = sysAxes[2];
data->axes.axes[5] = sysAxes[3];
// the start button for gamepads is not mapped on the FRC DriverStation
// platforms, so remove it if present
if (data->buttons.count == 11) {
--data->desc.buttonCount;
--data->buttons.count;
data->buttons.buttons = (data->buttons.buttons & 0xff) |
((data->buttons.buttons >> 1) & 0x300);
}
} else {
std::memcpy(data->axes.axes, sysAxes,
data->axes.count * sizeof(data->axes.axes[0]));
axesCount * sizeof(data->axes.axes[0]));
}
data->povs.count = data->desc.povCount;
for (int j = 0; j < data->povs.count; ++j) {
for (int j = 0; j < povsCount; ++j) {
#if __GNUC__ >= 12
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow="
@@ -706,20 +706,27 @@ void KeyboardJoystick::Update() {
m_povCount = 0;
}
m_data.axes.count =
int axesCount =
(std::min)(m_axisCount, static_cast<int>(m_axisConfig.size()));
m_data.buttons.count =
int buttonsCount =
(std::min)(m_buttonCount, static_cast<int>(m_buttonKey.size()));
m_data.povs.count =
(std::min)(m_povCount, static_cast<int>(m_povConfig.size()));
int povsCount = (std::min)(m_povCount, static_cast<int>(m_povConfig.size()));
if (m_data.axes.count > 0 || m_data.buttons.count > 0 ||
m_data.povs.count > 0) {
m_data.axes.available = (1 << axesCount) - 1;
m_data.povs.available = (1 << povsCount) - 1;
if (buttonsCount >= 64) {
m_data.buttons.available = (std::numeric_limits<uint64_t>::max)();
} else {
m_data.buttons.available = (1u << buttonsCount) - 1;
}
if (m_data.axes.available > 0 || m_data.buttons.available > 0 ||
m_data.povs.available > 0) {
m_present = true;
}
// axes
for (int i = 0; i < m_data.axes.count; ++i) {
for (int i = 0; i < axesCount; ++i) {
auto& config = m_axisConfig[i];
float& axisValue = m_data.axes.axes[i];
// increase/decrease while key held down (to saturation); decay back to 0
@@ -753,15 +760,15 @@ void KeyboardJoystick::Update() {
// buttons
m_data.buttons.buttons = 0;
m_anyButtonPressed = false;
for (int i = 0; i < m_data.buttons.count; ++i) {
for (int i = 0; i < buttonsCount; ++i) {
if (IsKeyDown(io, m_buttonKey[i])) {
m_data.buttons.buttons |= 1u << i;
m_data.buttons.buttons |= 1llu << i;
m_anyButtonPressed = true;
}
}
// povs
for (int i = 0; i < m_data.povs.count; ++i) {
for (int i = 0; i < povsCount; ++i) {
auto& config = m_povConfig[i];
auto& povValue = m_data.povs.povs[i];
povValue = HAL_JoystickPOV_kCentered;
@@ -791,11 +798,6 @@ void KeyboardJoystick::Update() {
break;
}
}
// update desc
m_data.desc.axisCount = m_data.axes.count;
m_data.desc.buttonCount = m_data.buttons.count;
m_data.desc.povCount = m_data.povs.count;
}
void KeyboardJoystick::ClearKey(int key) {
@@ -1010,10 +1012,20 @@ static void DriverStationExecute() {
// update sources
for (int i = 0; i < HAL_kMaxJoysticks; ++i) {
auto& source = gJoystickSources[i];
int32_t axisCount, buttonCount, povCount;
HALSIM_GetJoystickCounts(i, &axisCount, &buttonCount, &povCount);
if (axisCount != 0 || buttonCount != 0 || povCount != 0) {
if (!source || source->axisCount != axisCount ||
uint16_t axesAvailable;
uint8_t povsAvailable;
uint64_t buttonsAvailable;
HALSIM_GetJoystickAvailables(i, &axesAvailable, &buttonsAvailable,
&povsAvailable);
if (axesAvailable != 0 || buttonsAvailable != 0 || povsAvailable != 0) {
uint8_t axesCount =
static_cast<uint8_t>(16 - std::countl_zero(axesAvailable));
uint8_t buttonCount =
static_cast<uint8_t>(64 - std::countl_zero(buttonsAvailable));
uint8_t povCount =
static_cast<uint8_t>(8 - std::countl_zero(povsAvailable));
if (!source || source->axisCount != axesCount ||
source->buttonCount != buttonCount || source->povCount != povCount) {
source.reset();
source = std::make_unique<JoystickModel>(i);
@@ -1321,7 +1333,10 @@ static void DisplayJoysticks() {
}
}
for (int j = 0; j < joy.data.axes.count; ++j) {
uint8_t axesCount =
static_cast<uint8_t>(16 - std::countl_zero(joy.data.axes.available));
for (int j = 0; j < axesCount; ++j) {
if (source && source->axes[j]) {
char label[64];
wpi::format_to_n_c_str(label, sizeof(label), "Axis[{}]", j);
@@ -1335,7 +1350,10 @@ static void DisplayJoysticks() {
}
}
for (int j = 0; j < joy.data.povs.count; ++j) {
uint8_t povCount =
static_cast<uint8_t>(16 - std::countl_zero(joy.data.povs.available));
for (int j = 0; j < povCount; ++j) {
if (source && source->povs[j]) {
char label[64];
wpi::format_to_n_c_str(label, sizeof(label), "POVs[{}]", j);
@@ -1349,11 +1367,14 @@ static void DisplayJoysticks() {
}
}
uint8_t buttonCount = static_cast<uint8_t>(
64 - std::countl_zero(joy.data.buttons.available));
// show buttons as multiple lines of LED indicators, 8 per line
static const ImU32 color = IM_COL32(255, 255, 102, 255);
wpi::SmallVector<int, 64> buttons;
buttons.resize(joy.data.buttons.count);
for (int j = 0; j < joy.data.buttons.count; ++j) {
buttons.resize(buttonCount);
for (int j = 0; j < buttonCount; ++j) {
buttons[j] = joy.IsButtonPressed(j) ? 1 : -1;
}
DrawLEDSources(buttons.data(), source ? source->buttons : nullptr,

View File

@@ -37,7 +37,9 @@ void HALSimWSProviderJoystick::RegisterCallbacks() {
std::vector<double> axesValues;
HALSIM_GetJoystickAxes(provider->GetChannel(), &axes);
for (int i = 0; i < axes.count; i++) {
int axesCount = 16 - std::countl_zero(axes.available);
for (int i = 0; i < axesCount; i++) {
axesValues.push_back(axes.axes[i]);
}
@@ -46,7 +48,9 @@ void HALSimWSProviderJoystick::RegisterCallbacks() {
std::vector<int16_t> povsValues;
HALSIM_GetJoystickPOVs(provider->GetChannel(), &povs);
for (int i = 0; i < povs.count; i++) {
int povsCount = 8 - std::countl_zero(povs.available);
for (int i = 0; i < povsCount; i++) {
povsValues.push_back(povs.povs[i]);
}
@@ -54,7 +58,9 @@ void HALSimWSProviderJoystick::RegisterCallbacks() {
HAL_JoystickButtons buttons{};
std::vector<bool> buttonsValues;
for (int i = 0; i < buttons.count; i++) {
int buttonsCount = 64 - std::countl_zero(buttons.available);
for (int i = 0; i < buttonsCount; i++) {
buttonsValues.push_back(((buttons.buttons >> i) & 0x1) == 1);
}
@@ -96,10 +102,11 @@ void HALSimWSProviderJoystick::OnNetValueChanged(const wpi::json& json) {
wpi::json::const_iterator it;
if ((it = json.find(">axes")) != json.end()) {
HAL_JoystickAxes axes{};
axes.count =
wpi::json::size_type axesCount =
std::min(it.value().size(),
static_cast<wpi::json::size_type>(HAL_kMaxJoystickAxes));
for (int i = 0; i < axes.count; i++) {
axes.available = (1 << axesCount) - 1;
for (wpi::json::size_type i = 0; i < axesCount; i++) {
axes.axes[i] = it.value()[i];
}
@@ -108,11 +115,16 @@ void HALSimWSProviderJoystick::OnNetValueChanged(const wpi::json& json) {
if ((it = json.find(">buttons")) != json.end()) {
HAL_JoystickButtons buttons{};
buttons.count =
std::min(it.value().size(), static_cast<wpi::json::size_type>(32));
for (int i = 0; i < buttons.count; i++) {
wpi::json::size_type buttonsCount =
std::min(it.value().size(), static_cast<wpi::json::size_type>(64));
if (buttonsCount < 64) {
buttons.available = (1ULL << buttonsCount) - 1;
} else {
buttons.available = (std::numeric_limits<uint64_t>::max)();
}
for (wpi::json::size_type i = 0; i < buttonsCount; i++) {
if (it.value()[i]) {
buttons.buttons |= 1 << i;
buttons.buttons |= 1llu << i;
}
}
@@ -121,10 +133,11 @@ void HALSimWSProviderJoystick::OnNetValueChanged(const wpi::json& json) {
if ((it = json.find(">povs")) != json.end()) {
HAL_JoystickPOVs povs{};
povs.count =
wpi::json::size_type povsCount =
std::min(it.value().size(),
static_cast<wpi::json::size_type>(HAL_kMaxJoystickPOVs));
for (int i = 0; i < povs.count; i++) {
povs.available = (1 << povsCount) - 1;
for (wpi::json::size_type i = 0; i < povsCount; i++) {
povs.povs[i] = it.value()[i];
}

View File

@@ -0,0 +1,745 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj2.command.button;
import edu.wpi.first.wpilibj.Gamepad;
import edu.wpi.first.wpilibj.event.EventLoop;
import edu.wpi.first.wpilibj2.command.CommandScheduler;
/**
* A version of {@link Gamepad} with {@link Trigger} factories for command-based.
*
* @see Gamepad
*/
@SuppressWarnings("MethodName")
public class CommandGamepad extends CommandGenericHID {
private final Gamepad m_hid;
/**
* Construct an instance of a controller.
*
* @param port The port index on the Driver Station that the controller is plugged into.
*/
public CommandGamepad(int port) {
super(port);
m_hid = new Gamepad(port);
}
/**
* Get the underlying GenericHID object.
*
* @return the wrapped GenericHID object
*/
@Override
public Gamepad getHID() {
return m_hid;
}
/**
* Constructs a Trigger instance around the South Face button's digital signal.
*
* @return a Trigger instance representing the South Face button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #southFace(EventLoop)
*/
public Trigger southFace() {
return southFace(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the South Face button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the South Face button's digital signal attached to the
* given loop.
*/
public Trigger southFace(EventLoop loop) {
return button(Gamepad.Button.kSouthFace.value, loop);
}
/**
* Constructs a Trigger instance around the East Face button's digital signal.
*
* @return a Trigger instance representing the East Face button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #eastFace(EventLoop)
*/
public Trigger eastFace() {
return eastFace(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the East Face button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the East Face button's digital signal attached to the
* given loop.
*/
public Trigger eastFace(EventLoop loop) {
return button(Gamepad.Button.kEastFace.value, loop);
}
/**
* Constructs a Trigger instance around the West Face button's digital signal.
*
* @return a Trigger instance representing the West Face button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #westFace(EventLoop)
*/
public Trigger westFace() {
return westFace(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the West Face button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the West Face button's digital signal attached to the
* given loop.
*/
public Trigger westFace(EventLoop loop) {
return button(Gamepad.Button.kWestFace.value, loop);
}
/**
* Constructs a Trigger instance around the North Face button's digital signal.
*
* @return a Trigger instance representing the North Face button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #northFacen(EventLoop)
*/
public Trigger northFacen() {
return northFacen(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the North Face button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the North Face button's digital signal attached to the
* given loop.
*/
public Trigger northFacen(EventLoop loop) {
return button(Gamepad.Button.kNorthFacen.value, loop);
}
/**
* Constructs a Trigger instance around the Back button's digital signal.
*
* @return a Trigger instance representing the Back button's digital signal attached to the {@link
* CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #back(EventLoop)
*/
public Trigger back() {
return back(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Back button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Back button's digital signal attached to the given
* loop.
*/
public Trigger back(EventLoop loop) {
return button(Gamepad.Button.kBack.value, loop);
}
/**
* Constructs a Trigger instance around the Guide button's digital signal.
*
* @return a Trigger instance representing the Guide button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #guide(EventLoop)
*/
public Trigger guide() {
return guide(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Guide button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Guide button's digital signal attached to the given
* loop.
*/
public Trigger guide(EventLoop loop) {
return button(Gamepad.Button.kGuide.value, loop);
}
/**
* Constructs a Trigger instance around the Start button's digital signal.
*
* @return a Trigger instance representing the Start button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #start(EventLoop)
*/
public Trigger start() {
return start(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Start button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Start button's digital signal attached to the given
* loop.
*/
public Trigger start(EventLoop loop) {
return button(Gamepad.Button.kStart.value, loop);
}
/**
* Constructs a Trigger instance around the left stick button's digital signal.
*
* @return a Trigger instance representing the left stick button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #leftStick(EventLoop)
*/
public Trigger leftStick() {
return leftStick(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the left stick button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the left stick button's digital signal attached to the
* given loop.
*/
public Trigger leftStick(EventLoop loop) {
return button(Gamepad.Button.kLeftStick.value, loop);
}
/**
* Constructs a Trigger instance around the right stick button's digital signal.
*
* @return a Trigger instance representing the right stick button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #rightStick(EventLoop)
*/
public Trigger rightStick() {
return rightStick(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the right stick button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the right stick button's digital signal attached to the
* given loop.
*/
public Trigger rightStick(EventLoop loop) {
return button(Gamepad.Button.kRightStick.value, loop);
}
/**
* Constructs a Trigger instance around the right shoulder button's digital signal.
*
* @return a Trigger instance representing the right shoulder button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #leftShoulder(EventLoop)
*/
public Trigger leftShoulder() {
return leftShoulder(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the right shoulder button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the right shoulder button's digital signal attached to
* the given loop.
*/
public Trigger leftShoulder(EventLoop loop) {
return button(Gamepad.Button.kLeftShoulder.value, loop);
}
/**
* Constructs a Trigger instance around the right shoulder button's digital signal.
*
* @return a Trigger instance representing the right shoulder button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #rightShoulder(EventLoop)
*/
public Trigger rightShoulder() {
return rightShoulder(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the right shoulder button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the right shoulder button's digital signal attached to
* the given loop.
*/
public Trigger rightShoulder(EventLoop loop) {
return button(Gamepad.Button.kRightShoulder.value, loop);
}
/**
* Constructs a Trigger instance around the D-pad up button's digital signal.
*
* @return a Trigger instance representing the D-pad up button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #dpadUp(EventLoop)
*/
public Trigger dpadUp() {
return dpadUp(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the D-pad up button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the D-pad up button's digital signal attached to the
* given loop.
*/
public Trigger dpadUp(EventLoop loop) {
return button(Gamepad.Button.kDpadUp.value, loop);
}
/**
* Constructs a Trigger instance around the D-pad down button's digital signal.
*
* @return a Trigger instance representing the D-pad down button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #dpadDown(EventLoop)
*/
public Trigger dpadDown() {
return dpadDown(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the D-pad down button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the D-pad down button's digital signal attached to the
* given loop.
*/
public Trigger dpadDown(EventLoop loop) {
return button(Gamepad.Button.kDpadDown.value, loop);
}
/**
* Constructs a Trigger instance around the D-pad left button's digital signal.
*
* @return a Trigger instance representing the D-pad left button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #dpadLeft(EventLoop)
*/
public Trigger dpadLeft() {
return dpadLeft(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the D-pad left button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the D-pad left button's digital signal attached to the
* given loop.
*/
public Trigger dpadLeft(EventLoop loop) {
return button(Gamepad.Button.kDpadLeft.value, loop);
}
/**
* Constructs a Trigger instance around the D-pad right button's digital signal.
*
* @return a Trigger instance representing the D-pad right button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #dpadRight(EventLoop)
*/
public Trigger dpadRight() {
return dpadRight(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the D-pad right button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the D-pad right button's digital signal attached to the
* given loop.
*/
public Trigger dpadRight(EventLoop loop) {
return button(Gamepad.Button.kDpadRight.value, loop);
}
/**
* Constructs a Trigger instance around the Miscellaneous 1 button's digital signal.
*
* @return a Trigger instance representing the Miscellaneous 1 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #misc1(EventLoop)
*/
public Trigger misc1() {
return misc1(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Miscellaneous 1 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Miscellaneous 1 button's digital signal attached to
* the given loop.
*/
public Trigger misc1(EventLoop loop) {
return button(Gamepad.Button.kMisc1.value, loop);
}
/**
* Constructs a Trigger instance around the Right Paddle 1 button's digital signal.
*
* @return a Trigger instance representing the Right Paddle 1 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #rightPaddle1(EventLoop)
*/
public Trigger rightPaddle1() {
return rightPaddle1(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Right Paddle 1 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Right Paddle 1 button's digital signal attached to
* the given loop.
*/
public Trigger rightPaddle1(EventLoop loop) {
return button(Gamepad.Button.kRightPaddle1.value, loop);
}
/**
* Constructs a Trigger instance around the Left Paddle 1 button's digital signal.
*
* @return a Trigger instance representing the Left Paddle 1 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #leftPaddle1(EventLoop)
*/
public Trigger leftPaddle1() {
return leftPaddle1(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Left Paddle 1 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Left Paddle 1 button's digital signal attached to
* the given loop.
*/
public Trigger leftPaddle1(EventLoop loop) {
return button(Gamepad.Button.kLeftPaddle1.value, loop);
}
/**
* Constructs a Trigger instance around the Right Paddle 2 button's digital signal.
*
* @return a Trigger instance representing the Right Paddle 2 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #rightPaddle2(EventLoop)
*/
public Trigger rightPaddle2() {
return rightPaddle2(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Right Paddle 2 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Right Paddle 2 button's digital signal attached to
* the given loop.
*/
public Trigger rightPaddle2(EventLoop loop) {
return button(Gamepad.Button.kRightPaddle2.value, loop);
}
/**
* Constructs a Trigger instance around the Left Paddle 2 button's digital signal.
*
* @return a Trigger instance representing the Left Paddle 2 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #leftPaddle2(EventLoop)
*/
public Trigger leftPaddle2() {
return leftPaddle2(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Left Paddle 2 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Left Paddle 2 button's digital signal attached to
* the given loop.
*/
public Trigger leftPaddle2(EventLoop loop) {
return button(Gamepad.Button.kLeftPaddle2.value, loop);
}
/**
* Constructs a Trigger instance around the Touchpad button's digital signal.
*
* @return a Trigger instance representing the Touchpad button's digital signal attached to the
* {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #touchpad(EventLoop)
*/
public Trigger touchpad() {
return touchpad(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Touchpad button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Touchpad button's digital signal attached to the
* given loop.
*/
public Trigger touchpad(EventLoop loop) {
return button(Gamepad.Button.kTouchpad.value, loop);
}
/**
* Constructs a Trigger instance around the Miscellaneous 2 button's digital signal.
*
* @return a Trigger instance representing the Miscellaneous 2 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #misc2(EventLoop)
*/
public Trigger misc2() {
return misc2(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Miscellaneous 2 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Miscellaneous 2 button's digital signal attached to
* the given loop.
*/
public Trigger misc2(EventLoop loop) {
return button(Gamepad.Button.kMisc2.value, loop);
}
/**
* Constructs a Trigger instance around the Miscellaneous 3 button's digital signal.
*
* @return a Trigger instance representing the Miscellaneous 3 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #misc3(EventLoop)
*/
public Trigger misc3() {
return misc3(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Miscellaneous 3 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Miscellaneous 3 button's digital signal attached to
* the given loop.
*/
public Trigger misc3(EventLoop loop) {
return button(Gamepad.Button.kMisc3.value, loop);
}
/**
* Constructs a Trigger instance around the Miscellaneous 4 button's digital signal.
*
* @return a Trigger instance representing the Miscellaneous 4 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #misc4(EventLoop)
*/
public Trigger misc4() {
return misc4(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Miscellaneous 4 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Miscellaneous 4 button's digital signal attached to
* the given loop.
*/
public Trigger misc4(EventLoop loop) {
return button(Gamepad.Button.kMisc4.value, loop);
}
/**
* Constructs a Trigger instance around the Miscellaneous 5 button's digital signal.
*
* @return a Trigger instance representing the Miscellaneous 5 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #misc5(EventLoop)
*/
public Trigger misc5() {
return misc5(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Miscellaneous 5 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Miscellaneous 5 button's digital signal attached to
* the given loop.
*/
public Trigger misc5(EventLoop loop) {
return button(Gamepad.Button.kMisc5.value, loop);
}
/**
* Constructs a Trigger instance around the Miscellaneous 6 button's digital signal.
*
* @return a Trigger instance representing the Miscellaneous 6 button's digital signal attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
* @see #misc6(EventLoop)
*/
public Trigger misc6() {
return misc6(CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the Miscellaneous 6 button's digital signal.
*
* @param loop the event loop instance to attach the event to.
* @return a Trigger instance representing the Miscellaneous 6 button's digital signal attached to
* the given loop.
*/
public Trigger misc6(EventLoop loop) {
return button(Gamepad.Button.kMisc6.value, loop);
}
/**
* Constructs a Trigger instance around the axis value of the left trigger. The returned trigger
* will be true when the axis value is greater than {@code threshold}.
*
* @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value
* should be in the range [0, 1] where 0 is the unpressed state of the axis.
* @param loop the event loop instance to attach the Trigger to.
* @return a Trigger instance that is true when the left trigger's axis exceeds the provided
* threshold, attached to the given event loop
*/
public Trigger leftTrigger(double threshold, EventLoop loop) {
return axisGreaterThan(Gamepad.Axis.kLeftTrigger.value, threshold, loop);
}
/**
* Constructs a Trigger instance around the axis value of the left trigger. The returned trigger
* will be true when the axis value is greater than {@code threshold}.
*
* @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value
* should be in the range [0, 1] where 0 is the unpressed state of the axis.
* @return a Trigger instance that is true when the left trigger's axis exceeds the provided
* threshold, attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler
* button loop}.
*/
public Trigger leftTrigger(double threshold) {
return leftTrigger(threshold, CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the axis value of the left trigger. The returned trigger
* will be true when the axis value is greater than 0.5.
*
* @return a Trigger instance that is true when the left trigger's axis exceeds 0.5, attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
*/
public Trigger leftTrigger() {
return leftTrigger(0.5);
}
/**
* Constructs a Trigger instance around the axis value of the right trigger. The returned trigger
* will be true when the axis value is greater than {@code threshold}.
*
* @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value
* should be in the range [0, 1] where 0 is the unpressed state of the axis.
* @param loop the event loop instance to attach the Trigger to.
* @return a Trigger instance that is true when the right trigger's axis exceeds the provided
* threshold, attached to the given event loop
*/
public Trigger rightTrigger(double threshold, EventLoop loop) {
return axisGreaterThan(Gamepad.Axis.kRightTrigger.value, threshold, loop);
}
/**
* Constructs a Trigger instance around the axis value of the right trigger. The returned trigger
* will be true when the axis value is greater than {@code threshold}.
*
* @param threshold the minimum axis value for the returned {@link Trigger} to be true. This value
* should be in the range [0, 1] where 0 is the unpressed state of the axis.
* @return a Trigger instance that is true when the right trigger's axis exceeds the provided
* threshold, attached to the {@link CommandScheduler#getDefaultButtonLoop() default scheduler
* button loop}.
*/
public Trigger rightTrigger(double threshold) {
return rightTrigger(threshold, CommandScheduler.getInstance().getDefaultButtonLoop());
}
/**
* Constructs a Trigger instance around the axis value of the right trigger. The returned trigger
* will be true when the axis value is greater than 0.5.
*
* @return a Trigger instance that is true when the right trigger's axis exceeds 0.5, attached to
* the {@link CommandScheduler#getDefaultButtonLoop() default scheduler button loop}.
*/
public Trigger rightTrigger() {
return rightTrigger(0.5);
}
/**
* Get the X axis value of left side of the controller. Right is positive.
*
* @return The axis value.
*/
public double getLeftX() {
return m_hid.getLeftX();
}
/**
* Get the Y axis value of left side of the controller. Back is positive.
*
* @return The axis value.
*/
public double getLeftY() {
return m_hid.getLeftY();
}
/**
* Get the X axis value of right side of the controller. Right is positive.
*
* @return The axis value.
*/
public double getRightX() {
return m_hid.getRightX();
}
/**
* Get the Y axis value of right side of the controller. Back is positive.
*
* @return The axis value.
*/
public double getRightY() {
return m_hid.getRightY();
}
/**
* Get the left trigger axis value of the controller. Note that this axis is bound to the range of
* [0, 1] as opposed to the usual [-1, 1].
*
* @return The axis value.
*/
public double getLeftTriggerAxis() {
return m_hid.getLeftTriggerAxis();
}
/**
* Get the right trigger axis value of the controller. Note that this axis is bound to the range
* of [0, 1] as opposed to the usual [-1, 1].
*
* @return The axis value.
*/
public double getRightTriggerAxis() {
return m_hid.getRightTriggerAxis();
}
}

View File

@@ -0,0 +1,156 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc2/command/button/CommandGamepad.h"
using namespace frc2;
CommandGamepad::CommandGamepad(int port)
: CommandGenericHID(port), m_hid{frc::Gamepad(port)} {}
frc::Gamepad& CommandGamepad::GetHID() {
return m_hid;
}
Trigger CommandGamepad::SouthFace(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kSouthFace, loop);
}
Trigger CommandGamepad::EastFace(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kEastFace, loop);
}
Trigger CommandGamepad::WestFace(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kWestFace, loop);
}
Trigger CommandGamepad::NorthFacen(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kNorthFacen, loop);
}
Trigger CommandGamepad::Back(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kBack, loop);
}
Trigger CommandGamepad::Guide(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kGuide, loop);
}
Trigger CommandGamepad::Start(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kStart, loop);
}
Trigger CommandGamepad::LeftStick(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kLeftStick, loop);
}
Trigger CommandGamepad::RightStick(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kRightStick, loop);
}
Trigger CommandGamepad::LeftShoulder(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kLeftShoulder, loop);
}
Trigger CommandGamepad::RightShoulder(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kRightShoulder, loop);
}
Trigger CommandGamepad::DpadUp(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kDpadUp, loop);
}
Trigger CommandGamepad::DpadDown(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kDpadDown, loop);
}
Trigger CommandGamepad::DpadLeft(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kDpadLeft, loop);
}
Trigger CommandGamepad::DpadRight(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kDpadRight, loop);
}
Trigger CommandGamepad::Misc1(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kMisc1, loop);
}
Trigger CommandGamepad::RightPaddle1(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kRightPaddle1, loop);
}
Trigger CommandGamepad::LeftPaddle1(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kLeftPaddle1, loop);
}
Trigger CommandGamepad::RightPaddle2(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kRightPaddle2, loop);
}
Trigger CommandGamepad::LeftPaddle2(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kLeftPaddle2, loop);
}
Trigger CommandGamepad::Touchpad(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kTouchpad, loop);
}
Trigger CommandGamepad::Misc2(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kMisc2, loop);
}
Trigger CommandGamepad::Misc3(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kMisc3, loop);
}
Trigger CommandGamepad::Misc4(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kMisc4, loop);
}
Trigger CommandGamepad::Misc5(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kMisc5, loop);
}
Trigger CommandGamepad::Misc6(frc::EventLoop* loop) const {
return Button(frc::Gamepad::Button::kMisc6, loop);
}
Trigger CommandGamepad::LeftTrigger(double threshold,
frc::EventLoop* loop) const {
return Trigger(loop, [this, threshold] {
return m_hid.GetLeftTriggerAxis() > threshold;
});
}
Trigger CommandGamepad::RightTrigger(double threshold,
frc::EventLoop* loop) const {
return Trigger(loop, [this, threshold] {
return m_hid.GetRightTriggerAxis() > threshold;
});
}
double CommandGamepad::GetLeftX() const {
return m_hid.GetLeftX();
}
double CommandGamepad::GetLeftY() const {
return m_hid.GetLeftY();
}
double CommandGamepad::GetRightX() const {
return m_hid.GetRightX();
}
double CommandGamepad::GetRightY() const {
return m_hid.GetRightY();
}
double CommandGamepad::GetLeftTriggerAxis() const {
return m_hid.GetLeftTriggerAxis();
}
double CommandGamepad::GetRightTriggerAxis() const {
return m_hid.GetRightTriggerAxis();
}

View File

@@ -0,0 +1,434 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <frc/Gamepad.h>
#include "frc2/command/CommandScheduler.h"
#include "frc2/command/button/CommandGenericHID.h"
#include "frc2/command/button/Trigger.h"
namespace frc2 {
/**
* A version of {@link frc::Gamepad} with {@link Trigger} factories for
* command-based.
*
* @see frc::Gamepad
*/
class CommandGamepad : public CommandGenericHID {
public:
/**
* Construct an instance of a controller.
*
* @param port The port index on the Driver Station that the controller is
* plugged into.
*/
explicit CommandGamepad(int port);
/**
* Get the underlying GenericHID object.
*
* @return the wrapped GenericHID object
*/
frc::Gamepad& GetHID();
/**
* Constructs a Trigger instance around the South Face button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the South Face button's
* digital signal attached to the given loop.
*/
Trigger SouthFace(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the East Face button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the East Face button's
* digital signal attached to the given loop.
*/
Trigger EastFace(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the West Face button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the West Face button's
* digital signal attached to the given loop.
*/
Trigger WestFace(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the North Face button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the North Face button's
* digital signal attached to the given loop.
*/
Trigger NorthFacen(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Back button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Back button's
* digital signal attached to the given loop.
*/
Trigger Back(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Guide button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Guide button's
* digital signal attached to the given loop.
*/
Trigger Guide(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Start button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Start button's
* digital signal attached to the given loop.
*/
Trigger Start(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the left stick button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the left stick button's
* digital signal attached to the given loop.
*/
Trigger LeftStick(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the right stick button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the right stick button's
* digital signal attached to the given loop.
*/
Trigger RightStick(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the right shoulder button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the right shoulder button's
* digital signal attached to the given loop.
*/
Trigger LeftShoulder(
frc::EventLoop* loop =
CommandScheduler::GetInstance().GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the right shoulder button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the right shoulder button's
* digital signal attached to the given loop.
*/
Trigger RightShoulder(
frc::EventLoop* loop =
CommandScheduler::GetInstance().GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the D-pad up button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the D-pad up button's
* digital signal attached to the given loop.
*/
Trigger DpadUp(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the D-pad down button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the D-pad down button's
* digital signal attached to the given loop.
*/
Trigger DpadDown(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the D-pad left button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the D-pad left button's
* digital signal attached to the given loop.
*/
Trigger DpadLeft(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the D-pad right button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the D-pad right button's
* digital signal attached to the given loop.
*/
Trigger DpadRight(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Miscellaneous 1 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Miscellaneous 1 button's
* digital signal attached to the given loop.
*/
Trigger Misc1(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Right Paddle 1 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Right Paddle 1 button's
* digital signal attached to the given loop.
*/
Trigger RightPaddle1(
frc::EventLoop* loop =
CommandScheduler::GetInstance().GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Left Paddle 1 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Left Paddle 1 button's
* digital signal attached to the given loop.
*/
Trigger LeftPaddle1(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Right Paddle 2 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Right Paddle 2 button's
* digital signal attached to the given loop.
*/
Trigger RightPaddle2(
frc::EventLoop* loop =
CommandScheduler::GetInstance().GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Left Paddle 2 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Left Paddle 2 button's
* digital signal attached to the given loop.
*/
Trigger LeftPaddle2(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Touchpad button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Touchpad button's
* digital signal attached to the given loop.
*/
Trigger Touchpad(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Miscellaneous 2 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Miscellaneous 2 button's
* digital signal attached to the given loop.
*/
Trigger Misc2(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Miscellaneous 3 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Miscellaneous 3 button's
* digital signal attached to the given loop.
*/
Trigger Misc3(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Miscellaneous 4 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Miscellaneous 4 button's
* digital signal attached to the given loop.
*/
Trigger Misc4(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Miscellaneous 5 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Miscellaneous 5 button's
* digital signal attached to the given loop.
*/
Trigger Misc5(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the Miscellaneous 6 button's
* digital signal.
*
* @param loop the event loop instance to attach the event to. Defaults to the
* CommandScheduler's default loop.
* @return a Trigger instance representing the Miscellaneous 6 button's
* digital signal attached to the given loop.
*/
Trigger Misc6(frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the axis value of the left trigger.
* The returned Trigger will be true when the axis value is greater than
* {@code threshold}.
*
* @param threshold the minimum axis value for the returned Trigger to be
* true. This value should be in the range [0, 1] where 0 is the unpressed
* state of the axis. Defaults to 0.5.
* @param loop the event loop instance to attach the Trigger to. Defaults to
* the CommandScheduler's default loop.
* @return a Trigger instance that is true when the left trigger's axis
* exceeds the provided threshold, attached to the given loop
*/
Trigger LeftTrigger(double threshold = 0.5,
frc::EventLoop* loop = CommandScheduler::GetInstance()
.GetDefaultButtonLoop()) const;
/**
* Constructs a Trigger instance around the axis value of the right trigger.
* The returned Trigger will be true when the axis value is greater than
* {@code threshold}.
*
* @param threshold the minimum axis value for the returned Trigger to be
* true. This value should be in the range [0, 1] where 0 is the unpressed
* state of the axis. Defaults to 0.5.
* @param loop the event loop instance to attach the Trigger to. Defaults to
* the CommandScheduler's default loop.
* @return a Trigger instance that is true when the right trigger's axis
* exceeds the provided threshold, attached to the given loop
*/
Trigger RightTrigger(
double threshold = 0.5,
frc::EventLoop* loop =
CommandScheduler::GetInstance().GetDefaultButtonLoop()) const;
/**
* Get the X axis value of left side of the controller. Right is positive.
*
* @return The axis value.
*/
double GetLeftX() const;
/**
* Get the Y axis value of left side of the controller. Back is positive.
*
* @return The axis value.
*/
double GetLeftY() const;
/**
* Get the X axis value of right side of the controller. Right is positive.
*
* @return The axis value.
*/
double GetRightX() const;
/**
* Get the Y axis value of right side of the controller. Back is positive.
*
* @return The axis value.
*/
double GetRightY() const;
/**
* Get the left trigger axis value of the controller. Note that this axis is
* bound to the range of [0, 1] as opposed to the usual [-1, 1].
*
* @return The axis value.
*/
double GetLeftTriggerAxis() const;
/**
* Get the right trigger axis value of the controller. Note that this axis is
* bound to the range of [0, 1] as opposed to the usual [-1, 1].
*
* @return The axis value.
*/
double GetRightTriggerAxis() const;
private:
frc::Gamepad m_hid;
};
} // namespace frc2

View File

@@ -15,15 +15,15 @@ using namespace frc::sim;
{{ ConsoleName }}ControllerSim::{{ ConsoleName }}ControllerSim(const {{ ConsoleName }}Controller& joystick)
: GenericHIDSim{joystick} {
SetAxisCount({{ sticks|length + triggers|length }});
SetButtonCount({{ buttons|length }});
SetPOVCount(1);
SetAxesMaximumIndex({{ sticks|length + triggers|length }});
SetButtonsMaximumIndex({{ buttons|length }});
SetPOVsMaximumIndex(1);
}
{{ ConsoleName }}ControllerSim::{{ ConsoleName }}ControllerSim(int port) : GenericHIDSim{port} {
SetAxisCount({{ sticks|length + triggers|length }});
SetButtonCount({{ buttons|length }});
SetPOVCount(1);
SetAxesMaximumIndex({{ sticks|length + triggers|length }});
SetButtonsMaximumIndex({{ buttons|length }});
SetPOVsMaximumIndex(1);
}
{% for stick in sticks %}
void {{ ConsoleName }}ControllerSim::Set{{ stick.NameParts|map("capitalize")|join }}(double value) {

View File

@@ -13,15 +13,15 @@ using namespace frc::sim;
PS4ControllerSim::PS4ControllerSim(const PS4Controller& joystick)
: GenericHIDSim{joystick} {
SetAxisCount(6);
SetButtonCount(14);
SetPOVCount(1);
SetAxesMaximumIndex(6);
SetButtonsMaximumIndex(14);
SetPOVsMaximumIndex(1);
}
PS4ControllerSim::PS4ControllerSim(int port) : GenericHIDSim{port} {
SetAxisCount(6);
SetButtonCount(14);
SetPOVCount(1);
SetAxesMaximumIndex(6);
SetButtonsMaximumIndex(14);
SetPOVsMaximumIndex(1);
}
void PS4ControllerSim::SetLeftX(double value) {

View File

@@ -13,15 +13,15 @@ using namespace frc::sim;
PS5ControllerSim::PS5ControllerSim(const PS5Controller& joystick)
: GenericHIDSim{joystick} {
SetAxisCount(6);
SetButtonCount(14);
SetPOVCount(1);
SetAxesMaximumIndex(6);
SetButtonsMaximumIndex(14);
SetPOVsMaximumIndex(1);
}
PS5ControllerSim::PS5ControllerSim(int port) : GenericHIDSim{port} {
SetAxisCount(6);
SetButtonCount(14);
SetPOVCount(1);
SetAxesMaximumIndex(6);
SetButtonsMaximumIndex(14);
SetPOVsMaximumIndex(1);
}
void PS5ControllerSim::SetLeftX(double value) {

View File

@@ -13,15 +13,15 @@ using namespace frc::sim;
StadiaControllerSim::StadiaControllerSim(const StadiaController& joystick)
: GenericHIDSim{joystick} {
SetAxisCount(4);
SetButtonCount(15);
SetPOVCount(1);
SetAxesMaximumIndex(4);
SetButtonsMaximumIndex(15);
SetPOVsMaximumIndex(1);
}
StadiaControllerSim::StadiaControllerSim(int port) : GenericHIDSim{port} {
SetAxisCount(4);
SetButtonCount(15);
SetPOVCount(1);
SetAxesMaximumIndex(4);
SetButtonsMaximumIndex(15);
SetPOVsMaximumIndex(1);
}
void StadiaControllerSim::SetLeftX(double value) {

View File

@@ -13,15 +13,15 @@ using namespace frc::sim;
XboxControllerSim::XboxControllerSim(const XboxController& joystick)
: GenericHIDSim{joystick} {
SetAxisCount(6);
SetButtonCount(10);
SetPOVCount(1);
SetAxesMaximumIndex(6);
SetButtonsMaximumIndex(10);
SetPOVsMaximumIndex(1);
}
XboxControllerSim::XboxControllerSim(int port) : GenericHIDSim{port} {
SetAxisCount(6);
SetButtonCount(10);
SetPOVCount(1);
SetAxesMaximumIndex(6);
SetButtonsMaximumIndex(10);
SetPOVsMaximumIndex(1);
}
void XboxControllerSim::SetLeftX(double value) {

View File

@@ -557,33 +557,33 @@ class PS4Controller : public GenericHID,
/** Represents a digital button on an PS4Controller. */
struct Button {
/// Square button.
static constexpr int kSquare = 1;
static constexpr int kSquare = 0;
/// Cross button.
static constexpr int kCross = 2;
static constexpr int kCross = 1;
/// Circle button.
static constexpr int kCircle = 3;
static constexpr int kCircle = 2;
/// Triangle button.
static constexpr int kTriangle = 4;
static constexpr int kTriangle = 3;
/// Left trigger 1 button.
static constexpr int kL1 = 5;
static constexpr int kL1 = 4;
/// Right trigger 1 button.
static constexpr int kR1 = 6;
static constexpr int kR1 = 5;
/// Left trigger 2 button.
static constexpr int kL2 = 7;
static constexpr int kL2 = 6;
/// Right trigger 2 button.
static constexpr int kR2 = 8;
static constexpr int kR2 = 7;
/// Share button.
static constexpr int kShare = 9;
static constexpr int kShare = 8;
/// Options button.
static constexpr int kOptions = 10;
static constexpr int kOptions = 9;
/// L3 (left stick) button.
static constexpr int kL3 = 11;
static constexpr int kL3 = 10;
/// R3 (right stick) button.
static constexpr int kR3 = 12;
static constexpr int kR3 = 11;
/// PlayStation button.
static constexpr int kPS = 13;
static constexpr int kPS = 12;
/// Touchpad button.
static constexpr int kTouchpad = 14;
static constexpr int kTouchpad = 13;
};
/** Represents an axis on an PS4Controller. */

View File

@@ -557,33 +557,33 @@ class PS5Controller : public GenericHID,
/** Represents a digital button on an PS5Controller. */
struct Button {
/// Square button.
static constexpr int kSquare = 1;
static constexpr int kSquare = 0;
/// Cross button.
static constexpr int kCross = 2;
static constexpr int kCross = 1;
/// Circle button.
static constexpr int kCircle = 3;
static constexpr int kCircle = 2;
/// Triangle button.
static constexpr int kTriangle = 4;
static constexpr int kTriangle = 3;
/// Left trigger 1 button.
static constexpr int kL1 = 5;
static constexpr int kL1 = 4;
/// Right trigger 1 button.
static constexpr int kR1 = 6;
static constexpr int kR1 = 5;
/// Left trigger 2 button.
static constexpr int kL2 = 7;
static constexpr int kL2 = 6;
/// Right trigger 2 button.
static constexpr int kR2 = 8;
static constexpr int kR2 = 7;
/// Create button.
static constexpr int kCreate = 9;
static constexpr int kCreate = 8;
/// Options button.
static constexpr int kOptions = 10;
static constexpr int kOptions = 9;
/// L3 (left stick) button.
static constexpr int kL3 = 11;
static constexpr int kL3 = 10;
/// R3 (right stick) button.
static constexpr int kR3 = 12;
static constexpr int kR3 = 11;
/// PlayStation button.
static constexpr int kPS = 13;
static constexpr int kPS = 12;
/// Touchpad button.
static constexpr int kTouchpad = 14;
static constexpr int kTouchpad = 13;
};
/** Represents an axis on an PS5Controller. */

View File

@@ -606,35 +606,35 @@ class StadiaController : public GenericHID,
/** Represents a digital button on an StadiaController. */
struct Button {
/// A button.
static constexpr int kA = 1;
static constexpr int kA = 0;
/// B button.
static constexpr int kB = 2;
static constexpr int kB = 1;
/// X button.
static constexpr int kX = 3;
static constexpr int kX = 2;
/// Y button.
static constexpr int kY = 4;
static constexpr int kY = 3;
/// Left bumper button.
static constexpr int kLeftBumper = 5;
static constexpr int kLeftBumper = 4;
/// Right bumper button.
static constexpr int kRightBumper = 6;
static constexpr int kRightBumper = 5;
/// Left stick button.
static constexpr int kLeftStick = 7;
static constexpr int kLeftStick = 6;
/// Right stick button.
static constexpr int kRightStick = 8;
static constexpr int kRightStick = 7;
/// Ellipses button.
static constexpr int kEllipses = 9;
static constexpr int kEllipses = 8;
/// Hamburger button.
static constexpr int kHamburger = 10;
static constexpr int kHamburger = 9;
/// Stadia button.
static constexpr int kStadia = 11;
static constexpr int kStadia = 10;
/// Right trigger button.
static constexpr int kRightTrigger = 12;
static constexpr int kRightTrigger = 11;
/// Left trigger button.
static constexpr int kLeftTrigger = 13;
static constexpr int kLeftTrigger = 12;
/// Google button.
static constexpr int kGoogle = 14;
static constexpr int kGoogle = 13;
/// Frame button.
static constexpr int kFrame = 15;
static constexpr int kFrame = 14;
};
/** Represents an axis on an StadiaController. */

View File

@@ -511,25 +511,25 @@ class XboxController : public GenericHID,
/** Represents a digital button on an XboxController. */
struct Button {
/// A button.
static constexpr int kA = 1;
static constexpr int kA = 0;
/// B button.
static constexpr int kB = 2;
static constexpr int kB = 1;
/// X button.
static constexpr int kX = 3;
static constexpr int kX = 2;
/// Y button.
static constexpr int kY = 4;
static constexpr int kY = 3;
/// Left bumper button.
static constexpr int kLeftBumper = 5;
static constexpr int kLeftBumper = 4;
/// Right bumper button.
static constexpr int kRightBumper = 6;
static constexpr int kRightBumper = 5;
/// Back button.
static constexpr int kBack = 7;
static constexpr int kBack = 6;
/// Start button.
static constexpr int kStart = 8;
static constexpr int kStart = 7;
/// Left stick button.
static constexpr int kLeftStick = 9;
static constexpr int kLeftStick = 8;
/// Right stick button.
static constexpr int kRightStick = 10;
static constexpr int kRightStick = 9;
};
/** Represents an axis on an XboxController. */

View File

@@ -35,6 +35,10 @@
using namespace frc;
static constexpr int availableToCount(uint64_t available) {
return 64 - std::countl_zero(available);
}
namespace {
// A simple class which caches the previous value written to an NT entry
// Used to prevent redundant, repeated writes of the same value
@@ -157,14 +161,6 @@ static Instance& GetInstance() {
static void SendMatchData();
/**
* Reports errors related to unplugged joysticks.
*
* Throttles the errors so that they don't overwhelm the DS.
*/
static void ReportJoystickUnpluggedErrorV(fmt::string_view format,
fmt::format_args args);
template <typename S, typename... Args>
static inline void ReportJoystickUnpluggedError(const S& format,
Args&&... args) {
@@ -193,7 +189,7 @@ Instance::Instance() {
for (unsigned int i = 0; i < DriverStation::kJoystickPorts; i++) {
joystickButtonsPressed[i] = 0;
joystickButtonsReleased[i] = 0;
previousButtonStates[i].count = 0;
previousButtonStates[i].available = 0;
previousButtonStates[i].buttons = 0;
}
}
@@ -209,24 +205,49 @@ bool DriverStation::GetStickButton(int stick, int button) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return false;
}
if (button <= 0) {
ReportJoystickUnpluggedError(
"Joystick Button {} index out of range; indexes begin at 1", button);
if (button < 0 || button >= 64) {
FRC_ReportError(warn::BadJoystickIndex, "button {} out of range", button);
return false;
}
uint64_t mask = 1LLU << button;
HAL_JoystickButtons buttons;
HAL_GetJoystickButtons(stick, &buttons);
if (button > buttons.count) {
if ((buttons.available & mask) == 0) {
ReportJoystickUnpluggedWarning(
"Joystick Button {} missing (max {}), check if all controllers are "
"Joystick Button {} missing (available {}), check if all controllers "
"are "
"plugged in",
button, buttons.count);
button, buttons.available);
return false;
}
return buttons.buttons & 1 << (button - 1);
return (buttons.buttons & mask) != 0;
}
std::optional<bool> DriverStation::GetStickButtonIfAvailable(int stick,
int button) {
if (stick < 0 || stick >= kJoystickPorts) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return false;
}
if (button < 0 || button >= 64) {
FRC_ReportError(warn::BadJoystickIndex, "button {} out of range", button);
return false;
}
uint64_t mask = 1LLU << button;
HAL_JoystickButtons buttons;
HAL_GetJoystickButtons(stick, &buttons);
if ((buttons.available & mask) == 0) {
return std::nullopt;
}
return (buttons.buttons & mask) != 0;
}
bool DriverStation::GetStickButtonPressed(int stick, int button) {
@@ -234,27 +255,29 @@ bool DriverStation::GetStickButtonPressed(int stick, int button) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return false;
}
if (button <= 0) {
ReportJoystickUnpluggedError(
"Joystick Button {} index out of range; indexes begin at 1", button);
if (button < 0 || button >= 64) {
FRC_ReportError(warn::BadJoystickIndex, "button {} out of range", button);
return false;
}
HAL_JoystickButtons buttons;
HAL_GetJoystickButtons(stick, &buttons);
if (button > buttons.count) {
uint64_t mask = 1LLU << button;
if ((buttons.available & mask) == 0) {
ReportJoystickUnpluggedWarning(
"Joystick Button {} missing (max {}), check if all controllers are "
"Joystick Button {} missing (available {}), check if all controllers "
"are "
"plugged in",
button, buttons.count);
button, buttons.available);
return false;
}
auto& inst = ::GetInstance();
std::unique_lock lock(inst.buttonEdgeMutex);
// If button was pressed, clear flag and return true
if (inst.joystickButtonsPressed[stick] & 1 << (button - 1)) {
inst.joystickButtonsPressed[stick] &= ~(1 << (button - 1));
if (inst.joystickButtonsPressed[stick] & mask) {
inst.joystickButtonsPressed[stick] &= ~mask;
return true;
}
return false;
@@ -265,27 +288,29 @@ bool DriverStation::GetStickButtonReleased(int stick, int button) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return false;
}
if (button <= 0) {
ReportJoystickUnpluggedError(
"Joystick Button {} index out of range; indexes begin at 1", button);
if (button < 0 || button >= 64) {
FRC_ReportError(warn::BadJoystickIndex, "button {} out of range", button);
return false;
}
HAL_JoystickButtons buttons;
HAL_GetJoystickButtons(stick, &buttons);
if (button > buttons.count) {
uint64_t mask = 1LLU << button;
if ((buttons.available & mask) == 0) {
ReportJoystickUnpluggedWarning(
"Joystick Button {} missing (max {}), check if all controllers are "
"Joystick Button {} missing (available {}), check if all controllers "
"are "
"plugged in",
button, buttons.count);
button, buttons.available);
return false;
}
auto& inst = ::GetInstance();
std::unique_lock lock(inst.buttonEdgeMutex);
// If button was released, clear flag and return true
if (inst.joystickButtonsReleased[stick] & 1 << (button - 1)) {
inst.joystickButtonsReleased[stick] &= ~(1 << (button - 1));
if (inst.joystickButtonsReleased[stick] & mask) {
inst.joystickButtonsReleased[stick] &= ~mask;
return true;
}
return false;
@@ -301,20 +326,45 @@ double DriverStation::GetStickAxis(int stick, int axis) {
return 0.0;
}
uint16_t mask = 1 << axis;
HAL_JoystickAxes axes;
HAL_GetJoystickAxes(stick, &axes);
if (axis >= axes.count) {
if ((axes.available & mask) == 0) {
ReportJoystickUnpluggedWarning(
"Joystick Axis {} missing (max {}), check if all controllers are "
"Joystick Axis {} missing (available {}), check if all controllers are "
"plugged in",
axis, axes.count);
axis, axes.available);
return 0.0;
}
return axes.axes[axis];
}
std::optional<double> DriverStation::GetStickAxisIfAvailable(int stick,
int axis) {
if (stick < 0 || stick >= kJoystickPorts) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return 0.0;
}
if (axis < 0 || axis >= HAL_kMaxJoystickAxes) {
FRC_ReportError(warn::BadJoystickAxis, "axis {} out of range", axis);
return 0.0;
}
uint16_t mask = 1 << axis;
HAL_JoystickAxes axes;
HAL_GetJoystickAxes(stick, &axes);
if ((axes.available & mask) == 0) {
return std::nullopt;
}
return axes.axes[axis];
}
DriverStation::POVDirection DriverStation::GetStickPOV(int stick, int pov) {
if (stick < 0 || stick >= kJoystickPorts) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
@@ -325,21 +375,23 @@ DriverStation::POVDirection DriverStation::GetStickPOV(int stick, int pov) {
return kCenter;
}
uint16_t mask = 1 << pov;
HAL_JoystickPOVs povs;
HAL_GetJoystickPOVs(stick, &povs);
if (pov >= povs.count) {
if ((povs.available & mask) == 0) {
ReportJoystickUnpluggedWarning(
"Joystick POV {} missing (max {}), check if all controllers are "
"Joystick POV {} missing (available {}), check if all controllers are "
"plugged in",
pov, povs.count);
pov, povs.available);
return kCenter;
}
return static_cast<POVDirection>(povs.povs[pov]);
}
int DriverStation::GetStickButtons(int stick) {
uint64_t DriverStation::GetStickButtons(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return 0;
@@ -351,7 +403,11 @@ int DriverStation::GetStickButtons(int stick) {
return buttons.buttons;
}
int DriverStation::GetStickAxisCount(int stick) {
int DriverStation::GetStickAxesMaximumIndex(int stick) {
return availableToCount(GetStickAxesAvailable(stick));
}
int DriverStation::GetStickAxesAvailable(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return 0;
@@ -360,10 +416,14 @@ int DriverStation::GetStickAxisCount(int stick) {
HAL_JoystickAxes axes;
HAL_GetJoystickAxes(stick, &axes);
return axes.count;
return axes.available;
}
int DriverStation::GetStickPOVCount(int stick) {
int DriverStation::GetStickPOVsMaximumIndex(int stick) {
return availableToCount(GetStickPOVsAvailable(stick));
}
int DriverStation::GetStickPOVsAvailable(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return 0;
@@ -372,10 +432,14 @@ int DriverStation::GetStickPOVCount(int stick) {
HAL_JoystickPOVs povs;
HAL_GetJoystickPOVs(stick, &povs);
return povs.count;
return povs.available;
}
int DriverStation::GetStickButtonCount(int stick) {
int DriverStation::GetStickButtonsMaximumIndex(int stick) {
return availableToCount(GetStickButtonsAvailable(stick));
}
uint64_t DriverStation::GetStickButtonsAvailable(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return 0;
@@ -384,7 +448,7 @@ int DriverStation::GetStickButtonCount(int stick) {
HAL_JoystickButtons buttons;
HAL_GetJoystickButtons(stick, &buttons);
return buttons.count;
return buttons.available;
}
bool DriverStation::GetJoystickIsGamepad(int stick) {
@@ -422,25 +486,10 @@ std::string DriverStation::GetJoystickName(int stick) {
return descriptor.name;
}
int DriverStation::GetJoystickAxisType(int stick, int axis) {
if (stick < 0 || stick >= kJoystickPorts) {
FRC_ReportError(warn::BadJoystickIndex, "stick {} out of range", stick);
return -1;
}
if (axis < 0 || axis >= HAL_kMaxJoystickAxes) {
FRC_ReportError(warn::BadJoystickAxis, "axis {} out of range", axis);
return -1;
}
HAL_JoystickDescriptor descriptor;
HAL_GetJoystickDescriptor(stick, &descriptor);
return descriptor.axisTypes[axis];
}
bool DriverStation::IsJoystickConnected(int stick) {
return GetStickAxisCount(stick) > 0 || GetStickButtonCount(stick) > 0 ||
GetStickPOVCount(stick) > 0;
return GetStickAxesAvailable(stick) != 0 ||
GetStickButtonsAvailable(stick) != 0 ||
GetStickPOVsAvailable(stick) != 0;
}
bool DriverStation::IsEnabled() {
@@ -661,16 +710,6 @@ void DriverStation::StartDataLog(wpi::log::DataLog& log, bool logJoysticks) {
}
}
void ReportJoystickUnpluggedErrorV(fmt::string_view format,
fmt::format_args args) {
auto& inst = GetInstance();
auto currentTime = Timer::GetTimestamp();
if (currentTime > inst.nextMessageTime) {
ReportErrorV(err::Error, "", 0, "", format, args);
inst.nextMessageTime = currentTime + kJoystickUnpluggedMessageInterval;
}
}
void ReportJoystickUnpluggedWarningV(fmt::string_view format,
fmt::format_args args) {
auto& inst = GetInstance();
@@ -751,9 +790,9 @@ void JoystickLogSender::Init(wpi::log::DataLog& log, unsigned int stick,
HAL_GetJoystickAxes(m_stick, &m_prevAxes);
HAL_GetJoystickPOVs(m_stick, &m_prevPOVs);
AppendButtons(m_prevButtons, timestamp);
int axesCount = availableToCount(m_prevAxes.available);
m_logAxes.Append(
std::span<const float>{m_prevAxes.axes,
static_cast<size_t>(m_prevAxes.count)},
std::span<const float>{m_prevAxes.axes, static_cast<size_t>(axesCount)},
timestamp);
AppendPOVs(m_prevPOVs, timestamp);
}
@@ -761,7 +800,7 @@ void JoystickLogSender::Init(wpi::log::DataLog& log, unsigned int stick,
void JoystickLogSender::Send(uint64_t timestamp) {
HAL_JoystickButtons buttons;
HAL_GetJoystickButtons(m_stick, &buttons);
if (buttons.count != m_prevButtons.count ||
if (buttons.available != m_prevButtons.available ||
buttons.buttons != m_prevButtons.buttons) {
AppendButtons(buttons, timestamp);
}
@@ -769,20 +808,22 @@ void JoystickLogSender::Send(uint64_t timestamp) {
HAL_JoystickAxes axes;
HAL_GetJoystickAxes(m_stick, &axes);
if (axes.count != m_prevAxes.count ||
int axesCount = availableToCount(axes.available);
if (axes.available != m_prevAxes.available ||
std::memcmp(axes.axes, m_prevAxes.axes,
sizeof(axes.axes[0]) * axes.count) != 0) {
sizeof(axes.axes[0]) * axesCount) != 0) {
m_logAxes.Append(
std::span<const float>{axes.axes, static_cast<size_t>(axes.count)},
std::span<const float>{axes.axes, static_cast<size_t>(axesCount)},
timestamp);
}
m_prevAxes = axes;
HAL_JoystickPOVs povs;
HAL_GetJoystickPOVs(m_stick, &povs);
if (povs.count != m_prevPOVs.count ||
int povsCount = availableToCount(povs.available);
if (povs.available != m_prevPOVs.available ||
std::memcmp(povs.povs, m_prevPOVs.povs,
sizeof(povs.povs[0]) * povs.count) != 0) {
sizeof(povs.povs[0]) * povsCount) != 0) {
AppendPOVs(povs, timestamp);
}
m_prevPOVs = povs;
@@ -790,23 +831,25 @@ void JoystickLogSender::Send(uint64_t timestamp) {
void JoystickLogSender::AppendButtons(HAL_JoystickButtons buttons,
uint64_t timestamp) {
uint8_t buttonsArr[32];
for (unsigned int i = 0; i < buttons.count; ++i) {
buttonsArr[i] = (buttons.buttons & (1u << i)) != 0;
int count = availableToCount(buttons.available);
uint8_t buttonsArr[64];
for (int i = 0; i < count; ++i) {
buttonsArr[i] = (buttons.buttons & (1llu << i)) != 0;
}
m_logButtons.Append(std::span<const uint8_t>{buttonsArr, buttons.count},
timestamp);
m_logButtons.Append(
std::span<const uint8_t>{buttonsArr, static_cast<size_t>(count)},
timestamp);
}
void JoystickLogSender::AppendPOVs(const HAL_JoystickPOVs& povs,
uint64_t timestamp) {
int count = availableToCount(povs.available);
int64_t povsArr[HAL_kMaxJoystickPOVs];
for (int i = 0; i < povs.count; ++i) {
for (int i = 0; i < count; ++i) {
povsArr[i] = povs.povs[i];
}
m_logPOVs.Append(
std::span<const int64_t>{povsArr, static_cast<size_t>(povs.count)},
timestamp);
std::span<const int64_t>{povsArr, static_cast<size_t>(count)}, timestamp);
}
void DataLogSender::Init(wpi::log::DataLog& log, bool logJoysticks,

View File

@@ -0,0 +1,582 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/Gamepad.h"
#include <hal/UsageReporting.h>
#include <wpi/sendable/SendableBuilder.h>
#include "frc/event/BooleanEvent.h"
using namespace frc;
Gamepad::Gamepad(int port) : GenericHID(port) {
HAL_ReportUsage("HID", port, "Gamepad");
}
double Gamepad::GetLeftX() const {
return GetRawAxis(Axis::kLeftX);
}
double Gamepad::GetLeftY() const {
return GetRawAxis(Axis::kLeftY);
}
double Gamepad::GetRightX() const {
return GetRawAxis(Axis::kRightX);
}
double Gamepad::GetRightY() const {
return GetRawAxis(Axis::kRightY);
}
double Gamepad::GetLeftTriggerAxis() const {
return GetRawAxis(Axis::kLeftTrigger);
}
BooleanEvent Gamepad::LeftTrigger(double threshold, EventLoop* loop) const {
return BooleanEvent(loop, [this, threshold] {
return this->GetLeftTriggerAxis() > threshold;
});
}
BooleanEvent Gamepad::LeftTrigger(EventLoop* loop) const {
return this->LeftTrigger(0.5, loop);
}
double Gamepad::GetRightTriggerAxis() const {
return GetRawAxis(Axis::kRightTrigger);
}
BooleanEvent Gamepad::RightTrigger(double threshold, EventLoop* loop) const {
return BooleanEvent(loop, [this, threshold] {
return this->GetRightTriggerAxis() > threshold;
});
}
BooleanEvent Gamepad::RightTrigger(EventLoop* loop) const {
return this->RightTrigger(0.5, loop);
}
bool Gamepad::GetSouthFaceButton() const {
return GetRawButton(Button::kSouthFace);
}
bool Gamepad::GetSouthFaceButtonPressed() {
return GetRawButtonPressed(Button::kSouthFace);
}
bool Gamepad::GetSouthFaceButtonReleased() {
return GetRawButtonReleased(Button::kSouthFace);
}
BooleanEvent Gamepad::SouthFace(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetSouthFaceButton(); });
}
bool Gamepad::GetEastFaceButton() const {
return GetRawButton(Button::kEastFace);
}
bool Gamepad::GetEastFaceButtonPressed() {
return GetRawButtonPressed(Button::kEastFace);
}
bool Gamepad::GetEastFaceButtonReleased() {
return GetRawButtonReleased(Button::kEastFace);
}
BooleanEvent Gamepad::EastFace(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetEastFaceButton(); });
}
bool Gamepad::GetWestFaceButton() const {
return GetRawButton(Button::kWestFace);
}
bool Gamepad::GetWestFaceButtonPressed() {
return GetRawButtonPressed(Button::kWestFace);
}
bool Gamepad::GetWestFaceButtonReleased() {
return GetRawButtonReleased(Button::kWestFace);
}
BooleanEvent Gamepad::WestFace(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetWestFaceButton(); });
}
bool Gamepad::GetNorthFacenButton() const {
return GetRawButton(Button::kNorthFacen);
}
bool Gamepad::GetNorthFacenButtonPressed() {
return GetRawButtonPressed(Button::kNorthFacen);
}
bool Gamepad::GetNorthFacenButtonReleased() {
return GetRawButtonReleased(Button::kNorthFacen);
}
BooleanEvent Gamepad::NorthFacen(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetNorthFacenButton(); });
}
bool Gamepad::GetBackButton() const {
return GetRawButton(Button::kBack);
}
bool Gamepad::GetBackButtonPressed() {
return GetRawButtonPressed(Button::kBack);
}
bool Gamepad::GetBackButtonReleased() {
return GetRawButtonReleased(Button::kBack);
}
BooleanEvent Gamepad::Back(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetBackButton(); });
}
bool Gamepad::GetGuideButton() const {
return GetRawButton(Button::kGuide);
}
bool Gamepad::GetGuideButtonPressed() {
return GetRawButtonPressed(Button::kGuide);
}
bool Gamepad::GetGuideButtonReleased() {
return GetRawButtonReleased(Button::kGuide);
}
BooleanEvent Gamepad::Guide(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetGuideButton(); });
}
bool Gamepad::GetStartButton() const {
return GetRawButton(Button::kStart);
}
bool Gamepad::GetStartButtonPressed() {
return GetRawButtonPressed(Button::kStart);
}
bool Gamepad::GetStartButtonReleased() {
return GetRawButtonReleased(Button::kStart);
}
BooleanEvent Gamepad::Start(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetStartButton(); });
}
bool Gamepad::GetLeftStickButton() const {
return GetRawButton(Button::kLeftStick);
}
bool Gamepad::GetLeftStickButtonPressed() {
return GetRawButtonPressed(Button::kLeftStick);
}
bool Gamepad::GetLeftStickButtonReleased() {
return GetRawButtonReleased(Button::kLeftStick);
}
BooleanEvent Gamepad::LeftStick(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetLeftStickButton(); });
}
bool Gamepad::GetRightStickButton() const {
return GetRawButton(Button::kRightStick);
}
bool Gamepad::GetRightStickButtonPressed() {
return GetRawButtonPressed(Button::kRightStick);
}
bool Gamepad::GetRightStickButtonReleased() {
return GetRawButtonReleased(Button::kRightStick);
}
BooleanEvent Gamepad::RightStick(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetRightStickButton(); });
}
bool Gamepad::GetLeftShoulderButton() const {
return GetRawButton(Button::kLeftShoulder);
}
bool Gamepad::GetLeftShoulderButtonPressed() {
return GetRawButtonPressed(Button::kLeftShoulder);
}
bool Gamepad::GetLeftShoulderButtonReleased() {
return GetRawButtonReleased(Button::kLeftShoulder);
}
BooleanEvent Gamepad::LeftShoulder(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetLeftShoulderButton(); });
}
bool Gamepad::GetRightShoulderButton() const {
return GetRawButton(Button::kRightShoulder);
}
bool Gamepad::GetRightShoulderButtonPressed() {
return GetRawButtonPressed(Button::kRightShoulder);
}
bool Gamepad::GetRightShoulderButtonReleased() {
return GetRawButtonReleased(Button::kRightShoulder);
}
BooleanEvent Gamepad::RightShoulder(EventLoop* loop) const {
return BooleanEvent(loop,
[this]() { return this->GetRightShoulderButton(); });
}
bool Gamepad::GetDpadUpButton() const {
return GetRawButton(Button::kDpadUp);
}
bool Gamepad::GetDpadUpButtonPressed() {
return GetRawButtonPressed(Button::kDpadUp);
}
bool Gamepad::GetDpadUpButtonReleased() {
return GetRawButtonReleased(Button::kDpadUp);
}
BooleanEvent Gamepad::DpadUp(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetDpadUpButton(); });
}
bool Gamepad::GetDpadDownButton() const {
return GetRawButton(Button::kDpadDown);
}
bool Gamepad::GetDpadDownButtonPressed() {
return GetRawButtonPressed(Button::kDpadDown);
}
bool Gamepad::GetDpadDownButtonReleased() {
return GetRawButtonReleased(Button::kDpadDown);
}
BooleanEvent Gamepad::DpadDown(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetDpadDownButton(); });
}
bool Gamepad::GetDpadLeftButton() const {
return GetRawButton(Button::kDpadLeft);
}
bool Gamepad::GetDpadLeftButtonPressed() {
return GetRawButtonPressed(Button::kDpadLeft);
}
bool Gamepad::GetDpadLeftButtonReleased() {
return GetRawButtonReleased(Button::kDpadLeft);
}
BooleanEvent Gamepad::DpadLeft(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetDpadLeftButton(); });
}
bool Gamepad::GetDpadRightButton() const {
return GetRawButton(Button::kDpadRight);
}
bool Gamepad::GetDpadRightButtonPressed() {
return GetRawButtonPressed(Button::kDpadRight);
}
bool Gamepad::GetDpadRightButtonReleased() {
return GetRawButtonReleased(Button::kDpadRight);
}
BooleanEvent Gamepad::DpadRight(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetDpadRightButton(); });
}
bool Gamepad::GetMisc1Button() const {
return GetRawButton(Button::kMisc1);
}
bool Gamepad::GetMisc1ButtonPressed() {
return GetRawButtonPressed(Button::kMisc1);
}
bool Gamepad::GetMisc1ButtonReleased() {
return GetRawButtonReleased(Button::kMisc1);
}
BooleanEvent Gamepad::Misc1(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetMisc1Button(); });
}
bool Gamepad::GetRightPaddle1Button() const {
return GetRawButton(Button::kRightPaddle1);
}
bool Gamepad::GetRightPaddle1ButtonPressed() {
return GetRawButtonPressed(Button::kRightPaddle1);
}
bool Gamepad::GetRightPaddle1ButtonReleased() {
return GetRawButtonReleased(Button::kRightPaddle1);
}
BooleanEvent Gamepad::RightPaddle1(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetRightPaddle1Button(); });
}
bool Gamepad::GetLeftPaddle1Button() const {
return GetRawButton(Button::kLeftPaddle1);
}
bool Gamepad::GetLeftPaddle1ButtonPressed() {
return GetRawButtonPressed(Button::kLeftPaddle1);
}
bool Gamepad::GetLeftPaddle1ButtonReleased() {
return GetRawButtonReleased(Button::kLeftPaddle1);
}
BooleanEvent Gamepad::LeftPaddle1(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetLeftPaddle1Button(); });
}
bool Gamepad::GetRightPaddle2Button() const {
return GetRawButton(Button::kRightPaddle2);
}
bool Gamepad::GetRightPaddle2ButtonPressed() {
return GetRawButtonPressed(Button::kRightPaddle2);
}
bool Gamepad::GetRightPaddle2ButtonReleased() {
return GetRawButtonReleased(Button::kRightPaddle2);
}
BooleanEvent Gamepad::RightPaddle2(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetRightPaddle2Button(); });
}
bool Gamepad::GetLeftPaddle2Button() const {
return GetRawButton(Button::kLeftPaddle2);
}
bool Gamepad::GetLeftPaddle2ButtonPressed() {
return GetRawButtonPressed(Button::kLeftPaddle2);
}
bool Gamepad::GetLeftPaddle2ButtonReleased() {
return GetRawButtonReleased(Button::kLeftPaddle2);
}
BooleanEvent Gamepad::LeftPaddle2(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetLeftPaddle2Button(); });
}
bool Gamepad::GetTouchpadButton() const {
return GetRawButton(Button::kTouchpad);
}
bool Gamepad::GetTouchpadButtonPressed() {
return GetRawButtonPressed(Button::kTouchpad);
}
bool Gamepad::GetTouchpadButtonReleased() {
return GetRawButtonReleased(Button::kTouchpad);
}
BooleanEvent Gamepad::Touchpad(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetTouchpadButton(); });
}
bool Gamepad::GetMisc2Button() const {
return GetRawButton(Button::kMisc2);
}
bool Gamepad::GetMisc2ButtonPressed() {
return GetRawButtonPressed(Button::kMisc2);
}
bool Gamepad::GetMisc2ButtonReleased() {
return GetRawButtonReleased(Button::kMisc2);
}
BooleanEvent Gamepad::Misc2(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetMisc2Button(); });
}
bool Gamepad::GetMisc3Button() const {
return GetRawButton(Button::kMisc3);
}
bool Gamepad::GetMisc3ButtonPressed() {
return GetRawButtonPressed(Button::kMisc3);
}
bool Gamepad::GetMisc3ButtonReleased() {
return GetRawButtonReleased(Button::kMisc3);
}
BooleanEvent Gamepad::Misc3(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetMisc3Button(); });
}
bool Gamepad::GetMisc4Button() const {
return GetRawButton(Button::kMisc4);
}
bool Gamepad::GetMisc4ButtonPressed() {
return GetRawButtonPressed(Button::kMisc4);
}
bool Gamepad::GetMisc4ButtonReleased() {
return GetRawButtonReleased(Button::kMisc4);
}
BooleanEvent Gamepad::Misc4(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetMisc4Button(); });
}
bool Gamepad::GetMisc5Button() const {
return GetRawButton(Button::kMisc5);
}
bool Gamepad::GetMisc5ButtonPressed() {
return GetRawButtonPressed(Button::kMisc5);
}
bool Gamepad::GetMisc5ButtonReleased() {
return GetRawButtonReleased(Button::kMisc5);
}
BooleanEvent Gamepad::Misc5(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetMisc5Button(); });
}
bool Gamepad::GetMisc6Button() const {
return GetRawButton(Button::kMisc6);
}
bool Gamepad::GetMisc6ButtonPressed() {
return GetRawButtonPressed(Button::kMisc6);
}
bool Gamepad::GetMisc6ButtonReleased() {
return GetRawButtonReleased(Button::kMisc6);
}
BooleanEvent Gamepad::Misc6(EventLoop* loop) const {
return BooleanEvent(loop, [this]() { return this->GetMisc6Button(); });
}
double Gamepad::GetAxisForSendable(int axis) const {
return DriverStation::GetStickAxisIfAvailable(GetPort(), axis).value_or(0.0);
}
bool Gamepad::GetButtonForSendable(int button) const {
return DriverStation::GetStickButtonIfAvailable(GetPort(), button)
.value_or(false);
}
void Gamepad::InitSendable(wpi::SendableBuilder& builder) {
builder.SetSmartDashboardType("HID");
builder.PublishConstString("ControllerType", "Gamepad");
builder.AddDoubleProperty(
"LeftTrigger Axis",
[this] { return GetAxisForSendable(Axis::kLeftTrigger); }, nullptr);
builder.AddDoubleProperty(
"RightTrigger Axis",
[this] { return GetAxisForSendable(Axis::kRightTrigger); }, nullptr);
builder.AddDoubleProperty(
"LeftX", [this] { return GetAxisForSendable(Axis::kLeftX); }, nullptr);
builder.AddDoubleProperty(
"LeftY", [this] { return GetAxisForSendable(Axis::kLeftY); }, nullptr);
builder.AddDoubleProperty(
"RightX", [this] { return GetAxisForSendable(Axis::kRightX); }, nullptr);
builder.AddDoubleProperty(
"RightY", [this] { return GetAxisForSendable(Axis::kRightY); }, nullptr);
builder.AddBooleanProperty(
"SouthFace", [this] { return GetButtonForSendable(Button::kSouthFace); },
nullptr);
builder.AddBooleanProperty(
"EastFace", [this] { return GetButtonForSendable(Button::kEastFace); },
nullptr);
builder.AddBooleanProperty(
"WestFace", [this] { return GetButtonForSendable(Button::kWestFace); },
nullptr);
builder.AddBooleanProperty(
"NorthFacen",
[this] { return GetButtonForSendable(Button::kNorthFacen); }, nullptr);
builder.AddBooleanProperty(
"Back", [this] { return GetButtonForSendable(Button::kBack); }, nullptr);
builder.AddBooleanProperty(
"Guide", [this] { return GetButtonForSendable(Button::kGuide); },
nullptr);
builder.AddBooleanProperty(
"Start", [this] { return GetButtonForSendable(Button::kStart); },
nullptr);
builder.AddBooleanProperty(
"LeftStick", [this] { return GetButtonForSendable(Button::kLeftStick); },
nullptr);
builder.AddBooleanProperty(
"RightStick",
[this] { return GetButtonForSendable(Button::kRightStick); }, nullptr);
builder.AddBooleanProperty(
"LeftShoulder",
[this] { return GetButtonForSendable(Button::kLeftShoulder); }, nullptr);
builder.AddBooleanProperty(
"RightShoulder",
[this] { return GetButtonForSendable(Button::kRightShoulder); }, nullptr);
builder.AddBooleanProperty(
"DpadUp", [this] { return GetButtonForSendable(Button::kDpadUp); },
nullptr);
builder.AddBooleanProperty(
"DpadDown", [this] { return GetButtonForSendable(Button::kDpadDown); },
nullptr);
builder.AddBooleanProperty(
"DpadLeft", [this] { return GetButtonForSendable(Button::kDpadLeft); },
nullptr);
builder.AddBooleanProperty(
"DpadRight", [this] { return GetButtonForSendable(Button::kDpadRight); },
nullptr);
builder.AddBooleanProperty(
"Misc1", [this] { return GetButtonForSendable(Button::kMisc1); },
nullptr);
builder.AddBooleanProperty(
"RightPaddle1",
[this] { return GetButtonForSendable(Button::kRightPaddle1); }, nullptr);
builder.AddBooleanProperty(
"LeftPaddle1",
[this] { return GetButtonForSendable(Button::kLeftPaddle1); }, nullptr);
builder.AddBooleanProperty(
"RightPaddle2",
[this] { return GetButtonForSendable(Button::kRightPaddle2); }, nullptr);
builder.AddBooleanProperty(
"LeftPaddle2",
[this] { return GetButtonForSendable(Button::kLeftPaddle2); }, nullptr);
builder.AddBooleanProperty(
"Touchpad", [this] { return GetButtonForSendable(Button::kTouchpad); },
nullptr);
builder.AddBooleanProperty(
"Misc2", [this] { return GetButtonForSendable(Button::kMisc2); },
nullptr);
builder.AddBooleanProperty(
"Misc3", [this] { return GetButtonForSendable(Button::kMisc3); },
nullptr);
builder.AddBooleanProperty(
"Misc4", [this] { return GetButtonForSendable(Button::kMisc4); },
nullptr);
builder.AddBooleanProperty(
"Misc5", [this] { return GetButtonForSendable(Button::kMisc5); },
nullptr);
builder.AddBooleanProperty(
"Misc6", [this] { return GetButtonForSendable(Button::kMisc6); },
nullptr);
}

View File

@@ -107,16 +107,28 @@ BooleanEvent GenericHID::AxisGreaterThan(int axis, double threshold,
});
}
int GenericHID::GetAxisCount() const {
return DriverStation::GetStickAxisCount(m_port);
int GenericHID::GetAxesMaximumIndex() const {
return DriverStation::GetStickAxesMaximumIndex(m_port);
}
int GenericHID::GetPOVCount() const {
return DriverStation::GetStickPOVCount(m_port);
int GenericHID::GetAxesAvailable() const {
return DriverStation::GetStickAxesAvailable(m_port);
}
int GenericHID::GetButtonCount() const {
return DriverStation::GetStickButtonCount(m_port);
int GenericHID::GetPOVsMaximumIndex() const {
return DriverStation::GetStickPOVsMaximumIndex(m_port);
}
int GenericHID::GetPOVsAvailable() const {
return DriverStation::GetStickPOVsAvailable(m_port);
}
int GenericHID::GetButtonsMaximumIndex() const {
return DriverStation::GetStickButtonsMaximumIndex(m_port);
}
uint64_t GenericHID::GetButtonsAvailable() const {
return DriverStation::GetStickButtonsAvailable(m_port);
}
bool GenericHID::IsConnected() const {
@@ -131,10 +143,6 @@ std::string GenericHID::GetName() const {
return DriverStation::GetJoystickName(m_port);
}
int GenericHID::GetAxisType(int axis) const {
return DriverStation::GetJoystickAxisType(m_port, axis);
}
int GenericHID::GetPort() const {
return m_port;
}

View File

@@ -210,22 +210,54 @@ void DriverStationSim::SetJoystickPOV(int stick, int pov,
HALSIM_SetJoystickPOV(stick, pov, static_cast<HAL_JoystickPOV>(value));
}
void DriverStationSim::SetJoystickButtons(int stick, uint32_t buttons) {
HALSIM_SetJoystickButtonsValue(stick, buttons);
void DriverStationSim::SetJoystickAxesMaximumIndex(int stick,
int maximumIndex) {
SetJoystickAxesAvailable(stick, (1 << maximumIndex) - 1);
}
void DriverStationSim::SetJoystickAxisCount(int stick, int count) {
HALSIM_SetJoystickAxisCount(stick, count);
void DriverStationSim::SetJoystickAxesAvailable(int stick, int count) {
HALSIM_SetJoystickAxesAvailable(stick, count);
}
void DriverStationSim::SetJoystickPOVCount(int stick, int count) {
HALSIM_SetJoystickPOVCount(stick, count);
void DriverStationSim::SetJoystickPOVsMaximumIndex(int stick,
int maximumIndex) {
SetJoystickPOVsAvailable(stick, (1 << maximumIndex) - 1);
}
void DriverStationSim::SetJoystickButtonCount(int stick, int count) {
HALSIM_SetJoystickButtonCount(stick, count);
void DriverStationSim::SetJoystickPOVsAvailable(int stick, int count) {
HALSIM_SetJoystickPOVsAvailable(stick, count);
}
void DriverStationSim::SetJoystickButtonsMaximumIndex(int stick,
int maximumIndex) {
if (maximumIndex >= 64) {
SetJoystickButtonsAvailable(stick, 0xFFFFFFFFFFFFFFFFL);
} else {
SetJoystickButtonsAvailable(stick, (1L << maximumIndex) - 1);
}
}
void DriverStationSim::SetJoystickButtonsAvailable(int stick,
uint64_t available) {
HALSIM_SetJoystickButtonsAvailable(stick, available);
}
// void DriverStationSim::SetJoystickButtons(int stick, uint32_t buttons) {
// HALSIM_SetJoystickButtonsValue(stick, buttons);
// }
// void DriverStationSim::SetJoystickAxisCount(int stick, int count) {
// HALSIM_SetJoystickAxisCount(stick, count);
// }
// void DriverStationSim::SetJoystickPOVCount(int stick, int count) {
// HALSIM_SetJoystickPOVCount(stick, count);
// }
// void DriverStationSim::SetJoystickButtonCount(int stick, int count) {
// HALSIM_SetJoystickButtonCount(stick, count);
// }
void DriverStationSim::SetJoystickIsGamepad(int stick, bool isGamepad) {
HALSIM_SetJoystickIsGamepad(stick, isGamepad);
}
@@ -239,10 +271,6 @@ void DriverStationSim::SetJoystickName(int stick, std::string_view name) {
HALSIM_SetJoystickName(stick, &str);
}
void DriverStationSim::SetJoystickAxisType(int stick, int axis, int type) {
HALSIM_SetJoystickAxisType(stick, axis, type);
}
void DriverStationSim::SetGameSpecificMessage(std::string_view message) {
auto str = wpi::make_string(message);
HALSIM_SetGameSpecificMessage(&str);

View File

@@ -0,0 +1,150 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/simulation/GamepadSim.h"
#include "frc/Gamepad.h"
using namespace frc;
using namespace frc::sim;
GamepadSim::GamepadSim(const Gamepad& joystick) : GenericHIDSim{joystick} {
SetAxesMaximumIndex(6);
SetButtonsMaximumIndex(26);
SetPOVsMaximumIndex(1);
}
GamepadSim::GamepadSim(int port) : GenericHIDSim{port} {
SetAxesMaximumIndex(6);
SetButtonsMaximumIndex(26);
SetPOVsMaximumIndex(1);
}
void GamepadSim::SetLeftX(double value) {
SetRawAxis(Gamepad::Axis::kLeftX, value);
}
void GamepadSim::SetLeftY(double value) {
SetRawAxis(Gamepad::Axis::kLeftY, value);
}
void GamepadSim::SetRightX(double value) {
SetRawAxis(Gamepad::Axis::kRightX, value);
}
void GamepadSim::SetRightY(double value) {
SetRawAxis(Gamepad::Axis::kRightY, value);
}
void GamepadSim::SetLeftTriggerAxis(double value) {
SetRawAxis(Gamepad::Axis::kLeftTrigger, value);
}
void GamepadSim::SetRightTriggerAxis(double value) {
SetRawAxis(Gamepad::Axis::kRightTrigger, value);
}
void GamepadSim::SetSouthFaceButton(bool value) {
SetRawButton(Gamepad::Button::kSouthFace, value);
}
void GamepadSim::SetEastFaceButton(bool value) {
SetRawButton(Gamepad::Button::kEastFace, value);
}
void GamepadSim::SetWestFaceButton(bool value) {
SetRawButton(Gamepad::Button::kWestFace, value);
}
void GamepadSim::SetNorthFacenButton(bool value) {
SetRawButton(Gamepad::Button::kNorthFacen, value);
}
void GamepadSim::SetBackButton(bool value) {
SetRawButton(Gamepad::Button::kBack, value);
}
void GamepadSim::SetGuideButton(bool value) {
SetRawButton(Gamepad::Button::kGuide, value);
}
void GamepadSim::SetStartButton(bool value) {
SetRawButton(Gamepad::Button::kStart, value);
}
void GamepadSim::SetLeftStickButton(bool value) {
SetRawButton(Gamepad::Button::kLeftStick, value);
}
void GamepadSim::SetRightStickButton(bool value) {
SetRawButton(Gamepad::Button::kRightStick, value);
}
void GamepadSim::SetLeftShoulderButton(bool value) {
SetRawButton(Gamepad::Button::kLeftShoulder, value);
}
void GamepadSim::SetRightShoulderButton(bool value) {
SetRawButton(Gamepad::Button::kRightShoulder, value);
}
void GamepadSim::SetDpadUpButton(bool value) {
SetRawButton(Gamepad::Button::kDpadUp, value);
}
void GamepadSim::SetDpadDownButton(bool value) {
SetRawButton(Gamepad::Button::kDpadDown, value);
}
void GamepadSim::SetDpadLeftButton(bool value) {
SetRawButton(Gamepad::Button::kDpadLeft, value);
}
void GamepadSim::SetDpadRightButton(bool value) {
SetRawButton(Gamepad::Button::kDpadRight, value);
}
void GamepadSim::SetMisc1Button(bool value) {
SetRawButton(Gamepad::Button::kMisc1, value);
}
void GamepadSim::SetRightPaddle1Button(bool value) {
SetRawButton(Gamepad::Button::kRightPaddle1, value);
}
void GamepadSim::SetLeftPaddle1Button(bool value) {
SetRawButton(Gamepad::Button::kLeftPaddle1, value);
}
void GamepadSim::SetRightPaddle2Button(bool value) {
SetRawButton(Gamepad::Button::kRightPaddle2, value);
}
void GamepadSim::SetLeftPaddle2Button(bool value) {
SetRawButton(Gamepad::Button::kLeftPaddle2, value);
}
void GamepadSim::SetTouchpadButton(bool value) {
SetRawButton(Gamepad::Button::kTouchpad, value);
}
void GamepadSim::SetMisc2Button(bool value) {
SetRawButton(Gamepad::Button::kMisc2, value);
}
void GamepadSim::SetMisc3Button(bool value) {
SetRawButton(Gamepad::Button::kMisc3, value);
}
void GamepadSim::SetMisc4Button(bool value) {
SetRawButton(Gamepad::Button::kMisc4, value);
}
void GamepadSim::SetMisc5Button(bool value) {
SetRawButton(Gamepad::Button::kMisc5, value);
}
void GamepadSim::SetMisc6Button(bool value) {
SetRawButton(Gamepad::Button::kMisc6, value);
}

View File

@@ -36,16 +36,28 @@ void GenericHIDSim::SetPOV(DriverStation::POVDirection value) {
SetPOV(0, value);
}
void GenericHIDSim::SetAxisCount(int count) {
DriverStationSim::SetJoystickAxisCount(m_port, count);
void GenericHIDSim::SetAxesMaximumIndex(int maximumIndex) {
DriverStationSim::SetJoystickAxesMaximumIndex(m_port, maximumIndex);
}
void GenericHIDSim::SetPOVCount(int count) {
DriverStationSim::SetJoystickPOVCount(m_port, count);
void GenericHIDSim::SetAxesAvailable(int count) {
DriverStationSim::SetJoystickAxesAvailable(m_port, count);
}
void GenericHIDSim::SetButtonCount(int count) {
DriverStationSim::SetJoystickButtonCount(m_port, count);
void GenericHIDSim::SetPOVsMaximumIndex(int maximumIndex) {
DriverStationSim::SetJoystickPOVsMaximumIndex(m_port, maximumIndex);
}
void GenericHIDSim::SetPOVsAvailable(int count) {
DriverStationSim::SetJoystickPOVsAvailable(m_port, count);
}
void GenericHIDSim::SetButtonsMaximumIndex(int maximumIndex) {
DriverStationSim::SetJoystickButtonsMaximumIndex(m_port, maximumIndex);
}
void GenericHIDSim::SetButtonsAvailable(uint64_t count) {
DriverStationSim::SetJoystickButtonsAvailable(m_port, count);
}
void GenericHIDSim::SetType(GenericHID::HIDType type) {
@@ -56,10 +68,6 @@ void GenericHIDSim::SetName(const char* name) {
DriverStationSim::SetJoystickName(m_port, name);
}
void GenericHIDSim::SetAxisType(int axis, int type) {
DriverStationSim::SetJoystickAxisType(m_port, axis, type);
}
bool GenericHIDSim::GetOutput(int outputNumber) {
int64_t outputs = GetOutputs();
return (outputs & (static_cast<int64_t>(1) << (outputNumber - 1))) != 0;

View File

@@ -13,16 +13,16 @@ using namespace frc::sim;
JoystickSim::JoystickSim(const Joystick& joystick)
: GenericHIDSim{joystick}, m_joystick{&joystick} {
// default to a reasonable joystick configuration
SetAxisCount(5);
SetButtonCount(12);
SetPOVCount(1);
SetAxesMaximumIndex(5);
SetButtonsMaximumIndex(12);
SetPOVsMaximumIndex(1);
}
JoystickSim::JoystickSim(int port) : GenericHIDSim{port} {
// default to a reasonable joystick configuration
SetAxisCount(5);
SetButtonCount(12);
SetPOVCount(1);
SetAxesMaximumIndex(5);
SetButtonsMaximumIndex(12);
SetPOVsMaximumIndex(1);
}
void JoystickSim::SetX(double value) {

View File

@@ -109,20 +109,30 @@ class DriverStation final {
static constexpr int kJoystickPorts = 6;
/**
* The state of one joystick button. %Button indexes begin at 1.
* The state of one joystick button. Button indexes begin at 0.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @param button The button index, beginning at 0.
* @return The state of the joystick button.
*/
static bool GetStickButton(int stick, int button);
/**
* The state of one joystick button, only if available. Button indexes begin
* at 0.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 0.
* @return The state of the joystick button, or empty if unavailable.
*/
static std::optional<bool> GetStickButtonIfAvailable(int stick, int button);
/**
* Whether one joystick button was pressed since the last check. %Button
* indexes begin at 1.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @param button The button index, beginning at 0.
* @return Whether the joystick button was pressed since the last check.
*/
static bool GetStickButtonPressed(int stick, int button);
@@ -132,7 +142,7 @@ class DriverStation final {
* indexes begin at 1.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @param button The button index, beginning at 0.
* @return Whether the joystick button was released since the last check.
*/
static bool GetStickButtonReleased(int stick, int button);
@@ -149,6 +159,18 @@ class DriverStation final {
*/
static double GetStickAxis(int stick, int axis);
/**
* Get the value of the axis on a joystick, if available.
*
* This depends on the mapping of the joystick connected to the specified
* port.
*
* @param stick The joystick to read.
* @param axis The analog axis value to read from the joystick.
* @return The value of the axis on the joystick, or empty if not available.
*/
static std::optional<double> GetStickAxisIfAvailable(int stick, int axis);
/**
* Get the state of a POV on the joystick.
*
@@ -162,31 +184,55 @@ class DriverStation final {
* @param stick The joystick to read.
* @return The state of the buttons on the joystick.
*/
static int GetStickButtons(int stick);
static uint64_t GetStickButtons(int stick);
/**
* Returns the number of axes on a given joystick port.
* Returns the maximum axis index on a given joystick port.
*
* @param stick The joystick port number
* @return The number of axes on the indicated joystick
* @return The maximum axis index on the indicated joystick
*/
static int GetStickAxisCount(int stick);
static int GetStickAxesMaximumIndex(int stick);
/**
* Returns the number of POVs on a given joystick port.
* Returns the mask of available axes on a given joystick port.
*
* @param stick The joystick port number
* @return The number of POVs on the indicated joystick
* @return The mask of available axes on the indicated joystick
*/
static int GetStickPOVCount(int stick);
static int GetStickAxesAvailable(int stick);
/**
* Returns the number of buttons on a given joystick port.
* Returns the maximum POV index on a given joystick port.
*
* @param stick The joystick port number
* @return The number of buttons on the indicated joystick
* @return The maximum POV index on the indicated joystick
*/
static int GetStickButtonCount(int stick);
static int GetStickPOVsMaximumIndex(int stick);
/**
* Returns the mask of available POVs on a given joystick port.
*
* @param stick The joystick port number
* @return The mask of available POVs on the indicated joystick
*/
static int GetStickPOVsAvailable(int stick);
/**
* Returns the maximum button index on a given joystick port.
*
* @param stick The joystick port number
* @return The maximum button index on the indicated joystick
*/
static int GetStickButtonsMaximumIndex(int stick);
/**
* Returns the mask of available buttons on a given joystick port.
*
* @param stick The joystick port number
* @return The mask of available buttons on the indicated joystick
*/
static uint64_t GetStickButtonsAvailable(int stick);
/**
* Returns a boolean indicating if the controller is an xbox controller.
@@ -212,15 +258,6 @@ class DriverStation final {
*/
static std::string GetJoystickName(int stick);
/**
* Returns the types of Axes on a given joystick port.
*
* @param stick The joystick port number and the target axis
* @param axis The analog axis value to read from the joystick.
* @return What type of axis the axis is reporting to be
*/
static int GetJoystickAxisType(int stick, int axis);
/**
* Returns if a joystick is connected to the Driver Station.
*

File diff suppressed because it is too large Load Diff

View File

@@ -106,7 +106,7 @@ class GenericHID {
* since the last time this method was called. This is useful if you only
* want to call a function once when you press the button.
*
* @param button The button index, beginning at 1.
* @param button The button index, beginning at 0.
* @return Whether the button was pressed since the last check.
*/
bool GetRawButtonPressed(int button);
@@ -119,7 +119,7 @@ class GenericHID {
* since the last time this method was called. This is useful if you only
* want to call a function once when you release the button.
*
* @param button The button index, beginning at 1.
* @param button The button index, beginning at 0.
* @return Whether the button was released since the last check.
*/
bool GetRawButtonReleased(int button);
@@ -280,26 +280,32 @@ class GenericHID {
BooleanEvent AxisGreaterThan(int axis, double threshold,
EventLoop* loop) const;
int GetAxesMaximumIndex() const;
/**
* Get the number of axes for the HID.
*
* @return the number of axis for the current HID
*/
int GetAxisCount() const;
int GetAxesAvailable() const;
int GetPOVsMaximumIndex() const;
/**
* Get the number of POVs for the HID.
*
* @return the number of POVs for the current HID
*/
int GetPOVCount() const;
int GetPOVsAvailable() const;
int GetButtonsMaximumIndex() const;
/**
* Get the number of buttons for the HID.
*
* @return the number of buttons on the current HID
*/
int GetButtonCount() const;
uint64_t GetButtonsAvailable() const;
/**
* Get if the HID is connected.
@@ -322,13 +328,6 @@ class GenericHID {
*/
std::string GetName() const;
/**
* Get the axis type of a joystick axis.
*
* @return the axis type of a joystick axis.
*/
int GetAxisType(int axis) const;
/**
* Get the port number of the HID.
*

View File

@@ -264,10 +264,10 @@ class DriverStationSim {
static int GetJoystickRumble(int stick, int rumbleNum);
/**
* Sets the state of one joystick button. %Button indexes begin at 1.
* Sets the state of one joystick button. %Button indexes begin at 0.
*
* @param stick The joystick number
* @param button The button index, beginning at 1
* @param button The button index, beginning at 0
* @param state The state of the joystick button
*/
static void SetJoystickButton(int stick, int button, bool state);
@@ -292,28 +292,36 @@ class DriverStationSim {
DriverStation::POVDirection value);
/**
* Sets the state of all the buttons on a joystick.
* Sets the number of axes for a joystick.
*
* @param stick The joystick number
* @param buttons The bitmap state of the buttons on the joystick
* @param maximumIndex The number of axes on the indicated joystick
*/
static void SetJoystickButtons(int stick, uint32_t buttons);
static void SetJoystickAxesMaximumIndex(int stick, int maximumIndex);
/**
* Sets the number of axes for a joystick.
*
* @param stick The joystick number
* @param count The number of axes on the indicated joystick
* @param available The number of axes on the indicated joystick
*/
static void SetJoystickAxisCount(int stick, int count);
static void SetJoystickAxesAvailable(int stick, int available);
/**
* Sets the number of POVs for a joystick.
*
* @param stick The joystick number
* @param count The number of POVs on the indicated joystick
* @param maximumIndex The number of POVs on the indicated joystick
*/
static void SetJoystickPOVCount(int stick, int count);
static void SetJoystickPOVsMaximumIndex(int stick, int maximumIndex);
/**
* Sets the number of POVs for a joystick.
*
* @param stick The joystick number
* @param available The number of POVs on the indicated joystick
*/
static void SetJoystickPOVsAvailable(int stick, int available);
/**
* Sets the number of buttons for a joystick.
@@ -321,7 +329,9 @@ class DriverStationSim {
* @param stick The joystick number
* @param count The number of buttons on the indicated joystick
*/
static void SetJoystickButtonCount(int stick, int count);
static void SetJoystickButtonsMaximumIndex(int stick, int count);
static void SetJoystickButtonsAvailable(int stick, uint64_t available);
/**
* Sets the value of isGamepad for a joystick.
@@ -347,15 +357,6 @@ class DriverStationSim {
*/
static void SetJoystickName(int stick, std::string_view name);
/**
* Sets the types of Axes for a joystick.
*
* @param stick The joystick number
* @param axis The target axis
* @param type The type of axis
*/
static void SetJoystickAxisType(int stick, int axis, int type);
/**
* Sets the game specific message.
*

View File

@@ -0,0 +1,260 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include "frc/simulation/GenericHIDSim.h"
namespace frc {
class Gamepad;
namespace sim {
/**
* Class to control a simulated Gamepad controller.
*/
class GamepadSim : public GenericHIDSim {
public:
/**
* Constructs from a Gamepad object.
*
* @param joystick controller to simulate
*/
explicit GamepadSim(const Gamepad& joystick);
/**
* Constructs from a joystick port number.
*
* @param port port number
*/
explicit GamepadSim(int port);
/**
* Change the left X value of the controller's joystick.
*
* @param value the new value
*/
void SetLeftX(double value);
/**
* Change the left Y value of the controller's joystick.
*
* @param value the new value
*/
void SetLeftY(double value);
/**
* Change the right X value of the controller's joystick.
*
* @param value the new value
*/
void SetRightX(double value);
/**
* Change the right Y value of the controller's joystick.
*
* @param value the new value
*/
void SetRightY(double value);
/**
* Change the value of the left trigger axis on the controller.
*
* @param value the new value
*/
void SetLeftTriggerAxis(double value);
/**
* Change the value of the right trigger axis on the controller.
*
* @param value the new value
*/
void SetRightTriggerAxis(double value);
/**
* Change the value of the South Face button on the controller.
*
* @param value the new value
*/
void SetSouthFaceButton(bool value);
/**
* Change the value of the East Face button on the controller.
*
* @param value the new value
*/
void SetEastFaceButton(bool value);
/**
* Change the value of the West Face button on the controller.
*
* @param value the new value
*/
void SetWestFaceButton(bool value);
/**
* Change the value of the North Face button on the controller.
*
* @param value the new value
*/
void SetNorthFacenButton(bool value);
/**
* Change the value of the Back button on the controller.
*
* @param value the new value
*/
void SetBackButton(bool value);
/**
* Change the value of the Guide button on the controller.
*
* @param value the new value
*/
void SetGuideButton(bool value);
/**
* Change the value of the Start button on the controller.
*
* @param value the new value
*/
void SetStartButton(bool value);
/**
* Change the value of the left stick button on the controller.
*
* @param value the new value
*/
void SetLeftStickButton(bool value);
/**
* Change the value of the right stick button on the controller.
*
* @param value the new value
*/
void SetRightStickButton(bool value);
/**
* Change the value of the right shoulder button on the controller.
*
* @param value the new value
*/
void SetLeftShoulderButton(bool value);
/**
* Change the value of the right shoulder button on the controller.
*
* @param value the new value
*/
void SetRightShoulderButton(bool value);
/**
* Change the value of the D-pad up button on the controller.
*
* @param value the new value
*/
void SetDpadUpButton(bool value);
/**
* Change the value of the D-pad down button on the controller.
*
* @param value the new value
*/
void SetDpadDownButton(bool value);
/**
* Change the value of the D-pad left button on the controller.
*
* @param value the new value
*/
void SetDpadLeftButton(bool value);
/**
* Change the value of the D-pad right button on the controller.
*
* @param value the new value
*/
void SetDpadRightButton(bool value);
/**
* Change the value of the Miscellaneous 1 button on the controller.
*
* @param value the new value
*/
void SetMisc1Button(bool value);
/**
* Change the value of the Right Paddle 1 button on the controller.
*
* @param value the new value
*/
void SetRightPaddle1Button(bool value);
/**
* Change the value of the Left Paddle 1 button on the controller.
*
* @param value the new value
*/
void SetLeftPaddle1Button(bool value);
/**
* Change the value of the Right Paddle 2 button on the controller.
*
* @param value the new value
*/
void SetRightPaddle2Button(bool value);
/**
* Change the value of the Left Paddle 2 button on the controller.
*
* @param value the new value
*/
void SetLeftPaddle2Button(bool value);
/**
* Change the value of the Touchpad button on the controller.
*
* @param value the new value
*/
void SetTouchpadButton(bool value);
/**
* Change the value of the Miscellaneous 2 button on the controller.
*
* @param value the new value
*/
void SetMisc2Button(bool value);
/**
* Change the value of the Miscellaneous 3 button on the controller.
*
* @param value the new value
*/
void SetMisc3Button(bool value);
/**
* Change the value of the Miscellaneous 4 button on the controller.
*
* @param value the new value
*/
void SetMisc4Button(bool value);
/**
* Change the value of the Miscellaneous 5 button on the controller.
*
* @param value the new value
*/
void SetMisc5Button(bool value);
/**
* Change the value of the Miscellaneous 6 button on the controller.
*
* @param value the new value
*/
void SetMisc6Button(bool value);
};
} // namespace sim
} // namespace frc

View File

@@ -70,26 +70,32 @@ class GenericHIDSim {
*/
void SetPOV(DriverStation::POVDirection value);
void SetAxesMaximumIndex(int maximumIndex);
/**
* Set the axis count of this device.
*
* @param count the new axis count
*/
void SetAxisCount(int count);
void SetAxesAvailable(int count);
void SetPOVsMaximumIndex(int maximumIndex);
/**
* Set the POV count of this device.
*
* @param count the new POV count
*/
void SetPOVCount(int count);
void SetPOVsAvailable(int count);
void SetButtonsMaximumIndex(int maximumIndex);
/**
* Set the button count of this device.
*
* @param count the new button count
*/
void SetButtonCount(int count);
void SetButtonsAvailable(uint64_t count);
/**
* Set the type of this device.

View File

@@ -16,10 +16,12 @@ class IsJoystickConnectedParametersTest
: public ::testing::TestWithParam<std::tuple<int, int, int, bool>> {};
TEST_P(IsJoystickConnectedParametersTest, IsJoystickConnected) {
frc::sim::DriverStationSim::SetJoystickAxisCount(1, std::get<0>(GetParam()));
frc::sim::DriverStationSim::SetJoystickButtonCount(1,
std::get<1>(GetParam()));
frc::sim::DriverStationSim::SetJoystickPOVCount(1, std::get<2>(GetParam()));
frc::sim::DriverStationSim::SetJoystickAxesMaximumIndex(
1, std::get<0>(GetParam()));
frc::sim::DriverStationSim::SetJoystickButtonsMaximumIndex(
1, std::get<1>(GetParam()));
frc::sim::DriverStationSim::SetJoystickPOVsMaximumIndex(
1, std::get<2>(GetParam()));
frc::sim::DriverStationSim::NotifyNewData();
ASSERT_EQ(std::get<3>(GetParam()),
@@ -64,13 +66,13 @@ INSTANTIATE_TEST_SUITE_P(
std::make_tuple(false, true, true, ""),
std::make_tuple(
false, false, false,
"Warning: Joystick Button 1 missing (max 0), check if all "
"Warning: Joystick Button 1 missing (available 0), check if all "
"controllers are plugged in\n"),
std::make_tuple(
true, true, false,
"Warning: Joystick Button 1 missing (max 0), check if all "
"Warning: Joystick Button 1 missing (available 0), check if all "
"controllers are plugged in\n"),
std::make_tuple(
true, false, false,
"Warning: Joystick Button 1 missing (max 0), check if all "
"Warning: Joystick Button 1 missing (available 0), check if all "
"controllers are plugged in\n")));

View File

@@ -70,7 +70,7 @@ class PotentiometerPIDTest : public testing::Test {
frc::sim::PauseTiming();
frc::sim::DriverStationSim::ResetData();
m_joystickSim.SetButtonCount(12);
m_joystickSim.SetButtonsMaximumIndex(12);
m_callback =
HALSIM_RegisterSimPeriodicBeforeCallback(CallSimPeriodicBefore, this);

View File

@@ -6,50 +6,50 @@
"buttons": [
{
"name": "a",
"value": 1,
"value": 0,
"DocName": "A"
},
{
"name": "b",
"value": 2,
"value": 1,
"DocName": "B"
},
{
"name": "x",
"value": 3,
"value": 2,
"DocName": "X"
},
{
"name": "y",
"value": 4,
"value": 3,
"DocName": "Y"
},
{
"name": "leftBumper",
"value": 5,
"value": 4,
"DocName": "left bumper"
},
{
"name": "rightBumper",
"value": 6,
"value": 5,
"DocName": "right bumper"
},
{
"name": "back",
"value": 7
"value": 6
},
{
"name": "start",
"value": 8
"value": 7
},
{
"name": "leftStick",
"value": 9,
"value": 8,
"DocName": "left stick"
},
{
"name": "rightStick",
"value": 10,
"value": 9,
"DocName": "right stick"
}
],
@@ -109,66 +109,66 @@
"buttons": [
{
"name": "square",
"value": 1
"value": 0
},
{
"name": "cross",
"value": 2
"value": 1
},
{
"name": "circle",
"value": 3
"value": 2
},
{
"name": "triangle",
"value": 4
"value": 3
},
{
"name": "L1",
"value": 5,
"value": 4,
"DocName": "left trigger 1"
},
{
"name": "R1",
"value": 6,
"value": 5,
"DocName": "right trigger 1"
},
{
"name": "L2",
"value": 7,
"value": 6,
"DocName": "left trigger 2"
},
{
"name": "R2",
"value": 8,
"value": 7,
"DocName": "right trigger 2"
},
{
"name": "share",
"value": 9
"value": 8
},
{
"name": "options",
"value": 10
"value": 9
},
{
"name": "L3",
"value": 11,
"value": 10,
"DocName": "L3 (left stick)"
},
{
"name": "R3",
"value": 12,
"value": 11,
"DocName": "R3 (right stick)"
},
{
"name": "PS",
"value": 13,
"value": 12,
"DocName": "PlayStation"
},
{
"name": "touchpad",
"value": 14
"value": 13
}
],
"sticks": [
@@ -227,66 +227,66 @@
"buttons": [
{
"name": "square",
"value": 1
"value": 0
},
{
"name": "cross",
"value": 2
"value": 1
},
{
"name": "circle",
"value": 3
"value": 2
},
{
"name": "triangle",
"value": 4
"value": 3
},
{
"name": "L1",
"value": 5,
"value": 4,
"DocName": "left trigger 1"
},
{
"name": "R1",
"value": 6,
"value": 5,
"DocName": "right trigger 1"
},
{
"name": "L2",
"value": 7,
"value": 6,
"DocName": "left trigger 2"
},
{
"name": "R2",
"value": 8,
"value": 7,
"DocName": "right trigger 2"
},
{
"name": "create",
"value": 9
"value": 8
},
{
"name": "options",
"value": 10
"value": 9
},
{
"name": "L3",
"value": 11,
"value": 10,
"DocName": "L3 (left stick)"
},
{
"name": "R3",
"value": 12,
"value": 11,
"DocName": "R3 (right stick)"
},
{
"name": "PS",
"value": 13,
"value": 12,
"DocName": "PlayStation"
},
{
"name": "touchpad",
"value": 14
"value": 13
}
],
"sticks": [
@@ -345,73 +345,73 @@
"buttons": [
{
"name": "a",
"value": 1,
"value": 0,
"DocName": "A"
},
{
"name": "b",
"value": 2,
"value": 1,
"DocName": "B"
},
{
"name": "x",
"value": 3,
"value": 2,
"DocName": "X"
},
{
"name": "y",
"value": 4,
"value": 3,
"DocName": "Y"
},
{
"name": "leftBumper",
"value": 5,
"value": 4,
"DocName": "left bumper"
},
{
"name": "rightBumper",
"value": 6,
"value": 5,
"DocName": "right bumper"
},
{
"name": "leftStick",
"value": 7,
"value": 6,
"DocName": "left stick"
},
{
"name": "rightStick",
"value": 8,
"value": 7,
"DocName": "right stick"
},
{
"name": "ellipses",
"value": 9
"value": 8
},
{
"name": "hamburger",
"value": 10
"value": 9
},
{
"name": "stadia",
"value": 11
"value": 10
},
{
"name": "rightTrigger",
"value": 12,
"value": 11,
"DocName": "right trigger"
},
{
"name": "leftTrigger",
"value": 13,
"value": 12,
"DocName": "left trigger"
},
{
"name": "google",
"value": 14
"value": 13
},
{
"name": "frame",
"value": 15
"value": 14
}
],
"sticks": [

View File

@@ -20,9 +20,9 @@ public class {{ ConsoleName }}ControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public {{ ConsoleName }}ControllerSim({{ ConsoleName }}Controller joystick) {
super(joystick);
setAxisCount({{ sticks|length + triggers|length }});
setButtonCount({{ buttons|length }});
setPOVCount(1);
setAxesMaximumIndex({{ sticks|length + triggers|length }});
setButtonsMaximumIndex({{ buttons|length }});
setPOVsMaximumIndex(1);
}
/**
@@ -33,9 +33,9 @@ public class {{ ConsoleName }}ControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public {{ ConsoleName }}ControllerSim(int port) {
super(port);
setAxisCount({{ sticks|length + triggers|length }});
setButtonCount({{ buttons|length }});
setPOVCount(1);
setAxesMaximumIndex({{ sticks|length + triggers|length }});
setButtonsMaximumIndex({{ buttons|length }});
setPOVsMaximumIndex(1);
}
{% for stick in sticks %}
/**

View File

@@ -27,33 +27,33 @@ public class PS4Controller extends GenericHID implements Sendable {
/** Represents a digital button on a PS4Controller. */
public enum Button {
/** Square button. */
kSquare(1),
kSquare(0),
/** Cross button. */
kCross(2),
kCross(1),
/** Circle button. */
kCircle(3),
kCircle(2),
/** Triangle button. */
kTriangle(4),
kTriangle(3),
/** Left trigger 1 button. */
kL1(5),
kL1(4),
/** Right trigger 1 button. */
kR1(6),
kR1(5),
/** Left trigger 2 button. */
kL2(7),
kL2(6),
/** Right trigger 2 button. */
kR2(8),
kR2(7),
/** Share button. */
kShare(9),
kShare(8),
/** Options button. */
kOptions(10),
kOptions(9),
/** L3 (left stick) button. */
kL3(11),
kL3(10),
/** R3 (right stick) button. */
kR3(12),
kR3(11),
/** PlayStation button. */
kPS(13),
kPS(12),
/** Touchpad button. */
kTouchpad(14);
kTouchpad(13);
/** Button value. */
public final int value;

View File

@@ -27,33 +27,33 @@ public class PS5Controller extends GenericHID implements Sendable {
/** Represents a digital button on a PS5Controller. */
public enum Button {
/** Square button. */
kSquare(1),
kSquare(0),
/** Cross button. */
kCross(2),
kCross(1),
/** Circle button. */
kCircle(3),
kCircle(2),
/** Triangle button. */
kTriangle(4),
kTriangle(3),
/** Left trigger 1 button. */
kL1(5),
kL1(4),
/** Right trigger 1 button. */
kR1(6),
kR1(5),
/** Left trigger 2 button. */
kL2(7),
kL2(6),
/** Right trigger 2 button. */
kR2(8),
kR2(7),
/** Create button. */
kCreate(9),
kCreate(8),
/** Options button. */
kOptions(10),
kOptions(9),
/** L3 (left stick) button. */
kL3(11),
kL3(10),
/** R3 (right stick) button. */
kR3(12),
kR3(11),
/** PlayStation button. */
kPS(13),
kPS(12),
/** Touchpad button. */
kTouchpad(14);
kTouchpad(13);
/** Button value. */
public final int value;

View File

@@ -27,35 +27,35 @@ public class StadiaController extends GenericHID implements Sendable {
/** Represents a digital button on a StadiaController. */
public enum Button {
/** A button. */
kA(1),
kA(0),
/** B button. */
kB(2),
kB(1),
/** X button. */
kX(3),
kX(2),
/** Y button. */
kY(4),
kY(3),
/** Left bumper button. */
kLeftBumper(5),
kLeftBumper(4),
/** Right bumper button. */
kRightBumper(6),
kRightBumper(5),
/** Left stick button. */
kLeftStick(7),
kLeftStick(6),
/** Right stick button. */
kRightStick(8),
kRightStick(7),
/** Ellipses button. */
kEllipses(9),
kEllipses(8),
/** Hamburger button. */
kHamburger(10),
kHamburger(9),
/** Stadia button. */
kStadia(11),
kStadia(10),
/** Right trigger button. */
kRightTrigger(12),
kRightTrigger(11),
/** Left trigger button. */
kLeftTrigger(13),
kLeftTrigger(12),
/** Google button. */
kGoogle(14),
kGoogle(13),
/** Frame button. */
kFrame(15);
kFrame(14);
/** Button value. */
public final int value;

View File

@@ -27,25 +27,25 @@ public class XboxController extends GenericHID implements Sendable {
/** Represents a digital button on a XboxController. */
public enum Button {
/** A button. */
kA(1),
kA(0),
/** B button. */
kB(2),
kB(1),
/** X button. */
kX(3),
kX(2),
/** Y button. */
kY(4),
kY(3),
/** Left bumper button. */
kLeftBumper(5),
kLeftBumper(4),
/** Right bumper button. */
kRightBumper(6),
kRightBumper(5),
/** Back button. */
kBack(7),
kBack(6),
/** Start button. */
kStart(8),
kStart(7),
/** Left stick button. */
kLeftStick(9),
kLeftStick(8),
/** Right stick button. */
kRightStick(10);
kRightStick(9);
/** Button value. */
public final int value;

View File

@@ -18,9 +18,9 @@ public class PS4ControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public PS4ControllerSim(PS4Controller joystick) {
super(joystick);
setAxisCount(6);
setButtonCount(14);
setPOVCount(1);
setAxesMaximumIndex(6);
setButtonsMaximumIndex(14);
setPOVsMaximumIndex(1);
}
/**
@@ -31,9 +31,9 @@ public class PS4ControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public PS4ControllerSim(int port) {
super(port);
setAxisCount(6);
setButtonCount(14);
setPOVCount(1);
setAxesMaximumIndex(6);
setButtonsMaximumIndex(14);
setPOVsMaximumIndex(1);
}
/**

View File

@@ -18,9 +18,9 @@ public class PS5ControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public PS5ControllerSim(PS5Controller joystick) {
super(joystick);
setAxisCount(6);
setButtonCount(14);
setPOVCount(1);
setAxesMaximumIndex(6);
setButtonsMaximumIndex(14);
setPOVsMaximumIndex(1);
}
/**
@@ -31,9 +31,9 @@ public class PS5ControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public PS5ControllerSim(int port) {
super(port);
setAxisCount(6);
setButtonCount(14);
setPOVCount(1);
setAxesMaximumIndex(6);
setButtonsMaximumIndex(14);
setPOVsMaximumIndex(1);
}
/**

View File

@@ -18,9 +18,9 @@ public class StadiaControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public StadiaControllerSim(StadiaController joystick) {
super(joystick);
setAxisCount(4);
setButtonCount(15);
setPOVCount(1);
setAxesMaximumIndex(4);
setButtonsMaximumIndex(15);
setPOVsMaximumIndex(1);
}
/**
@@ -31,9 +31,9 @@ public class StadiaControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public StadiaControllerSim(int port) {
super(port);
setAxisCount(4);
setButtonCount(15);
setPOVCount(1);
setAxesMaximumIndex(4);
setButtonsMaximumIndex(15);
setPOVsMaximumIndex(1);
}
/**

View File

@@ -18,9 +18,9 @@ public class XboxControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public XboxControllerSim(XboxController joystick) {
super(joystick);
setAxisCount(6);
setButtonCount(10);
setPOVCount(1);
setAxesMaximumIndex(6);
setButtonsMaximumIndex(10);
setPOVsMaximumIndex(1);
}
/**
@@ -31,9 +31,9 @@ public class XboxControllerSim extends GenericHIDSim {
@SuppressWarnings("this-escape")
public XboxControllerSim(int port) {
super(port);
setAxisCount(6);
setButtonCount(10);
setPOVCount(1);
setAxesMaximumIndex(6);
setButtonsMaximumIndex(10);
setPOVsMaximumIndex(1);
}
/**

View File

@@ -22,9 +22,9 @@ import edu.wpi.first.networktables.StringPublisher;
import edu.wpi.first.networktables.StringTopic;
import edu.wpi.first.util.EventVector;
import edu.wpi.first.util.WPIUtilJNI;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.concurrent.locks.ReentrantLock;
@@ -33,14 +33,32 @@ public final class DriverStation {
/** Number of Joystick ports. */
public static final int kJoystickPorts = 6;
private static final long[] m_metadataCache = new long[4];
private static int availableToCount(long available) {
// Top bit has to be set
if (available < 0) {
return 64;
}
int count = 0;
// Top bit not set, we will eventually get a 0 bit
while ((available & 0x1) != 0) {
count++;
available >>= 1;
}
return count;
}
private static final class HALJoystickButtons {
public int m_buttons;
public byte m_count;
public long m_buttons;
public long m_available;
}
private static class HALJoystickAxes {
public final float[] m_axes;
public int m_count;
public int m_available;
HALJoystickAxes(int count) {
m_axes = new float[count];
@@ -51,7 +69,7 @@ public final class DriverStation {
public final short[] m_axes;
@SuppressWarnings("unused")
public int m_count;
public int m_available;
HALJoystickAxesRaw(int count) {
m_axes = new short[count];
@@ -60,7 +78,7 @@ public final class DriverStation {
private static class HALJoystickPOVs {
public final byte[] m_povs;
public int m_count;
public int m_available;
HALJoystickPOVs(int count) {
m_povs = new byte[count];
@@ -294,18 +312,18 @@ public final class DriverStation {
public void send(long timestamp) {
HALJoystickButtons buttons = m_joystickButtons[m_stick];
if (buttons.m_count != m_prevButtons.m_count
if (buttons.m_available != m_prevButtons.m_available
|| buttons.m_buttons != m_prevButtons.m_buttons) {
appendButtons(buttons, timestamp);
}
HALJoystickAxes axes = m_joystickAxes[m_stick];
int count = axes.m_count;
int available = axes.m_available;
boolean needToLog = false;
if (count != m_prevAxes.m_count) {
if (available != m_prevAxes.m_available) {
needToLog = true;
} else {
for (int i = 0; i < count; i++) {
for (int i = 0; i < m_prevAxes.m_axes.length; i++) {
if (axes.m_axes[i] != m_prevAxes.m_axes[i]) {
needToLog = true;
break;
@@ -317,12 +335,12 @@ public final class DriverStation {
}
HALJoystickPOVs povs = m_joystickPOVs[m_stick];
count = m_joystickPOVs[m_stick].m_count;
available = m_joystickPOVs[m_stick].m_available;
needToLog = false;
if (count != m_prevPOVs.m_count) {
if (available != m_prevPOVs.m_available) {
needToLog = true;
} else {
for (int i = 0; i < count; i++) {
for (int i = 0; i < m_prevPOVs.m_povs.length; i++) {
if (povs.m_povs[i] != m_prevPOVs.m_povs[i]) {
needToLog = true;
break;
@@ -335,32 +353,32 @@ public final class DriverStation {
}
void appendButtons(HALJoystickButtons buttons, long timestamp) {
byte count = buttons.m_count;
int count = availableToCount(buttons.m_available);
if (m_sizedButtons == null || m_sizedButtons.length != count) {
m_sizedButtons = new boolean[count];
}
int buttonsValue = buttons.m_buttons;
long buttonsValue = buttons.m_buttons;
for (int i = 0; i < count; i++) {
m_sizedButtons[i] = (buttonsValue & (1 << i)) != 0;
m_sizedButtons[i] = (buttonsValue & (1L << i)) != 0;
}
m_logButtons.append(m_sizedButtons, timestamp);
m_prevButtons.m_count = count;
m_prevButtons.m_available = buttons.m_available;
m_prevButtons.m_buttons = buttons.m_buttons;
}
void appendAxes(HALJoystickAxes axes, long timestamp) {
int count = axes.m_count;
int count = availableToCount(axes.m_available);
if (m_sizedAxes == null || m_sizedAxes.length != count) {
m_sizedAxes = new float[count];
}
System.arraycopy(axes.m_axes, 0, m_sizedAxes, 0, count);
m_logAxes.append(m_sizedAxes, timestamp);
m_prevAxes.m_count = count;
m_prevAxes.m_available = axes.m_available;
System.arraycopy(axes.m_axes, 0, m_prevAxes.m_axes, 0, count);
}
void appendPOVs(HALJoystickPOVs povs, long timestamp) {
int count = povs.m_count;
int count = availableToCount(povs.m_available);
if (m_sizedPOVs == null || m_sizedPOVs.length != count) {
m_sizedPOVs = new long[count];
}
@@ -368,7 +386,7 @@ public final class DriverStation {
m_sizedPOVs[i] = povs.m_povs[i];
}
m_logPOVs.append(m_sizedPOVs, timestamp);
m_prevPOVs.m_count = count;
m_prevPOVs.m_available = povs.m_available;
System.arraycopy(povs.m_povs, 0, m_prevPOVs.m_povs, 0, count);
}
@@ -476,11 +494,8 @@ public final class DriverStation {
private static ControlWord m_controlWordCache = new ControlWord();
// Joystick button rising/falling edge flags
private static int[] m_joystickButtonsPressed = new int[kJoystickPorts];
private static int[] m_joystickButtonsReleased = new int[kJoystickPorts];
// preallocated byte buffer for button count
private static final ByteBuffer m_buttonCountBuffer = ByteBuffer.allocateDirect(1);
private static long[] m_joystickButtonsPressed = new long[kJoystickPorts];
private static long[] m_joystickButtonsReleased = new long[kJoystickPorts];
private static final MatchDataSender m_matchDataSender;
private static DataLogSender m_dataLogSender;
@@ -595,25 +610,26 @@ public final class DriverStation {
}
/**
* The state of one joystick button. Button indexes begin at 1.
* The state of one joystick button.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @param button The button index.
* @return The state of the joystick button.
*/
public static boolean getStickButton(final int stick, final int button) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
if (button <= 0) {
reportJoystickUnpluggedError("Button indexes begin at 1 in WPILib for C++ and Java\n");
return false;
if (button < 0 || button >= DriverStationJNI.kMaxJoystickButtons) {
throw new IllegalArgumentException("Joystick Button is out of range");
}
long mask = 1L << button;
m_cacheDataMutex.lock();
try {
if (button <= m_joystickButtons[stick].m_count) {
return (m_joystickButtons[stick].m_buttons & 1 << (button - 1)) != 0;
if ((m_joystickButtons[stick].m_available & mask) != 0) {
return (m_joystickButtons[stick].m_buttons & mask) != 0;
}
} finally {
m_cacheDataMutex.unlock();
@@ -629,27 +645,56 @@ public final class DriverStation {
}
/**
* Whether one joystick button was pressed since the last check. Button indexes begin at 1.
* The state of one joystick button if available.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return Whether the joystick button was pressed since the last check.
* @param button The button index.
* @return The state of the joystick button, or false if the button is not available.
*/
public static boolean getStickButtonPressed(final int stick, final int button) {
if (button <= 0) {
reportJoystickUnpluggedError("Button indexes begin at 1 in WPILib for C++ and Java\n");
return false;
}
public static Optional<Boolean> getStickButtonIfAvailable(final int stick, final int button) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
if (button < 0 || button >= DriverStationJNI.kMaxJoystickButtons) {
throw new IllegalArgumentException("Joystick Button is out of range");
}
long mask = 1L << button;
m_cacheDataMutex.lock();
try {
if (button <= m_joystickButtons[stick].m_count) {
if ((m_joystickButtons[stick].m_available & mask) != 0) {
return Optional.of((m_joystickButtons[stick].m_buttons & mask) != 0);
}
} finally {
m_cacheDataMutex.unlock();
}
return Optional.empty();
}
/**
* Whether one joystick button was pressed since the last check.
*
* @param stick The joystick to read.
* @param button The button index.
* @return Whether the joystick button was pressed since the last check.
*/
public static boolean getStickButtonPressed(final int stick, final int button) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
if (button < 0 || button >= DriverStationJNI.kMaxJoystickButtons) {
throw new IllegalArgumentException("Joystick Button is out of range");
}
long mask = 1L << button;
m_cacheDataMutex.lock();
try {
if ((m_joystickButtons[stick].m_available & mask) != 0) {
// If button was pressed, clear flag and return true
if ((m_joystickButtonsPressed[stick] & 1 << (button - 1)) != 0) {
m_joystickButtonsPressed[stick] &= ~(1 << (button - 1));
if ((m_joystickButtonsPressed[stick] & mask) != 0) {
m_joystickButtonsPressed[stick] &= ~mask;
return true;
} else {
return false;
@@ -669,27 +714,28 @@ public final class DriverStation {
}
/**
* Whether one joystick button was released since the last check. Button indexes begin at 1.
* Whether one joystick button was released since the last check.
*
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @param button The button index, beginning at 0.
* @return Whether the joystick button was released since the last check.
*/
public static boolean getStickButtonReleased(final int stick, final int button) {
if (button <= 0) {
reportJoystickUnpluggedError("Button indexes begin at 1 in WPILib for C++ and Java\n");
return false;
}
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
if (button < 0 || button >= DriverStationJNI.kMaxJoystickButtons) {
throw new IllegalArgumentException("Joystick Button is out of range");
}
long mask = 1L << button;
m_cacheDataMutex.lock();
try {
if (button <= m_joystickButtons[stick].m_count) {
if ((m_joystickButtons[stick].m_available & mask) != 0) {
// If button was released, clear flag and return true
if ((m_joystickButtonsReleased[stick] & 1 << (button - 1)) != 0) {
m_joystickButtonsReleased[stick] &= ~(1 << (button - 1));
if ((m_joystickButtonsReleased[stick] & mask) != 0) {
m_joystickButtonsReleased[stick] &= ~mask;
return true;
} else {
return false;
@@ -724,9 +770,11 @@ public final class DriverStation {
throw new IllegalArgumentException("Joystick axis is out of range");
}
int mask = 1 << axis;
m_cacheDataMutex.lock();
try {
if (axis < m_joystickAxes[stick].m_count) {
if ((m_joystickAxes[stick].m_available & mask) != 0) {
return m_joystickAxes[stick].m_axes[axis];
}
} finally {
@@ -742,6 +790,36 @@ public final class DriverStation {
return 0.0;
}
/**
* Get the value of the axis on a joystick if available. This depends on the mapping of the
* joystick connected to the specified port.
*
* @param stick The joystick to read.
* @param axis The analog axis value to read from the joystick.
* @return The value of the axis on the joystick, or 0 if the axis is not available.
*/
public static OptionalDouble getStickAxisIfAvailable(int stick, int axis) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
if (axis < 0 || axis >= DriverStationJNI.kMaxJoystickAxes) {
throw new IllegalArgumentException("Joystick axis is out of range");
}
int mask = 1 << axis;
m_cacheDataMutex.lock();
try {
if ((m_joystickAxes[stick].m_available & mask) != 0) {
return OptionalDouble.of(m_joystickAxes[stick].m_axes[axis]);
}
} finally {
m_cacheDataMutex.unlock();
}
return OptionalDouble.empty();
}
/**
* Get the state of a POV on the joystick.
*
@@ -757,9 +835,11 @@ public final class DriverStation {
throw new IllegalArgumentException("Joystick POV is out of range");
}
int mask = 1 << pov;
m_cacheDataMutex.lock();
try {
if (pov < m_joystickPOVs[stick].m_count) {
if ((m_joystickPOVs[stick].m_available & mask) != 0) {
return POVDirection.of(m_joystickPOVs[stick].m_povs[pov]);
}
} finally {
@@ -781,7 +861,7 @@ public final class DriverStation {
* @param stick The joystick to read.
* @return The state of the buttons on the joystick.
*/
public static int getStickButtons(final int stick) {
public static long getStickButtons(final int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
@@ -795,57 +875,87 @@ public final class DriverStation {
}
/**
* Returns the number of axes on a given joystick port.
* Gets the maximum index of axes on a given joystick port.
*
* @param stick The joystick port number
* @return The number of axes on the indicated joystick
* @return The maximum index of axes on the indicated joystick
*/
public static int getStickAxisCount(int stick) {
public static int getStickAxesMaximumIndex(int stick) {
return availableToCount(getStickAxesAvailable(stick));
}
/**
* Returns the available bitmask of axes on a given joystick port.
*
* @param stick The joystick port number
* @return The number of axes available on the indicated joystick
*/
public static int getStickAxesAvailable(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
m_cacheDataMutex.lock();
try {
return m_joystickAxes[stick].m_count;
return m_joystickAxes[stick].m_available;
} finally {
m_cacheDataMutex.unlock();
}
}
/**
* Returns the number of povs on a given joystick port.
* Gets the maximum index of povs on a given joystick port.
*
* @param stick The joystick port number
* @return The number of povs on the indicated joystick
* @return The maximum index of povs on the indicated joystick
*/
public static int getStickPOVCount(int stick) {
public static int getStickPOVsMaximumIndex(int stick) {
return availableToCount(getStickPOVsAvailable(stick));
}
/**
* Returns the available bitmask of povs on a given joystick port.
*
* @param stick The joystick port number
* @return The number of povs available on the indicated joystick
*/
public static int getStickPOVsAvailable(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
m_cacheDataMutex.lock();
try {
return m_joystickPOVs[stick].m_count;
return m_joystickPOVs[stick].m_available;
} finally {
m_cacheDataMutex.unlock();
}
}
/**
* Gets the number of buttons on a joystick.
* Gets the maximum index of buttons on a given joystick port.
*
* @param stick The joystick port number
* @return The number of buttons on the indicated joystick
* @return The maximum index of buttons on the indicated joystick
*/
public static int getStickButtonCount(int stick) {
public static int getStickButtonsMaximumIndex(int stick) {
return availableToCount(getStickButtonsAvailable(stick));
}
/**
* Gets the bitmask of buttons available.
*
* @param stick The joystick port number
* @return The buttons available on the indicated joystick
*/
public static long getStickButtonsAvailable(int stick) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
m_cacheDataMutex.lock();
try {
return m_joystickButtons[stick].m_count;
return m_joystickButtons[stick].m_available;
} finally {
m_cacheDataMutex.unlock();
}
@@ -893,21 +1003,6 @@ public final class DriverStation {
return DriverStationJNI.getJoystickName((byte) stick);
}
/**
* Returns the types of Axes on a given joystick port.
*
* @param stick The joystick port number
* @param axis The target axis
* @return What type of axis the axis is reporting to be
*/
public static int getJoystickAxisType(int stick, int axis) {
if (stick < 0 || stick >= kJoystickPorts) {
throw new IllegalArgumentException("Joystick index is out of range, should be 0-5");
}
return DriverStationJNI.getJoystickAxisType((byte) stick, (byte) axis);
}
/**
* Returns if a joystick is connected to the Driver Station.
*
@@ -918,9 +1013,9 @@ public final class DriverStation {
* @return true if a joystick is connected
*/
public static boolean isJoystickConnected(int stick) {
return getStickAxisCount(stick) > 0
|| getStickButtonCount(stick) > 0
|| getStickPOVCount(stick) > 0;
return getStickAxesAvailable(stick) != 0
|| getStickButtonsAvailable(stick) != 0
|| getStickPOVsAvailable(stick) != 0;
}
/**
@@ -1284,15 +1379,17 @@ public final class DriverStation {
// Get the status of all the joysticks
for (byte stick = 0; stick < kJoystickPorts; stick++) {
m_joystickAxesCache[stick].m_count =
DriverStationJNI.getJoystickAxes(stick, m_joystickAxesCache[stick].m_axes);
m_joystickAxesRawCache[stick].m_count =
DriverStationJNI.getJoystickAxesRaw(stick, m_joystickAxesRawCache[stick].m_axes);
m_joystickPOVsCache[stick].m_count =
DriverStationJNI.getJoystickPOVs(stick, m_joystickPOVsCache[stick].m_povs);
m_joystickButtonsCache[stick].m_buttons =
DriverStationJNI.getJoystickButtons(stick, m_buttonCountBuffer);
m_joystickButtonsCache[stick].m_count = m_buttonCountBuffer.get(0);
DriverStationJNI.getAllJoystickData(
stick,
m_joystickAxesCache[stick].m_axes,
m_joystickAxesRawCache[stick].m_axes,
m_joystickPOVsCache[stick].m_povs,
m_metadataCache);
m_joystickAxesCache[stick].m_available = (int) m_metadataCache[0];
m_joystickAxesRawCache[stick].m_available = (int) m_metadataCache[0];
m_joystickPOVsCache[stick].m_available = (int) m_metadataCache[1];
m_joystickButtonsCache[stick].m_available = m_metadataCache[2];
m_joystickButtonsCache[stick].m_buttons = m_metadataCache[3];
}
DriverStationJNI.getMatchInfo(m_matchInfoCache);
@@ -1369,18 +1466,6 @@ public final class DriverStation {
m_refreshEvents.remove(handle);
}
/**
* Reports errors related to unplugged joysticks Throttles the errors so that they don't overwhelm
* the DS.
*/
private static void reportJoystickUnpluggedError(String message) {
double currentTime = Timer.getTimestamp();
if (currentTime > m_nextMessageTime) {
reportError(message, false);
m_nextMessageTime = currentTime + JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL;
}
}
/**
* Reports errors related to unplugged joysticks Throttles the errors so that they don't overwhelm
* the DS.

File diff suppressed because it is too large Load Diff

View File

@@ -136,7 +136,7 @@ public class GenericHID {
* time this method was called. This is useful if you only want to call a function once when you
* press the button.
*
* @param button The button index, beginning at 1.
* @param button The button index, beginning at 0.
* @return Whether the button was pressed since the last check.
*/
public boolean getRawButtonPressed(int button) {
@@ -150,7 +150,7 @@ public class GenericHID {
* time this method was called. This is useful if you only want to call a function once when you
* release the button.
*
* @param button The button index, beginning at 1.
* @param button The button index, beginning at 0.
* @return Whether the button was released since the last check.
*/
public boolean getRawButtonReleased(int button) {
@@ -364,13 +364,31 @@ public class GenericHID {
}
}
/**
* Get the maximum axis index for the joystick.
*
* @return the maximum axis index for the joystick
*/
public int getAxesMaximumIndex() {
return DriverStation.getStickAxesMaximumIndex(m_port);
}
/**
* Get the number of axes for the HID.
*
* @return the number of axis for the current HID
*/
public int getAxisCount() {
return DriverStation.getStickAxisCount(m_port);
public int getAxesAvailable() {
return DriverStation.getStickAxesAvailable(m_port);
}
/**
* Get the maximum POV index for the joystick.
*
* @return the maximum POV index for the joystick
*/
public int getPOVsMaximumIndex() {
return DriverStation.getStickPOVsMaximumIndex(m_port);
}
/**
@@ -378,8 +396,17 @@ public class GenericHID {
*
* @return the number of POVs for the current HID
*/
public int getPOVCount() {
return DriverStation.getStickPOVCount(m_port);
public int getPOVsAvailable() {
return DriverStation.getStickPOVsAvailable(m_port);
}
/**
* Get the maximum button index for the joystick.
*
* @return the maximum button index for the joystick
*/
public int getButtonsMaximumIndex() {
return DriverStation.getStickButtonsMaximumIndex(m_port);
}
/**
@@ -387,8 +414,8 @@ public class GenericHID {
*
* @return the number of buttons for the current HID
*/
public int getButtonCount() {
return DriverStation.getStickButtonCount(m_port);
public long getButtonsAvailable() {
return DriverStation.getStickButtonsAvailable(m_port);
}
/**
@@ -418,16 +445,6 @@ public class GenericHID {
return DriverStation.getJoystickName(m_port);
}
/**
* Get the axis type of the provided joystick axis.
*
* @param axis The axis to read, starting at 0.
* @return the axis type of the given joystick axis
*/
public int getAxisType(int axis) {
return DriverStation.getJoystickAxisType(m_port, axis);
}
/**
* Get the port number of the HID.
*

View File

@@ -338,10 +338,10 @@ public final class DriverStationSim {
}
/**
* Sets the state of one joystick button. Button indexes begin at 1.
* Sets the state of one joystick button. Button indexes begin at 0.
*
* @param stick The joystick number
* @param button The button index, beginning at 1
* @param button The button index, beginning at 0
* @param state The state of the joystick button
*/
public static void setJoystickButton(int stick, int button, boolean state) {
@@ -371,13 +371,13 @@ public final class DriverStationSim {
}
/**
* Sets the state of all the buttons on a joystick.
* Sets the maximum index that an axis is available at.
*
* @param stick The joystick number
* @param buttons The bitmap state of the buttons on the joystick
* @param maximumIndex The maximum index an axis is available at.
*/
public static void setJoystickButtons(int stick, int buttons) {
DriverStationDataJNI.setJoystickButtonsValue(stick, buttons);
public static void setJoystickAxesMaximumIndex(int stick, int maximumIndex) {
setJoystickAxesAvailable(stick, (1 << maximumIndex) - 1);
}
/**
@@ -386,8 +386,18 @@ public final class DriverStationSim {
* @param stick The joystick number
* @param count The number of axes on the indicated joystick
*/
public static void setJoystickAxisCount(int stick, int count) {
DriverStationDataJNI.setJoystickAxisCount(stick, count);
public static void setJoystickAxesAvailable(int stick, int count) {
DriverStationDataJNI.setJoystickAxesAvailable(stick, count);
}
/**
* Sets the maximum index that a pov is available at.
*
* @param stick The joystick number
* @param maximumIndex The maximum index a pov is available at.
*/
public static void setJoystickPOVsMaximumIndex(int stick, int maximumIndex) {
setJoystickPOVsAvailable(stick, (1 << maximumIndex) - 1);
}
/**
@@ -396,8 +406,22 @@ public final class DriverStationSim {
* @param stick The joystick number
* @param count The number of POVs on the indicated joystick
*/
public static void setJoystickPOVCount(int stick, int count) {
DriverStationDataJNI.setJoystickPOVCount(stick, count);
public static void setJoystickPOVsAvailable(int stick, int count) {
DriverStationDataJNI.setJoystickPOVsAvailable(stick, count);
}
/**
* Sets the maximum index that a button is available at.
*
* @param stick The joystick number
* @param maximumIndex The maximum index a button is available at.
*/
public static void setJoystickButtonsMaximumIndex(int stick, int maximumIndex) {
if (maximumIndex >= 64) {
setJoystickButtonsAvailable(stick, 0xFFFFFFFFFFFFFFFFL);
} else {
setJoystickButtonsAvailable(stick, (1L << maximumIndex) - 1);
}
}
/**
@@ -406,8 +430,8 @@ public final class DriverStationSim {
* @param stick The joystick number
* @param count The number of buttons on the indicated joystick
*/
public static void setJoystickButtonCount(int stick, int count) {
DriverStationDataJNI.setJoystickButtonCount(stick, count);
public static void setJoystickButtonsAvailable(int stick, long count) {
DriverStationDataJNI.setJoystickButtonsAvailable(stick, count);
}
/**
@@ -440,17 +464,6 @@ public final class DriverStationSim {
DriverStationDataJNI.setJoystickName(stick, name);
}
/**
* Sets the types of Axes for a joystick.
*
* @param stick The joystick number
* @param axis The target axis
* @param type The type of axis
*/
public static void setJoystickAxisType(int stick, int axis, int type) {
DriverStationDataJNI.setJoystickAxisType(stick, axis, type);
}
/**
* Sets the game specific message.
*

View File

@@ -0,0 +1,324 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.wpilibj.simulation;
import edu.wpi.first.wpilibj.Gamepad;
/** Class to control a simulated Gamepad controller. */
public class GamepadSim extends GenericHIDSim {
/**
* Constructs from a Gamepad object.
*
* @param joystick controller to simulate
*/
@SuppressWarnings("this-escape")
public GamepadSim(Gamepad joystick) {
super(joystick);
setAxesMaximumIndex(6);
setButtonsMaximumIndex(26);
setPOVsMaximumIndex(1);
}
/**
* Constructs from a joystick port number.
*
* @param port port number
*/
@SuppressWarnings("this-escape")
public GamepadSim(int port) {
super(port);
setAxesMaximumIndex(6);
setButtonsMaximumIndex(26);
setPOVsMaximumIndex(1);
}
/**
* Change the left X value of the controller's joystick.
*
* @param value the new value
*/
public void setLeftX(double value) {
setRawAxis(Gamepad.Axis.kLeftX.value, value);
}
/**
* Change the left Y value of the controller's joystick.
*
* @param value the new value
*/
public void setLeftY(double value) {
setRawAxis(Gamepad.Axis.kLeftY.value, value);
}
/**
* Change the right X value of the controller's joystick.
*
* @param value the new value
*/
public void setRightX(double value) {
setRawAxis(Gamepad.Axis.kRightX.value, value);
}
/**
* Change the right Y value of the controller's joystick.
*
* @param value the new value
*/
public void setRightY(double value) {
setRawAxis(Gamepad.Axis.kRightY.value, value);
}
/**
* Change the value of the left trigger axis on the controller.
*
* @param value the new value
*/
public void setLeftTriggerAxis(double value) {
setRawAxis(Gamepad.Axis.kLeftTrigger.value, value);
}
/**
* Change the value of the right trigger axis on the controller.
*
* @param value the new value
*/
public void setRightTriggerAxis(double value) {
setRawAxis(Gamepad.Axis.kRightTrigger.value, value);
}
/**
* Change the value of the South Face button on the controller.
*
* @param value the new value
*/
public void setSouthFaceButton(boolean value) {
setRawButton(Gamepad.Button.kSouthFace.value, value);
}
/**
* Change the value of the East Face button on the controller.
*
* @param value the new value
*/
public void setEastFaceButton(boolean value) {
setRawButton(Gamepad.Button.kEastFace.value, value);
}
/**
* Change the value of the West Face button on the controller.
*
* @param value the new value
*/
public void setWestFaceButton(boolean value) {
setRawButton(Gamepad.Button.kWestFace.value, value);
}
/**
* Change the value of the North Face button on the controller.
*
* @param value the new value
*/
public void setNorthFacenButton(boolean value) {
setRawButton(Gamepad.Button.kNorthFacen.value, value);
}
/**
* Change the value of the Back button on the controller.
*
* @param value the new value
*/
public void setBackButton(boolean value) {
setRawButton(Gamepad.Button.kBack.value, value);
}
/**
* Change the value of the Guide button on the controller.
*
* @param value the new value
*/
public void setGuideButton(boolean value) {
setRawButton(Gamepad.Button.kGuide.value, value);
}
/**
* Change the value of the Start button on the controller.
*
* @param value the new value
*/
public void setStartButton(boolean value) {
setRawButton(Gamepad.Button.kStart.value, value);
}
/**
* Change the value of the left stick button on the controller.
*
* @param value the new value
*/
public void setLeftStickButton(boolean value) {
setRawButton(Gamepad.Button.kLeftStick.value, value);
}
/**
* Change the value of the right stick button on the controller.
*
* @param value the new value
*/
public void setRightStickButton(boolean value) {
setRawButton(Gamepad.Button.kRightStick.value, value);
}
/**
* Change the value of the right shoulder button on the controller.
*
* @param value the new value
*/
public void setLeftShoulderButton(boolean value) {
setRawButton(Gamepad.Button.kLeftShoulder.value, value);
}
/**
* Change the value of the right shoulder button on the controller.
*
* @param value the new value
*/
public void setRightShoulderButton(boolean value) {
setRawButton(Gamepad.Button.kRightShoulder.value, value);
}
/**
* Change the value of the D-pad up button on the controller.
*
* @param value the new value
*/
public void setDpadUpButton(boolean value) {
setRawButton(Gamepad.Button.kDpadUp.value, value);
}
/**
* Change the value of the D-pad down button on the controller.
*
* @param value the new value
*/
public void setDpadDownButton(boolean value) {
setRawButton(Gamepad.Button.kDpadDown.value, value);
}
/**
* Change the value of the D-pad left button on the controller.
*
* @param value the new value
*/
public void setDpadLeftButton(boolean value) {
setRawButton(Gamepad.Button.kDpadLeft.value, value);
}
/**
* Change the value of the D-pad right button on the controller.
*
* @param value the new value
*/
public void setDpadRightButton(boolean value) {
setRawButton(Gamepad.Button.kDpadRight.value, value);
}
/**
* Change the value of the Miscellaneous 1 button on the controller.
*
* @param value the new value
*/
public void setMisc1Button(boolean value) {
setRawButton(Gamepad.Button.kMisc1.value, value);
}
/**
* Change the value of the Right Paddle 1 button on the controller.
*
* @param value the new value
*/
public void setRightPaddle1Button(boolean value) {
setRawButton(Gamepad.Button.kRightPaddle1.value, value);
}
/**
* Change the value of the Left Paddle 1 button on the controller.
*
* @param value the new value
*/
public void setLeftPaddle1Button(boolean value) {
setRawButton(Gamepad.Button.kLeftPaddle1.value, value);
}
/**
* Change the value of the Right Paddle 2 button on the controller.
*
* @param value the new value
*/
public void setRightPaddle2Button(boolean value) {
setRawButton(Gamepad.Button.kRightPaddle2.value, value);
}
/**
* Change the value of the Left Paddle 2 button on the controller.
*
* @param value the new value
*/
public void setLeftPaddle2Button(boolean value) {
setRawButton(Gamepad.Button.kLeftPaddle2.value, value);
}
/**
* Change the value of the Touchpad button on the controller.
*
* @param value the new value
*/
public void setTouchpadButton(boolean value) {
setRawButton(Gamepad.Button.kTouchpad.value, value);
}
/**
* Change the value of the Miscellaneous 2 button on the controller.
*
* @param value the new value
*/
public void setMisc2Button(boolean value) {
setRawButton(Gamepad.Button.kMisc2.value, value);
}
/**
* Change the value of the Miscellaneous 3 button on the controller.
*
* @param value the new value
*/
public void setMisc3Button(boolean value) {
setRawButton(Gamepad.Button.kMisc3.value, value);
}
/**
* Change the value of the Miscellaneous 4 button on the controller.
*
* @param value the new value
*/
public void setMisc4Button(boolean value) {
setRawButton(Gamepad.Button.kMisc4.value, value);
}
/**
* Change the value of the Miscellaneous 5 button on the controller.
*
* @param value the new value
*/
public void setMisc5Button(boolean value) {
setRawButton(Gamepad.Button.kMisc5.value, value);
}
/**
* Change the value of the Miscellaneous 6 button on the controller.
*
* @param value the new value
*/
public void setMisc6Button(boolean value) {
setRawButton(Gamepad.Button.kMisc6.value, value);
}
}

View File

@@ -74,13 +74,31 @@ public class GenericHIDSim {
setPOV(0, value);
}
/**
* Set the maximum axis index for this device.
*
* @param maximumIndex the new maximum axis index
*/
public void setAxesMaximumIndex(int maximumIndex) {
DriverStationSim.setJoystickAxesMaximumIndex(m_port, maximumIndex);
}
/**
* Set the axis count of this device.
*
* @param count the new axis count
*/
public void setAxisCount(int count) {
DriverStationSim.setJoystickAxisCount(m_port, count);
public void setAxesAvailable(int count) {
DriverStationSim.setJoystickAxesAvailable(m_port, count);
}
/**
* Set the maximum POV index for this device.
*
* @param maximumIndex the new maximum POV index
*/
public void setPOVsMaximumIndex(int maximumIndex) {
DriverStationSim.setJoystickPOVsMaximumIndex(m_port, maximumIndex);
}
/**
@@ -88,8 +106,17 @@ public class GenericHIDSim {
*
* @param count the new POV count
*/
public void setPOVCount(int count) {
DriverStationSim.setJoystickPOVCount(m_port, count);
public void setPOVsAvailable(int count) {
DriverStationSim.setJoystickPOVsAvailable(m_port, count);
}
/**
* Set the maximum button index for this device.
*
* @param maximumIndex the new maximum button index
*/
public void setButtonsMaximumIndex(int maximumIndex) {
DriverStationSim.setJoystickButtonsMaximumIndex(m_port, maximumIndex);
}
/**
@@ -97,8 +124,8 @@ public class GenericHIDSim {
*
* @param count the new button count
*/
public void setButtonCount(int count) {
DriverStationSim.setJoystickButtonCount(m_port, count);
public void setButtonsAvailable(long count) {
DriverStationSim.setJoystickButtonsAvailable(m_port, count);
}
/**
@@ -119,16 +146,6 @@ public class GenericHIDSim {
DriverStationSim.setJoystickName(m_port, name);
}
/**
* Set the type of the provided axis channel.
*
* @param axis the axis
* @param type the type
*/
public void setAxisType(int axis, int type) {
DriverStationSim.setJoystickAxisType(m_port, axis, type);
}
/**
* Read the output of a button.
*

View File

@@ -20,9 +20,9 @@ public class JoystickSim extends GenericHIDSim {
super(joystick);
m_joystick = joystick;
// default to a reasonable joystick configuration
setAxisCount(5);
setButtonCount(12);
setPOVCount(1);
setAxesMaximumIndex(5);
setButtonsMaximumIndex(12);
setPOVsMaximumIndex(1);
}
/**
@@ -34,9 +34,9 @@ public class JoystickSim extends GenericHIDSim {
public JoystickSim(int port) {
super(port);
// default to a reasonable joystick configuration
setAxisCount(5);
setButtonCount(12);
setPOVCount(1);
setAxesMaximumIndex(5);
setButtonsMaximumIndex(12);
setPOVsMaximumIndex(1);
}
/**

View File

@@ -17,9 +17,9 @@ class DriverStationTest {
@ParameterizedTest
@MethodSource("isConnectedProvider")
void testIsConnected(int axisCount, int buttonCount, int povCount, boolean expected) {
DriverStationSim.setJoystickAxisCount(1, axisCount);
DriverStationSim.setJoystickButtonCount(1, buttonCount);
DriverStationSim.setJoystickPOVCount(1, povCount);
DriverStationSim.setJoystickAxesMaximumIndex(1, axisCount);
DriverStationSim.setJoystickButtonsMaximumIndex(1, buttonCount);
DriverStationSim.setJoystickPOVsMaximumIndex(1, povCount);
DriverStationSim.notifyNewData();