blob: 5be4d3fe85435d35b244b381ec2bc2f8a544565b [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2014-2018 FIRST. 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 "TestBench.h"
9#include "frc/AnalogInput.h"
10#include "frc/Compressor.h"
11#include "frc/DigitalInput.h"
12#include "frc/DigitalOutput.h"
13#include "frc/DoubleSolenoid.h"
14#include "frc/Solenoid.h"
15#include "frc/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}
160
161TEST_F(PCMTest, OneShot) {
162 Reset();
163 Solenoid solenoid1(TestBench::kSolenoidChannel1);
164 Solenoid solenoid2(TestBench::kSolenoidChannel2);
165
166 // Turn both solenoids off
167 solenoid1.Set(false);
168 solenoid2.Set(false);
169 Wait(kSolenoidDelayTime);
170 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
171 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
172 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
173 EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
174
175 // Pulse Solenoid #1 on, and turn Solenoid #2 off
176 solenoid1.SetPulseDuration(2 * kSolenoidDelayTime);
177 solenoid2.Set(false);
178 solenoid1.StartPulse();
179 Wait(kSolenoidDelayTime);
180 EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
181 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
182 EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
183 EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
184 Wait(2 * kSolenoidDelayTime);
185 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
186 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
187 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
188 EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
189
190 // Turn Solenoid #1 off, and pulse Solenoid #2 on
191 solenoid1.Set(false);
192 solenoid2.SetPulseDuration(2 * kSolenoidDelayTime);
193 solenoid2.StartPulse();
194 Wait(kSolenoidDelayTime);
195 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
196 EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
197 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
198 EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
199 Wait(2 * kSolenoidDelayTime);
200 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
201 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
202 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
203 EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
204
205 // Pulse both Solenoids on
206 solenoid1.SetPulseDuration(2 * kSolenoidDelayTime);
207 solenoid2.SetPulseDuration(2 * kSolenoidDelayTime);
208 solenoid1.StartPulse();
209 solenoid2.StartPulse();
210 Wait(kSolenoidDelayTime);
211 EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
212 EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
213 EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
214 EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
215 Wait(2 * kSolenoidDelayTime);
216 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
217 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
218 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
219 EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
220
221 // Pulse both Solenoids on with different durations
222 solenoid1.SetPulseDuration(1.5 * kSolenoidDelayTime);
223 solenoid2.SetPulseDuration(2.5 * kSolenoidDelayTime);
224 solenoid1.StartPulse();
225 solenoid2.StartPulse();
226 Wait(kSolenoidDelayTime);
227 EXPECT_FALSE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn on";
228 EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
229 EXPECT_TRUE(solenoid1.Get()) << "Solenoid #1 did not read on";
230 EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
231 Wait(kSolenoidDelayTime);
232 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
233 EXPECT_FALSE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn on";
234 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
235 EXPECT_TRUE(solenoid2.Get()) << "Solenoid #2 did not read on";
236 Wait(2 * kSolenoidDelayTime);
237 EXPECT_TRUE(m_fakeSolenoid1->Get()) << "Solenoid #1 did not turn off";
238 EXPECT_TRUE(m_fakeSolenoid2->Get()) << "Solenoid #2 did not turn off";
239 EXPECT_FALSE(solenoid1.Get()) << "Solenoid #1 did not read off";
240 EXPECT_FALSE(solenoid2.Get()) << "Solenoid #2 did not read off";
241}