test heater state machine

This commit is contained in:
Matthew Kennedy 2023-11-13 14:15:22 -08:00
parent b3b73135a6
commit c2cb3b9015
3 changed files with 88 additions and 4 deletions

View File

@ -83,6 +83,8 @@ HeaterState HeaterControllerBase::GetNextState(HeaterState currentState, HeaterA
// Stay in preheat - wait for time to elapse
break;
case HeaterState::WarmupRamp:
timeCounter--;
if (sensorTemp > closedLoopTemp)
{
return HeaterState::ClosedLoop;
@ -93,8 +95,6 @@ HeaterState HeaterControllerBase::GetNextState(HeaterState currentState, HeaterA
return HeaterState::Stopped;
}
timeCounter--;
break;
case HeaterState::ClosedLoop:
// Check that the sensor's ESR is acceptable for normal operation
@ -116,7 +116,7 @@ HeaterState HeaterControllerBase::GetNextState(HeaterState currentState, HeaterA
break;
}
return heaterState;
return currentState;
}
float HeaterControllerBase::GetVoltageForState(HeaterState state, float sensorEsr)

View File

@ -42,6 +42,11 @@ public:
HeaterState GetNextState(HeaterState currentState, HeaterAllow haeterAllowState, float batteryVoltage, float sensorTemp);
float GetVoltageForState(HeaterState state, float sensorEsr);
int GetTimeCounter() const
{
return timeCounter;
}
private:
Pid heaterPid =
{

View File

@ -52,7 +52,86 @@ TEST(HeaterStateOutput, Cases)
EXPECT_EQ(0, dut.GetVoltageForState(HeaterState::NoHeaterSupply, 0));
}
TEST(HeaterStateMachine, x)
TEST(HeaterStateMachine, PreheatToWarmupTimeout)
{
MockHeater dut;
dut.Configure(780, 300);
for (size_t i = 0; i < HeaterControllerBase::preheatTimeCounter - 1; i++)
{
EXPECT_EQ(HeaterState::Preheat, dut.GetNextState(HeaterState::Preheat, HeaterAllow::Allowed, 12, 500));
}
// Timer expired, transition to warmup ramp
EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::Preheat, HeaterAllow::Allowed, 12, 500));
}
TEST(HeaterStateMachine, PreheatToWarmupAlreadyWarm)
{
MockHeater dut;
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;
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;
dut.Configure(780, 300);
size_t timeoutPeriod = dut.GetTimeCounter();
// Warm up for a little while
for (size_t i = 0; i < timeoutPeriod - 1; i++)
{
EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Allowed, 12, 500)) << "i = " << i;
}
// Warmup times out, sensor transitions to stopped
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));
}