blob: 3540095b0ca055345ab21780ecb10eda1b804493 [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.
4
5#include <units/time.h>
Brian Silverman8fce7482020-01-05 13:18:21 -08006
7#include "TestBench.h"
8#include "frc/AnalogInput.h"
9#include "frc/AnalogOutput.h"
10#include "frc/AnalogTrigger.h"
Austin Schuh812d0d12021-11-04 20:16:48 -070011#include "frc/AsynchronousInterrupt.h"
Brian Silverman8fce7482020-01-05 13:18:21 -080012#include "frc/Counter.h"
13#include "frc/Timer.h"
14#include "gtest/gtest.h"
15
Austin Schuh812d0d12021-11-04 20:16:48 -070016static constexpr auto kDelayTime = 10_ms;
Brian Silverman8fce7482020-01-05 13:18:21 -080017
18/**
19 * Test analog inputs and outputs by setting one and making sure the other
20 * matches.
21 */
Austin Schuh812d0d12021-11-04 20:16:48 -070022TEST(AnalogLoopTest, AnalogInputWorks) {
23 frc::AnalogInput input{TestBench::kFakeAnalogOutputChannel};
24 frc::AnalogOutput output{TestBench::kAnalogOutputChannel};
25
Brian Silverman8fce7482020-01-05 13:18:21 -080026 // Set the output voltage and check if the input measures the same voltage
27 for (int32_t i = 0; i < 50; i++) {
Austin Schuh812d0d12021-11-04 20:16:48 -070028 output.SetVoltage(i / 10.0);
Brian Silverman8fce7482020-01-05 13:18:21 -080029
Austin Schuh812d0d12021-11-04 20:16:48 -070030 frc::Wait(kDelayTime);
Brian Silverman8fce7482020-01-05 13:18:21 -080031
Austin Schuh812d0d12021-11-04 20:16:48 -070032 EXPECT_NEAR(output.GetVoltage(), input.GetVoltage(), 0.01);
Brian Silverman8fce7482020-01-05 13:18:21 -080033 }
34}
35
36/**
37 * Test if we can use an analog trigger to check if the output is within a
38 * range correctly.
39 */
Austin Schuh812d0d12021-11-04 20:16:48 -070040TEST(AnalogLoopTest, AnalogTriggerWorks) {
41 frc::AnalogInput input{TestBench::kFakeAnalogOutputChannel};
42 frc::AnalogOutput output{TestBench::kAnalogOutputChannel};
43
44 frc::AnalogTrigger trigger{&input};
Brian Silverman8fce7482020-01-05 13:18:21 -080045 trigger.SetLimitsVoltage(2.0, 3.0);
46
Austin Schuh812d0d12021-11-04 20:16:48 -070047 output.SetVoltage(1.0);
48 frc::Wait(kDelayTime);
Brian Silverman8fce7482020-01-05 13:18:21 -080049
50 EXPECT_FALSE(trigger.GetInWindow())
51 << "Analog trigger is in the window (2V, 3V)";
52 EXPECT_FALSE(trigger.GetTriggerState()) << "Analog trigger is on";
53
Austin Schuh812d0d12021-11-04 20:16:48 -070054 output.SetVoltage(2.5);
55 frc::Wait(kDelayTime);
Brian Silverman8fce7482020-01-05 13:18:21 -080056
57 EXPECT_TRUE(trigger.GetInWindow())
58 << "Analog trigger is not in the window (2V, 3V)";
59 EXPECT_FALSE(trigger.GetTriggerState()) << "Analog trigger is on";
60
Austin Schuh812d0d12021-11-04 20:16:48 -070061 output.SetVoltage(4.0);
62 frc::Wait(kDelayTime);
Brian Silverman8fce7482020-01-05 13:18:21 -080063
64 EXPECT_FALSE(trigger.GetInWindow())
65 << "Analog trigger is in the window (2V, 3V)";
66 EXPECT_TRUE(trigger.GetTriggerState()) << "Analog trigger is not on";
67}
68
69/**
70 * Test if we can count the right number of ticks from an analog trigger with
71 * a counter.
72 */
Austin Schuh812d0d12021-11-04 20:16:48 -070073TEST(AnalogLoopTest, AnalogTriggerCounterWorks) {
74 frc::AnalogInput input{TestBench::kFakeAnalogOutputChannel};
75 frc::AnalogOutput output{TestBench::kAnalogOutputChannel};
76
77 frc::AnalogTrigger trigger{&input};
Brian Silverman8fce7482020-01-05 13:18:21 -080078 trigger.SetLimitsVoltage(2.0, 3.0);
79
Austin Schuh812d0d12021-11-04 20:16:48 -070080 frc::Counter counter{trigger};
Brian Silverman8fce7482020-01-05 13:18:21 -080081
82 // Turn the analog output low and high 50 times
83 for (int32_t i = 0; i < 50; i++) {
Austin Schuh812d0d12021-11-04 20:16:48 -070084 output.SetVoltage(1.0);
85 frc::Wait(kDelayTime);
86 output.SetVoltage(4.0);
87 frc::Wait(kDelayTime);
Brian Silverman8fce7482020-01-05 13:18:21 -080088 }
89
90 // The counter should be 50
91 EXPECT_EQ(50, counter.Get())
92 << "Analog trigger counter did not count 50 ticks";
93}
94
Austin Schuh812d0d12021-11-04 20:16:48 -070095TEST(AnalogLoopTest, AsynchronusInterruptWorks) {
96 frc::AnalogInput input{TestBench::kFakeAnalogOutputChannel};
97 frc::AnalogOutput output{TestBench::kAnalogOutputChannel};
Brian Silverman8fce7482020-01-05 13:18:21 -080098
Brian Silverman8fce7482020-01-05 13:18:21 -080099 int32_t param = 0;
Austin Schuh812d0d12021-11-04 20:16:48 -0700100 frc::AnalogTrigger trigger{&input};
Brian Silverman8fce7482020-01-05 13:18:21 -0800101 trigger.SetLimitsVoltage(2.0, 3.0);
102
103 // Given an interrupt handler that sets an int32_t to 12345
Austin Schuh812d0d12021-11-04 20:16:48 -0700104 std::shared_ptr<frc::AnalogTriggerOutput> triggerOutput =
105 trigger.CreateOutput(frc::AnalogTriggerType::kState);
106
107 frc::AsynchronousInterrupt interrupt{triggerOutput,
108 [&](auto a, auto b) { param = 12345; }};
109
110 interrupt.Enable();
Brian Silverman8fce7482020-01-05 13:18:21 -0800111
112 // If the analog output moves from below to above the window
Austin Schuh812d0d12021-11-04 20:16:48 -0700113 output.SetVoltage(0.0);
114 frc::Wait(kDelayTime);
115 output.SetVoltage(5.0);
Brian Silverman8fce7482020-01-05 13:18:21 -0800116 // Then the int32_t should be 12345
Austin Schuh812d0d12021-11-04 20:16:48 -0700117 frc::Wait(kDelayTime);
118 interrupt.Disable();
119
Brian Silverman8fce7482020-01-05 13:18:21 -0800120 EXPECT_EQ(12345, param) << "The interrupt did not run.";
121}