|
7 | 7 | namespace |
8 | 8 | { |
9 | 9 |
|
10 | | -constexpr float kHeaterPreheatTime = 5.0f; |
11 | | -constexpr float kHeaterWarmupTimeout = 10.0f; |
| 10 | + constexpr float kHeaterPreheatTime = 5.0f; |
| 11 | + constexpr float kHeaterWarmupTimeout = 10.0f; |
12 | 12 |
|
13 | | -constexpr float kTargetTempC = 780.0f; |
14 | | -constexpr float kTargetEsr = 300.0f; |
| 13 | + constexpr float kTargetTempC = 780.0f; |
| 14 | + constexpr float kTargetEsr = 300.0f; |
15 | 15 |
|
16 | | -constexpr float kOverTempC = kTargetTempC + 300.0f; |
17 | | -constexpr float kUnderTempC = kTargetTempC - 200.0f; |
| 16 | + constexpr float kOverTempC = over(kTargetTempC + 100.0f); |
| 17 | + constexpr float kUnderTempC = under(kTargetTempC - 100.0f); |
18 | 18 |
|
19 | | -constexpr float kGoodVoltage = 12.0f; |
| 19 | + constexpr float kGoodVoltage = 12.0f; |
20 | 20 |
|
21 | | -constexpr float kOffVoltage = 6.0f; |
22 | | -constexpr float kOnVoltage = 11.0f; |
| 21 | + constexpr float kOffVoltage = 8.0f; |
| 22 | + constexpr float kOnVoltage = 9.5f; |
23 | 23 |
|
24 | | -constexpr float kVoltageStabDelaySec = 0.5f; |
25 | | -constexpr float kOverUnderheatFaultDelaySec = 0.5f; |
26 | | -constexpr float kClosedLoopStabDelaySec = 0.5f; |
| 24 | + constexpr float kVoltageStabDelaySec = 0.5f; |
| 25 | + constexpr float kOverUnderheatFaultDelaySec = 0.5f; |
| 26 | + constexpr float kClosedLoopStabDelaySec = 0.5f; |
27 | 27 |
|
28 | | -struct MockHeater : public HeaterControllerBase |
29 | | -{ |
30 | | - MockHeater() : HeaterControllerBase(0, kHeaterPreheatTime, kHeaterWarmupTimeout) { } |
31 | | - |
32 | | - MOCK_METHOD(void, SetDuty, (float), (const, override)); |
33 | | -}; |
| 28 | + struct MockHeater : public HeaterControllerBase |
| 29 | + { |
| 30 | + MockHeater() : HeaterControllerBase(0, kHeaterPreheatTime, kHeaterWarmupTimeout) { } |
34 | 31 |
|
35 | | -void configureDut(MockHeater& dut) |
36 | | -{ |
37 | | - Timer::setMockTime(0); |
38 | | - dut.Configure(kTargetTempC, kTargetEsr); |
39 | | -} |
| 32 | + MOCK_METHOD(void, SetDuty, (float), (const, override)); |
| 33 | + }; |
40 | 34 |
|
| 35 | + void configureDut(MockHeater& dut) |
| 36 | + { |
| 37 | + Timer::setMockTime(0); |
| 38 | + dut.Configure(kTargetTempC, kTargetEsr); |
| 39 | + } |
41 | 40 |
|
42 | 41 | } |
43 | 42 |
|
@@ -344,19 +343,24 @@ TEST(HeaterStateMachine, Warmup_IfNoExitCondition_AndUnknown) |
344 | 343 | Timer::setMockTime(toUs(over(kVoltageStabDelaySec))); |
345 | 344 | EXPECT_EQ(HeaterState::WarmupRamp, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Unknown, over(kOnVoltage), kUnderTempC)); |
346 | 345 |
|
347 | | - // issue: Voltage momentarily drops below OffVoltage because heater turned on |
| 346 | + // issue: Voltage momentarily drops below OnVoltage because heater turned on |
348 | 347 | // this resets the stability timer and drops us back to the preheat state, even though it is a transient spike |
349 | 348 | // while it may be the indication of weak wiring or bad connection, we at least should report the condition |
350 | 349 | // especially since this is only in the Unknown state. Allowed state does not check for that at all. |
351 | | - EXPECT_EQ(HeaterState::Preheat, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Unknown, under(kOffVoltage), kUnderTempC)); |
| 350 | + // There should be two modifications to fix this issue: |
| 351 | + // 1. Introduce hysteresis by checking OffVoltage for dropping back to preheat, and OnVoltage for transitioning to warmup ramp |
| 352 | + // 2. Use a timer not only for transitioning from preheat to warmup ramp, but also for dropping back to preheat |
| 353 | + EXPECT_EQ(HeaterState::Preheat, dut.GetNextState(HeaterState::WarmupRamp, HeaterAllow::Unknown, under(kOnVoltage), kUnderTempC)); |
| 354 | + |
| 355 | + // Also check ClosedLoop state |
| 356 | + EXPECT_EQ(HeaterState::Preheat, dut.GetNextState(HeaterState::ClosedLoop, HeaterAllow::Unknown, under(kOnVoltage), kUnderTempC)); |
352 | 357 | } |
353 | 358 |
|
354 | 359 |
|
355 | 360 | // ==================== |
356 | 361 | // State: ClosedLoop |
357 | 362 | // ==================== |
358 | 363 |
|
359 | | - |
360 | 364 | TEST(HeaterStateMachine, ClosedLoop_WhenAllowed) |
361 | 365 | { |
362 | 366 | MockHeater dut; |
@@ -469,7 +473,6 @@ TEST(HeaterStateMachine, ClosedLoop_NoUnderheatFaultBeforeStabilization) |
469 | 473 | EXPECT_EQ(HeaterState::Stopped, dut.GetNextState(HeaterState::ClosedLoop, HeaterAllow::Allowed, kGoodVoltage, kUnderTempC)); |
470 | 474 | } |
471 | 475 |
|
472 | | - |
473 | 476 | TEST(HeaterStateMachine, ClosedLoop_NoOverheatFaultBeforeStabilization) |
474 | 477 | { |
475 | 478 | MockHeater dut; |
@@ -504,6 +507,7 @@ TEST(HeaterStateMachine, ClosedLoop_RecoveryToNormalTempResetsFaultTimers) |
504 | 507 | EXPECT_EQ(HeaterState::ClosedLoop, dut.GetNextState(HeaterState::ClosedLoop, HeaterAllow::Allowed, kGoodVoltage, kOverTempC)); |
505 | 508 | } |
506 | 509 |
|
| 510 | + |
507 | 511 | // ==================== |
508 | 512 | // State: Stopped |
509 | 513 | // ==================== |
|
0 commit comments