blob: 1423e6eb7ef47c432fb65d4b059c9e4b1228d7f0 [file] [log] [blame]
Brian Silvermanf7f267a2017-02-04 16:16:08 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2014-2017. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "AnalogInput.h"
9#include "Compressor.h"
10#include "DigitalInput.h"
11#include "DigitalOutput.h"
12#include "DoubleSolenoid.h"
13#include "Solenoid.h"
14#include "TestBench.h"
15#include "Timer.h"
16#include "gtest/gtest.h"
17
18using namespace frc;
19
20/* The PCM switches the compressor up to a couple seconds after the pressure
21 switch changes. */
22static const double kCompressorDelayTime = 3.0;
23
24/* Solenoids should change much more quickly */
25static const double kSolenoidDelayTime = 0.5;
26
27/* The voltage divider on the test bench should bring the compressor output
28 to around these values. */
29static const double kCompressorOnVoltage = 5.00;
30static const double kCompressorOffVoltage = 1.68;
31
32class PCMTest : public testing::Test {
33 protected:
34 Compressor* m_compressor;
35
36 DigitalOutput* m_fakePressureSwitch;
37 AnalogInput* m_fakeCompressor;
38 DoubleSolenoid* m_doubleSolenoid;
39 DigitalInput *m_fakeSolenoid1, *m_fakeSolenoid2;
40
41 void SetUp() override {
42 m_compressor = new Compressor();
43
44 m_fakePressureSwitch =
45 new DigitalOutput(TestBench::kFakePressureSwitchChannel);
46 m_fakeCompressor = new AnalogInput(TestBench::kFakeCompressorChannel);
47 m_fakeSolenoid1 = new DigitalInput(TestBench::kFakeSolenoid1Channel);
48 m_fakeSolenoid2 = new DigitalInput(TestBench::kFakeSolenoid2Channel);
49 }
50
51 void TearDown() override {
52 delete m_compressor;
53 delete m_fakePressureSwitch;
54 delete m_fakeCompressor;
55 delete m_fakeSolenoid1;
56 delete m_fakeSolenoid2;
57 }
58
59 void Reset() {
60 m_compressor->Stop();
61 m_fakePressureSwitch->Set(false);
62 }
63};
64
65/**
66 * Test if the compressor turns on and off when the pressure switch is toggled
67 */
68TEST_F(PCMTest, PressureSwitch) {
69 Reset();
70
71 m_compressor->SetClosedLoopControl(true);
72
73 // Turn on the compressor
74 m_fakePressureSwitch->Set(true);
75 Wait(kCompressorDelayTime);
76 EXPECT_NEAR(kCompressorOnVoltage, m_fakeCompressor->GetVoltage(), 0.5)
77 << "Compressor did not turn on when the pressure switch turned on.";
78
79 // Turn off the compressor
80 m_fakePressureSwitch->Set(false);
81 Wait(kCompressorDelayTime);
82 EXPECT_NEAR(kCompressorOffVoltage, m_fakeCompressor->GetVoltage(), 0.5)
83 << "Compressor did not turn off when the pressure switch turned off.";
84}
85
86/**
87 * Test if the correct solenoids turn on and off when they should
88 */
89TEST_F(PCMTest, Solenoid) {
90 Reset();
91 Solenoid solenoid1(TestBench::kSolenoidChannel1);
92 Solenoid solenoid2(TestBench::kSolenoidChannel2);
93
94 // Turn both solenoids off
95 solenoid1.Set(false);
96 solenoid2.Set(false);
97 Wait(kSolenoidDelayTime);
98 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
99 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
100 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
101 EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
102
103 // Turn one solenoid on and one off
104 solenoid1.Set(true);
105 solenoid2.Set(false);
106 Wait(kSolenoidDelayTime);
107 EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
108 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
109 EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
110 EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
111
112 // Turn one solenoid on and one off
113 solenoid1.Set(false);
114 solenoid2.Set(true);
115 Wait(kSolenoidDelayTime);
116 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
117 EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
118 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
119 EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
120
121 // Turn both on
122 solenoid1.Set(true);
123 solenoid2.Set(true);
124 Wait(kSolenoidDelayTime);
125 EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
126 EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
127 EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
128 EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
129}
130
131/**
132 * Test if the correct solenoids turn on and off when they should when used
133 * with the DoubleSolenoid class.
134 */
135TEST_F(PCMTest, DoubleSolenoid) {
136 DoubleSolenoid solenoid(TestBench::kSolenoidChannel1,
137 TestBench::kSolenoidChannel2);
138
139 solenoid.Set(DoubleSolenoid::kOff);
140 Wait(kSolenoidDelayTime);
141 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
142 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
143 EXPECT_TRUE(solenoid.Get() == DoubleSolenoid::kOff)
144 << "Solenoid does not read off";
145
146 solenoid.Set(DoubleSolenoid::kForward);
147 Wait(kSolenoidDelayTime);
148 EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
149 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
150 EXPECT_TRUE(solenoid.Get() == DoubleSolenoid::kForward)
151 << "Solenoid does not read forward";
152
153 solenoid.Set(DoubleSolenoid::kReverse);
154 Wait(kSolenoidDelayTime);
155 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
156 EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
157 EXPECT_TRUE(solenoid.Get() == DoubleSolenoid::kReverse)
158 << "Solenoid does not read reverse";
159}