[hal,wpilib] Add function to control "Radio" LED (#6073)

This commit is contained in:
Ryan Blue
2023-12-22 13:57:52 -05:00
committed by GitHub
parent 0b2cfb3abc
commit 4059e0cd9f
22 changed files with 531 additions and 3 deletions

View File

@@ -0,0 +1,28 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.hal;
public class LEDJNI extends JNIWrapper {
public static final int RADIO_LED_STATE_OFF = 0;
public static final int RADIO_LED_STATE_GREEN = 1;
public static final int RADIO_LED_STATE_RED = 2;
public static final int RADIO_LED_STATE_ORANGE = 3;
/**
* Set the state of the "Radio" LED.
*
* @param state The state to set the LED to.
* @see "HAL_SetRadioLEDState"
*/
public static native void setRadioLEDState(int state);
/**
* Get the state of the "Radio" LED.
*
* @return The state of the LED.
* @see "HAL_GetRadioLEDState"
*/
public static native int getRadioLEDState();
}

View File

@@ -176,5 +176,14 @@ public class RoboRioDataJNI extends JNIWrapper {
public static native void setComments(String comments);
public static native int registerRadioLEDStateCallback(
NotifyCallback callback, boolean initialNotify);
public static native void cancelRadioLEDStateCallback(int uid);
public static native int getRadioLEDState();
public static native void setRadioLEDState(int state);
public static native void resetData();
}

View File

@@ -83,6 +83,7 @@ void InitializeHAL() {
InitializeFRCDriverStation();
InitializeI2C();
InitializeInterrupts();
InitializeLEDs();
InitializeMain();
InitializeNotifier();
InitializeCTREPDP();

View File

@@ -40,6 +40,7 @@ extern void InitializeFRCDriverStation();
extern void InitializeHAL();
extern void InitializeI2C();
extern void InitializeInterrupts();
extern void InitializeLEDs();
extern void InitializeMain();
extern void InitializeNotifier();
extern void InitializeCTREPDP();

View File

@@ -0,0 +1,89 @@
// 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 "hal/LEDs.h"
#include <unistd.h>
#include <fstream>
#include <wpi/fs.h>
#include "hal/Errors.h"
namespace hal::init {
void InitializeLEDs() {
int32_t status = 0;
HAL_SetRadioLEDState(HAL_RadioLED_kOff, &status);
}
} // namespace hal::init
static const fs::path radioLEDGreenFilePath =
"/sys/class/leds/nilrt:wifi:primary/brightness";
static const fs::path radioLEDRedFilePath =
"/sys/class/leds/nilrt:wifi:secondary/brightness";
static const char* onStr = "1";
static const char* offStr = "0";
extern "C" {
void HAL_SetRadioLEDState(HAL_RadioLEDState state, int32_t* status) {
std::error_code ec;
fs::file_t greenFile = fs::OpenFileForWrite(radioLEDGreenFilePath, ec,
fs::CD_OpenExisting, fs::OF_Text);
if (ec) {
*status = INCOMPATIBLE_STATE;
return;
}
fs::file_t redFile = fs::OpenFileForWrite(radioLEDRedFilePath, ec,
fs::CD_OpenExisting, fs::OF_Text);
if (ec) {
*status = INCOMPATIBLE_STATE;
return;
}
write(greenFile, state & HAL_RadioLED_kGreen ? onStr : offStr, 1);
write(redFile, state & HAL_RadioLED_kRed ? onStr : offStr, 1);
fs::CloseFile(greenFile);
fs::CloseFile(redFile);
}
bool ReadStateFromFile(fs::path path, int32_t* status) {
std::error_code ec;
fs::file_t file = fs::OpenFileForRead(path, ec, fs::OF_Text);
if (ec) {
*status = INCOMPATIBLE_STATE;
return false;
}
// We only need to read one byte because the file won't have leading zeros.
char buf[1]{};
size_t count = read(file, buf, 1);
if (count == 0) {
*status = INCOMPATIBLE_STATE;
return false;
}
// If the brightness is not zero, the LED is on.
return buf[0] != '0';
}
HAL_RadioLEDState HAL_GetRadioLEDState(int32_t* status) {
bool green = ReadStateFromFile(radioLEDGreenFilePath, status);
bool red = ReadStateFromFile(radioLEDRedFilePath, status);
if (*status == 0) {
if (green && red) {
return HAL_RadioLED_kOrange;
} else if (green) {
return HAL_RadioLED_kGreen;
} else if (red) {
return HAL_RadioLED_kRed;
} else {
return HAL_RadioLED_kOff;
}
} else {
return HAL_RadioLED_kOff;
}
}
} // extern "C"

View File

@@ -30,6 +30,7 @@ DEFINE_CAPI(int32_t, UserFaults3V3, 0)
DEFINE_CAPI(double, BrownoutVoltage, 6.75)
DEFINE_CAPI(double, CPUTemp, 45.0)
DEFINE_CAPI(int32_t, TeamNumber, 0)
DEFINE_CAPI(HAL_RadioLEDState, RadioLEDState, HAL_RadioLED_kOff);
int32_t HALSIM_RegisterRoboRioSerialNumberCallback(
HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify) {

View File

@@ -0,0 +1,51 @@
// 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 <fmt/core.h>
#include "HALUtil.h"
#include "edu_wpi_first_hal_LEDJNI.h"
#include "hal/LEDs.h"
static_assert(edu_wpi_first_hal_LEDJNI_RADIO_LED_STATE_OFF ==
HAL_RadioLEDState::HAL_RadioLED_kOff);
static_assert(edu_wpi_first_hal_LEDJNI_RADIO_LED_STATE_GREEN ==
HAL_RadioLEDState::HAL_RadioLED_kGreen);
static_assert(edu_wpi_first_hal_LEDJNI_RADIO_LED_STATE_RED ==
HAL_RadioLEDState::HAL_RadioLED_kRed);
static_assert(edu_wpi_first_hal_LEDJNI_RADIO_LED_STATE_ORANGE ==
HAL_RadioLEDState::HAL_RadioLED_kOrange);
using namespace hal;
extern "C" {
/*
* Class: edu_wpi_first_hal_LEDJNI
* Method: setRadioLEDState
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_LEDJNI_setRadioLEDState
(JNIEnv* env, jclass, jint state)
{
int32_t status = 0;
HAL_SetRadioLEDState(static_cast<HAL_RadioLEDState>(state), &status);
CheckStatus(env, status);
}
/*
* Class: edu_wpi_first_hal_LEDJNI
* Method: getRadioLEDState
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_LEDJNI_getRadioLEDState
(JNIEnv* env, jclass)
{
int32_t status = 0;
auto retVal = HAL_GetRadioLEDState(&status);
CheckStatus(env, status);
return retVal;
}
} // extern "C"

View File

@@ -983,6 +983,57 @@ Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_setComments
HALSIM_SetRoboRioComments(commentsJString.c_str(), commentsJString.size());
}
/*
* Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
* Method: registerRadioLEDStateCallback
* Signature: (Ljava/lang/Object;Z)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_registerRadioLEDStateCallback
(JNIEnv* env, jclass, jobject callback, jboolean initialNotify)
{
return sim::AllocateCallbackNoIndex(
env, callback, initialNotify,
&HALSIM_RegisterRoboRioRadioLEDStateCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
* Method: cancelRadioLEDStateCallback
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_cancelRadioLEDStateCallback
(JNIEnv* env, jclass, jint handle)
{
return sim::FreeCallbackNoIndex(env, handle,
&HALSIM_CancelRoboRioRadioLEDStateCallback);
}
/*
* Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
* Method: getRadioLEDState
* Signature: ()I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_getRadioLEDState
(JNIEnv*, jclass)
{
return HALSIM_GetRoboRioRadioLEDState();
}
/*
* Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
* Method: setRadioLEDState
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_simulation_RoboRioDataJNI_setRadioLEDState
(JNIEnv*, jclass, jint value)
{
HALSIM_SetRoboRioRadioLEDState(static_cast<HAL_RadioLEDState>(value));
}
/*
* Class: edu_wpi_first_hal_simulation_RoboRioDataJNI
* Method: resetData

View File

@@ -25,6 +25,7 @@
#include "hal/HALBase.h"
#include "hal/I2C.h"
#include "hal/Interrupts.h"
#include "hal/LEDs.h"
#include "hal/Main.h"
#include "hal/Notifier.h"
#include "hal/PWM.h"

View File

@@ -0,0 +1,30 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include "hal/Types.h"
HAL_ENUM(HAL_RadioLEDState){HAL_RadioLED_kOff = 0, HAL_RadioLED_kGreen = 1,
HAL_RadioLED_kRed = 2, HAL_RadioLED_kOrange = 3};
#ifdef __cplusplus
extern "C" {
#endif
/**
* Set the state of the "Radio" LED.
* @param state The state to set the LED to.
* @param[out] status the error code, or 0 for success
*/
void HAL_SetRadioLEDState(HAL_RadioLEDState state, int32_t* status);
/**
* Get the state of the "Radio" LED.
*
* @param[out] status the error code, or 0 for success
* @return The state of the LED.
*/
HAL_RadioLEDState HAL_GetRadioLEDState(int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -6,6 +6,7 @@
#include <cstddef>
#include "hal/LEDs.h"
#include "hal/Types.h"
#include "hal/simulation/NotifyListener.h"
@@ -145,9 +146,6 @@ void HALSIM_CancelRoboRioCommentsCallback(int32_t uid);
size_t HALSIM_GetRoboRioComments(char* buffer, size_t size);
void HALSIM_SetRoboRioComments(const char* comments, size_t size);
void HALSIM_RegisterRoboRioAllCallbacks(HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
int32_t HALSIM_RegisterRoboRioCPUTempCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
@@ -155,6 +153,15 @@ void HALSIM_CancelRoboRioCPUTempCallback(int32_t uid);
double HALSIM_GetRoboRioCPUTemp(void);
void HALSIM_SetRoboRioCPUTemp(double cpuTemp);
int32_t HALSIM_RegisterRoboRioRadioLEDStateCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify);
void HALSIM_CancelRoboRioRadioLEDStateCallback(int32_t uid);
HAL_RadioLEDState HALSIM_GetRoboRioRadioLEDState(void);
void HALSIM_SetRoboRioRadioLEDState(HAL_RadioLEDState state);
void HALSIM_RegisterRoboRioAllCallbacks(HAL_NotifyCallback callback,
void* param, HAL_Bool initialNotify);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -0,0 +1,21 @@
// 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 "hal/LEDs.h"
#include "hal/simulation/RoboRioData.h"
namespace hal::init {
void InitializeLEDs() {}
} // namespace hal::init
extern "C" {
void HAL_SetRadioLEDState(HAL_RadioLEDState state, int32_t* status) {
HALSIM_SetRoboRioRadioLEDState(state);
}
HAL_RadioLEDState HAL_GetRadioLEDState(int32_t* status) {
return HALSIM_GetRoboRioRadioLEDState();
}
} // extern "C"

View File

@@ -136,6 +136,7 @@ DEFINE_CAPI(int32_t, UserFaults3V3, userFaults3V3)
DEFINE_CAPI(double, BrownoutVoltage, brownoutVoltage)
DEFINE_CAPI(double, CPUTemp, cpuTemp)
DEFINE_CAPI(int32_t, TeamNumber, teamNumber)
DEFINE_CAPI(HAL_RadioLEDState, RadioLEDState, radioLedState)
int32_t HALSIM_RegisterRoboRioSerialNumberCallback(
HAL_RoboRioStringCallback callback, void* param, HAL_Bool initialNotify) {
@@ -192,5 +193,6 @@ void HALSIM_RegisterRoboRioAllCallbacks(HAL_NotifyCallback callback,
REGISTER(userFaults3V3);
REGISTER(brownoutVoltage);
REGISTER(cpuTemp);
REGISTER(radioLedState);
}
} // extern "C"

View File

@@ -32,10 +32,15 @@ class RoboRioData {
HAL_SIMDATAVALUE_DEFINE_NAME(BrownoutVoltage)
HAL_SIMDATAVALUE_DEFINE_NAME(CPUTemp)
HAL_SIMDATAVALUE_DEFINE_NAME(TeamNumber)
HAL_SIMDATAVALUE_DEFINE_NAME(RadioLEDState)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(SerialNumber)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(Comments);
static inline HAL_Value MakeRadioLEDStateValue(HAL_RadioLEDState value) {
return HAL_MakeEnum(value);
}
public:
SimDataValue<HAL_Bool, HAL_MakeBoolean, GetFPGAButtonName> fpgaButton{false};
SimDataValue<double, HAL_MakeDouble, GetVInVoltageName> vInVoltage{12.0};
@@ -61,6 +66,8 @@ class RoboRioData {
6.75};
SimDataValue<double, HAL_MakeDouble, GetCPUTempName> cpuTemp{45.0};
SimDataValue<int32_t, HAL_MakeInt, GetTeamNumberName> teamNumber{0};
SimDataValue<HAL_RadioLEDState, MakeRadioLEDStateValue, GetRadioLEDStateName>
radioLedState{HAL_RadioLED_kOff};
int32_t RegisterSerialNumberCallback(HAL_RoboRioStringCallback callback,
void* param, HAL_Bool initialNotify);

View File

@@ -8,6 +8,7 @@
#include <hal/CAN.h>
#include <hal/HALBase.h>
#include <hal/LEDs.h>
#include <hal/Power.h>
#include "frc/Errors.h"
@@ -230,6 +231,30 @@ units::celsius_t RobotController::GetCPUTemp() {
return units::celsius_t{retVal};
}
static_assert(RadioLEDState::kOff ==
static_cast<RadioLEDState>(HAL_RadioLEDState::HAL_RadioLED_kOff));
static_assert(
RadioLEDState::kGreen ==
static_cast<RadioLEDState>(HAL_RadioLEDState::HAL_RadioLED_kGreen));
static_assert(RadioLEDState::kRed ==
static_cast<RadioLEDState>(HAL_RadioLEDState::HAL_RadioLED_kRed));
static_assert(
RadioLEDState::kOrange ==
static_cast<RadioLEDState>(HAL_RadioLEDState::HAL_RadioLED_kOrange));
void RobotController::SetRadioLEDState(RadioLEDState state) {
int32_t status = 0;
HAL_SetRadioLEDState(static_cast<HAL_RadioLEDState>(state), &status);
FRC_CheckErrorStatus(status, "SetRadioLEDState");
}
RadioLEDState RobotController::GetRadioLEDState() {
int32_t status = 0;
auto retVal = static_cast<RadioLEDState>(HAL_GetRadioLEDState(&status));
FRC_CheckErrorStatus(status, "GetRadioLEDState");
return retVal;
}
CANStatus RobotController::GetCANStatus() {
int32_t status = 0;
float percentBusUtilization = 0;

View File

@@ -338,6 +338,23 @@ void RoboRioSim::SetComments(std::string_view comments) {
HALSIM_SetRoboRioComments(comments.data(), comments.size());
}
std::unique_ptr<CallbackStore> RoboRioSim::RegisterRadioLEDStateCallback(
NotifyCallback callback, bool initialNotify) {
auto store = std::make_unique<CallbackStore>(
-1, callback, &HALSIM_CancelRoboRioRadioLEDStateCallback);
store->SetUid(HALSIM_RegisterRoboRioRadioLEDStateCallback(
&CallbackStoreThunk, store.get(), initialNotify));
return store;
}
RadioLEDState RoboRioSim::GetRadioLEDState() {
return static_cast<RadioLEDState>(HALSIM_GetRoboRioRadioLEDState());
}
void RoboRioSim::SetRadioLEDState(RadioLEDState state) {
HALSIM_SetRoboRioRadioLEDState(static_cast<HAL_RadioLEDState>(state));
}
void RoboRioSim::ResetData() {
HALSIM_ResetRoboRioData();
}

View File

@@ -21,6 +21,8 @@ struct CANStatus {
int transmitErrorCount;
};
enum RadioLEDState { kOff = 0, kGreen = 1, kRed = 2, kOrange = 3 };
class RobotController {
public:
RobotController() = delete;
@@ -274,6 +276,23 @@ class RobotController {
*/
static units::celsius_t GetCPUTemp();
/**
* Set the state of the "Radio" LED. On the RoboRIO, this writes to sysfs, so
* this function should not be called multiple times per loop cycle to avoid
* overruns.
* @param state The state to set the LED to.
*/
static void SetRadioLEDState(RadioLEDState state);
/**
* Get the state of the "Radio" LED. On the RoboRIO, this reads from sysfs, so
* this function should not be called multiple times per loop cycle to avoid
* overruns.
*
* @return The state of the LED.
*/
static RadioLEDState GetRadioLEDState();
/**
* Get the current status of the CAN bus.
*

View File

@@ -11,6 +11,7 @@
#include <units/temperature.h>
#include <units/voltage.h>
#include "frc/RobotController.h"
#include "frc/simulation/CallbackStore.h"
namespace frc::sim {
@@ -514,6 +515,32 @@ class RoboRioSim {
*/
static void SetComments(std::string_view comments);
/**
* Register a callback to be run whenever the Radio led state changes.
*
* @param callback the callback
* @param initialNotify whether the callback should be called with the
* initial value
* @return the CallbackStore object associated with this callback
*/
[[nodiscard]]
static std::unique_ptr<CallbackStore> RegisterRadioLEDStateCallback(
NotifyCallback callback, bool initialNotify);
/**
* Get the state of the radio led.
*
* @return The state of the radio led.
*/
static RadioLEDState GetRadioLEDState();
/**
* Set the state of the radio led.
*
* @param state The state of the radio led.
*/
static void SetRadioLEDState(RadioLEDState state);
/**
* Reset all simulation data.
*/

View File

@@ -274,4 +274,26 @@ TEST(RoboRioSimTest, SetComments) {
EXPECT_EQ(kCommentsTruncated, RobotController::GetComments());
}
TEST(RoboRioSimTest, SetRadioLEDState) {
RoboRioSim::ResetData();
EnumCallback callback;
auto cbHandle =
RoboRioSim::RegisterRadioLEDStateCallback(callback.GetCallback(), false);
RobotController::SetRadioLEDState(RadioLEDState::kGreen);
EXPECT_TRUE(callback.WasTriggered());
EXPECT_EQ(RadioLEDState::kGreen, callback.GetLastValue());
EXPECT_EQ(RadioLEDState::kGreen, RoboRioSim::GetRadioLEDState());
EXPECT_EQ(RadioLEDState::kGreen, RobotController::GetRadioLEDState());
callback.Reset();
RoboRioSim::SetRadioLEDState(RadioLEDState::kOrange);
EXPECT_TRUE(callback.WasTriggered());
EXPECT_EQ(RadioLEDState::kOrange, callback.GetLastValue());
EXPECT_EQ(RadioLEDState::kOrange, RoboRioSim::GetRadioLEDState());
EXPECT_EQ(RadioLEDState::kOrange, RobotController::GetRadioLEDState());
}
} // namespace frc::sim

View File

@@ -6,6 +6,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.HALUtil;
import edu.wpi.first.hal.LEDJNI;
import edu.wpi.first.hal.PowerJNI;
import edu.wpi.first.hal.can.CANJNI;
import edu.wpi.first.hal.can.CANStatus;
@@ -315,6 +316,66 @@ public final class RobotController {
return PowerJNI.getCPUTemp();
}
/** State for the radio led. */
public enum RadioLEDState {
/** Off. */
kOff(LEDJNI.RADIO_LED_STATE_OFF),
/** Green. */
kGreen(LEDJNI.RADIO_LED_STATE_GREEN),
/** Red. */
kRed(LEDJNI.RADIO_LED_STATE_RED),
/** Orange. */
kOrange(LEDJNI.RADIO_LED_STATE_ORANGE);
/** The native value for this state. */
public final int value;
RadioLEDState(int value) {
this.value = value;
}
/**
* Gets a state from an int value.
*
* @param value int value
* @return state
*/
public static RadioLEDState fromValue(int value) {
switch (value) {
case LEDJNI.RADIO_LED_STATE_OFF:
return RadioLEDState.kOff;
case LEDJNI.RADIO_LED_STATE_GREEN:
return RadioLEDState.kGreen;
case LEDJNI.RADIO_LED_STATE_RED:
return RadioLEDState.kRed;
case LEDJNI.RADIO_LED_STATE_ORANGE:
return RadioLEDState.kOrange;
default:
return RadioLEDState.kOff;
}
}
}
/**
* Set the state of the "Radio" LED. On the RoboRIO, this writes to sysfs, so this function should
* not be called multiple times per loop cycle to avoid overruns.
*
* @param state The state to set the LED to.
*/
public static void setRadioLEDState(RadioLEDState state) {
LEDJNI.setRadioLEDState(state.value);
}
/**
* Get the state of the "Radio" LED. On the RoboRIO, this reads from sysfs, so this function
* should not be called multiple times per loop cycle to avoid overruns.
*
* @return The state of the LED.
*/
public static RadioLEDState getRadioLEDState() {
return RadioLEDState.fromValue(LEDJNI.getRadioLEDState());
}
/**
* Get the current status of the CAN bus.
*

View File

@@ -6,6 +6,8 @@ package edu.wpi.first.wpilibj.simulation;
import edu.wpi.first.hal.simulation.NotifyCallback;
import edu.wpi.first.hal.simulation.RoboRioDataJNI;
import edu.wpi.first.wpilibj.RobotController;
import edu.wpi.first.wpilibj.RobotController.RadioLEDState;
/** A utility class to control a simulated RoboRIO. */
public final class RoboRioSim {
@@ -625,6 +627,38 @@ public final class RoboRioSim {
RoboRioDataJNI.setComments(comments);
}
/**
* Register a callback to be run whenever the Radio led state changes.
*
* @param callback the callback
* @param initialNotify whether to call the callback with the initial state
* @return the {@link CallbackStore} object associated with this callback. Save a reference to
* this object so GC doesn't cancel the callback.
*/
public static CallbackStore registerRadioLEDStateCallback(
NotifyCallback callback, boolean initialNotify) {
int uid = RoboRioDataJNI.registerRadioLEDStateCallback(callback, initialNotify);
return new CallbackStore(uid, RoboRioDataJNI::cancelRadioLEDStateCallback);
}
/**
* Get the state of the radio led.
*
* @return The state of the radio led.
*/
public static RadioLEDState getRadioLEDState() {
return RadioLEDState.fromValue(RoboRioDataJNI.getRadioLEDState());
}
/**
* Set the state of the radio led.
*
* @param state The state of the radio led.
*/
public static void setRadioLEDState(RobotController.RadioLEDState state) {
RoboRioDataJNI.setRadioLEDState(state.value);
}
/** Reset all simulation data. */
public static void resetData() {
RoboRioDataJNI.resetData();

View File

@@ -10,8 +10,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import edu.wpi.first.hal.HALUtil;
import edu.wpi.first.wpilibj.RobotController;
import edu.wpi.first.wpilibj.RobotController.RadioLEDState;
import edu.wpi.first.wpilibj.simulation.testutils.BooleanCallback;
import edu.wpi.first.wpilibj.simulation.testutils.DoubleCallback;
import edu.wpi.first.wpilibj.simulation.testutils.EnumCallback;
import edu.wpi.first.wpilibj.simulation.testutils.IntCallback;
import org.junit.jupiter.api.Test;
@@ -279,4 +281,26 @@ class RoboRioSimTest {
assertEquals(kCommentsTruncated, RoboRioSim.getComments());
assertEquals(kCommentsTruncated, RobotController.getComments());
}
@Test
void testRadioLEDState() {
RoboRioSim.resetData();
EnumCallback callback = new EnumCallback();
try (CallbackStore cb = RoboRioSim.registerRadioLEDStateCallback(callback, false)) {
RobotController.setRadioLEDState(RadioLEDState.kGreen);
assertTrue(callback.wasTriggered());
assertEquals(RadioLEDState.kGreen.value, callback.getSetValue());
assertEquals(RadioLEDState.kGreen, RoboRioSim.getRadioLEDState());
assertEquals(RadioLEDState.kGreen, RobotController.getRadioLEDState());
callback.reset();
RoboRioSim.setRadioLEDState(RadioLEDState.kOrange);
assertTrue(callback.wasTriggered());
assertEquals(RadioLEDState.kOrange.value, callback.getSetValue());
assertEquals(RadioLEDState.kOrange, RoboRioSim.getRadioLEDState());
assertEquals(RadioLEDState.kOrange, RobotController.getRadioLEDState());
}
}
}