mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-29 02:21:44 +00:00
[wpilib] Add method to enable/disable LiveWindow in test mode (#4678)
This commit is contained in:
@@ -94,6 +94,18 @@ void IterativeRobotBase::SetNetworkTablesFlushEnabled(bool enabled) {
|
||||
m_ntFlushEnabled = enabled;
|
||||
}
|
||||
|
||||
void IterativeRobotBase::EnableLiveWindowInTest(bool testLW) {
|
||||
if (IsTest()) {
|
||||
throw FRC_MakeError(err::IncompatibleMode,
|
||||
"Can't configure test mode while in test mode!");
|
||||
}
|
||||
m_lwEnabledInTest = testLW;
|
||||
}
|
||||
|
||||
bool IterativeRobotBase::IsLiveWindowEnabledInTest() {
|
||||
return m_lwEnabledInTest;
|
||||
}
|
||||
|
||||
units::second_t IterativeRobotBase::GetPeriod() const {
|
||||
return m_period;
|
||||
}
|
||||
@@ -125,8 +137,10 @@ void IterativeRobotBase::LoopFunc() {
|
||||
} else if (m_lastMode == Mode::kTeleop) {
|
||||
TeleopExit();
|
||||
} else if (m_lastMode == Mode::kTest) {
|
||||
LiveWindow::SetEnabled(false);
|
||||
Shuffleboard::DisableActuatorWidgets();
|
||||
if (m_lwEnabledInTest) {
|
||||
LiveWindow::SetEnabled(false);
|
||||
Shuffleboard::DisableActuatorWidgets();
|
||||
}
|
||||
TestExit();
|
||||
}
|
||||
|
||||
@@ -141,8 +155,10 @@ void IterativeRobotBase::LoopFunc() {
|
||||
TeleopInit();
|
||||
m_watchdog.AddEpoch("TeleopInit()");
|
||||
} else if (mode == Mode::kTest) {
|
||||
LiveWindow::SetEnabled(true);
|
||||
Shuffleboard::EnableActuatorWidgets();
|
||||
if (m_lwEnabledInTest) {
|
||||
LiveWindow::SetEnabled(true);
|
||||
Shuffleboard::EnableActuatorWidgets();
|
||||
}
|
||||
TestInit();
|
||||
m_watchdog.AddEpoch("TestInit()");
|
||||
}
|
||||
|
||||
@@ -201,6 +201,19 @@ class IterativeRobotBase : public RobotBase {
|
||||
*/
|
||||
void SetNetworkTablesFlushEnabled(bool enabled);
|
||||
|
||||
/**
|
||||
* Sets whether LiveWindow operation is enabled during test mode.
|
||||
*
|
||||
* @param testLW True to enable, false to disable. Defaults to true.
|
||||
* @throws if called in test mode.
|
||||
*/
|
||||
void EnableLiveWindowInTest(bool testLW);
|
||||
|
||||
/**
|
||||
* Whether LiveWindow operation is enabled during test mode.
|
||||
*/
|
||||
bool IsLiveWindowEnabledInTest();
|
||||
|
||||
/**
|
||||
* Gets time period between calls to Periodic() functions.
|
||||
*/
|
||||
@@ -228,6 +241,7 @@ class IterativeRobotBase : public RobotBase {
|
||||
units::second_t m_period;
|
||||
Watchdog m_watchdog;
|
||||
bool m_ntFlushEnabled = true;
|
||||
bool m_lwEnabledInTest = true;
|
||||
|
||||
void PrintLoopOverrunMessage();
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "frc/livewindow/LiveWindow.h"
|
||||
#include "frc/simulation/DriverStationSim.h"
|
||||
#include "frc/simulation/SimHooks.h"
|
||||
#include "gtest/gtest.h"
|
||||
@@ -16,7 +17,7 @@
|
||||
using namespace frc;
|
||||
|
||||
namespace {
|
||||
class TimedRobotTest : public ::testing::Test {
|
||||
class TimedRobotTest : public ::testing::TestWithParam<bool> {
|
||||
protected:
|
||||
void SetUp() override { frc::sim::PauseTiming(); }
|
||||
|
||||
@@ -304,8 +305,11 @@ TEST_F(TimedRobotTest, TeleopMode) {
|
||||
robotThread.join();
|
||||
}
|
||||
|
||||
TEST_F(TimedRobotTest, TestMode) {
|
||||
TEST_P(TimedRobotTest, TestMode) {
|
||||
bool isTestLW = GetParam();
|
||||
|
||||
MockRobot robot;
|
||||
robot.EnableLiveWindowInTest(isTestLW);
|
||||
|
||||
std::thread robotThread{[&] { robot.StartCompetition(); }};
|
||||
|
||||
@@ -321,6 +325,7 @@ TEST_F(TimedRobotTest, TestMode) {
|
||||
EXPECT_EQ(0u, robot.m_autonomousInitCount);
|
||||
EXPECT_EQ(0u, robot.m_teleopInitCount);
|
||||
EXPECT_EQ(0u, robot.m_testInitCount);
|
||||
EXPECT_FALSE(frc::LiveWindow::IsEnabled());
|
||||
|
||||
EXPECT_EQ(0u, robot.m_robotPeriodicCount);
|
||||
EXPECT_EQ(0u, robot.m_simulationPeriodicCount);
|
||||
@@ -342,6 +347,9 @@ TEST_F(TimedRobotTest, TestMode) {
|
||||
EXPECT_EQ(0u, robot.m_autonomousInitCount);
|
||||
EXPECT_EQ(0u, robot.m_teleopInitCount);
|
||||
EXPECT_EQ(1u, robot.m_testInitCount);
|
||||
EXPECT_EQ(isTestLW, frc::LiveWindow::IsEnabled());
|
||||
|
||||
EXPECT_THROW(robot.EnableLiveWindowInTest(isTestLW), std::runtime_error);
|
||||
|
||||
EXPECT_EQ(1u, robot.m_robotPeriodicCount);
|
||||
EXPECT_EQ(1u, robot.m_simulationPeriodicCount);
|
||||
@@ -376,6 +384,32 @@ TEST_F(TimedRobotTest, TestMode) {
|
||||
EXPECT_EQ(0u, robot.m_teleopExitCount);
|
||||
EXPECT_EQ(0u, robot.m_testExitCount);
|
||||
|
||||
frc::sim::DriverStationSim::SetEnabled(false);
|
||||
frc::sim::DriverStationSim::SetAutonomous(false);
|
||||
frc::sim::DriverStationSim::SetTest(false);
|
||||
frc::sim::DriverStationSim::NotifyNewData();
|
||||
frc::sim::StepTiming(20_ms); // Wait for Notifiers
|
||||
|
||||
EXPECT_EQ(1u, robot.m_robotInitCount);
|
||||
EXPECT_EQ(1u, robot.m_simulationInitCount);
|
||||
EXPECT_EQ(1u, robot.m_disabledInitCount);
|
||||
EXPECT_EQ(0u, robot.m_autonomousInitCount);
|
||||
EXPECT_EQ(0u, robot.m_teleopInitCount);
|
||||
EXPECT_EQ(1u, robot.m_testInitCount);
|
||||
EXPECT_FALSE(frc::LiveWindow::IsEnabled());
|
||||
|
||||
EXPECT_EQ(3u, robot.m_robotPeriodicCount);
|
||||
EXPECT_EQ(3u, robot.m_simulationPeriodicCount);
|
||||
EXPECT_EQ(1u, robot.m_disabledPeriodicCount);
|
||||
EXPECT_EQ(0u, robot.m_autonomousPeriodicCount);
|
||||
EXPECT_EQ(0u, robot.m_teleopPeriodicCount);
|
||||
EXPECT_EQ(2u, robot.m_testPeriodicCount);
|
||||
|
||||
EXPECT_EQ(0u, robot.m_disabledExitCount);
|
||||
EXPECT_EQ(0u, robot.m_autonomousExitCount);
|
||||
EXPECT_EQ(0u, robot.m_teleopExitCount);
|
||||
EXPECT_EQ(1u, robot.m_testExitCount);
|
||||
|
||||
robot.EndCompetition();
|
||||
robotThread.join();
|
||||
}
|
||||
@@ -572,3 +606,5 @@ TEST_F(TimedRobotTest, AddPeriodicWithOffset) {
|
||||
robot.EndCompetition();
|
||||
robotThread.join();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(TimedRobotTests, TimedRobotTest, testing::Bool());
|
||||
|
||||
@@ -10,6 +10,7 @@ import edu.wpi.first.networktables.NetworkTableInstance;
|
||||
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
|
||||
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
|
||||
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
|
||||
import java.util.ConcurrentModificationException;
|
||||
|
||||
/**
|
||||
* IterativeRobotBase implements a specific type of robot program framework, extending the RobotBase
|
||||
@@ -67,6 +68,7 @@ public abstract class IterativeRobotBase extends RobotBase {
|
||||
private final double m_period;
|
||||
private final Watchdog m_watchdog;
|
||||
private boolean m_ntFlushEnabled = true;
|
||||
private boolean m_lwEnabledInTest = true;
|
||||
|
||||
/**
|
||||
* Constructor for IterativeRobotBase.
|
||||
@@ -244,6 +246,28 @@ public abstract class IterativeRobotBase extends RobotBase {
|
||||
m_ntFlushEnabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether LiveWindow operation is enabled during test mode. Calling
|
||||
*
|
||||
* @param testLW True to enable, false to disable. Defaults to true.
|
||||
* @throws ConcurrentModificationException if this is called during test mode.
|
||||
*/
|
||||
public void enableLiveWindowInTest(boolean testLW) {
|
||||
if (isTest()) {
|
||||
throw new ConcurrentModificationException("Can't configure test mode while in test mode!");
|
||||
}
|
||||
m_lwEnabledInTest = testLW;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether LiveWindow operation is enabled during test mode.
|
||||
*
|
||||
* @return whether LiveWindow should be enabled in test mode.
|
||||
*/
|
||||
public boolean isLiveWindowEnabledInTest() {
|
||||
return m_lwEnabledInTest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets time period between calls to Periodic() functions.
|
||||
*
|
||||
@@ -281,8 +305,10 @@ public abstract class IterativeRobotBase extends RobotBase {
|
||||
} else if (m_lastMode == Mode.kTeleop) {
|
||||
teleopExit();
|
||||
} else if (m_lastMode == Mode.kTest) {
|
||||
LiveWindow.setEnabled(false);
|
||||
Shuffleboard.disableActuatorWidgets();
|
||||
if (m_lwEnabledInTest) {
|
||||
LiveWindow.setEnabled(false);
|
||||
Shuffleboard.disableActuatorWidgets();
|
||||
}
|
||||
testExit();
|
||||
}
|
||||
|
||||
@@ -297,8 +323,10 @@ public abstract class IterativeRobotBase extends RobotBase {
|
||||
teleopInit();
|
||||
m_watchdog.addEpoch("teleopInit()");
|
||||
} else if (mode == Mode.kTest) {
|
||||
LiveWindow.setEnabled(true);
|
||||
Shuffleboard.enableActuatorWidgets();
|
||||
if (m_lwEnabledInTest) {
|
||||
LiveWindow.setEnabled(true);
|
||||
Shuffleboard.enableActuatorWidgets();
|
||||
}
|
||||
testInit();
|
||||
m_watchdog.addEpoch("testInit()");
|
||||
}
|
||||
|
||||
@@ -5,14 +5,20 @@
|
||||
package edu.wpi.first.wpilibj;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
|
||||
import edu.wpi.first.wpilibj.simulation.DriverStationSim;
|
||||
import edu.wpi.first.wpilibj.simulation.SimHooks;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.parallel.ResourceLock;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
class TimedRobotTest {
|
||||
static class MockRobot extends TimedRobot {
|
||||
@@ -119,6 +125,7 @@ class TimedRobotTest {
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
SimHooks.pauseTiming();
|
||||
DriverStationSim.resetData();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@@ -391,10 +398,12 @@ class TimedRobotTest {
|
||||
robot.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ValueSource(booleans = {true, false})
|
||||
@ParameterizedTest
|
||||
@ResourceLock("timing")
|
||||
void testModeTest() {
|
||||
void testModeTest(boolean isLW) {
|
||||
MockRobot robot = new MockRobot();
|
||||
robot.enableLiveWindowInTest(isLW);
|
||||
|
||||
Thread robotThread =
|
||||
new Thread(
|
||||
@@ -415,6 +424,7 @@ class TimedRobotTest {
|
||||
assertEquals(0, robot.m_autonomousInitCount.get());
|
||||
assertEquals(0, robot.m_teleopInitCount.get());
|
||||
assertEquals(0, robot.m_testInitCount.get());
|
||||
assertFalse(LiveWindow.isEnabled());
|
||||
|
||||
assertEquals(0, robot.m_robotPeriodicCount.get());
|
||||
assertEquals(0, robot.m_simulationPeriodicCount.get());
|
||||
@@ -457,6 +467,9 @@ class TimedRobotTest {
|
||||
assertEquals(0, robot.m_autonomousInitCount.get());
|
||||
assertEquals(0, robot.m_teleopInitCount.get());
|
||||
assertEquals(1, robot.m_testInitCount.get());
|
||||
assertEquals(isLW, LiveWindow.isEnabled());
|
||||
|
||||
assertThrows(ConcurrentModificationException.class, () -> robot.enableLiveWindowInTest(isLW));
|
||||
|
||||
assertEquals(2, robot.m_robotPeriodicCount.get());
|
||||
assertEquals(2, robot.m_simulationPeriodicCount.get());
|
||||
@@ -470,6 +483,33 @@ class TimedRobotTest {
|
||||
assertEquals(0, robot.m_teleopExitCount.get());
|
||||
assertEquals(0, robot.m_testExitCount.get());
|
||||
|
||||
DriverStationSim.setEnabled(false);
|
||||
DriverStationSim.setAutonomous(false);
|
||||
DriverStationSim.setTest(false);
|
||||
DriverStationSim.notifyNewData();
|
||||
|
||||
SimHooks.stepTiming(0.02);
|
||||
|
||||
assertEquals(1, robot.m_robotInitCount.get());
|
||||
assertEquals(1, robot.m_simulationInitCount.get());
|
||||
assertEquals(1, robot.m_disabledInitCount.get());
|
||||
assertEquals(0, robot.m_autonomousInitCount.get());
|
||||
assertEquals(0, robot.m_teleopInitCount.get());
|
||||
assertEquals(1, robot.m_testInitCount.get());
|
||||
assertFalse(LiveWindow.isEnabled());
|
||||
|
||||
assertEquals(3, robot.m_robotPeriodicCount.get());
|
||||
assertEquals(3, robot.m_simulationPeriodicCount.get());
|
||||
assertEquals(1, robot.m_disabledPeriodicCount.get());
|
||||
assertEquals(0, robot.m_autonomousPeriodicCount.get());
|
||||
assertEquals(0, robot.m_teleopPeriodicCount.get());
|
||||
assertEquals(2, robot.m_testPeriodicCount.get());
|
||||
|
||||
assertEquals(0, robot.m_disabledExitCount.get());
|
||||
assertEquals(0, robot.m_autonomousExitCount.get());
|
||||
assertEquals(0, robot.m_teleopExitCount.get());
|
||||
assertEquals(1, robot.m_testExitCount.get());
|
||||
|
||||
robot.endCompetition();
|
||||
try {
|
||||
robotThread.interrupt();
|
||||
|
||||
Reference in New Issue
Block a user