mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-04 03:11:43 +00:00
[hal] Add SimValue reset() function (#3064)
This enables correct behavior for resetting incremental sensor values like encoder counts or gyro accumulated angle with WebSockets.
This commit is contained in:
@@ -40,6 +40,8 @@ void HAL_GetSimValue(HAL_SimValueHandle handle, struct HAL_Value* value) {
|
||||
void HAL_SetSimValue(HAL_SimValueHandle handle, const struct HAL_Value* value) {
|
||||
}
|
||||
|
||||
void HAL_ResetSimValue(HAL_SimValueHandle handle) {}
|
||||
|
||||
hal::SimDevice::SimDevice(const char* name, int index) {}
|
||||
|
||||
hal::SimDevice::SimDevice(const char* name, int index, int channel) {}
|
||||
|
||||
@@ -63,6 +63,15 @@ int32_t HALSIM_RegisterSimValueChangedCallback(HAL_SimValueHandle handle,
|
||||
|
||||
void HALSIM_CancelSimValueChangedCallback(int32_t uid) {}
|
||||
|
||||
int32_t HALSIM_RegisterSimValueResetCallback(HAL_SimValueHandle handle,
|
||||
void* param,
|
||||
HALSIM_SimValueCallback callback,
|
||||
HAL_Bool initialNotify) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HALSIM_CancelSimValueResetCallback(int32_t uid) {}
|
||||
|
||||
HAL_SimValueHandle HALSIM_GetSimValueHandle(HAL_SimDeviceHandle device,
|
||||
const char* name) {
|
||||
return 0;
|
||||
|
||||
@@ -225,4 +225,16 @@ Java_edu_wpi_first_hal_SimDeviceJNI_setSimValueNative
|
||||
HAL_SetSimValue(handle, ValueFromJava(type, value1, value2));
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_SimDeviceJNI
|
||||
* Method: resetSimValue
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_SimDeviceJNI_resetSimValue
|
||||
(JNIEnv*, jclass, jint handle)
|
||||
{
|
||||
HAL_ResetSimValue(handle);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@@ -600,6 +600,32 @@ Java_edu_wpi_first_hal_simulation_SimDeviceDataJNI_cancelSimValueChangedCallback
|
||||
FreeValueCallback(env, uid, &HALSIM_CancelSimValueChangedCallback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_simulation_SimDeviceDataJNI
|
||||
* Method: registerSimValueResetCallback
|
||||
* Signature: (ILjava/lang/Object;Z)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_edu_wpi_first_hal_simulation_SimDeviceDataJNI_registerSimValueResetCallback
|
||||
(JNIEnv* env, jclass, jint handle, jobject callback, jboolean initialNotify)
|
||||
{
|
||||
return AllocateValueCallback(env, static_cast<HAL_SimValueHandle>(handle),
|
||||
callback, true, initialNotify,
|
||||
&HALSIM_RegisterSimValueResetCallback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_simulation_SimDeviceDataJNI
|
||||
* Method: cancelSimValueResetCallback
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL
|
||||
Java_edu_wpi_first_hal_simulation_SimDeviceDataJNI_cancelSimValueResetCallback
|
||||
(JNIEnv* env, jclass, jint uid)
|
||||
{
|
||||
FreeValueCallback(env, uid, &HALSIM_CancelSimValueResetCallback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: edu_wpi_first_hal_simulation_SimDeviceDataJNI
|
||||
* Method: getSimValueHandle
|
||||
|
||||
@@ -327,6 +327,17 @@ inline void HAL_SetSimValueBoolean(HAL_SimValueHandle handle, HAL_Bool value) {
|
||||
HAL_SetSimValue(handle, &v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets a simulated double or integral value to 0.
|
||||
* Has no effect on other value types.
|
||||
* Use this instead of Set(0) for resetting incremental sensor values like
|
||||
* encoder counts or gyro accumulated angle to ensure correct behavior in a
|
||||
* distributed system (e.g. WebSockets).
|
||||
*
|
||||
* @param handle simulated value handle
|
||||
*/
|
||||
void HAL_ResetSimValue(HAL_SimValueHandle handle);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -420,6 +431,13 @@ class SimInt : public SimValue {
|
||||
* @param value the value to set
|
||||
*/
|
||||
void Set(int32_t value) { HAL_SetSimValueInt(m_handle, value); }
|
||||
|
||||
/**
|
||||
* Resets the simulated value to 0. Use this instead of Set(0) for resetting
|
||||
* incremental sensor values like encoder counts or gyro accumulated angle
|
||||
* to ensure correct behavior in a distributed system (e.g. WebSockets).
|
||||
*/
|
||||
void Reset() { HAL_ResetSimValue(m_handle); }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -454,6 +472,13 @@ class SimLong : public SimValue {
|
||||
* @param value the value to set
|
||||
*/
|
||||
void Set(int64_t value) { HAL_SetSimValueLong(m_handle, value); }
|
||||
|
||||
/**
|
||||
* Resets the simulated value to 0. Use this instead of Set(0) for resetting
|
||||
* incremental sensor values like encoder counts or gyro accumulated angle
|
||||
* to ensure correct behavior in a distributed system (e.g. WebSockets).
|
||||
*/
|
||||
void Reset() { HAL_ResetSimValue(m_handle); }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -488,6 +513,13 @@ class SimDouble : public SimValue {
|
||||
* @param value the value to set
|
||||
*/
|
||||
void Set(double value) { HAL_SetSimValueDouble(m_handle, value); }
|
||||
|
||||
/**
|
||||
* Resets the simulated value to 0. Use this instead of Set(0) for resetting
|
||||
* incremental sensor values like encoder counts or gyro accumulated angle
|
||||
* to ensure correct behavior in a distributed system (e.g. WebSockets).
|
||||
*/
|
||||
void Reset() { HAL_ResetSimValue(m_handle); }
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,6 +57,21 @@ int32_t HALSIM_RegisterSimValueChangedCallback(HAL_SimValueHandle handle,
|
||||
|
||||
void HALSIM_CancelSimValueChangedCallback(int32_t uid);
|
||||
|
||||
/**
|
||||
* Register a callback for HAL_SimValueReset(). The callback is called with
|
||||
* the old value.
|
||||
*
|
||||
* @param handle simulated value handle
|
||||
* @param callback callback
|
||||
* @param initialNotify ignored (present for consistency)
|
||||
*/
|
||||
int32_t HALSIM_RegisterSimValueResetCallback(HAL_SimValueHandle handle,
|
||||
void* param,
|
||||
HALSIM_SimValueCallback callback,
|
||||
HAL_Bool initialNotify);
|
||||
|
||||
void HALSIM_CancelSimValueResetCallback(int32_t uid);
|
||||
|
||||
HAL_SimValueHandle HALSIM_GetSimValueHandle(HAL_SimDeviceHandle device,
|
||||
const char* name);
|
||||
|
||||
|
||||
@@ -61,6 +61,10 @@ void HAL_SetSimValue(HAL_SimValueHandle handle, const struct HAL_Value* value) {
|
||||
SimSimDeviceData->SetValue(handle, *value);
|
||||
}
|
||||
|
||||
void HAL_ResetSimValue(HAL_SimValueHandle handle) {
|
||||
SimSimDeviceData->ResetValue(handle);
|
||||
}
|
||||
|
||||
hal::SimDevice::SimDevice(const char* name, int index) {
|
||||
wpi::SmallString<128> fullname;
|
||||
wpi::raw_svector_ostream os(fullname);
|
||||
|
||||
@@ -220,6 +220,47 @@ void SimDeviceData::SetValue(HAL_SimValueHandle handle,
|
||||
valueImpl->direction, &value);
|
||||
}
|
||||
|
||||
void SimDeviceData::ResetValue(HAL_SimValueHandle handle) {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
Value* valueImpl = LookupValue(handle);
|
||||
if (!valueImpl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// don't notify reset if we aren't going to actually reset anything
|
||||
switch (valueImpl->value.type) {
|
||||
case HAL_INT:
|
||||
case HAL_LONG:
|
||||
case HAL_DOUBLE:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// notify reset callbacks (done here so they're called with the old value)
|
||||
valueImpl->reset(valueImpl->name.c_str(), valueImpl->handle,
|
||||
valueImpl->direction, &valueImpl->value);
|
||||
|
||||
// set user-facing value to 0
|
||||
switch (valueImpl->value.type) {
|
||||
case HAL_INT:
|
||||
valueImpl->value.data.v_int = 0;
|
||||
break;
|
||||
case HAL_LONG:
|
||||
valueImpl->value.data.v_long = 0;
|
||||
break;
|
||||
case HAL_DOUBLE:
|
||||
valueImpl->value.data.v_double = 0;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// notify changed callbacks
|
||||
valueImpl->changed(valueImpl->name.c_str(), valueImpl->handle,
|
||||
valueImpl->direction, &valueImpl->value);
|
||||
}
|
||||
|
||||
int32_t SimDeviceData::RegisterDeviceCreatedCallback(
|
||||
const char* prefix, void* param, HALSIM_SimDeviceCallback callback,
|
||||
bool initialNotify) {
|
||||
@@ -368,6 +409,35 @@ void SimDeviceData::CancelValueChangedCallback(int32_t uid) {
|
||||
valueImpl->changed.Cancel(uid & 0x7f);
|
||||
}
|
||||
|
||||
int32_t SimDeviceData::RegisterValueResetCallback(
|
||||
HAL_SimValueHandle handle, void* param, HALSIM_SimValueCallback callback,
|
||||
bool initialNotify) {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
Value* valueImpl = LookupValue(handle);
|
||||
if (!valueImpl) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// register callback
|
||||
int32_t index = valueImpl->reset.Register(callback, param);
|
||||
|
||||
// encode device and value into uid
|
||||
return (((handle >> 16) & 0xfff) << 19) | ((handle & 0xfff) << 7) |
|
||||
(index & 0x7f);
|
||||
}
|
||||
|
||||
void SimDeviceData::CancelValueResetCallback(int32_t uid) {
|
||||
if (uid <= 0) {
|
||||
return;
|
||||
}
|
||||
std::scoped_lock lock(m_mutex);
|
||||
Value* valueImpl = LookupValue(((uid >> 19) << 16) | ((uid >> 7) & 0xfff));
|
||||
if (!valueImpl) {
|
||||
return;
|
||||
}
|
||||
valueImpl->reset.Cancel(uid & 0x7f);
|
||||
}
|
||||
|
||||
HAL_SimValueHandle SimDeviceData::GetValueHandle(HAL_SimDeviceHandle device,
|
||||
const char* name) {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
@@ -517,6 +587,18 @@ void HALSIM_CancelSimValueChangedCallback(int32_t uid) {
|
||||
SimSimDeviceData->CancelValueChangedCallback(uid);
|
||||
}
|
||||
|
||||
int32_t HALSIM_RegisterSimValueResetCallback(HAL_SimValueHandle handle,
|
||||
void* param,
|
||||
HALSIM_SimValueCallback callback,
|
||||
HAL_Bool initialNotify) {
|
||||
return SimSimDeviceData->RegisterValueResetCallback(handle, param, callback,
|
||||
initialNotify);
|
||||
}
|
||||
|
||||
void HALSIM_CancelSimValueResetCallback(int32_t uid) {
|
||||
SimSimDeviceData->CancelValueResetCallback(uid);
|
||||
}
|
||||
|
||||
HAL_SimValueHandle HALSIM_GetSimValueHandle(HAL_SimDeviceHandle device,
|
||||
const char* name) {
|
||||
return SimSimDeviceData->GetValueHandle(device, name);
|
||||
|
||||
@@ -150,6 +150,7 @@ class SimDeviceData {
|
||||
std::vector<const char*> cstrEnumOptions;
|
||||
std::vector<double> enumOptionValues;
|
||||
impl::SimUnnamedCallbackRegistry<HALSIM_SimValueCallback> changed;
|
||||
impl::SimUnnamedCallbackRegistry<HALSIM_SimValueCallback> reset;
|
||||
};
|
||||
|
||||
struct Device {
|
||||
@@ -188,6 +189,7 @@ class SimDeviceData {
|
||||
const HAL_Value& initialValue);
|
||||
HAL_Value GetValue(HAL_SimValueHandle handle);
|
||||
void SetValue(HAL_SimValueHandle handle, const HAL_Value& value);
|
||||
void ResetValue(HAL_SimValueHandle handle);
|
||||
|
||||
int32_t RegisterDeviceCreatedCallback(const char* prefix, void* param,
|
||||
HALSIM_SimDeviceCallback callback,
|
||||
@@ -218,6 +220,12 @@ class SimDeviceData {
|
||||
|
||||
void CancelValueChangedCallback(int32_t uid);
|
||||
|
||||
int32_t RegisterValueResetCallback(HAL_SimValueHandle handle, void* param,
|
||||
HALSIM_SimValueCallback callback,
|
||||
bool initialNotify);
|
||||
|
||||
void CancelValueResetCallback(int32_t uid);
|
||||
|
||||
HAL_SimValueHandle GetValueHandle(HAL_SimDeviceHandle device,
|
||||
const char* name);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user