mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-30 02:31:44 +00:00
[sim] Add WebSocket extension (client/server) (#2589)
This allows access to HAL-level simulation data via a WebSocket connection. The server additionally serves local files. The following environment variables can be used for configuration: HALSIMWS_USERROOT (server) - local directory to use for file serving for /user/ URIs, defaults to ./sim/user HALSIMWS_SYSROOT (server) - local directory to use for file serving for all other URIs, defaults to ./sim HALSIMWS_URI (client or server) - WebSocket URI, defaults to /wpilibws HALSIMWS_PORT (client or server) - port number, defaults to 8080 HALSIMWS_HOST (client) - host to connect to, defaults to localhost Co-authored-by: Zhiquan Yeo <zyeo8@bloomberg.net> Co-authored-by: Peter Johnson <johnson.peter@gmail.com> Co-authored-by: jpokornyiii <jpokornyiii@gmail.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSBaseProvider.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
HALSimWSBaseProvider::HALSimWSBaseProvider(const std::string& key,
|
||||
const std::string& type)
|
||||
: m_key(key), m_type(type) {}
|
||||
|
||||
void HALSimWSBaseProvider::OnNetValueChanged(const wpi::json& json) {
|
||||
// empty
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,40 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSHalProvider::OnNetworkConnected(
|
||||
std::shared_ptr<HALSimBaseWebSocketConnection> ws) {
|
||||
{
|
||||
// store a weak reference to the websocket object
|
||||
m_ws = ws;
|
||||
}
|
||||
|
||||
RegisterCallbacks();
|
||||
}
|
||||
|
||||
void HALSimWSHalProvider::OnNetworkDisconnected() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSHalProvider::ProcessHalCallback(const wpi::json& payload) {
|
||||
auto ws = m_ws.lock();
|
||||
if (ws) {
|
||||
wpi::json netValue = {
|
||||
{"type", m_type}, {"device", m_deviceId}, {"data", payload}};
|
||||
ws->OnSimValueChanged(netValue);
|
||||
}
|
||||
}
|
||||
|
||||
HALSimWSHalChanProvider::HALSimWSHalChanProvider(int32_t channel,
|
||||
const std::string& key,
|
||||
const std::string& type)
|
||||
: HALSimWSHalProvider(key, type), m_channel(channel) {
|
||||
m_deviceId = std::to_string(channel);
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,128 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_Analog.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/AnalogInData.h>
|
||||
#include <hal/simulation/AnalogOutData.h>
|
||||
|
||||
#define REGISTER_AIN(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterAnalogIn##halsim##Callback( \
|
||||
m_channel, \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderAnalogIn*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
#define REGISTER_AIN_ACCUM(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterAnalogInAccumulator##halsim##Callback( \
|
||||
m_channel, \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderAnalogIn*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
#define REGISTER_AOUT(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterAnalogOut##halsim##Callback( \
|
||||
m_channel, \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderAnalogOut*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSProviderAnalogIn::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateProviders<HALSimWSProviderAnalogIn>("AI", HAL_GetNumAnalogInputs(),
|
||||
webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderAnalogIn::~HALSimWSProviderAnalogIn() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderAnalogIn::RegisterCallbacks() {
|
||||
m_initCbKey = REGISTER_AIN(Initialized, "<init", bool, boolean);
|
||||
m_avgbitsCbKey = REGISTER_AIN(AverageBits, "<avg_bits", int32_t, int);
|
||||
m_oversampleCbKey =
|
||||
REGISTER_AIN(OversampleBits, "<oversample_bits", int32_t, int);
|
||||
m_voltageCbKey = REGISTER_AIN(Voltage, ">voltage", double, double);
|
||||
|
||||
m_accumInitCbKey =
|
||||
REGISTER_AIN_ACCUM(Initialized, "<accum_init", bool, boolean);
|
||||
m_accumValueCbKey = REGISTER_AIN_ACCUM(Value, ">accum_value", int64_t,
|
||||
long); // NOLINT(runtime/int)
|
||||
m_accumCountCbKey = REGISTER_AIN_ACCUM(Count, ">accum_count", int64_t,
|
||||
long); // NOLINT(runtime/int)
|
||||
m_accumCenterCbKey =
|
||||
REGISTER_AIN_ACCUM(Center, "<accum_center", int32_t, int);
|
||||
m_accumDeadbandCbKey =
|
||||
REGISTER_AIN_ACCUM(Deadband, "<accum_deadband", int32_t, int);
|
||||
}
|
||||
|
||||
void HALSimWSProviderAnalogIn::CancelCallbacks() {
|
||||
// Cancel callbacks
|
||||
HALSIM_CancelAnalogInInitializedCallback(m_channel, m_initCbKey);
|
||||
HALSIM_CancelAnalogInAverageBitsCallback(m_channel, m_avgbitsCbKey);
|
||||
HALSIM_CancelAnalogInOversampleBitsCallback(m_channel, m_oversampleCbKey);
|
||||
HALSIM_CancelAnalogInVoltageCallback(m_channel, m_voltageCbKey);
|
||||
HALSIM_CancelAnalogInAccumulatorInitializedCallback(m_channel,
|
||||
m_accumInitCbKey);
|
||||
HALSIM_CancelAnalogInAccumulatorValueCallback(m_channel, m_accumValueCbKey);
|
||||
HALSIM_CancelAnalogInAccumulatorCountCallback(m_channel, m_accumCountCbKey);
|
||||
HALSIM_CancelAnalogInAccumulatorCenterCallback(m_channel, m_accumCenterCbKey);
|
||||
HALSIM_CancelAnalogInAccumulatorDeadbandCallback(m_channel,
|
||||
m_accumDeadbandCbKey);
|
||||
|
||||
// Reset callback IDs
|
||||
m_initCbKey = 0;
|
||||
m_avgbitsCbKey = 0;
|
||||
m_oversampleCbKey = 0;
|
||||
m_voltageCbKey = 0;
|
||||
m_accumInitCbKey = 0;
|
||||
m_accumValueCbKey = 0;
|
||||
m_accumCountCbKey = 0;
|
||||
m_accumCenterCbKey = 0;
|
||||
m_accumDeadbandCbKey = 0;
|
||||
}
|
||||
|
||||
void HALSimWSProviderAnalogIn::OnNetValueChanged(const wpi::json& json) {
|
||||
wpi::json::const_iterator it;
|
||||
if ((it = json.find(">voltage")) != json.end()) {
|
||||
HALSIM_SetAnalogInVoltage(m_channel, it.value());
|
||||
}
|
||||
if ((it = json.find(">accum_value")) != json.end()) {
|
||||
HALSIM_SetAnalogInAccumulatorValue(m_channel, it.value());
|
||||
}
|
||||
if ((it = json.find(">accum_count")) != json.end()) {
|
||||
HALSIM_SetAnalogInAccumulatorCount(m_channel, it.value());
|
||||
}
|
||||
}
|
||||
|
||||
void HALSimWSProviderAnalogOut::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateProviders<HALSimWSProviderAnalogOut>("AO", HAL_GetNumAnalogOutputs(),
|
||||
webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderAnalogOut::~HALSimWSProviderAnalogOut() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderAnalogOut::RegisterCallbacks() {
|
||||
m_initCbKey = REGISTER_AOUT(Initialized, "<init", bool, boolean);
|
||||
m_voltageCbKey = REGISTER_AOUT(Voltage, "<voltage", double, double);
|
||||
}
|
||||
|
||||
void HALSimWSProviderAnalogOut::CancelCallbacks() {
|
||||
HALSIM_CancelAnalogOutInitializedCallback(m_channel, m_initCbKey);
|
||||
HALSIM_CancelAnalogOutVoltageCallback(m_channel, m_voltageCbKey);
|
||||
|
||||
m_initCbKey = 0;
|
||||
m_voltageCbKey = 0;
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,57 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_DIO.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/DIOData.h>
|
||||
|
||||
#define REGISTER(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterDIO##halsim##Callback( \
|
||||
m_channel, \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderDIO*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSProviderDIO::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateProviders<HALSimWSProviderDIO>("DIO", HAL_GetNumDigitalChannels(),
|
||||
webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderDIO::~HALSimWSProviderDIO() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderDIO::RegisterCallbacks() {
|
||||
m_initCbKey = REGISTER(Initialized, "<init", bool, boolean);
|
||||
m_valueCbKey = REGISTER(Value, "<>value", bool, boolean);
|
||||
m_pulseLengthCbKey = REGISTER(PulseLength, "<pulse_length", double, double);
|
||||
m_inputCbKey = REGISTER(IsInput, "<input", bool, boolean);
|
||||
}
|
||||
|
||||
void HALSimWSProviderDIO::CancelCallbacks() {
|
||||
HALSIM_CancelDIOInitializedCallback(m_channel, m_initCbKey);
|
||||
HALSIM_CancelDIOValueCallback(m_channel, m_valueCbKey);
|
||||
HALSIM_CancelDIOPulseLengthCallback(m_channel, m_pulseLengthCbKey);
|
||||
HALSIM_CancelDIOIsInputCallback(m_channel, m_inputCbKey);
|
||||
|
||||
m_initCbKey = 0;
|
||||
m_valueCbKey = 0;
|
||||
m_pulseLengthCbKey = 0;
|
||||
m_inputCbKey = 0;
|
||||
}
|
||||
|
||||
void HALSimWSProviderDIO::OnNetValueChanged(const wpi::json& json) {
|
||||
wpi::json::const_iterator it;
|
||||
if ((it = json.find("<>value")) != json.end()) {
|
||||
HALSIM_SetDIOValue(m_channel, static_cast<bool>(it.value()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,150 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_DriverStation.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <hal/DriverStation.h>
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/DriverStationData.h>
|
||||
#include <wpi/raw_ostream.h>
|
||||
|
||||
#define REGISTER(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterDriverStation##halsim##Callback( \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderDriverStation*>(param) \
|
||||
->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSProviderDriverStation::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateSingleProvider<HALSimWSProviderDriverStation>("DriverStation",
|
||||
webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderDriverStation::~HALSimWSProviderDriverStation() {
|
||||
CancelCallbacks();
|
||||
}
|
||||
|
||||
void HALSimWSProviderDriverStation::RegisterCallbacks() {
|
||||
m_enabledCbKey = REGISTER(Enabled, ">enabled", bool, boolean);
|
||||
m_autonomousCbKey = REGISTER(Autonomous, ">autonomous", bool, boolean);
|
||||
m_testCbKey = REGISTER(Test, ">test", bool, boolean);
|
||||
m_estopCbKey = REGISTER(EStop, ">estop", bool, boolean);
|
||||
m_fmsCbKey = REGISTER(FmsAttached, ">fms", bool, boolean);
|
||||
m_dsCbKey = REGISTER(DsAttached, ">ds", bool, boolean);
|
||||
|
||||
// Special case for new data, since the HAL_Value is empty
|
||||
m_newDataCbKey = HALSIM_RegisterDriverStationNewDataCallback(
|
||||
[](const char* name, void* param, const struct HAL_Value* value) {
|
||||
static_cast<HALSimWSProviderDriverStation*>(param)->ProcessHalCallback(
|
||||
{{">new_data", true}});
|
||||
},
|
||||
this, true);
|
||||
|
||||
m_allianceCbKey = HALSIM_RegisterDriverStationAllianceStationIdCallback(
|
||||
[](const char* name, void* param, const struct HAL_Value* value) {
|
||||
std::string station;
|
||||
switch (static_cast<HAL_AllianceStationID>(value->data.v_enum)) {
|
||||
case HAL_AllianceStationID_kRed1:
|
||||
station = "red1";
|
||||
break;
|
||||
case HAL_AllianceStationID_kBlue1:
|
||||
station = "blue1";
|
||||
break;
|
||||
case HAL_AllianceStationID_kRed2:
|
||||
station = "red2";
|
||||
break;
|
||||
case HAL_AllianceStationID_kBlue2:
|
||||
station = "blue2";
|
||||
break;
|
||||
case HAL_AllianceStationID_kRed3:
|
||||
station = "red3";
|
||||
break;
|
||||
case HAL_AllianceStationID_kBlue3:
|
||||
station = "blue3";
|
||||
break;
|
||||
}
|
||||
static_cast<HALSimWSProviderDriverStation*>(param)->ProcessHalCallback(
|
||||
{{">station", station}});
|
||||
},
|
||||
this, true);
|
||||
|
||||
m_matchTimeCbKey = REGISTER(MatchTime, "<match_time", double, double);
|
||||
}
|
||||
|
||||
void HALSimWSProviderDriverStation::CancelCallbacks() {
|
||||
HALSIM_CancelDriverStationEnabledCallback(m_enabledCbKey);
|
||||
HALSIM_CancelDriverStationAutonomousCallback(m_autonomousCbKey);
|
||||
HALSIM_CancelDriverStationTestCallback(m_testCbKey);
|
||||
HALSIM_CancelDriverStationEStopCallback(m_estopCbKey);
|
||||
HALSIM_CancelDriverStationFmsAttachedCallback(m_fmsCbKey);
|
||||
HALSIM_CancelDriverStationDsAttachedCallback(m_dsCbKey);
|
||||
HALSIM_CancelDriverStationNewDataCallback(m_newDataCbKey);
|
||||
HALSIM_CancelDriverStationAllianceStationIdCallback(m_allianceCbKey);
|
||||
HALSIM_CancelDriverStationMatchTimeCallback(m_matchTimeCbKey);
|
||||
|
||||
m_enabledCbKey = 0;
|
||||
m_autonomousCbKey = 0;
|
||||
m_testCbKey = 0;
|
||||
m_estopCbKey = 0;
|
||||
m_fmsCbKey = 0;
|
||||
m_dsCbKey = 0;
|
||||
m_newDataCbKey = 0;
|
||||
m_allianceCbKey = 0;
|
||||
m_matchTimeCbKey = 0;
|
||||
}
|
||||
|
||||
void HALSimWSProviderDriverStation::OnNetValueChanged(const wpi::json& json) {
|
||||
wpi::json::const_iterator it;
|
||||
if ((it = json.find(">enabled")) != json.end()) {
|
||||
HALSIM_SetDriverStationEnabled(it.value());
|
||||
}
|
||||
if ((it = json.find(">autonomous")) != json.end()) {
|
||||
HALSIM_SetDriverStationAutonomous(it.value());
|
||||
}
|
||||
if ((it = json.find(">test")) != json.end()) {
|
||||
HALSIM_SetDriverStationTest(it.value());
|
||||
}
|
||||
if ((it = json.find(">estop")) != json.end()) {
|
||||
HALSIM_SetDriverStationEStop(it.value());
|
||||
}
|
||||
if ((it = json.find(">fms")) != json.end()) {
|
||||
HALSIM_SetDriverStationFmsAttached(it.value());
|
||||
}
|
||||
if ((it = json.find(">ds")) != json.end()) {
|
||||
HALSIM_SetDriverStationDsAttached(it.value());
|
||||
}
|
||||
|
||||
if ((it = json.find(">station")) != json.end()) {
|
||||
auto& station = it.value().get_ref<const std::string&>();
|
||||
if (station == "red1") {
|
||||
HALSIM_SetDriverStationAllianceStationId(HAL_AllianceStationID_kRed1);
|
||||
} else if (station == "red2") {
|
||||
HALSIM_SetDriverStationAllianceStationId(HAL_AllianceStationID_kRed2);
|
||||
} else if (station == "red3") {
|
||||
HALSIM_SetDriverStationAllianceStationId(HAL_AllianceStationID_kRed3);
|
||||
} else if (station == "blue1") {
|
||||
HALSIM_SetDriverStationAllianceStationId(HAL_AllianceStationID_kBlue1);
|
||||
} else if (station == "blue2") {
|
||||
HALSIM_SetDriverStationAllianceStationId(HAL_AllianceStationID_kBlue2);
|
||||
} else if (station == "blue3") {
|
||||
HALSIM_SetDriverStationAllianceStationId(HAL_AllianceStationID_kBlue3);
|
||||
}
|
||||
}
|
||||
|
||||
// Only notify usercode if we get the new data message
|
||||
if ((it = json.find(">new_data")) != json.end()) {
|
||||
HALSIM_NotifyDriverStationNewData();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,87 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_Encoder.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/EncoderData.h>
|
||||
|
||||
#define REGISTER(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterEncoder##halsim##Callback( \
|
||||
m_channel, \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderEncoder*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSProviderEncoder::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateProviders<HALSimWSProviderEncoder>("Encoder", HAL_GetNumEncoders(),
|
||||
webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderEncoder::~HALSimWSProviderEncoder() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderEncoder::RegisterCallbacks() {
|
||||
// Special case for initialization since we will need to send
|
||||
// the digital channels down the line as well
|
||||
m_initCbKey = HALSIM_RegisterEncoderInitializedCallback(
|
||||
m_channel,
|
||||
[](const char* name, void* param, const struct HAL_Value* value) {
|
||||
auto provider = static_cast<HALSimWSProviderEncoder*>(param);
|
||||
bool init = static_cast<bool>(value->data.v_boolean);
|
||||
|
||||
wpi::json payload = {{"<init", init}};
|
||||
|
||||
if (init) {
|
||||
payload["<channel_a"] =
|
||||
HALSIM_GetEncoderDigitalChannelA(provider->GetChannel());
|
||||
payload["<channel_b"] =
|
||||
HALSIM_GetEncoderDigitalChannelB(provider->GetChannel());
|
||||
}
|
||||
|
||||
provider->ProcessHalCallback(payload);
|
||||
},
|
||||
this, true);
|
||||
m_countCbKey = REGISTER(Count, ">count", int32_t, int);
|
||||
m_periodCbKey = REGISTER(Period, ">period", double, double);
|
||||
m_resetCbKey = REGISTER(Reset, "<reset", bool, boolean);
|
||||
m_reverseDirectionCbKey =
|
||||
REGISTER(ReverseDirection, "<reverse_direction", bool, boolean);
|
||||
m_samplesCbKey = REGISTER(SamplesToAverage, "<samples_to_avg", int32_t, int);
|
||||
}
|
||||
|
||||
void HALSimWSProviderEncoder::CancelCallbacks() {
|
||||
HALSIM_CancelEncoderInitializedCallback(m_channel, m_initCbKey);
|
||||
HALSIM_CancelEncoderCountCallback(m_channel, m_countCbKey);
|
||||
HALSIM_CancelEncoderPeriodCallback(m_channel, m_periodCbKey);
|
||||
HALSIM_CancelEncoderResetCallback(m_channel, m_resetCbKey);
|
||||
HALSIM_CancelEncoderReverseDirectionCallback(m_channel,
|
||||
m_reverseDirectionCbKey);
|
||||
HALSIM_CancelEncoderSamplesToAverageCallback(m_channel, m_samplesCbKey);
|
||||
|
||||
m_initCbKey = 0;
|
||||
m_countCbKey = 0;
|
||||
m_periodCbKey = 0;
|
||||
m_resetCbKey = 0;
|
||||
m_reverseDirectionCbKey = 0;
|
||||
m_samplesCbKey = 0;
|
||||
}
|
||||
|
||||
void HALSimWSProviderEncoder::OnNetValueChanged(const wpi::json& json) {
|
||||
wpi::json::const_iterator it;
|
||||
if ((it = json.find(">count")) != json.end()) {
|
||||
HALSIM_SetEncoderCount(m_channel, it.value());
|
||||
}
|
||||
if ((it = json.find(">period")) != json.end()) {
|
||||
HALSIM_SetEncoderPeriod(m_channel, it.value());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,110 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_Joystick.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/DriverStationData.h>
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSProviderJoystick::Initialize(WSRegisterFunc webregisterFunc) {
|
||||
CreateProviders<HALSimWSProviderJoystick>("Joystick", HAL_kMaxJoysticks,
|
||||
webregisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderJoystick::~HALSimWSProviderJoystick() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderJoystick::RegisterCallbacks() {
|
||||
m_dsNewDataCbKey = HALSIM_RegisterDriverStationNewDataCallback(
|
||||
[](const char* name, void* param, const struct HAL_Value* value) {
|
||||
auto provider = static_cast<HALSimWSProviderJoystick*>(param);
|
||||
|
||||
// Grab all joystick data and send it at once
|
||||
wpi::json payload;
|
||||
|
||||
// Axes data
|
||||
HAL_JoystickAxes axes{};
|
||||
std::vector<double> axesValues;
|
||||
HALSIM_GetJoystickAxes(provider->GetChannel(), &axes);
|
||||
|
||||
for (int i = 0; i < axes.count; i++) {
|
||||
axesValues.push_back(axes.axes[i]);
|
||||
}
|
||||
|
||||
// POVs data
|
||||
HAL_JoystickPOVs povs{};
|
||||
std::vector<int16_t> povsValues;
|
||||
HALSIM_GetJoystickPOVs(provider->GetChannel(), &povs);
|
||||
|
||||
for (int i = 0; i < povs.count; i++) {
|
||||
povsValues.push_back(povs.povs[i]);
|
||||
}
|
||||
|
||||
// Button data
|
||||
HAL_JoystickButtons buttons{};
|
||||
std::vector<bool> buttonsValues;
|
||||
|
||||
for (int i = 0; i < buttons.count; i++) {
|
||||
buttonsValues.push_back(((buttons.buttons >> i) & 0x1) == 1);
|
||||
}
|
||||
|
||||
payload[">axes"] = axesValues;
|
||||
payload[">povs"] = povsValues;
|
||||
payload[">buttons"] = buttonsValues;
|
||||
|
||||
provider->ProcessHalCallback(payload);
|
||||
},
|
||||
this, true);
|
||||
}
|
||||
|
||||
void HALSimWSProviderJoystick::CancelCallbacks() {
|
||||
HALSIM_CancelDriverStationNewDataCallback(m_dsNewDataCbKey);
|
||||
|
||||
m_dsNewDataCbKey = 0;
|
||||
}
|
||||
|
||||
void HALSimWSProviderJoystick::OnNetValueChanged(const wpi::json& json) {
|
||||
wpi::json::const_iterator it;
|
||||
if ((it = json.find(">axes")) != json.end()) {
|
||||
HAL_JoystickAxes axes{};
|
||||
axes.count =
|
||||
std::min(it.value().size(), (wpi::json::size_type)HAL_kMaxJoystickAxes);
|
||||
for (int i = 0; i < axes.count; i++) {
|
||||
axes.axes[i] = it.value()[i];
|
||||
}
|
||||
|
||||
HALSIM_SetJoystickAxes(m_channel, &axes);
|
||||
}
|
||||
|
||||
if ((it = json.find(">buttons")) != json.end()) {
|
||||
HAL_JoystickButtons buttons{};
|
||||
buttons.count = std::min(it.value().size(), (wpi::json::size_type)32);
|
||||
for (int i = 0; i < buttons.count; i++) {
|
||||
if (it.value()[i]) {
|
||||
buttons.buttons |= 1 << (i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
HALSIM_SetJoystickButtons(m_channel, &buttons);
|
||||
}
|
||||
|
||||
if ((it = json.find(">povs")) != json.end()) {
|
||||
HAL_JoystickPOVs povs{};
|
||||
povs.count =
|
||||
std::min(it.value().size(), (wpi::json::size_type)HAL_kMaxJoystickPOVs);
|
||||
for (int i = 0; i < povs.count; i++) {
|
||||
povs.povs[i] = it.value()[i];
|
||||
}
|
||||
|
||||
HALSIM_SetJoystickPOVs(m_channel, &povs);
|
||||
}
|
||||
// We won't send any updates to user code until the new data message
|
||||
// is received by the driver station provider
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,55 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_PWM.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/PWMData.h>
|
||||
|
||||
#define REGISTER(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterPWM##halsim##Callback( \
|
||||
m_channel, \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderPWM*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSProviderPWM::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateProviders<HALSimWSProviderPWM>("PWM", HAL_GetNumPWMChannels(),
|
||||
webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderPWM::~HALSimWSProviderPWM() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderPWM::RegisterCallbacks() {
|
||||
m_initCbKey = REGISTER(Initialized, "<init", bool, boolean);
|
||||
m_speedCbKey = REGISTER(Speed, "<speed", double, double);
|
||||
m_positionCbKey = REGISTER(Position, "<position", double, double);
|
||||
m_rawCbKey = REGISTER(RawValue, "<raw", int32_t, int);
|
||||
m_periodScaleCbKey = REGISTER(PeriodScale, "<period_scale", int32_t, int);
|
||||
m_zeroLatchCbKey = REGISTER(ZeroLatch, "<zero_latch", bool, boolean);
|
||||
}
|
||||
|
||||
void HALSimWSProviderPWM::CancelCallbacks() {
|
||||
HALSIM_CancelPWMInitializedCallback(m_channel, m_initCbKey);
|
||||
HALSIM_CancelPWMSpeedCallback(m_channel, m_speedCbKey);
|
||||
HALSIM_CancelPWMPositionCallback(m_channel, m_positionCbKey);
|
||||
HALSIM_CancelPWMRawValueCallback(m_channel, m_rawCbKey);
|
||||
HALSIM_CancelPWMPeriodScaleCallback(m_channel, m_periodScaleCbKey);
|
||||
HALSIM_CancelPWMZeroLatchCallback(m_channel, m_zeroLatchCbKey);
|
||||
|
||||
m_initCbKey = 0;
|
||||
m_speedCbKey = 0;
|
||||
m_positionCbKey = 0;
|
||||
m_rawCbKey = 0;
|
||||
m_periodScaleCbKey = 0;
|
||||
m_zeroLatchCbKey = 0;
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,49 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_Relay.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/RelayData.h>
|
||||
|
||||
#define REGISTER(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterRelay##halsim##Callback( \
|
||||
m_channel, \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderRelay*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
namespace wpilibws {
|
||||
void HALSimWSProviderRelay::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateProviders<HALSimWSProviderRelay>("Relay", HAL_GetNumRelayHeaders(),
|
||||
webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderRelay::~HALSimWSProviderRelay() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderRelay::RegisterCallbacks() {
|
||||
m_initFwdCbKey = REGISTER(InitializedForward, "<init_fwd", bool, boolean);
|
||||
m_initRevCbKey = REGISTER(InitializedReverse, "<init_rev", bool, boolean);
|
||||
m_fwdCbKey = REGISTER(Forward, "<fwd", bool, boolean);
|
||||
m_revCbKey = REGISTER(Reverse, "<rev", bool, boolean);
|
||||
}
|
||||
|
||||
void HALSimWSProviderRelay::CancelCallbacks() {
|
||||
HALSIM_CancelRelayInitializedForwardCallback(m_channel, m_initFwdCbKey);
|
||||
HALSIM_CancelRelayInitializedReverseCallback(m_channel, m_initRevCbKey);
|
||||
HALSIM_CancelRelayForwardCallback(m_channel, m_fwdCbKey);
|
||||
HALSIM_CancelRelayReverseCallback(m_channel, m_revCbKey);
|
||||
|
||||
m_initFwdCbKey = 0;
|
||||
m_initRevCbKey = 0;
|
||||
m_fwdCbKey = 0;
|
||||
m_revCbKey = 0;
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,140 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_RoboRIO.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/RoboRioData.h>
|
||||
|
||||
#define REGISTER(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterRoboRio##halsim##Callback( \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderRoboRIO*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSProviderRoboRIO::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateSingleProvider<HALSimWSProviderRoboRIO>("RoboRIO", webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderRoboRIO::~HALSimWSProviderRoboRIO() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderRoboRIO::RegisterCallbacks() {
|
||||
m_fpgaCbKey = REGISTER(FPGAButton, ">fpga_button", bool, boolean);
|
||||
m_vinVoltageCbKey = REGISTER(VInVoltage, ">vin_voltage", double, double);
|
||||
m_vinCurrentCbKey = REGISTER(VInCurrent, ">vin_current", double, double);
|
||||
|
||||
m_6vVoltageCbKey = REGISTER(UserVoltage6V, ">6v_voltage", double, double);
|
||||
m_6vCurrentCbKey = REGISTER(UserCurrent6V, ">6v_current", double, double);
|
||||
m_6vActiveCbKey = REGISTER(UserActive6V, ">6v_active", bool, boolean);
|
||||
m_6vFaultsCbKey = REGISTER(UserFaults6V, ">6v_faults", int32_t, int);
|
||||
|
||||
m_5vVoltageCbKey = REGISTER(UserVoltage5V, ">5v_voltage", double, double);
|
||||
m_5vCurrentCbKey = REGISTER(UserCurrent5V, ">5v_current", double, double);
|
||||
m_5vActiveCbKey = REGISTER(UserActive5V, ">5v_active", bool, boolean);
|
||||
m_5vFaultsCbKey = REGISTER(UserFaults5V, ">5v_faults", int32_t, int);
|
||||
|
||||
m_3v3VoltageCbKey = REGISTER(UserVoltage3V3, ">3v3_voltage", double, double);
|
||||
m_3v3CurrentCbKey = REGISTER(UserCurrent3V3, ">3v3_current", double, double);
|
||||
m_3v3ActiveCbKey = REGISTER(UserActive3V3, ">3v3_active", bool, boolean);
|
||||
m_3v3FaultsCbKey = REGISTER(UserFaults3V3, ">3v3_faults", int32_t, int);
|
||||
}
|
||||
|
||||
void HALSimWSProviderRoboRIO::CancelCallbacks() {
|
||||
HALSIM_CancelRoboRioFPGAButtonCallback(m_fpgaCbKey);
|
||||
HALSIM_CancelRoboRioVInVoltageCallback(m_vinVoltageCbKey);
|
||||
HALSIM_CancelRoboRioVInCurrentCallback(m_vinCurrentCbKey);
|
||||
|
||||
HALSIM_CancelRoboRioUserVoltage6VCallback(m_6vVoltageCbKey);
|
||||
HALSIM_CancelRoboRioUserCurrent6VCallback(m_6vCurrentCbKey);
|
||||
HALSIM_CancelRoboRioUserActive6VCallback(m_6vActiveCbKey);
|
||||
HALSIM_CancelRoboRioUserFaults6VCallback(m_6vFaultsCbKey);
|
||||
|
||||
HALSIM_CancelRoboRioUserVoltage5VCallback(m_5vVoltageCbKey);
|
||||
HALSIM_CancelRoboRioUserCurrent5VCallback(m_5vCurrentCbKey);
|
||||
HALSIM_CancelRoboRioUserActive5VCallback(m_5vActiveCbKey);
|
||||
HALSIM_CancelRoboRioUserFaults5VCallback(m_5vFaultsCbKey);
|
||||
|
||||
HALSIM_CancelRoboRioUserVoltage3V3Callback(m_3v3VoltageCbKey);
|
||||
HALSIM_CancelRoboRioUserCurrent3V3Callback(m_3v3CurrentCbKey);
|
||||
HALSIM_CancelRoboRioUserActive3V3Callback(m_3v3ActiveCbKey);
|
||||
HALSIM_CancelRoboRioUserFaults3V3Callback(m_3v3FaultsCbKey);
|
||||
|
||||
m_fpgaCbKey = 0;
|
||||
m_vinVoltageCbKey = 0;
|
||||
m_vinCurrentCbKey = 0;
|
||||
m_6vActiveCbKey = 0;
|
||||
m_6vCurrentCbKey = 0;
|
||||
m_6vFaultsCbKey = 0;
|
||||
m_6vVoltageCbKey = 0;
|
||||
m_5vActiveCbKey = 0;
|
||||
m_5vCurrentCbKey = 0;
|
||||
m_5vFaultsCbKey = 0;
|
||||
m_5vVoltageCbKey = 0;
|
||||
m_3v3ActiveCbKey = 0;
|
||||
m_3v3CurrentCbKey = 0;
|
||||
m_3v3FaultsCbKey = 0;
|
||||
m_3v3VoltageCbKey = 0;
|
||||
}
|
||||
|
||||
void HALSimWSProviderRoboRIO::OnNetValueChanged(const wpi::json& json) {
|
||||
wpi::json::const_iterator it;
|
||||
if ((it = json.find(">fpga_button")) != json.end()) {
|
||||
HALSIM_SetRoboRioFPGAButton(static_cast<bool>(it.value()));
|
||||
}
|
||||
|
||||
if ((it = json.find(">vin_voltage")) != json.end()) {
|
||||
HALSIM_SetRoboRioVInVoltage(it.value());
|
||||
}
|
||||
if ((it = json.find(">vin_current")) != json.end()) {
|
||||
HALSIM_SetRoboRioVInCurrent(it.value());
|
||||
}
|
||||
|
||||
if ((it = json.find(">6v_voltage")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserVoltage6V(it.value());
|
||||
}
|
||||
if ((it = json.find(">6v_current")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserCurrent6V(it.value());
|
||||
}
|
||||
if ((it = json.find(">6v_active")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserActive6V(static_cast<bool>(it.value()));
|
||||
}
|
||||
if ((it = json.find(">6v_faults")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserFaults6V(it.value());
|
||||
}
|
||||
|
||||
if ((it = json.find(">5v_voltage")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserVoltage5V(it.value());
|
||||
}
|
||||
if ((it = json.find(">5v_current")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserCurrent5V(it.value());
|
||||
}
|
||||
if ((it = json.find(">5v_active")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserActive5V(static_cast<bool>(it.value()));
|
||||
}
|
||||
if ((it = json.find(">5v_faults")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserFaults5V(it.value());
|
||||
}
|
||||
|
||||
if ((it = json.find(">3v3_voltage")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserVoltage3V3(it.value());
|
||||
}
|
||||
if ((it = json.find(">3v3_current")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserCurrent3V3(it.value());
|
||||
}
|
||||
if ((it = json.find(">3v3_active")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserActive3V3(static_cast<bool>(it.value()));
|
||||
}
|
||||
if ((it = json.find(">3v3_faults")) != json.end()) {
|
||||
HALSIM_SetRoboRioUserFaults3V3(it.value());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,197 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_SimDevice.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
HALSimWSProviderSimDevice::~HALSimWSProviderSimDevice() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderSimDevice::OnNetworkConnected(
|
||||
std::shared_ptr<HALSimBaseWebSocketConnection> ws) {
|
||||
auto storedWS = m_ws.lock();
|
||||
|
||||
if (ws == storedWS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, run the disconnection code first so we get
|
||||
// back to a clean slate (only if the stored websocket is
|
||||
// not null)
|
||||
if (storedWS) {
|
||||
OnNetworkDisconnected();
|
||||
}
|
||||
|
||||
m_ws = ws;
|
||||
|
||||
m_simValueCreatedCbKey = HALSIM_RegisterSimValueCreatedCallback(
|
||||
m_handle, this, HALSimWSProviderSimDevice::OnValueCreatedStatic, 1);
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevice::OnNetworkDisconnected() {
|
||||
// Cancel all callbacks
|
||||
CancelCallbacks();
|
||||
|
||||
m_ws.reset();
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevice::CancelCallbacks() {
|
||||
HALSIM_CancelSimValueCreatedCallback(m_simValueCreatedCbKey);
|
||||
|
||||
m_simValueCreatedCbKey = 0;
|
||||
|
||||
for (auto& kv : m_simValueChangedCbKeys) {
|
||||
HALSIM_CancelSimValueChangedCallback(kv.getValue());
|
||||
}
|
||||
|
||||
m_simValueChangedCbKeys.clear();
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevice::OnNetValueChanged(const wpi::json& json) {
|
||||
auto it = json.cbegin();
|
||||
auto end = json.cend();
|
||||
|
||||
std::shared_lock lock(m_vhLock);
|
||||
for (; it != end; ++it) {
|
||||
auto vd = m_valueHandles.find(it.key());
|
||||
if (vd != m_valueHandles.end()) {
|
||||
HAL_Value value;
|
||||
value.type = vd->second->valueType;
|
||||
switch (value.type) {
|
||||
case HAL_BOOLEAN:
|
||||
value.data.v_boolean = static_cast<bool>(it.value()) ? 1 : 0;
|
||||
break;
|
||||
case HAL_DOUBLE:
|
||||
value.data.v_double = it.value();
|
||||
break;
|
||||
case HAL_ENUM:
|
||||
value.data.v_enum = it.value();
|
||||
break;
|
||||
case HAL_INT:
|
||||
value.data.v_int = it.value();
|
||||
break;
|
||||
case HAL_LONG:
|
||||
value.data.v_long = it.value();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
HAL_SetSimValue(vd->second->handle, &value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevice::OnValueCreated(const char* name,
|
||||
HAL_SimValueHandle handle,
|
||||
HAL_Bool readonly,
|
||||
const struct HAL_Value* value) {
|
||||
wpi::Twine key = wpi::Twine(readonly ? "<" : "<>") + name;
|
||||
auto data = std::make_unique<SimDeviceValueData>();
|
||||
data->device = this;
|
||||
data->handle = handle;
|
||||
data->key = key.str();
|
||||
data->valueType = value->type;
|
||||
|
||||
auto param = data.get();
|
||||
|
||||
{
|
||||
std::unique_lock lock(m_vhLock);
|
||||
m_valueHandles[data->key] = std::move(data);
|
||||
}
|
||||
|
||||
int32_t cbKey = HALSIM_RegisterSimValueChangedCallback(
|
||||
handle, param, HALSimWSProviderSimDevice::OnValueChangedStatic, true);
|
||||
|
||||
m_simValueChangedCbKeys[key.str()] = cbKey;
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevice::OnValueChanged(SimDeviceValueData* valueData,
|
||||
const struct HAL_Value* value) {
|
||||
auto ws = m_ws.lock();
|
||||
if (ws) {
|
||||
switch (value->type) {
|
||||
case HAL_BOOLEAN:
|
||||
ProcessHalCallback({{valueData->key, value->data.v_boolean}});
|
||||
break;
|
||||
case HAL_DOUBLE:
|
||||
ProcessHalCallback({{valueData->key, value->data.v_double}});
|
||||
break;
|
||||
case HAL_ENUM:
|
||||
ProcessHalCallback({{valueData->key, value->data.v_enum}});
|
||||
break;
|
||||
case HAL_INT:
|
||||
ProcessHalCallback({{valueData->key, value->data.v_int}});
|
||||
break;
|
||||
case HAL_LONG:
|
||||
ProcessHalCallback({{valueData->key, value->data.v_long}});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevice::ProcessHalCallback(const wpi::json& payload) {
|
||||
auto ws = m_ws.lock();
|
||||
if (ws) {
|
||||
wpi::json netValue = {
|
||||
{"type", "SimDevices"}, {"device", m_deviceId}, {"data", payload}};
|
||||
ws->OnSimValueChanged(netValue);
|
||||
}
|
||||
}
|
||||
|
||||
HALSimWSProviderSimDevices::~HALSimWSProviderSimDevices() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderSimDevices::DeviceCreatedCallback(
|
||||
const char* name, HAL_SimDeviceHandle handle) {
|
||||
auto key = (wpi::Twine("SimDevices/") + name).str();
|
||||
auto dev = std::make_shared<HALSimWSProviderSimDevice>(
|
||||
handle, key, wpi::Twine(name).str());
|
||||
m_providers.Add(key, dev);
|
||||
|
||||
if (m_ws) {
|
||||
m_exec->Call([this, dev]() { dev->OnNetworkConnected(GetWSConnection()); });
|
||||
}
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevices::DeviceFreedCallback(
|
||||
const char* name, HAL_SimDeviceHandle handle) {
|
||||
m_providers.Delete(name);
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevices::Initialize(
|
||||
std::shared_ptr<wpi::uv::Loop> loop) {
|
||||
m_deviceCreatedCbKey = HALSIM_RegisterSimDeviceCreatedCallback(
|
||||
"", this, HALSimWSProviderSimDevices::DeviceCreatedCallbackStatic, 1);
|
||||
m_deviceFreedCbKey = HALSIM_RegisterSimDeviceFreedCallback(
|
||||
"", this, HALSimWSProviderSimDevices::DeviceFreedCallbackStatic);
|
||||
|
||||
m_exec = UvExecFn::Create(loop, [](auto out, LoopFn func) {
|
||||
func();
|
||||
out.set_value();
|
||||
});
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevices::CancelCallbacks() {
|
||||
HALSIM_CancelSimDeviceCreatedCallback(m_deviceCreatedCbKey);
|
||||
HALSIM_CancelSimDeviceFreedCallback(m_deviceFreedCbKey);
|
||||
|
||||
m_deviceCreatedCbKey = 0;
|
||||
m_deviceFreedCbKey = 0;
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevices::OnNetworkConnected(
|
||||
std::shared_ptr<HALSimBaseWebSocketConnection> hws) {
|
||||
m_ws = hws;
|
||||
}
|
||||
|
||||
void HALSimWSProviderSimDevices::OnNetworkDisconnected() { m_ws = nullptr; }
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,47 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WSProvider_dPWM.h"
|
||||
|
||||
#include <hal/Ports.h>
|
||||
#include <hal/simulation/DigitalPWMData.h>
|
||||
|
||||
#define REGISTER(halsim, jsonid, ctype, haltype) \
|
||||
HALSIM_RegisterDigitalPWM##halsim##Callback( \
|
||||
m_channel, \
|
||||
[](const char* name, void* param, const struct HAL_Value* value) { \
|
||||
static_cast<HALSimWSProviderDigitalPWM*>(param)->ProcessHalCallback( \
|
||||
{{jsonid, static_cast<ctype>(value->data.v_##haltype)}}); \
|
||||
}, \
|
||||
this, true)
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
void HALSimWSProviderDigitalPWM::Initialize(WSRegisterFunc webRegisterFunc) {
|
||||
CreateProviders<HALSimWSProviderDigitalPWM>(
|
||||
"dPWM", HAL_GetNumDigitalPWMOutputs(), webRegisterFunc);
|
||||
}
|
||||
|
||||
HALSimWSProviderDigitalPWM::~HALSimWSProviderDigitalPWM() { CancelCallbacks(); }
|
||||
|
||||
void HALSimWSProviderDigitalPWM::RegisterCallbacks() {
|
||||
m_initCbKey = REGISTER(Initialized, "<init", bool, boolean);
|
||||
m_dutyCycleCbKey = REGISTER(DutyCycle, "<duty_cycle", double, double);
|
||||
m_pinCbKey = REGISTER(Pin, "<dio_pin", int32_t, int);
|
||||
}
|
||||
|
||||
void HALSimWSProviderDigitalPWM::CancelCallbacks() {
|
||||
HALSIM_CancelDigitalPWMInitializedCallback(m_channel, m_initCbKey);
|
||||
HALSIM_CancelDigitalPWMDutyCycleCallback(m_channel, m_dutyCycleCbKey);
|
||||
HALSIM_CancelDigitalPWMPinCallback(m_channel, m_pinCbKey);
|
||||
|
||||
m_initCbKey = 0;
|
||||
m_dutyCycleCbKey = 0;
|
||||
m_pinCbKey = 0;
|
||||
}
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,24 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <wpi/json.h>
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimBaseWebSocketConnection {
|
||||
public:
|
||||
virtual void OnSimValueChanged(const wpi::json& msg) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~HALSimBaseWebSocketConnection() = default;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,53 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <wpi/json.h>
|
||||
|
||||
#include "HALSimBaseWebSocketConnection.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSBaseProvider {
|
||||
public:
|
||||
explicit HALSimWSBaseProvider(const std::string& key,
|
||||
const std::string& type = "");
|
||||
virtual ~HALSimWSBaseProvider() {}
|
||||
|
||||
HALSimWSBaseProvider(const HALSimWSBaseProvider&) = delete;
|
||||
HALSimWSBaseProvider& operator=(const HALSimWSBaseProvider&) = delete;
|
||||
|
||||
// Called when the websocket connects. This will cause providers
|
||||
// to register their HAL callbacks
|
||||
virtual void OnNetworkConnected(
|
||||
std::shared_ptr<HALSimBaseWebSocketConnection> ws) = 0;
|
||||
|
||||
// Called when the websocket disconnects. This will cause provider
|
||||
// to cancel their HAL callbacks
|
||||
virtual void OnNetworkDisconnected() = 0;
|
||||
|
||||
// network -> sim
|
||||
virtual void OnNetValueChanged(const wpi::json& json);
|
||||
|
||||
const std::string GetDeviceType() { return m_type; }
|
||||
const std::string GetDeviceId() { return m_deviceId; }
|
||||
|
||||
protected:
|
||||
// sim -> network
|
||||
std::weak_ptr<HALSimBaseWebSocketConnection> m_ws;
|
||||
std::string m_key;
|
||||
|
||||
std::string m_type;
|
||||
std::string m_deviceId = "";
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,68 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <hal/simulation/NotifyListener.h>
|
||||
#include <wpi/json.h>
|
||||
#include <wpi/mutex.h>
|
||||
|
||||
#include "WSBaseProvider.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
typedef void (*HALCbRegisterIndexedFunc)(int32_t index,
|
||||
HAL_NotifyCallback callback,
|
||||
void* param, HAL_Bool initialNotify);
|
||||
typedef void (*HALCbRegisterSingleFunc)(HAL_NotifyCallback callback,
|
||||
void* param, HAL_Bool initialNotify);
|
||||
|
||||
// provider generates diffs based on values
|
||||
class HALSimWSHalProvider : public HALSimWSBaseProvider {
|
||||
public:
|
||||
using HALSimWSBaseProvider::HALSimWSBaseProvider;
|
||||
|
||||
void OnNetworkConnected(std::shared_ptr<HALSimBaseWebSocketConnection> ws);
|
||||
void OnNetworkDisconnected();
|
||||
|
||||
void ProcessHalCallback(const wpi::json& payload);
|
||||
|
||||
protected:
|
||||
virtual void RegisterCallbacks() = 0;
|
||||
virtual void CancelCallbacks() = 0;
|
||||
};
|
||||
|
||||
// provider generates per-channel diffs
|
||||
class HALSimWSHalChanProvider : public HALSimWSHalProvider {
|
||||
public:
|
||||
explicit HALSimWSHalChanProvider(int32_t channel, const std::string& key,
|
||||
const std::string& type);
|
||||
|
||||
int32_t GetChannel() { return m_channel; }
|
||||
|
||||
protected:
|
||||
int32_t m_channel;
|
||||
};
|
||||
|
||||
using WSRegisterFunc = std::function<void(
|
||||
const std::string&, std::shared_ptr<HALSimWSBaseProvider>)>;
|
||||
|
||||
template <typename T>
|
||||
void CreateProviders(const std::string& prefix, int32_t numChannels,
|
||||
WSRegisterFunc webRegisterFunc);
|
||||
|
||||
template <typename T>
|
||||
void CreateSingleProvider(const std::string& key,
|
||||
WSRegisterFunc webRegisterFunc);
|
||||
|
||||
#include "WSHalProviders.inl"
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,29 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
template <typename T>
|
||||
void CreateProviders(const std::string& prefix, int numChannels,
|
||||
WSRegisterFunc webRegisterFunc) {
|
||||
for (int32_t i = 0; i < numChannels; i++) {
|
||||
auto key = (prefix + "/" + wpi::Twine(i)).str();
|
||||
auto ptr = std::make_unique<T>(i, key, prefix);
|
||||
webRegisterFunc(key, std::move(ptr));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void CreateSingleProvider(const std::string& key,
|
||||
WSRegisterFunc webRegisterFunc) {
|
||||
auto ptr = std::make_unique<T>(key, key);
|
||||
webRegisterFunc(key, std::move(ptr));
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include <wpi/StringMap.h>
|
||||
|
||||
#include "WSBaseProvider.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class ProviderContainer {
|
||||
public:
|
||||
using ProviderPtr = std::shared_ptr<HALSimWSBaseProvider>;
|
||||
using IterFn = std::function<void(ProviderPtr)>;
|
||||
|
||||
ProviderContainer() {}
|
||||
|
||||
ProviderContainer(const ProviderContainer&) = delete;
|
||||
ProviderContainer& operator=(const ProviderContainer&) = delete;
|
||||
|
||||
void Add(wpi::StringRef key, std::shared_ptr<HALSimWSBaseProvider> provider) {
|
||||
std::unique_lock lock(m_mutex);
|
||||
m_providers[key] = provider;
|
||||
}
|
||||
|
||||
void Delete(wpi::StringRef key) {
|
||||
std::unique_lock lock(m_mutex);
|
||||
m_providers.erase(key);
|
||||
}
|
||||
|
||||
void ForEach(IterFn fn) {
|
||||
std::shared_lock lock(m_mutex);
|
||||
for (auto& kv : m_providers) {
|
||||
fn(kv.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
ProviderPtr Get(wpi::StringRef key) {
|
||||
std::shared_lock lock(m_mutex);
|
||||
auto fiter = m_providers.find(key);
|
||||
return fiter != m_providers.end() ? fiter->second : ProviderPtr();
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_mutex m_mutex;
|
||||
wpi::StringMap<std::shared_ptr<HALSimWSBaseProvider>> m_providers;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,57 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderAnalogIn : public HALSimWSHalChanProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalChanProvider::HALSimWSHalChanProvider;
|
||||
~HALSimWSProviderAnalogIn();
|
||||
|
||||
void OnNetValueChanged(const wpi::json& json) override;
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_initCbKey = 0;
|
||||
int32_t m_avgbitsCbKey = 0;
|
||||
int32_t m_oversampleCbKey = 0;
|
||||
int32_t m_voltageCbKey = 0;
|
||||
int32_t m_accumInitCbKey = 0;
|
||||
int32_t m_accumValueCbKey = 0;
|
||||
int32_t m_accumCountCbKey = 0;
|
||||
int32_t m_accumCenterCbKey = 0;
|
||||
int32_t m_accumDeadbandCbKey = 0;
|
||||
};
|
||||
|
||||
class HALSimWSProviderAnalogOut : public HALSimWSHalChanProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalChanProvider::HALSimWSHalChanProvider;
|
||||
~HALSimWSProviderAnalogOut();
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_initCbKey = 0;
|
||||
int32_t m_voltageCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,36 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderDIO : public HALSimWSHalChanProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalChanProvider::HALSimWSHalChanProvider;
|
||||
~HALSimWSProviderDIO();
|
||||
|
||||
void OnNetValueChanged(const wpi::json& json) override;
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_initCbKey = 0;
|
||||
int32_t m_valueCbKey = 0;
|
||||
int32_t m_pulseLengthCbKey = 0;
|
||||
int32_t m_inputCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,41 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderDriverStation : public HALSimWSHalProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalProvider::HALSimWSHalProvider;
|
||||
~HALSimWSProviderDriverStation();
|
||||
|
||||
void OnNetValueChanged(const wpi::json& json) override;
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_enabledCbKey = 0;
|
||||
int32_t m_autonomousCbKey = 0;
|
||||
int32_t m_testCbKey = 0;
|
||||
int32_t m_estopCbKey = 0;
|
||||
int32_t m_fmsCbKey = 0;
|
||||
int32_t m_dsCbKey = 0;
|
||||
int32_t m_allianceCbKey = 0;
|
||||
int32_t m_matchTimeCbKey = 0;
|
||||
int32_t m_newDataCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,38 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderEncoder : public HALSimWSHalChanProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalChanProvider::HALSimWSHalChanProvider;
|
||||
~HALSimWSProviderEncoder();
|
||||
|
||||
void OnNetValueChanged(const wpi::json& json) override;
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_initCbKey = 0;
|
||||
int32_t m_countCbKey = 0;
|
||||
int32_t m_periodCbKey = 0;
|
||||
int32_t m_resetCbKey = 0;
|
||||
int32_t m_reverseDirectionCbKey = 0;
|
||||
int32_t m_samplesCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,33 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderJoystick : public HALSimWSHalChanProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalChanProvider::HALSimWSHalChanProvider;
|
||||
~HALSimWSProviderJoystick();
|
||||
|
||||
void OnNetValueChanged(const wpi::json& json) override;
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_dsNewDataCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,36 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderPWM : public HALSimWSHalChanProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalChanProvider::HALSimWSHalChanProvider;
|
||||
~HALSimWSProviderPWM();
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_initCbKey = 0;
|
||||
int32_t m_speedCbKey = 0;
|
||||
int32_t m_positionCbKey = 0;
|
||||
int32_t m_rawCbKey = 0;
|
||||
int32_t m_periodScaleCbKey = 0;
|
||||
int32_t m_zeroLatchCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,34 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderRelay : public HALSimWSHalChanProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalChanProvider::HALSimWSHalChanProvider;
|
||||
~HALSimWSProviderRelay();
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_initFwdCbKey = 0;
|
||||
int32_t m_initRevCbKey = 0;
|
||||
int32_t m_fwdCbKey = 0;
|
||||
int32_t m_revCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,47 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderRoboRIO : public HALSimWSHalProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalProvider::HALSimWSHalProvider;
|
||||
~HALSimWSProviderRoboRIO();
|
||||
|
||||
void OnNetValueChanged(const wpi::json& json) override;
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_fpgaCbKey = 0;
|
||||
int32_t m_vinVoltageCbKey = 0;
|
||||
int32_t m_vinCurrentCbKey = 0;
|
||||
int32_t m_6vVoltageCbKey = 0;
|
||||
int32_t m_6vCurrentCbKey = 0;
|
||||
int32_t m_6vActiveCbKey = 0;
|
||||
int32_t m_6vFaultsCbKey = 0;
|
||||
int32_t m_5vVoltageCbKey = 0;
|
||||
int32_t m_5vCurrentCbKey = 0;
|
||||
int32_t m_5vActiveCbKey = 0;
|
||||
int32_t m_5vFaultsCbKey = 0;
|
||||
int32_t m_3v3VoltageCbKey = 0;
|
||||
int32_t m_3v3CurrentCbKey = 0;
|
||||
int32_t m_3v3ActiveCbKey = 0;
|
||||
int32_t m_3v3FaultsCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,128 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <hal/SimDevice.h>
|
||||
#include <hal/simulation/SimDeviceData.h>
|
||||
#include <wpi/StringMap.h>
|
||||
#include <wpi/uv/AsyncFunction.h>
|
||||
|
||||
#include "WSBaseProvider.h"
|
||||
#include "WSProviderContainer.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderSimDevice;
|
||||
class HALSimWSProviderSimDevices;
|
||||
|
||||
struct SimDeviceValueData {
|
||||
HALSimWSProviderSimDevice* device;
|
||||
HAL_SimValueHandle handle;
|
||||
std::string key;
|
||||
HAL_Type valueType;
|
||||
};
|
||||
|
||||
class HALSimWSProviderSimDevice : public HALSimWSBaseProvider {
|
||||
public:
|
||||
HALSimWSProviderSimDevice(HAL_SimDeviceHandle handle, const std::string& key,
|
||||
const std::string& deviceId)
|
||||
: HALSimWSBaseProvider(key, "SimDevices"), m_handle(handle) {
|
||||
m_deviceId = deviceId;
|
||||
}
|
||||
|
||||
~HALSimWSProviderSimDevice();
|
||||
|
||||
void OnNetworkConnected(
|
||||
std::shared_ptr<HALSimBaseWebSocketConnection> ws) override;
|
||||
|
||||
void OnNetworkDisconnected() override;
|
||||
|
||||
void OnNetValueChanged(const wpi::json& json) override;
|
||||
|
||||
void ProcessHalCallback(const wpi::json& payload);
|
||||
|
||||
private:
|
||||
static void OnValueCreatedStatic(const char* name, void* param,
|
||||
HAL_SimValueHandle handle, HAL_Bool readonly,
|
||||
const struct HAL_Value* value) {
|
||||
(reinterpret_cast<HALSimWSProviderSimDevice*>(param))
|
||||
->OnValueCreated(name, handle, readonly, value);
|
||||
}
|
||||
void OnValueCreated(const char* name, HAL_SimValueHandle handle,
|
||||
HAL_Bool readonly, const struct HAL_Value* value);
|
||||
|
||||
static void OnValueChangedStatic(const char* name, void* param,
|
||||
HAL_SimValueHandle handle, HAL_Bool readonly,
|
||||
const struct HAL_Value* value) {
|
||||
auto valueData = (reinterpret_cast<SimDeviceValueData*>(param));
|
||||
valueData->device->OnValueChanged(valueData, value);
|
||||
}
|
||||
void OnValueChanged(SimDeviceValueData* valueData,
|
||||
const struct HAL_Value* value);
|
||||
|
||||
void CancelCallbacks();
|
||||
|
||||
wpi::StringMap<std::unique_ptr<SimDeviceValueData>> m_valueHandles;
|
||||
std::shared_mutex m_vhLock;
|
||||
|
||||
HAL_SimDeviceHandle m_handle;
|
||||
|
||||
std::shared_ptr<HALSimWSProviderSimDevices> m_simDevicesBase;
|
||||
|
||||
int32_t m_simValueCreatedCbKey = 0;
|
||||
wpi::StringMap<int32_t> m_simValueChangedCbKeys;
|
||||
};
|
||||
|
||||
class HALSimWSProviderSimDevices {
|
||||
public:
|
||||
using LoopFn = std::function<void(void)>;
|
||||
using UvExecFn = wpi::uv::AsyncFunction<void(LoopFn)>;
|
||||
|
||||
explicit HALSimWSProviderSimDevices(ProviderContainer& providers)
|
||||
: m_providers(providers) {}
|
||||
~HALSimWSProviderSimDevices();
|
||||
|
||||
void Initialize(std::shared_ptr<wpi::uv::Loop> loop);
|
||||
|
||||
void OnNetworkConnected(std::shared_ptr<HALSimBaseWebSocketConnection> hws);
|
||||
void OnNetworkDisconnected();
|
||||
|
||||
std::shared_ptr<HALSimBaseWebSocketConnection> GetWSConnection() {
|
||||
return m_ws;
|
||||
}
|
||||
|
||||
private:
|
||||
static void DeviceCreatedCallbackStatic(const char* name, void* param,
|
||||
HAL_SimDeviceHandle handle) {
|
||||
(reinterpret_cast<HALSimWSProviderSimDevices*>(param))
|
||||
->DeviceCreatedCallback(name, handle);
|
||||
}
|
||||
void DeviceCreatedCallback(const char* name, HAL_SimDeviceHandle handle);
|
||||
|
||||
static void DeviceFreedCallbackStatic(const char* name, void* param,
|
||||
HAL_SimDeviceHandle handle) {
|
||||
(reinterpret_cast<HALSimWSProviderSimDevices*>(param))
|
||||
->DeviceFreedCallback(name, handle);
|
||||
}
|
||||
void DeviceFreedCallback(const char* name, HAL_SimDeviceHandle handle);
|
||||
|
||||
void CancelCallbacks();
|
||||
|
||||
ProviderContainer& m_providers;
|
||||
|
||||
std::shared_ptr<HALSimBaseWebSocketConnection> m_ws;
|
||||
std::shared_ptr<UvExecFn> m_exec;
|
||||
|
||||
int32_t m_deviceCreatedCbKey = 0;
|
||||
int32_t m_deviceFreedCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
@@ -0,0 +1,33 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017-2020 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "WSHalProviders.h"
|
||||
|
||||
namespace wpilibws {
|
||||
|
||||
class HALSimWSProviderDigitalPWM : public HALSimWSHalChanProvider {
|
||||
public:
|
||||
static void Initialize(WSRegisterFunc webRegisterFunc);
|
||||
|
||||
using HALSimWSHalChanProvider::HALSimWSHalChanProvider;
|
||||
~HALSimWSProviderDigitalPWM();
|
||||
|
||||
protected:
|
||||
void RegisterCallbacks() override;
|
||||
void CancelCallbacks() override;
|
||||
|
||||
private:
|
||||
int32_t m_initCbKey = 0;
|
||||
int32_t m_dutyCycleCbKey = 0;
|
||||
int32_t m_pinCbKey = 0;
|
||||
};
|
||||
|
||||
} // namespace wpilibws
|
||||
Reference in New Issue
Block a user