mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-22 01:11:42 +00:00
[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:
@@ -2,6 +2,8 @@
|
||||
// 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 <utility>
|
||||
|
||||
#include "wpi/hal/proto/ControlData.h"
|
||||
#include "wpi/util/protobuf/ProtobufCallbacks.hpp"
|
||||
|
||||
@@ -85,7 +87,7 @@ std::optional<mrc::ControlData> wpi::util::Protobuf<mrc::ControlData>::Unpack(
|
||||
ControlData.SetJoystickCount(Joysticks.size());
|
||||
|
||||
for (size_t i = 0; i < ControlData.GetJoystickCount(); i++) {
|
||||
ControlData.Joysticks()[i] = Joysticks[i];
|
||||
ControlData.Joysticks()[i] = std::move(Joysticks[i]);
|
||||
}
|
||||
|
||||
return ControlData;
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
// 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 <string>
|
||||
#include <utility>
|
||||
|
||||
#include "wpi/hal/proto/JoystickDescriptor.h"
|
||||
#include "wpi/util/protobuf/ProtobufCallbacks.hpp"
|
||||
|
||||
std::optional<mrc::JoystickDescriptor>
|
||||
wpi::util::Protobuf<mrc::JoystickDescriptor>::Unpack(InputStream& Stream) {
|
||||
wpi::util::UnpackCallback<std::string> JoystickNameCb;
|
||||
wpi::util::UnpackCallback<uint8_t, MRC_MAX_NUM_AXES> AxisTypesCb;
|
||||
|
||||
mrc_proto_ProtobufJoystickDescriptor Msg;
|
||||
Msg.JoystickName = JoystickNameCb.Callback();
|
||||
Msg.AxisTypes = AxisTypesCb.Callback();
|
||||
|
||||
if (!Stream.Decode(Msg)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto JoystickName = JoystickNameCb.Items();
|
||||
auto AxisTypes = AxisTypesCb.Items();
|
||||
|
||||
if (JoystickName.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
mrc::JoystickDescriptor OutputData;
|
||||
OutputData.MoveName(std::move(JoystickName[0]));
|
||||
|
||||
OutputData.SetAxesCount(AxisTypes.size());
|
||||
|
||||
for (size_t i = 0; i < OutputData.GetAxesCount(); i++) {
|
||||
OutputData.AxesTypes()[i] = AxisTypes[i];
|
||||
}
|
||||
|
||||
OutputData.SetPovsCount(Msg.PovCount);
|
||||
OutputData.SetButtonsCount(Msg.ButtonCount);
|
||||
|
||||
OutputData.IsGamepad = Msg.IsGamepad ? 1 : 0;
|
||||
OutputData.Type = Msg.JoystickType;
|
||||
OutputData.RumbleCount = Msg.RumbleCount;
|
||||
|
||||
return OutputData;
|
||||
}
|
||||
|
||||
bool wpi::util::Protobuf<mrc::JoystickDescriptor>::Pack(
|
||||
OutputStream& Stream, const mrc::JoystickDescriptor& Value) {
|
||||
std::string_view JoystickName = Value.GetName();
|
||||
wpi::util::PackCallback JoystickNameCb{&JoystickName};
|
||||
|
||||
std::span<const uint8_t> AxisTypes = Value.AxesTypes();
|
||||
wpi::util::PackCallback AxisTypesCb{AxisTypes};
|
||||
|
||||
mrc_proto_ProtobufJoystickDescriptor Msg{
|
||||
.JoystickName = JoystickNameCb.Callback(),
|
||||
.AxisTypes = AxisTypesCb.Callback(),
|
||||
.IsGamepad = Value.IsGamepad ? true : false,
|
||||
.JoystickType = Value.Type,
|
||||
.ButtonCount = static_cast<int32_t>(Value.GetButtonsCount()),
|
||||
.PovCount = static_cast<int32_t>(Value.GetPovsCount()),
|
||||
.RumbleCount = Value.RumbleCount,
|
||||
};
|
||||
|
||||
return Stream.Encode(Msg);
|
||||
}
|
||||
84
hal/src/main/native/cpp/proto/JoystickDescriptorsProto.cpp
Normal file
84
hal/src/main/native/cpp/proto/JoystickDescriptorsProto.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
// 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 <string>
|
||||
#include <utility>
|
||||
|
||||
#include "wpi/hal/proto/JoystickDescriptors.h"
|
||||
#include "wpi/util/protobuf/ProtobufCallbacks.hpp"
|
||||
|
||||
std::optional<mrc::JoystickDescriptors>
|
||||
wpi::util::Protobuf<mrc::JoystickDescriptors>::Unpack(InputStream& Stream) {
|
||||
wpi::util::UnpackCallback<mrc::JoystickDescriptor, MRC_MAX_NUM_JOYSTICKS>
|
||||
JoystickDescriptorsCb;
|
||||
|
||||
mrc_proto_ProtobufJoystickDescriptors Msg;
|
||||
Msg.Descriptors = JoystickDescriptorsCb.Callback();
|
||||
|
||||
if (!Stream.Decode(Msg)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto Descriptors = JoystickDescriptorsCb.Items();
|
||||
|
||||
mrc::JoystickDescriptors OutputData;
|
||||
OutputData.SetDescriptorCount(Descriptors.size());
|
||||
for (size_t i = 0; i < OutputData.GetDescriptorCount(); i++) {
|
||||
OutputData.Descriptors()[i] = std::move(Descriptors[i]);
|
||||
}
|
||||
|
||||
return OutputData;
|
||||
}
|
||||
|
||||
bool wpi::util::Protobuf<mrc::JoystickDescriptors>::Pack(
|
||||
OutputStream& Stream, const mrc::JoystickDescriptors& Value) {
|
||||
std::span<const mrc::JoystickDescriptor> Descriptors = Value.Descriptors();
|
||||
wpi::util::PackCallback JoystickDescriptorsCb{Descriptors};
|
||||
|
||||
mrc_proto_ProtobufJoystickDescriptors Msg{
|
||||
.Descriptors = JoystickDescriptorsCb.Callback(),
|
||||
};
|
||||
|
||||
return Stream.Encode(Msg);
|
||||
}
|
||||
|
||||
std::optional<mrc::JoystickDescriptor>
|
||||
wpi::util::Protobuf<mrc::JoystickDescriptor>::Unpack(InputStream& Stream) {
|
||||
wpi::util::UnpackCallback<std::string> JoystickNameCb;
|
||||
|
||||
mrc_proto_ProtobufJoystickDescriptor Msg;
|
||||
Msg.JoystickName = JoystickNameCb.Callback();
|
||||
|
||||
if (!Stream.Decode(Msg)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto JoystickName = JoystickNameCb.Items();
|
||||
|
||||
mrc::JoystickDescriptor OutputData;
|
||||
if (!JoystickName.empty()) {
|
||||
OutputData.MoveName(std::move(JoystickName[0]));
|
||||
}
|
||||
|
||||
OutputData.IsGamepad = Msg.IsGamepad ? 1 : 0;
|
||||
OutputData.GamepadType = Msg.GamepadType;
|
||||
OutputData.SupportedOutputs = Msg.SupportedOutputs;
|
||||
|
||||
return OutputData;
|
||||
}
|
||||
|
||||
bool wpi::util::Protobuf<mrc::JoystickDescriptor>::Pack(
|
||||
OutputStream& Stream, const mrc::JoystickDescriptor& Value) {
|
||||
std::string_view JoystickName = Value.GetName();
|
||||
wpi::util::PackCallback JoystickNameCb{&JoystickName};
|
||||
|
||||
mrc_proto_ProtobufJoystickDescriptor Msg{
|
||||
.JoystickName = JoystickNameCb.Callback(),
|
||||
.IsGamepad = Value.IsGamepad ? true : false,
|
||||
.GamepadType = Value.GamepadType,
|
||||
.SupportedOutputs = Value.SupportedOutputs,
|
||||
};
|
||||
|
||||
return Stream.Encode(Msg);
|
||||
}
|
||||
79
hal/src/main/native/cpp/proto/JoystickOutputDataProto.cpp
Normal file
79
hal/src/main/native/cpp/proto/JoystickOutputDataProto.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
// 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 <string>
|
||||
#include <utility>
|
||||
|
||||
#include "wpi/hal/proto/JoystickOutput.h"
|
||||
#include "wpi/util/protobuf/ProtobufCallbacks.hpp"
|
||||
|
||||
std::optional<mrc::JoystickOutputs>
|
||||
wpi::util::Protobuf<mrc::JoystickOutputs>::Unpack(InputStream& Stream) {
|
||||
wpi::util::UnpackCallback<mrc::JoystickOutput, MRC_MAX_NUM_JOYSTICKS>
|
||||
JoystickOutputsCb;
|
||||
|
||||
mrc_proto_ProtobufJoystickOutputs Msg;
|
||||
Msg.Outputs = JoystickOutputsCb.Callback();
|
||||
|
||||
if (!Stream.Decode(Msg)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto Outputs = JoystickOutputsCb.Items();
|
||||
|
||||
mrc::JoystickOutputs OutputData;
|
||||
OutputData.SetOutputCount(Outputs.size());
|
||||
for (size_t i = 0; i < OutputData.GetOutputCount(); i++) {
|
||||
OutputData.Outputs()[i] = std::move(Outputs[i]);
|
||||
}
|
||||
|
||||
return OutputData;
|
||||
}
|
||||
|
||||
bool wpi::util::Protobuf<mrc::JoystickOutputs>::Pack(
|
||||
OutputStream& Stream, const mrc::JoystickOutputs& Value) {
|
||||
std::span<const mrc::JoystickOutput> Outputs = Value.Outputs();
|
||||
wpi::util::PackCallback JoystickOutputsCb{Outputs};
|
||||
|
||||
mrc_proto_ProtobufJoystickOutputs Msg{
|
||||
.Outputs = JoystickOutputsCb.Callback(),
|
||||
};
|
||||
|
||||
return Stream.Encode(Msg);
|
||||
}
|
||||
|
||||
std::optional<mrc::JoystickOutput>
|
||||
wpi::util::Protobuf<mrc::JoystickOutput>::Unpack(InputStream& Stream) {
|
||||
mrc_proto_ProtobufJoystickOutput Msg;
|
||||
|
||||
if (!Stream.Decode(Msg)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return mrc::JoystickOutput{
|
||||
.R = static_cast<uint8_t>((Msg.LEDs >> 16) & 0xFF),
|
||||
.G = static_cast<uint8_t>((Msg.LEDs >> 8) & 0xFF),
|
||||
.B = static_cast<uint8_t>(Msg.LEDs & 0xFF),
|
||||
.LeftRumble = static_cast<uint16_t>((Msg.Rumble >> 16) & 0xFFFF),
|
||||
.RightRumble = static_cast<uint16_t>(Msg.Rumble & 0xFFFF),
|
||||
.LeftTriggerRumble =
|
||||
static_cast<uint16_t>((Msg.TriggerRumble >> 16) & 0xFFFF),
|
||||
.RightTriggerRumble = static_cast<uint16_t>(Msg.TriggerRumble & 0xFFFF),
|
||||
};
|
||||
}
|
||||
|
||||
bool wpi::util::Protobuf<mrc::JoystickOutput>::Pack(
|
||||
OutputStream& Stream, const mrc::JoystickOutput& Value) {
|
||||
mrc_proto_ProtobufJoystickOutput Msg{
|
||||
.LEDs = (static_cast<uint32_t>(Value.R) << 16) |
|
||||
(static_cast<uint32_t>(Value.G) << 8) |
|
||||
static_cast<uint32_t>(Value.B),
|
||||
.Rumble = (static_cast<uint32_t>(Value.LeftRumble) << 16) |
|
||||
static_cast<uint32_t>(Value.RightRumble),
|
||||
.TriggerRumble = (static_cast<uint32_t>(Value.LeftTriggerRumble) << 16) |
|
||||
static_cast<uint32_t>(Value.RightTriggerRumble),
|
||||
};
|
||||
|
||||
return Stream.Encode(Msg);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// 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 "wpi/hal/proto/JoystickRumbleData.h"
|
||||
#include "wpi/util/protobuf/ProtobufCallbacks.hpp"
|
||||
|
||||
std::optional<mrc::JoystickRumbleData>
|
||||
wpi::util::Protobuf<mrc::JoystickRumbleData>::Unpack(InputStream& Stream) {
|
||||
wpi::util::UnpackCallback<uint16_t, MRC_MAX_NUM_RUMBLE> RumbleCb;
|
||||
|
||||
mrc_proto_ProtobufJoystickRumbleData Msg{
|
||||
.Value = RumbleCb.Callback(),
|
||||
};
|
||||
|
||||
if (!Stream.Decode(Msg)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto Rumbles = RumbleCb.Items();
|
||||
|
||||
mrc::JoystickRumbleData Rumble;
|
||||
Rumble.SetCount(Rumbles.size());
|
||||
|
||||
for (size_t i = 0; i < Rumble.GetCount(); i++) {
|
||||
Rumble.Rumbles()[i] = Rumbles[i];
|
||||
}
|
||||
|
||||
return Rumble;
|
||||
}
|
||||
|
||||
bool wpi::util::Protobuf<mrc::JoystickRumbleData>::Pack(
|
||||
OutputStream& Stream, const mrc::JoystickRumbleData& Value) {
|
||||
wpi::util::PackCallback RumbleCb{Value.Rumbles()};
|
||||
|
||||
mrc_proto_ProtobufJoystickRumbleData Msg{
|
||||
.Value = RumbleCb.Callback(),
|
||||
};
|
||||
|
||||
return Stream.Encode(Msg);
|
||||
}
|
||||
Reference in New Issue
Block a user