blob: 3a5dbbbae2ac4896efdff8c3eb955c3c7f37bd64 [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2014. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code
4 */
5/* must be accompanied by the FIRST BSD license file in the root directory of */
6/* the project. */
7/*----------------------------------------------------------------------------*/
8
9#include <AnalogOutput.h>
10#include <AnalogTrigger.h>
11#include <DigitalOutput.h>
12#include <Encoder.h>
13#include <Timer.h>
14#include "gtest/gtest.h"
15#include "TestBench.h"
16
17static const double kDelayTime = 0.001;
18
19class FakeEncoderTest : public testing::Test {
20 protected:
21 DigitalOutput *m_outputA;
22 DigitalOutput *m_outputB;
23 AnalogOutput *m_indexOutput;
24
25 Encoder *m_encoder;
26 AnalogTrigger *m_indexAnalogTrigger;
27 std::shared_ptr<AnalogTriggerOutput> m_indexAnalogTriggerOutput;
28
29 virtual void SetUp() override {
30 m_outputA = new DigitalOutput(TestBench::kLoop2OutputChannel);
31 m_outputB = new DigitalOutput(TestBench::kLoop1OutputChannel);
32 m_indexOutput = new AnalogOutput(TestBench::kAnalogOutputChannel);
33 m_outputA->Set(false);
34 m_outputB->Set(false);
35 m_encoder = new Encoder(TestBench::kLoop1InputChannel,
36 TestBench::kLoop2InputChannel);
37 m_indexAnalogTrigger =
38 new AnalogTrigger(TestBench::kFakeAnalogOutputChannel);
39 m_indexAnalogTrigger->SetLimitsVoltage(2.0, 3.0);
40 m_indexAnalogTriggerOutput =
41 m_indexAnalogTrigger->CreateOutput(AnalogTriggerType::kState);
42 }
43
44 virtual void TearDown() override {
45 delete m_outputA;
46 delete m_outputB;
47 delete m_indexOutput;
48 delete m_encoder;
49 delete m_indexAnalogTrigger;
50 }
51
52 /**
53 * Output pulses to the encoder's input channels to simulate a change of 100
54 * ticks
55 */
56 void Simulate100QuadratureTicks() {
57 for (int i = 0; i < 100; i++) {
58 m_outputA->Set(true);
59 Wait(kDelayTime);
60 m_outputB->Set(true);
61 Wait(kDelayTime);
62 m_outputA->Set(false);
63 Wait(kDelayTime);
64 m_outputB->Set(false);
65 Wait(kDelayTime);
66 }
67 }
68
69 void SetIndexHigh() {
70 m_indexOutput->SetVoltage(5.0);
71 Wait(kDelayTime);
72 }
73
74 void SetIndexLow() {
75 m_indexOutput->SetVoltage(0.0);
76 Wait(kDelayTime);
77 }
78};
79
80/**
81 * Test the encoder by reseting it to 0 and reading the value.
82 */
83TEST_F(FakeEncoderTest, TestDefaultState) {
84 EXPECT_FLOAT_EQ(0.0f, m_encoder->Get()) << "The encoder did not start at 0.";
85}
86
87/**
88 * Test the encoder by setting the digital outputs and reading the value.
89 */
90TEST_F(FakeEncoderTest, TestCountUp) {
91 m_encoder->Reset();
92 Simulate100QuadratureTicks();
93
94 EXPECT_FLOAT_EQ(100.0f, m_encoder->Get()) << "Encoder did not count to 100.";
95}
96
97/**
98 * Test that the encoder can stay reset while the index source is high
99 */
100TEST_F(FakeEncoderTest, TestResetWhileHigh) {
101 m_encoder->SetIndexSource(*m_indexAnalogTriggerOutput,
102 Encoder::IndexingType::kResetWhileHigh);
103
104 SetIndexLow();
105 Simulate100QuadratureTicks();
106 SetIndexHigh();
107 EXPECT_EQ(0, m_encoder->Get());
108
109 Simulate100QuadratureTicks();
110 EXPECT_EQ(0, m_encoder->Get());
111}
112
113/**
114 * Test that the encoder can reset when the index source goes from low to high
115 */
116TEST_F(FakeEncoderTest, TestResetOnRisingEdge) {
117 m_encoder->SetIndexSource(*m_indexAnalogTriggerOutput,
118 Encoder::IndexingType::kResetOnRisingEdge);
119
120 SetIndexLow();
121 Simulate100QuadratureTicks();
122 SetIndexHigh();
123 EXPECT_EQ(0, m_encoder->Get());
124
125 Simulate100QuadratureTicks();
126 EXPECT_EQ(100, m_encoder->Get());
127}
128
129/**
130 * Test that the encoder can stay reset while the index source is low
131 */
132TEST_F(FakeEncoderTest, TestResetWhileLow) {
133 m_encoder->SetIndexSource(*m_indexAnalogTriggerOutput,
134 Encoder::IndexingType::kResetWhileLow);
135
136 SetIndexHigh();
137 Simulate100QuadratureTicks();
138 SetIndexLow();
139 EXPECT_EQ(0, m_encoder->Get());
140
141 Simulate100QuadratureTicks();
142 EXPECT_EQ(0, m_encoder->Get());
143}
144
145/**
146 * Test that the encoder can reset when the index source goes from high to low
147 */
148TEST_F(FakeEncoderTest, TestResetOnFallingEdge) {
149 m_encoder->SetIndexSource(*m_indexAnalogTriggerOutput,
150 Encoder::IndexingType::kResetOnFallingEdge);
151
152 SetIndexHigh();
153 Simulate100QuadratureTicks();
154 SetIndexLow();
155 EXPECT_EQ(0, m_encoder->Get());
156
157 Simulate100QuadratureTicks();
158 EXPECT_EQ(100, m_encoder->Get());
159}