blob: 0d4999fe19b520c96cb86cbd040fc1783f62b677 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "frc/Encoder.h" // NOLINT(build/include_order)
6
James Kuszmaulb13e13f2023-11-22 20:44:04 -08007#include <gtest/gtest.h>
Austin Schuh812d0d12021-11-04 20:16:48 -07008#include <units/time.h>
9
Brian Silverman8fce7482020-01-05 13:18:21 -080010#include "TestBench.h"
11#include "frc/AnalogOutput.h"
12#include "frc/AnalogTrigger.h"
13#include "frc/DigitalOutput.h"
14#include "frc/Timer.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080015
Austin Schuh812d0d12021-11-04 20:16:48 -070016static constexpr auto kDelayTime = 1_ms;
Brian Silverman8fce7482020-01-05 13:18:21 -080017
18class FakeEncoderTest : public testing::Test {
19 protected:
Austin Schuh812d0d12021-11-04 20:16:48 -070020 frc::DigitalOutput m_outputA{TestBench::kLoop2OutputChannel};
21 frc::DigitalOutput m_outputB{TestBench::kLoop1OutputChannel};
22 frc::AnalogOutput m_indexOutput{TestBench::kAnalogOutputChannel};
Brian Silverman8fce7482020-01-05 13:18:21 -080023
Austin Schuh812d0d12021-11-04 20:16:48 -070024 frc::Encoder m_encoder{TestBench::kLoop1InputChannel,
25 TestBench::kLoop2InputChannel};
26 frc::AnalogTrigger m_indexAnalogTrigger{TestBench::kFakeAnalogOutputChannel};
27 std::shared_ptr<frc::AnalogTriggerOutput> m_indexAnalogTriggerOutput =
28 m_indexAnalogTrigger.CreateOutput(frc::AnalogTriggerType::kState);
Brian Silverman8fce7482020-01-05 13:18:21 -080029
Austin Schuh812d0d12021-11-04 20:16:48 -070030 FakeEncoderTest() {
31 m_outputA.Set(false);
32 m_outputB.Set(false);
33 m_indexAnalogTrigger.SetLimitsVoltage(2.0, 3.0);
Brian Silverman8fce7482020-01-05 13:18:21 -080034 }
35
36 /**
37 * Output pulses to the encoder's input channels to simulate a change of 100
38 * ticks
39 */
40 void Simulate100QuadratureTicks() {
41 for (int32_t i = 0; i < 100; i++) {
Austin Schuh812d0d12021-11-04 20:16:48 -070042 m_outputA.Set(true);
43 frc::Wait(kDelayTime);
44 m_outputB.Set(true);
45 frc::Wait(kDelayTime);
46 m_outputA.Set(false);
47 frc::Wait(kDelayTime);
48 m_outputB.Set(false);
49 frc::Wait(kDelayTime);
Brian Silverman8fce7482020-01-05 13:18:21 -080050 }
51 }
52
53 void SetIndexHigh() {
Austin Schuh812d0d12021-11-04 20:16:48 -070054 m_indexOutput.SetVoltage(5.0);
55 frc::Wait(kDelayTime);
Brian Silverman8fce7482020-01-05 13:18:21 -080056 }
57
58 void SetIndexLow() {
Austin Schuh812d0d12021-11-04 20:16:48 -070059 m_indexOutput.SetVoltage(0.0);
60 frc::Wait(kDelayTime);
Brian Silverman8fce7482020-01-05 13:18:21 -080061 }
62};
63
64/**
James Kuszmaulb13e13f2023-11-22 20:44:04 -080065 * Test the encoder by resetting it to 0 and reading the value.
Brian Silverman8fce7482020-01-05 13:18:21 -080066 */
Austin Schuh812d0d12021-11-04 20:16:48 -070067TEST_F(FakeEncoderTest, DefaultState) {
68 EXPECT_DOUBLE_EQ(0.0, m_encoder.Get()) << "The encoder did not start at 0.";
Brian Silverman8fce7482020-01-05 13:18:21 -080069}
70
71/**
72 * Test the encoder by setting the digital outputs and reading the value.
73 */
Austin Schuh812d0d12021-11-04 20:16:48 -070074TEST_F(FakeEncoderTest, CountUp) {
75 m_encoder.Reset();
Brian Silverman8fce7482020-01-05 13:18:21 -080076 Simulate100QuadratureTicks();
77
Austin Schuh812d0d12021-11-04 20:16:48 -070078 EXPECT_DOUBLE_EQ(100.0, m_encoder.Get()) << "Encoder did not count to 100.";
Brian Silverman8fce7482020-01-05 13:18:21 -080079}
80
81/**
82 * Test that the encoder can stay reset while the index source is high
83 */
Austin Schuh812d0d12021-11-04 20:16:48 -070084TEST_F(FakeEncoderTest, ResetWhileHigh) {
85 m_encoder.SetIndexSource(*m_indexAnalogTriggerOutput,
86 frc::Encoder::IndexingType::kResetWhileHigh);
Brian Silverman8fce7482020-01-05 13:18:21 -080087
88 SetIndexLow();
89 Simulate100QuadratureTicks();
90 SetIndexHigh();
Austin Schuh812d0d12021-11-04 20:16:48 -070091 EXPECT_EQ(0, m_encoder.Get());
Brian Silverman8fce7482020-01-05 13:18:21 -080092
93 Simulate100QuadratureTicks();
Austin Schuh812d0d12021-11-04 20:16:48 -070094 EXPECT_EQ(0, m_encoder.Get());
Brian Silverman8fce7482020-01-05 13:18:21 -080095}
96
97/**
98 * Test that the encoder can reset when the index source goes from low to high
99 */
Austin Schuh812d0d12021-11-04 20:16:48 -0700100TEST_F(FakeEncoderTest, ResetOnRisingEdge) {
101 m_encoder.SetIndexSource(*m_indexAnalogTriggerOutput,
102 frc::Encoder::IndexingType::kResetOnRisingEdge);
Brian Silverman8fce7482020-01-05 13:18:21 -0800103
104 SetIndexLow();
105 Simulate100QuadratureTicks();
106 SetIndexHigh();
Austin Schuh812d0d12021-11-04 20:16:48 -0700107 EXPECT_EQ(0, m_encoder.Get());
Brian Silverman8fce7482020-01-05 13:18:21 -0800108
109 Simulate100QuadratureTicks();
Austin Schuh812d0d12021-11-04 20:16:48 -0700110 EXPECT_EQ(100, m_encoder.Get());
Brian Silverman8fce7482020-01-05 13:18:21 -0800111}
112
113/**
114 * Test that the encoder can stay reset while the index source is low
115 */
Austin Schuh812d0d12021-11-04 20:16:48 -0700116TEST_F(FakeEncoderTest, ResetWhileLow) {
117 m_encoder.SetIndexSource(*m_indexAnalogTriggerOutput,
118 frc::Encoder::IndexingType::kResetWhileLow);
Brian Silverman8fce7482020-01-05 13:18:21 -0800119
120 SetIndexHigh();
121 Simulate100QuadratureTicks();
122 SetIndexLow();
Austin Schuh812d0d12021-11-04 20:16:48 -0700123 EXPECT_EQ(0, m_encoder.Get());
Brian Silverman8fce7482020-01-05 13:18:21 -0800124
125 Simulate100QuadratureTicks();
Austin Schuh812d0d12021-11-04 20:16:48 -0700126 EXPECT_EQ(0, m_encoder.Get());
Brian Silverman8fce7482020-01-05 13:18:21 -0800127}
128
129/**
130 * Test that the encoder can reset when the index source goes from high to low
131 */
Austin Schuh812d0d12021-11-04 20:16:48 -0700132TEST_F(FakeEncoderTest, ResetOnFallingEdge) {
133 m_encoder.SetIndexSource(*m_indexAnalogTriggerOutput,
134 frc::Encoder::IndexingType::kResetOnFallingEdge);
Brian Silverman8fce7482020-01-05 13:18:21 -0800135
136 SetIndexHigh();
137 Simulate100QuadratureTicks();
138 SetIndexLow();
Austin Schuh812d0d12021-11-04 20:16:48 -0700139 EXPECT_EQ(0, m_encoder.Get());
Brian Silverman8fce7482020-01-05 13:18:21 -0800140
141 Simulate100QuadratureTicks();
Austin Schuh812d0d12021-11-04 20:16:48 -0700142 EXPECT_EQ(100, m_encoder.Get());
Brian Silverman8fce7482020-01-05 13:18:21 -0800143}