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

Support joystick outputs, including Rumble and LEDs.

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

View File

@@ -36,14 +36,22 @@ void DriverStationData::ResetData() {
m_joystickAxesCallbacks.Reset();
m_joystickPOVsCallbacks.Reset();
m_joystickButtonsCallbacks.Reset();
m_joystickOutputsCallbacks.Reset();
m_joystickLedsCallbacks.Reset();
m_joystickRumblesCallbacks.Reset();
m_joystickDescriptorCallbacks.Reset();
for (int i = 0; i < kNumJoysticks; i++) {
m_joystickData[i].axes = HAL_JoystickAxes{};
m_joystickData[i].povs = HAL_JoystickPOVs{};
m_joystickData[i].buttons = HAL_JoystickButtons{};
m_joystickData[i].descriptor = HAL_JoystickDescriptor{};
m_joystickData[i].descriptor.type = -1;
m_joystickData[i].outputs.leds = 0;
m_joystickData[i].outputs.leftRumble = 0;
m_joystickData[i].outputs.rightRumble = 0;
m_joystickData[i].outputs.leftTriggerRumble = 0;
m_joystickData[i].outputs.rightTriggerRumble = 0;
m_joystickData[i].descriptor.gamepadType = 0;
m_joystickData[i].descriptor.isGamepad = 0;
m_joystickData[i].descriptor.supportedOutputs = 0;
m_joystickData[i].descriptor.name[0] = '\0';
}
}
@@ -121,50 +129,96 @@ void DriverStationData::SetJoystickDescriptor(
m_joystickDescriptorCallbacks(joystickNum, descriptor);
}
int32_t DriverStationData::RegisterJoystickOutputsCallback(
int32_t joystickNum, HAL_JoystickOutputsCallback callback, void* param,
int32_t DriverStationData::RegisterJoystickLedsCallback(
int32_t joystickNum, HAL_JoystickLedsCallback callback, void* param,
HAL_Bool initialNotify) {
if (joystickNum < 0 || joystickNum >= DriverStationData::kNumJoysticks) {
return 0;
}
std::scoped_lock lock(m_joystickDataMutex);
int32_t uid = m_joystickOutputsCallbacks.Register(callback, param);
int32_t uid = m_joystickLedsCallbacks.Register(callback, param);
if (initialNotify) {
const auto& outputs = m_joystickData[joystickNum].outputs;
callback(DriverStationData::GetJoystickOutputsName(), param, joystickNum,
outputs.outputs, outputs.leftRumble, outputs.rightRumble);
callback(DriverStationData::GetJoystickLedsName(), param, joystickNum,
outputs.leds);
}
return uid;
}
void DriverStationData::CancelJoystickOutputsCallback(int32_t uid) {
m_joystickOutputsCallbacks.Cancel(uid);
void DriverStationData::CancelJoystickLedsCallback(int32_t uid) {
m_joystickLedsCallbacks.Cancel(uid);
}
void DriverStationData::GetJoystickOutputs(int32_t joystickNum,
int64_t* outputs,
void DriverStationData::GetJoystickLeds(int32_t joystickNum, int32_t* leds) {
if (joystickNum < 0 || joystickNum >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
*leds = m_joystickData[joystickNum].outputs.leds;
}
void DriverStationData::SetJoystickLeds(int32_t joystickNum, int32_t leds) {
if (joystickNum < 0 || joystickNum >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
m_joystickData[joystickNum].outputs.leds = leds;
m_joystickLedsCallbacks(joystickNum, leds);
}
int32_t DriverStationData::RegisterJoystickRumblesCallback(
int32_t joystickNum, HAL_JoystickRumblesCallback callback, void* param,
HAL_Bool initialNotify) {
if (joystickNum < 0 || joystickNum >= DriverStationData::kNumJoysticks) {
return 0;
}
std::scoped_lock lock(m_joystickDataMutex);
int32_t uid = m_joystickRumblesCallbacks.Register(callback, param);
if (initialNotify) {
const auto& outputs = m_joystickData[joystickNum].outputs;
callback(DriverStationData::GetJoystickRumblesName(), param, joystickNum,
outputs.leftRumble, outputs.rightRumble, outputs.leftTriggerRumble,
outputs.rightTriggerRumble);
}
return uid;
}
void DriverStationData::CancelJoystickRumblesCallback(int32_t uid) {
m_joystickRumblesCallbacks.Cancel(uid);
}
void DriverStationData::GetJoystickRumbles(int32_t joystickNum,
int32_t* leftRumble,
int32_t* rightRumble) {
int32_t* rightRumble,
int32_t* leftTriggerRumble,
int32_t* rightTriggerRumble) {
if (joystickNum < 0 || joystickNum >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
*leftRumble = m_joystickData[joystickNum].outputs.leftRumble;
*outputs = m_joystickData[joystickNum].outputs.outputs;
*rightRumble = m_joystickData[joystickNum].outputs.rightRumble;
const auto& outputs = m_joystickData[joystickNum].outputs;
*leftRumble = outputs.leftRumble;
*rightRumble = outputs.rightRumble;
*leftTriggerRumble = outputs.leftTriggerRumble;
*rightTriggerRumble = outputs.rightTriggerRumble;
}
void DriverStationData::SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
void DriverStationData::SetJoystickRumbles(int32_t joystickNum,
int32_t leftRumble,
int32_t rightRumble) {
int32_t rightRumble,
int32_t leftTriggerRumble,
int32_t rightTriggerRumble) {
if (joystickNum < 0 || joystickNum >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
m_joystickData[joystickNum].outputs.leftRumble = leftRumble;
m_joystickData[joystickNum].outputs.outputs = outputs;
m_joystickData[joystickNum].outputs.rightRumble = rightRumble;
m_joystickOutputsCallbacks(joystickNum, outputs, leftRumble, rightRumble);
auto& outputs = m_joystickData[joystickNum].outputs;
outputs.leftRumble = leftRumble;
outputs.rightRumble = rightRumble;
outputs.leftTriggerRumble = leftTriggerRumble;
outputs.rightTriggerRumble = rightTriggerRumble;
m_joystickRumblesCallbacks(joystickNum, leftRumble, rightRumble,
leftTriggerRumble, rightTriggerRumble);
}
int32_t DriverStationData::RegisterMatchInfoCallback(
@@ -328,12 +382,22 @@ void DriverStationData::SetJoystickIsGamepad(int32_t stick,
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
void DriverStationData::SetJoystickType(int32_t stick, int32_t type) {
void DriverStationData::SetJoystickGamepadType(int32_t stick, int32_t type) {
if (stick < 0 || stick >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
m_joystickData[stick].descriptor.type = type;
m_joystickData[stick].descriptor.gamepadType = type;
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
void DriverStationData::SetJoystickSupportedOutputs(int32_t stick,
int32_t supportedOutputs) {
if (stick < 0 || stick >= kNumJoysticks) {
return;
}
std::scoped_lock lock(m_joystickDataMutex);
m_joystickData[stick].descriptor.supportedOutputs = supportedOutputs;
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
@@ -428,27 +492,51 @@ DEFINE_CAPI(POVs, povs)
DEFINE_CAPI(Buttons, buttons)
DEFINE_CAPI(Descriptor, descriptor)
int32_t HALSIM_RegisterJoystickOutputsCallback(
int32_t joystickNum, HAL_JoystickOutputsCallback callback, void* param,
HAL_Bool initialNotify) {
return SimDriverStationData->RegisterJoystickOutputsCallback(
int32_t HALSIM_RegisterJoystickLedsCallback(int32_t joystickNum,
HAL_JoystickLedsCallback callback,
void* param,
HAL_Bool initialNotify) {
return SimDriverStationData->RegisterJoystickLedsCallback(
joystickNum, callback, param, initialNotify);
}
void HALSIM_CancelJoystickOutputsCallback(int32_t uid) {
SimDriverStationData->CancelJoystickOutputsCallback(uid);
void HALSIM_CancelJoystickLedsCallback(int32_t uid) {
SimDriverStationData->CancelJoystickLedsCallback(uid);
}
void HALSIM_GetJoystickOutputs(int32_t joystickNum, int64_t* outputs,
int32_t* leftRumble, int32_t* rightRumble) {
SimDriverStationData->GetJoystickOutputs(joystickNum, outputs, leftRumble,
rightRumble);
void HALSIM_GetJoystickLeds(int32_t joystickNum, int32_t* leds) {
SimDriverStationData->GetJoystickLeds(joystickNum, leds);
}
void HALSIM_SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble) {
SimDriverStationData->SetJoystickOutputs(joystickNum, outputs, leftRumble,
rightRumble);
void HALSIM_SetJoystickLeds(int32_t joystickNum, int32_t leds) {
SimDriverStationData->SetJoystickLeds(joystickNum, leds);
}
int32_t HALSIM_RegisterJoystickRumblesCallback(
int32_t joystickNum, HAL_JoystickRumblesCallback callback, void* param,
HAL_Bool initialNotify) {
return SimDriverStationData->RegisterJoystickRumblesCallback(
joystickNum, callback, param, initialNotify);
}
void HALSIM_CancelJoystickRumblesCallback(int32_t uid) {
SimDriverStationData->CancelJoystickRumblesCallback(uid);
}
void HALSIM_GetJoystickRumbles(int32_t joystickNum, int32_t* leftRumble,
int32_t* rightRumble, int32_t* leftTriggerRumble,
int32_t* rightTriggerRumble) {
SimDriverStationData->GetJoystickRumbles(joystickNum, leftRumble, rightRumble,
leftTriggerRumble,
rightTriggerRumble);
}
void HALSIM_SetJoystickRumbles(int32_t joystickNum, int32_t leftRumble,
int32_t rightRumble, int32_t leftTriggerRumble,
int32_t rightTriggerRumble) {
SimDriverStationData->SetJoystickRumbles(joystickNum, leftRumble, rightRumble,
leftTriggerRumble,
rightTriggerRumble);
}
int32_t HALSIM_RegisterMatchInfoCallback(HAL_MatchInfoCallback callback,
@@ -523,8 +611,13 @@ void HALSIM_SetJoystickIsGamepad(int32_t stick, HAL_Bool isGamepad) {
SimDriverStationData->SetJoystickIsGamepad(stick, isGamepad);
}
void HALSIM_SetJoystickType(int32_t stick, int32_t type) {
SimDriverStationData->SetJoystickType(stick, type);
void HALSIM_SetJoystickGamepadType(int32_t stick, int32_t type) {
SimDriverStationData->SetJoystickGamepadType(stick, type);
}
void HALSIM_SetJoystickSupportedOutputs(int32_t stick,
int32_t supportedOutputs) {
SimDriverStationData->SetJoystickSupportedOutputs(stick, supportedOutputs);
}
void HALSIM_SetJoystickName(int32_t stick, const WPI_String* name) {

View File

@@ -26,7 +26,8 @@ class DriverStationData {
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickPOVs)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickButtons)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickDescriptor)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickOutputs)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickLeds)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickRumbles)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(MatchInfo)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(NewData)
@@ -70,14 +71,22 @@ class DriverStationData {
void SetJoystickDescriptor(int32_t joystickNum,
const HAL_JoystickDescriptor* descriptor);
int32_t RegisterJoystickOutputsCallback(int32_t joystickNum,
HAL_JoystickOutputsCallback callback,
int32_t RegisterJoystickLedsCallback(int32_t joystickNum,
HAL_JoystickLedsCallback callback,
void* param, HAL_Bool initialNotify);
void CancelJoystickLedsCallback(int32_t uid);
void GetJoystickLeds(int32_t joystickNum, int32_t* leds);
void SetJoystickLeds(int32_t joystickNum, int32_t leds);
int32_t RegisterJoystickRumblesCallback(int32_t joystickNum,
HAL_JoystickRumblesCallback callback,
void* param, HAL_Bool initialNotify);
void CancelJoystickOutputsCallback(int32_t uid);
void GetJoystickOutputs(int32_t joystickNum, int64_t* outputs,
int32_t* leftRumble, int32_t* rightRumble);
void SetJoystickOutputs(int32_t joystickNum, int64_t outputs,
int32_t leftRumble, int32_t rightRumble);
void CancelJoystickRumblesCallback(int32_t uid);
void GetJoystickRumbles(int32_t joystickNum, int32_t* leftRumble,
int32_t* rightRumble, int32_t* leftTriggerRumble,
int32_t* rightTriggerRumble);
void SetJoystickRumbles(int32_t joystickNum, int32_t leftRumble,
int32_t rightRumble, int32_t leftTriggerRumble,
int32_t rightTriggerRumble);
int32_t RegisterMatchInfoCallback(HAL_MatchInfoCallback callback, void* param,
HAL_Bool initialNotify);
@@ -106,8 +115,9 @@ class DriverStationData {
uint8_t* povsAvailable);
void SetJoystickIsGamepad(int32_t stick, HAL_Bool isGamepad);
void SetJoystickType(int32_t stick, int32_t type);
void SetJoystickGamepadType(int32_t stick, int32_t type);
void SetJoystickName(int32_t stick, std::string_view message);
void SetJoystickSupportedOutputs(int32_t stick, int32_t supportedOutputs);
void SetGameSpecificMessage(std::string_view message);
void SetEventName(std::string_view name);
@@ -134,8 +144,10 @@ class DriverStationData {
m_joystickPOVsCallbacks;
SimCallbackRegistry<HAL_JoystickButtonsCallback, GetJoystickButtonsName>
m_joystickButtonsCallbacks;
SimCallbackRegistry<HAL_JoystickOutputsCallback, GetJoystickOutputsName>
m_joystickOutputsCallbacks;
SimCallbackRegistry<HAL_JoystickLedsCallback, GetJoystickLedsName>
m_joystickLedsCallbacks;
SimCallbackRegistry<HAL_JoystickRumblesCallback, GetJoystickRumblesName>
m_joystickRumblesCallbacks;
SimCallbackRegistry<HAL_JoystickDescriptorCallback, GetJoystickDescriptorName>
m_joystickDescriptorCallbacks;
SimCallbackRegistry<HAL_MatchInfoCallback, GetMatchInfoName>
@@ -143,9 +155,11 @@ class DriverStationData {
SimCallbackRegistry<HAL_NotifyCallback, GetNewDataName> m_newDataCallbacks;
struct JoystickOutputStore {
int64_t outputs = 0;
int32_t leds = 0;
int32_t leftRumble = 0;
int32_t rightRumble = 0;
int32_t leftTriggerRumble = 0;
int32_t rightTriggerRumble = 0;
};
struct JoystickData {