From 858a13264bba8726c9db9881458adfd81f4fbc25 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Wed, 26 Jul 2023 00:35:28 -0700 Subject: [PATCH] test lambda monitor response #75 --- firmware/controllers/math/lambda_monitor.cpp | 6 +- firmware/controllers/math/lambda_monitor.h | 7 ++- unit_tests/tests/test_lambda_monitor.cpp | 60 +++++++++++++++++++- 3 files changed, 69 insertions(+), 4 deletions(-) diff --git a/firmware/controllers/math/lambda_monitor.cpp b/firmware/controllers/math/lambda_monitor.cpp index e23336c533..b895be1ce9 100644 --- a/firmware/controllers/math/lambda_monitor.cpp +++ b/firmware/controllers/math/lambda_monitor.cpp @@ -12,6 +12,10 @@ float LambdaMonitor::getMaxAllowedLambda(float rpm, float load) const { ); } +float LambdaMonitor::getTimeout() const { + return engineConfiguration->lambdaProtectionTimeout; +} + bool LambdaMonitorBase::isCut() const { return lambdaMonitorCut; } @@ -25,7 +29,7 @@ void LambdaMonitorBase::update(float rpm, float load) { lambdaTimeSinceGood = m_timeSinceGoodLambda.getElapsedSeconds(); - if (m_timeSinceGoodLambda.hasElapsedSec(engineConfiguration->lambdaProtectionTimeout)) { + if (m_timeSinceGoodLambda.hasElapsedSec(getTimeout())) { // Things have been bad long enough, cut! lambdaMonitorCut = true; } diff --git a/firmware/controllers/math/lambda_monitor.h b/firmware/controllers/math/lambda_monitor.h index 936da4824a..786c166c86 100644 --- a/firmware/controllers/math/lambda_monitor.h +++ b/firmware/controllers/math/lambda_monitor.h @@ -12,12 +12,14 @@ protected: // Returns false if the current lambda reading is leaner than allowable. // Returns true in any other case (rich enough, bad sensor, recent fuel cut, rpm to low, load too low, etc) - bool isCurrentlyGood(float rpm, float load) const; + virtual bool isCurrentlyGood(float rpm, float load) const; + virtual float getMaxAllowedLambda(float rpm, float load) const = 0; + virtual float getTimeout() const = 0; // Determine whether fuel should be restored after a cut occurs // Returns true if OK to leave the "cut" state - bool restoreConditionsMet(float rpm, float load) const; + virtual bool restoreConditionsMet(float rpm, float load) const; private: Timer m_timeSinceGoodLambda; @@ -25,4 +27,5 @@ private: class LambdaMonitor : public LambdaMonitorBase { float getMaxAllowedLambda(float rpm, float load) const override; + float getTimeout() const override; }; diff --git a/unit_tests/tests/test_lambda_monitor.cpp b/unit_tests/tests/test_lambda_monitor.cpp index 987686d74d..b3a2ff1a09 100644 --- a/unit_tests/tests/test_lambda_monitor.cpp +++ b/unit_tests/tests/test_lambda_monitor.cpp @@ -1,5 +1,63 @@ #include "pch.h" -TEST(LambdaMonitor, x) { +struct MockLambdaMonitor : public LambdaMonitorBase { + bool isGood = true; + bool isCurrentlyGood(float /*rpm*/, float /*load*/) const override { + return isGood; + } + bool isRestore = false; + bool restoreConditionsMet(float /*rpm*/, float /*load*/) const override { + return isRestore; + } + + float getTimeout() const override { + // Timeout of 1 second + return 1; + } + + MOCK_METHOD(float, getMaxAllowedLambda, (float rpm, float load), (const, override)); +}; + +TEST(LambdaMonitor, Response) { + MockLambdaMonitor mlm; + + extern int timeNowUs; + int startTime = 1e6; + timeNowUs = startTime; + + mlm.isGood = true; + mlm.isRestore = false; + mlm.update(2000, 50); + EXPECT_TRUE(mlm.lambdaCurrentlyGood); + EXPECT_FALSE(mlm.isCut()); + + // now lambda will be bad, but we don't cut yet + mlm.isGood = false; + mlm.update(2000, 50); + EXPECT_FALSE(mlm.lambdaCurrentlyGood); + EXPECT_FALSE(mlm.isCut()); + + // 0.9 second later, still not cut + timeNowUs = startTime + 0.9e6; + mlm.update(2000, 50); + EXPECT_FALSE(mlm.lambdaCurrentlyGood); + EXPECT_FALSE(mlm.isCut()); + + // 1.1 second later, cut! + timeNowUs = startTime + 1.1e6; + mlm.update(2000, 50); + EXPECT_FALSE(mlm.lambdaCurrentlyGood); + EXPECT_TRUE(mlm.isCut()); + + // Lambda goes back to normal, but restore conditions not met so we should stay cut + mlm.isGood = true; + mlm.update(2000, 50); + EXPECT_TRUE(mlm.lambdaCurrentlyGood); + EXPECT_TRUE(mlm.isCut()); + + mlm.isRestore = true; + mlm.update(2000, 50); + EXPECT_TRUE(mlm.lambdaCurrentlyGood); + EXPECT_FALSE(mlm.isCut()); }