2023-08-09 12:26:56 -07:00
|
|
|
#include <gtest/gtest.h>
|
2023-11-13 13:30:23 -08:00
|
|
|
#include <gmock/gmock.h>
|
|
|
|
|
|
|
|
#include "heater_control.h"
|
|
|
|
|
2023-11-13 13:56:03 -08:00
|
|
|
struct MockHeater : public HeaterControllerBase
|
|
|
|
{
|
2023-11-15 17:42:37 -08:00
|
|
|
MockHeater() : HeaterControllerBase(0, 5, 10) { }
|
2023-11-13 13:30:23 -08:00
|
|
|
|
|
|
|
MOCK_METHOD(void, SetDuty, (float), (const, override));
|
|
|
|
};
|
2023-08-09 12:26:56 -07:00
|
|
|
|
2023-11-13 13:56:03 -08:00
|
|
|
TEST(HeaterStateOutput, Preheat)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
|
|
|
|
|
|
|
// Shouldn't depend upon sensor ESR
|
|
|
|
EXPECT_EQ(1.5f, dut.GetVoltageForState(HeaterState::Preheat, 0));
|
|
|
|
EXPECT_EQ(1.5f, dut.GetVoltageForState(HeaterState::Preheat, 300));
|
|
|
|
EXPECT_EQ(1.5f, dut.GetVoltageForState(HeaterState::Preheat, 1000));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(HeaterStateOutput, WarmupRamp)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
|
|
|
|
|
|
|
EXPECT_EQ(1.5f, dut.GetVoltageForState(HeaterState::Preheat, 0));
|
|
|
|
EXPECT_EQ(1.5f, dut.GetVoltageForState(HeaterState::Preheat, 300));
|
|
|
|
EXPECT_EQ(1.5f, dut.GetVoltageForState(HeaterState::Preheat, 1000));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(HeaterStateOutput, ClosedLoop)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
|
|
|
dut.Configure(780, 300);
|
|
|
|
|
|
|
|
// At target -> zero output but with 7.5v offset
|
|
|
|
EXPECT_EQ(dut.GetVoltageForState(HeaterState::ClosedLoop, 300), 7.5f);
|
|
|
|
|
|
|
|
// Below target -> more voltage
|
|
|
|
EXPECT_GT(dut.GetVoltageForState(HeaterState::ClosedLoop, 400), 7.5f);
|
|
|
|
|
|
|
|
// Above target -> less voltage
|
|
|
|
EXPECT_LT(dut.GetVoltageForState(HeaterState::ClosedLoop, 200), 7.5f);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(HeaterStateOutput, Cases)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
|
|
|
|
|
|
|
EXPECT_EQ(0, dut.GetVoltageForState(HeaterState::Stopped, 0));
|
|
|
|
EXPECT_EQ(0, dut.GetVoltageForState(HeaterState::NoHeaterSupply, 0));
|
|
|
|
}
|
|
|
|
|
2023-11-13 14:15:22 -08:00
|
|
|
TEST(HeaterStateMachine, PreheatToWarmupTimeout)
|
2023-08-09 12:26:56 -07:00
|
|
|
{
|
2023-11-13 13:30:23 -08:00
|
|
|
MockHeater dut;
|
2023-11-15 17:42:37 -08:00
|
|
|
Timer::setMockTime(0);
|
2023-11-13 14:15:22 -08:00
|
|
|
dut.Configure(780, 300);
|
|
|
|
|
2023-11-15 17:42:37 -08:00
|
|
|
// For a while it should stay in preheat
|
|
|
|
Timer::setMockTime(1e6);
|
|
|
|
EXPECT_EQ(HeaterState::Preheat, dut.GetNextState(HeaterState::Preheat, HeaterAllow::Allowed, 12, 500));
|
|
|
|
Timer::setMockTime(2e6);
|
|
|
|
EXPECT_EQ(HeaterState::Preheat, dut.GetNextState(HeaterState::Preheat, HeaterAllow::Allowed, 12, 500));
|
|
|
|
Timer::setMockTime(4.9e6);
|
|
|
|
EXPECT_EQ(HeaterState::Preheat, dut.GetNextState(HeaterState::Preheat, HeaterAllow::Allowed, 12, 500));
|
2023-11-13 14:15:22 -08:00
|
|
|
|
|
|
|
// Timer expired, transition to warmup ramp
|
2023-11-15 17:42:37 -08:00
|
|
|
Timer::setMockTime(5.1e6);
|
2023-11-13 14:15:22 -08:00
|
|
|
EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::Preheat, HeaterAllow::Allowed, 12, 500));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(HeaterStateMachine, PreheatToWarmupAlreadyWarm)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
2023-11-15 17:42:37 -08:00
|
|
|
Timer::setMockTime(0);
|
2023-11-13 14:15:22 -08:00
|
|
|
dut.Configure(780, 300);
|
|
|
|
|
|
|
|
// Preheat for a little while
|
|
|
|
for (size_t i = 0; i < 10; i++)
|
|
|
|
{
|
|
|
|
EXPECT_EQ(HeaterState::Preheat, dut.GetNextState(HeaterState::Preheat, HeaterAllow::Allowed, 12, 500));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sensor magically warms up, skip to warmup ramp!
|
|
|
|
EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::Preheat, HeaterAllow::Allowed, 12, 780));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(HeaterStateMachine, WarmupToClosedLoop)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
2023-11-15 17:42:37 -08:00
|
|
|
Timer::setMockTime(0);
|
2023-11-13 14:15:22 -08:00
|
|
|
dut.Configure(780, 300);
|
|
|
|
|
|
|
|
// Warm up for a little while
|
|
|
|
for (size_t i = 0; i < 10; i++)
|
|
|
|
{
|
|
|
|
EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Allowed, 12, 500));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sensor warms up, time for closed loop!
|
|
|
|
EXPECT_EQ(HeaterState::ClosedLoop, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Allowed, 12, 780));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(HeaterStateMachine, WarmupTimeout)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
2023-11-15 17:42:37 -08:00
|
|
|
Timer::setMockTime(0);
|
2023-11-13 14:15:22 -08:00
|
|
|
dut.Configure(780, 300);
|
|
|
|
|
2023-11-15 17:42:37 -08:00
|
|
|
// For a while it should stay in warmup
|
|
|
|
Timer::setMockTime(1e6);
|
|
|
|
EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Allowed, 12, 500));
|
|
|
|
Timer::setMockTime(2e6);
|
|
|
|
EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Allowed, 12, 500));
|
|
|
|
Timer::setMockTime(9.9e6);
|
|
|
|
EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Allowed, 12, 500));
|
2023-11-13 14:15:22 -08:00
|
|
|
|
|
|
|
// Warmup times out, sensor transitions to stopped
|
2023-11-15 17:42:37 -08:00
|
|
|
Timer::setMockTime(10.1e6);
|
2023-11-13 14:15:22 -08:00
|
|
|
EXPECT_EQ(HeaterState::Stopped, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Allowed, 12, 500));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(HeaterStateMachine, ClosedLoop)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
|
|
|
dut.Configure(780, 300);
|
|
|
|
|
|
|
|
// Temperature is reasonable, stay in closed loop
|
|
|
|
EXPECT_EQ(HeaterState::ClosedLoop, dut.GetNextState(HeaterState::ClosedLoop, HeaterAllow::Allowed, 12, 780));
|
|
|
|
|
|
|
|
// Temperature is too hot, overheat
|
|
|
|
EXPECT_EQ(HeaterState::Stopped, dut.GetNextState(HeaterState::ClosedLoop, HeaterAllow::Allowed, 12, 1000));
|
|
|
|
|
|
|
|
// Temperature is too cold, underheat
|
|
|
|
EXPECT_EQ(HeaterState::Stopped, dut.GetNextState(HeaterState::ClosedLoop, HeaterAllow::Allowed, 12, 600));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(HeaterStateMachine, TerminalStates)
|
|
|
|
{
|
|
|
|
MockHeater dut;
|
|
|
|
dut.Configure(780, 300);
|
|
|
|
|
|
|
|
EXPECT_EQ(HeaterState::Stopped, dut.GetNextState(HeaterState::Stopped, HeaterAllow::Allowed, 12, 780));
|
2023-08-09 12:26:56 -07:00
|
|
|
}
|