mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
Subsections are alphabetized according to lexographic ordering. Also, HAL includes were moved from headers to source files where possible. This change may cause user code which uses HAL functionality and does not include the relevant HAL header (since it may have been provided by another WPILib header) to fail to compile.
131 lines
3.7 KiB
C++
131 lines
3.7 KiB
C++
/*----------------------------------------------------------------------------*/
|
|
/* Copyright (c) FIRST 2014-2016. All Rights Reserved. */
|
|
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
|
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
|
/* the project. */
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "AnalogInput.h"
|
|
#include "AnalogOutput.h"
|
|
#include "AnalogTrigger.h"
|
|
#include "Counter.h"
|
|
#include "TestBench.h"
|
|
#include "Timer.h"
|
|
|
|
static const double kDelayTime = 0.01;
|
|
|
|
/**
|
|
* A fixture with an analog input and an analog output wired together
|
|
*/
|
|
class AnalogLoopTest : public testing::Test {
|
|
protected:
|
|
AnalogInput* m_input;
|
|
AnalogOutput* m_output;
|
|
|
|
virtual void SetUp() override {
|
|
m_input = new AnalogInput(TestBench::kFakeAnalogOutputChannel);
|
|
m_output = new AnalogOutput(TestBench::kAnalogOutputChannel);
|
|
}
|
|
|
|
virtual void TearDown() override {
|
|
delete m_input;
|
|
delete m_output;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Test analog inputs and outputs by setting one and making sure the other
|
|
* matches.
|
|
*/
|
|
TEST_F(AnalogLoopTest, AnalogInputWorks) {
|
|
// Set the output voltage and check if the input measures the same voltage
|
|
for (int i = 0; i < 50; i++) {
|
|
m_output->SetVoltage(i / 10.0f);
|
|
|
|
Wait(kDelayTime);
|
|
|
|
EXPECT_NEAR(m_output->GetVoltage(), m_input->GetVoltage(), 0.01f);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Test if we can use an analog trigger to check if the output is within a
|
|
* range correctly.
|
|
*/
|
|
TEST_F(AnalogLoopTest, AnalogTriggerWorks) {
|
|
AnalogTrigger trigger(m_input);
|
|
trigger.SetLimitsVoltage(2.0f, 3.0f);
|
|
|
|
m_output->SetVoltage(1.0f);
|
|
Wait(kDelayTime);
|
|
|
|
EXPECT_FALSE(trigger.GetInWindow())
|
|
<< "Analog trigger is in the window (2V, 3V)";
|
|
EXPECT_FALSE(trigger.GetTriggerState()) << "Analog trigger is on";
|
|
|
|
m_output->SetVoltage(2.5f);
|
|
Wait(kDelayTime);
|
|
|
|
EXPECT_TRUE(trigger.GetInWindow())
|
|
<< "Analog trigger is not in the window (2V, 3V)";
|
|
EXPECT_FALSE(trigger.GetTriggerState()) << "Analog trigger is on";
|
|
|
|
m_output->SetVoltage(4.0f);
|
|
Wait(kDelayTime);
|
|
|
|
EXPECT_FALSE(trigger.GetInWindow())
|
|
<< "Analog trigger is in the window (2V, 3V)";
|
|
EXPECT_TRUE(trigger.GetTriggerState()) << "Analog trigger is not on";
|
|
}
|
|
|
|
/**
|
|
* Test if we can count the right number of ticks from an analog trigger with
|
|
* a counter.
|
|
*/
|
|
TEST_F(AnalogLoopTest, AnalogTriggerCounterWorks) {
|
|
AnalogTrigger trigger(m_input);
|
|
trigger.SetLimitsVoltage(2.0f, 3.0f);
|
|
|
|
Counter counter(trigger);
|
|
|
|
// Turn the analog output low and high 50 times
|
|
for (int i = 0; i < 50; i++) {
|
|
m_output->SetVoltage(1.0);
|
|
Wait(kDelayTime);
|
|
m_output->SetVoltage(4.0);
|
|
Wait(kDelayTime);
|
|
}
|
|
|
|
// The counter should be 50
|
|
EXPECT_EQ(50, counter.Get())
|
|
<< "Analog trigger counter did not count 50 ticks";
|
|
}
|
|
|
|
static void InterruptHandler(uint32_t interruptAssertedMask, void* param) {
|
|
*(int*)param = 12345;
|
|
}
|
|
|
|
TEST_F(AnalogLoopTest, AsynchronusInterruptWorks) {
|
|
int param = 0;
|
|
AnalogTrigger trigger(m_input);
|
|
trigger.SetLimitsVoltage(2.0f, 3.0f);
|
|
|
|
// Given an interrupt handler that sets an int to 12345
|
|
std::shared_ptr<AnalogTriggerOutput> triggerOutput =
|
|
trigger.CreateOutput(kState);
|
|
triggerOutput->RequestInterrupts(InterruptHandler, ¶m);
|
|
triggerOutput->EnableInterrupts();
|
|
|
|
// If the analog output moves from below to above the window
|
|
m_output->SetVoltage(0.0);
|
|
Wait(kDelayTime);
|
|
m_output->SetVoltage(5.0);
|
|
triggerOutput->CancelInterrupts();
|
|
|
|
// Then the int should be 12345
|
|
Wait(kDelayTime);
|
|
EXPECT_EQ(12345, param) << "The interrupt did not run.";
|
|
}
|