fome-fw/unit_tests/tests/test_limp.cpp

205 lines
5.6 KiB
C++

#include "pch.h"
#include "limp_manager.h"
TEST(limp, testFatalError) {
LimpManager dut;
// Everything should work by default
ASSERT_TRUE(dut.allowElectronicThrottle());
ASSERT_TRUE(dut.allowIgnition());
ASSERT_TRUE(dut.allowInjection());
ASSERT_TRUE(dut.allowTriggerInput());
dut.fatalError();
// Fatal error should kill everything
EXPECT_FALSE(dut.allowElectronicThrottle());
EXPECT_FALSE(dut.allowIgnition());
EXPECT_FALSE(dut.allowInjection());
EXPECT_FALSE(dut.allowTriggerInput());
}
TEST(limp, revLimit) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
engineConfiguration->rpmHardLimit = 2500;
engineConfiguration->cutFuelOnHardLimit = true;
engineConfiguration->cutSparkOnHardLimit = true;
LimpManager dut;
// Under rev limit, inj/ign allowed
dut.updateState(2000, 0);
EXPECT_TRUE(dut.allowIgnition());
EXPECT_TRUE(dut.allowInjection());
// Over rev limit, no injection
dut.updateState(3000, 0);
EXPECT_FALSE(dut.allowIgnition());
EXPECT_FALSE(dut.allowInjection());
// Now recover back to under limit
dut.updateState(2000, 0);
EXPECT_TRUE(dut.allowIgnition());
EXPECT_TRUE(dut.allowInjection());
}
TEST(limp, revLimitCltBased) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
engineConfiguration->rpmHardLimit = 2500;
engineConfiguration->cutFuelOnHardLimit = true;
engineConfiguration->cutSparkOnHardLimit = true;
// Configure CLT-based rev limit curve
engineConfiguration->useCltBasedRpmLimit = true;
copyArray(config->cltRevLimitRpmBins, { 10, 20, 30, 40 });
copyArray(config->cltRevLimitRpm, { 1000, 2000, 3000, 4000 });
LimpManager dut;
// Check low temperature first
Sensor::setMockValue(SensorType::Clt, 10);
// Under rev limit, inj/ign allowed
dut.updateState(900, 0);
EXPECT_TRUE(dut.allowIgnition());
EXPECT_TRUE(dut.allowInjection());
// Over rev limit, no injection
dut.updateState(1100, 0);
EXPECT_FALSE(dut.allowIgnition());
EXPECT_FALSE(dut.allowInjection());
// Now recover back to under limit
dut.updateState(900, 0);
EXPECT_TRUE(dut.allowIgnition());
EXPECT_TRUE(dut.allowInjection());
// Check middle temperature
Sensor::setMockValue(SensorType::Clt, 35);
// Under rev limit, inj/ign allowed
dut.updateState(3400, 0);
EXPECT_TRUE(dut.allowIgnition());
EXPECT_TRUE(dut.allowInjection());
// Over rev limit, no injection
dut.updateState(3600, 0);
EXPECT_FALSE(dut.allowIgnition());
EXPECT_FALSE(dut.allowInjection());
// Now recover back to under limit
dut.updateState(3400, 0);
EXPECT_TRUE(dut.allowIgnition());
EXPECT_TRUE(dut.allowInjection());
}
TEST(limp, boostCut) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
// Cut above 100kPa
engineConfiguration->boostCutPressure = 100;
LimpManager dut;
// Below threshold, injection allowed
Sensor::setMockValue(SensorType::Map, 80);
dut.updateState(1000, 0);
EXPECT_TRUE(dut.allowInjection());
// Above rising threshold, injection cut
Sensor::setMockValue(SensorType::Map, 105);
dut.updateState(1000, 0);
EXPECT_FALSE(dut.allowInjection());
// Below rising threshold, but should have hysteresis, so not cut yet
Sensor::setMockValue(SensorType::Map, 95);
dut.updateState(1000, 0);
EXPECT_FALSE(dut.allowInjection());
// Below falling threshold, fuel restored
Sensor::setMockValue(SensorType::Map, 79);
dut.updateState(1000, 0);
EXPECT_TRUE(dut.allowInjection());
// SPECIAL CASE: threshold of 0 means never boost cut
engineConfiguration->boostCutPressure = 0;
Sensor::setMockValue(SensorType::Map, 500);
dut.updateState(1000, 0);
EXPECT_TRUE(dut.allowInjection());
}
TEST(limp, oilPressureFailureCase) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
engineConfiguration->minOilPressureAfterStart = 200;
LimpManager dut;
// Low oil pressure!
Sensor::setMockValue(SensorType::OilPressure, 50);
// Start the engine
engine->rpmCalculator.setRpmValue(1000);
// update & check: injection should be allowed
dut.updateState(1000, getTimeNowNt());
EXPECT_TRUE(dut.allowInjection());
// 4.5 seconds later, should still be allowed (even though pressure is low)
advanceTimeUs(4.5e6);
dut.updateState(1000, getTimeNowNt());
EXPECT_TRUE(dut.allowInjection());
// 1 second later (5.5 since start), injection should cut
advanceTimeUs(1.0e6);
dut.updateState(1000, getTimeNowNt());
ASSERT_FALSE(dut.allowInjection());
// But then oil pressure arrives!
// Injection still isn't allowed, since now we're late.
Sensor::setMockValue(SensorType::OilPressure, 250);
dut.updateState(1000, getTimeNowNt());
ASSERT_FALSE(dut.allowInjection());
}
TEST(limp, oilPressureSuccessCase) {
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
engineConfiguration->minOilPressureAfterStart = 200;
LimpManager dut;
// Low oil pressure!
Sensor::setMockValue(SensorType::OilPressure, 50);
// Start the engine
engine->rpmCalculator.setRpmValue(1000);
// update & check: injection should be allowed
dut.updateState(1000, getTimeNowNt());
EXPECT_TRUE(dut.allowInjection());
// 4.5 seconds later, should still be allowed (even though pressure is low)
advanceTimeUs(4.5e6);
dut.updateState(1000, getTimeNowNt());
EXPECT_TRUE(dut.allowInjection());
// But then oil pressure arrives!
Sensor::setMockValue(SensorType::OilPressure, 250);
dut.updateState(1000, getTimeNowNt());
ASSERT_TRUE(dut.allowInjection());
// 1 second later (5.5 since start), injection should be allowed since we saw pressure before the timeout
advanceTimeUs(1.0e6);
dut.updateState(1000, getTimeNowNt());
ASSERT_TRUE(dut.allowInjection());
// Later, we lose oil pressure, but engine should stay running
advanceTimeUs(10e6);
Sensor::setMockValue(SensorType::OilPressure, 10);
dut.updateState(1000, getTimeNowNt());
ASSERT_TRUE(dut.allowInjection());
}