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