Squashed 'third_party/allwpilib_2019/' content from commit bd05dfa1c
Change-Id: I2b1c2250cdb9b055133780c33593292098c375b7
git-subtree-dir: third_party/allwpilib_2019
git-subtree-split: bd05dfa1c7cca74c4fac451e7b9d6a37e7b53447
diff --git a/wpilibcIntegrationTests/src/main/native/cpp/PCMTest.cpp b/wpilibcIntegrationTests/src/main/native/cpp/PCMTest.cpp
new file mode 100644
index 0000000..5be4d3f
--- /dev/null
+++ b/wpilibcIntegrationTests/src/main/native/cpp/PCMTest.cpp
@@ -0,0 +1,241 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) 2014-2018 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 "TestBench.h"
+#include "frc/AnalogInput.h"
+#include "frc/Compressor.h"
+#include "frc/DigitalInput.h"
+#include "frc/DigitalOutput.h"
+#include "frc/DoubleSolenoid.h"
+#include "frc/Solenoid.h"
+#include "frc/Timer.h"
+#include "gtest/gtest.h"
+
+using namespace frc;
+
+/* The PCM switches the compressor up to a couple seconds after the pressure
+ switch changes. */
+static const double kCompressorDelayTime = 3.0;
+
+/* Solenoids should change much more quickly */
+static const double kSolenoidDelayTime = 0.5;
+
+/* The voltage divider on the test bench should bring the compressor output
+ to around these values. */
+static const double kCompressorOnVoltage = 5.00;
+static const double kCompressorOffVoltage = 1.68;
+
+class PCMTest : public testing::Test {
+ protected:
+ Compressor* m_compressor;
+
+ DigitalOutput* m_fakePressureSwitch;
+ AnalogInput* m_fakeCompressor;
+ DoubleSolenoid* m_doubleSolenoid;
+ DigitalInput *m_fakeSolenoid1, *m_fakeSolenoid2;
+
+ void SetUp() override {
+ m_compressor = new Compressor();
+
+ m_fakePressureSwitch =
+ new DigitalOutput(TestBench::kFakePressureSwitchChannel);
+ m_fakeCompressor = new AnalogInput(TestBench::kFakeCompressorChannel);
+ m_fakeSolenoid1 = new DigitalInput(TestBench::kFakeSolenoid1Channel);
+ m_fakeSolenoid2 = new DigitalInput(TestBench::kFakeSolenoid2Channel);
+ }
+
+ void TearDown() override {
+ delete m_compressor;
+ delete m_fakePressureSwitch;
+ delete m_fakeCompressor;
+ delete m_fakeSolenoid1;
+ delete m_fakeSolenoid2;
+ }
+
+ void Reset() {
+ m_compressor->Stop();
+ m_fakePressureSwitch->Set(false);
+ }
+};
+
+/**
+ * Test if the compressor turns on and off when the pressure switch is toggled
+ */
+TEST_F(PCMTest, PressureSwitch) {
+ Reset();
+
+ m_compressor->SetClosedLoopControl(true);
+
+ // Turn on the compressor
+ m_fakePressureSwitch->Set(true);
+ Wait(kCompressorDelayTime);
+ EXPECT_NEAR(kCompressorOnVoltage, m_fakeCompressor->GetVoltage(), 0.5)
+ << "Compressor did not turn on when the pressure switch turned on.";
+
+ // Turn off the compressor
+ m_fakePressureSwitch->Set(false);
+ Wait(kCompressorDelayTime);
+ EXPECT_NEAR(kCompressorOffVoltage, m_fakeCompressor->GetVoltage(), 0.5)
+ << "Compressor did not turn off when the pressure switch turned off.";
+}
+
+/**
+ * Test if the correct solenoids turn on and off when they should
+ */
+TEST_F(PCMTest, Solenoid) {
+ Reset();
+ Solenoid solenoid1(TestBench::kSolenoidChannel1);
+ Solenoid solenoid2(TestBench::kSolenoidChannel2);
+
+ // Turn both solenoids off
+ solenoid1.Set(false);
+ solenoid2.Set(false);
+ Wait(kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
+
+ // Turn one solenoid on and one off
+ solenoid1.Set(true);
+ solenoid2.Set(false);
+ Wait(kSolenoidDelayTime);
+ EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
+ EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
+
+ // Turn one solenoid on and one off
+ solenoid1.Set(false);
+ solenoid2.Set(true);
+ Wait(kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
+
+ // Turn both on
+ solenoid1.Set(true);
+ solenoid2.Set(true);
+ Wait(kSolenoidDelayTime);
+ EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
+ EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
+ EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
+ EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
+}
+
+/**
+ * Test if the correct solenoids turn on and off when they should when used
+ * with the DoubleSolenoid class.
+ */
+TEST_F(PCMTest, DoubleSolenoid) {
+ DoubleSolenoid solenoid(TestBench::kSolenoidChannel1,
+ TestBench::kSolenoidChannel2);
+
+ solenoid.Set(DoubleSolenoid::kOff);
+ Wait(kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_TRUE(solenoid.Get() == DoubleSolenoid::kOff)
+ << "Solenoid does not read off";
+
+ solenoid.Set(DoubleSolenoid::kForward);
+ Wait(kSolenoidDelayTime);
+ EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_TRUE(solenoid.Get() == DoubleSolenoid::kForward)
+ << "Solenoid does not read forward";
+
+ solenoid.Set(DoubleSolenoid::kReverse);
+ Wait(kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
+ EXPECT_TRUE(solenoid.Get() == DoubleSolenoid::kReverse)
+ << "Solenoid does not read reverse";
+}
+
+TEST_F(PCMTest, OneShot) {
+ Reset();
+ Solenoid solenoid1(TestBench::kSolenoidChannel1);
+ Solenoid solenoid2(TestBench::kSolenoidChannel2);
+
+ // Turn both solenoids off
+ solenoid1.Set(false);
+ solenoid2.Set(false);
+ Wait(kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
+
+ // Pulse Solenoid #1 on, and turn Solenoid #2 off
+ solenoid1.SetPulseDuration(2 * kSolenoidDelayTime);
+ solenoid2.Set(false);
+ solenoid1.StartPulse();
+ Wait(kSolenoidDelayTime);
+ EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
+ EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
+ Wait(2 * kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
+
+ // Turn Solenoid #1 off, and pulse Solenoid #2 on
+ solenoid1.Set(false);
+ solenoid2.SetPulseDuration(2 * kSolenoidDelayTime);
+ solenoid2.StartPulse();
+ Wait(kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
+ Wait(2 * kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
+
+ // Pulse both Solenoids on
+ solenoid1.SetPulseDuration(2 * kSolenoidDelayTime);
+ solenoid2.SetPulseDuration(2 * kSolenoidDelayTime);
+ solenoid1.StartPulse();
+ solenoid2.StartPulse();
+ Wait(kSolenoidDelayTime);
+ EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
+ EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
+ EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
+ EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
+ Wait(2 * kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
+
+ // Pulse both Solenoids on with different durations
+ solenoid1.SetPulseDuration(1.5 * kSolenoidDelayTime);
+ solenoid2.SetPulseDuration(2.5 * kSolenoidDelayTime);
+ solenoid1.StartPulse();
+ solenoid2.StartPulse();
+ Wait(kSolenoidDelayTime);
+ EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
+ EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
+ EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
+ EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
+ Wait(kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
+ Wait(2 * kSolenoidDelayTime);
+ EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
+ EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
+ EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
+ EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
+}