From 4c349de3d1e1cc279efeca2bf788bbc5811bed6d Mon Sep 17 00:00:00 2001 From: kifir Date: Wed, 31 Jul 2024 15:10:09 +0300 Subject: [PATCH] Now we use `Coolant Temperature Boost Adder` and `Intake Air Temperature Boost Adder` in close loop target calculation #6424 --- .../controllers/actuators/boost_control.cpp | 43 +++- .../controllers/actuators/boost_control.h | 10 +- .../controllers/algo/engine_configuration.cpp | 10 +- .../tests/actuators/boost/boost_test_base.cpp | 64 ++++++ .../tests/actuators/boost/boost_test_base.h | 37 ++++ .../boost/test_closed_loop_adders.cpp | 202 ++++++++++++++++++ .../boost/test_open_loop_multipliers.cpp | 112 +++------- unit_tests/tests/actuators/test_boost.cpp | 52 ++++- unit_tests/tests/tests.mk | 2 + 9 files changed, 433 insertions(+), 99 deletions(-) create mode 100644 unit_tests/tests/actuators/boost/boost_test_base.cpp create mode 100644 unit_tests/tests/actuators/boost/boost_test_base.h create mode 100644 unit_tests/tests/actuators/boost/test_closed_loop_adders.cpp diff --git a/firmware/controllers/actuators/boost_control.cpp b/firmware/controllers/actuators/boost_control.cpp index 9f4709c37a..ea0bf99de4 100644 --- a/firmware/controllers/actuators/boost_control.cpp +++ b/firmware/controllers/actuators/boost_control.cpp @@ -23,6 +23,8 @@ namespace { static Map3D boostMapClosed{"bc"}; Map2D boostCltCorr { "clt" }; Map2D boostIatCorr { "iat" }; + Map2D boostCltAdder { "clt (adder)" }; + Map2D boostIatAdder { "iat (adder)" }; static SimplePwm boostPwmControl("boost"); } @@ -32,6 +34,8 @@ void BoostController::init( const ValueProvider3D* const closedLoopTargetMap, const ValueProvider2D& cltMultiplierProvider, const ValueProvider2D& iatMultiplierProvider, + const ValueProvider2D& cltAdderProvider, + const ValueProvider2D& iatAdderProvider, pid_s* const pidParams ) { m_pwm = pwm; @@ -39,6 +43,8 @@ void BoostController::init( m_closedLoopTargetMap = closedLoopTargetMap; m_cltBoostCorrMap = &cltMultiplierProvider; m_iatBoostCorrMap = &iatMultiplierProvider; + m_cltBoostAdderMap = &cltAdderProvider; + m_iatBoostAdderMap = &iatAdderProvider; m_pid.initPidClass(pidParams); resetLua(); @@ -106,7 +112,13 @@ expected BoostController::getSetpoint() { } #endif //EFI_ENGINE_CONTROL - return target * luaTargetMult + luaTargetAdd; + target *= luaTargetMult; + target += luaTargetAdd; + const std::optional temperatureAdder = getBoostControlTargetTemperatureAdder(); + if (temperatureAdder.has_value()) { + target += temperatureAdder.value(); + } + return target; } expected BoostController::getOpenLoop(float target) { @@ -185,26 +197,39 @@ float BoostController::getBoostControlDutyCycleWithTemperatureCorrections( const float driverIntent ) const { float result = m_openLoopMap->getValue(rpm, driverIntent); - std::optional cltBoostMultiplier = getBoostMultiplier(SensorType::Clt, *m_cltBoostCorrMap); + std::optional cltBoostMultiplier = getBoostTemperatureCorrection(SensorType::Clt, *m_cltBoostCorrMap); if (cltBoostMultiplier.has_value()) { result *= cltBoostMultiplier.value(); } - std::optional iatBoostMultiplier = getBoostMultiplier(SensorType::Iat, *m_iatBoostCorrMap); + std::optional iatBoostMultiplier = getBoostTemperatureCorrection(SensorType::Iat, *m_iatBoostCorrMap); if (iatBoostMultiplier.has_value()) { result *= iatBoostMultiplier.value(); } return result; } -std::optional BoostController::getBoostMultiplier( +std::optional BoostController::getBoostControlTargetTemperatureAdder() const { + std::optional result = getBoostTemperatureCorrection(SensorType::Clt, *m_cltBoostAdderMap); + const std::optional iatBoostAdder = getBoostTemperatureCorrection(SensorType::Iat, *m_iatBoostAdderMap); + if (iatBoostAdder.has_value()) { + if (result.has_value()) { + result.value() += iatBoostAdder.value(); + } else { + result = iatBoostAdder; + } + } + return result; +} + +std::optional BoostController::getBoostTemperatureCorrection( const SensorType sensorType, - const ValueProvider2D& multiplierCurve + const ValueProvider2D& correctionCurve ) const { const SensorResult temperature = Sensor::get(sensorType); if (temperature.Valid) { - const std::optional boostMultiplier = multiplierCurve.getValue(temperature.Value); - if (boostMultiplier.has_value()) { - return std::make_optional(boostMultiplier.value()); + const std::optional boostCorrection = correctionCurve.getValue(temperature.Value); + if (boostCorrection.has_value()) { + return std::make_optional(boostCorrection.value()); } } return {}; @@ -344,6 +369,8 @@ void initBoostCtrl() { &boostMapClosed, boostCltCorr, boostIatCorr, + boostCltAdder, + boostIatAdder, &engineConfiguration->boostPid ); diff --git a/firmware/controllers/actuators/boost_control.h b/firmware/controllers/actuators/boost_control.h index bbd98bb274..a756cfa9ed 100644 --- a/firmware/controllers/actuators/boost_control.h +++ b/firmware/controllers/actuators/boost_control.h @@ -23,6 +23,8 @@ public: const ValueProvider3D* const closedLoopTargetMap, const ValueProvider2D& cltMultiplierProvider, const ValueProvider2D& iatMultiplierProvider, + const ValueProvider2D& cltAdderProvider, + const ValueProvider2D& iatAdderProvider, pid_s* const pidParams ); @@ -46,7 +48,11 @@ private: percent_t getClosedLoopImpl(float target, float manifoldPressure); float getBoostControlDutyCycleWithTemperatureCorrections(const float rpm, const float driverIntent) const; - std::optional getBoostMultiplier(const SensorType sensorType, const ValueProvider2D& multiplierCurve) const; + std::optional getBoostControlTargetTemperatureAdder() const; + std::optional getBoostTemperatureCorrection( + const SensorType sensorType, + const ValueProvider2D& correctionCurve + ) const; Pid m_pid; @@ -54,6 +60,8 @@ private: const ValueProvider3D* m_closedLoopTargetMap = nullptr; const ValueProvider2D* m_cltBoostCorrMap = nullptr; const ValueProvider2D* m_iatBoostCorrMap = nullptr; + const ValueProvider2D* m_cltBoostAdderMap = nullptr; + const ValueProvider2D* m_iatBoostAdderMap = nullptr; IPwm* m_pwm = nullptr; }; diff --git a/firmware/controllers/algo/engine_configuration.cpp b/firmware/controllers/algo/engine_configuration.cpp index 9f7f0bb53f..c105aefd56 100644 --- a/firmware/controllers/algo/engine_configuration.cpp +++ b/firmware/controllers/algo/engine_configuration.cpp @@ -260,8 +260,8 @@ namespace { } } - void initBoostTemperatureCurve(float* const bins, float* const values) { - initTemperatureCurve(bins, values, BOOST_CURVE_SIZE, 1.0f, 20.0f, 20.0f); + void initBoostTemperatureCurve(float* const bins, float* const values, const float defaultValue) { + initTemperatureCurve(bins, values, BOOST_CURVE_SIZE, defaultValue, 20.0f, 20.0f); } } #endif // EFI_ENGINE_CONTROL @@ -490,8 +490,10 @@ static void setDefaultEngineConfiguration() { initTemperatureCurve(IAT_FUEL_CORRECTION_CURVE, 1); - initBoostTemperatureCurve(config->cltBoostCorrBins, config->cltBoostCorr); - initBoostTemperatureCurve(config->iatBoostCorrBins, config->iatBoostCorr); + initBoostTemperatureCurve(config->cltBoostCorrBins, config->cltBoostCorr, 1.0f); + initBoostTemperatureCurve(config->iatBoostCorrBins, config->iatBoostCorr, 1.0f); + initBoostTemperatureCurve(config->cltBoostAdderBins, config->cltBoostAdder, 0.0f); + initBoostTemperatureCurve(config->iatBoostAdderBins, config->iatBoostAdder, 0.0f); engineConfiguration->alternatorControl.minValue = 0; engineConfiguration->alternatorControl.maxValue = 90; diff --git a/unit_tests/tests/actuators/boost/boost_test_base.cpp b/unit_tests/tests/actuators/boost/boost_test_base.cpp new file mode 100644 index 0000000000..da28f7ce4a --- /dev/null +++ b/unit_tests/tests/actuators/boost/boost_test_base.cpp @@ -0,0 +1,64 @@ +// +// Created by kifir on 7/31/24. +// + +#include "pch.h" + +#include "boost_test_base.h" + +const BoostTestBase::ValueByIndexRetriever BoostTestBase::emptyValue = [](const int) -> std::optional { + return {}; +}; + +void BoostTestBase::SetUp() { + TestBase::SetUp(); + + bc = std::make_unique(); + initBoostControllerTables(); + + Sensor::resetAllMocks(); +} + +void BoostTestBase::TearDown() { + bc.reset(); + TestBase::TearDown(); +} + +void BoostTestBase::initTestBoostCurve( + const float (&testBins)[BOOST_CURVE_SIZE], + float (&dstBins)[BOOST_CURVE_SIZE], + const float (&testValues)[BOOST_CURVE_SIZE], + float (&dstValues)[BOOST_CURVE_SIZE] +) { + initBoostCurveArray(testBins, dstBins); + initBoostCurveArray(testValues, dstValues); +} + +void BoostTestBase::initBoostCurveArray(const float (&src)[BOOST_CURVE_SIZE], float (&dst)[BOOST_CURVE_SIZE]) { + std::copy(std::begin(src), std::end(src), std::begin(dst)); +} + +void BoostTestBase::initBoostControllerTables() { + // The code below is very similar to code in file boost_control.cpp + // TODO: think how we can get rid of duplicated code + + // Set up open & closed loop tables + boostMapOpen.initTable(config->boostTableOpenLoop, config->boostRpmBins, config->boostTpsBins); + boostMapClosed.initTable(config->boostTableClosedLoop, config->boostRpmBins, config->boostTpsBins); + boostCltCorr.initTable(config->cltBoostCorr, config->cltBoostCorrBins); + boostIatCorr.initTable(config->iatBoostCorr, config->iatBoostCorrBins); + boostCltAdder.initTable(config->cltBoostAdder, config->cltBoostAdderBins); + boostIatAdder.initTable(config->iatBoostAdder, config->iatBoostAdderBins); + + // Set up boost controller instance + bc->init( + &boostPwmControl, + &boostMapOpen, + &boostMapClosed, + boostCltCorr, + boostIatCorr, + boostCltAdder, + boostIatAdder, + &engineConfiguration->boostPid + ); +} \ No newline at end of file diff --git a/unit_tests/tests/actuators/boost/boost_test_base.h b/unit_tests/tests/actuators/boost/boost_test_base.h new file mode 100644 index 0000000000..5790ce0976 --- /dev/null +++ b/unit_tests/tests/actuators/boost/boost_test_base.h @@ -0,0 +1,37 @@ +// +// Created by kifir on 7/31/24. +// + +#pragma once + +#include "util/test_base.h" + +class BoostTestBase : public TestBase { +protected: + using ValueByIndexRetriever = std::function(int)>; + + static const ValueByIndexRetriever emptyValue; + + virtual void SetUp() override; + virtual void TearDown() override; + + void initTestBoostCurve( + const float (&testBins)[BOOST_CURVE_SIZE], + float (&dstBins)[BOOST_CURVE_SIZE], + const float (&testValues)[BOOST_CURVE_SIZE], + float (&dstValues)[BOOST_CURVE_SIZE] + ); + + std::unique_ptr bc; +private: + void initBoostCurveArray(const float (&src)[BOOST_CURVE_SIZE], float (&dst)[BOOST_CURVE_SIZE]); + void initBoostControllerTables(); + + Map3D boostMapOpen{ "bo" }; + Map3D boostMapClosed{ "bc" }; + Map2D boostCltCorr { "clt" }; + Map2D boostIatCorr { "iat" }; + Map2D boostCltAdder { "clt (adder)" }; + Map2D boostIatAdder { "iat (adder)" }; + SimplePwm boostPwmControl { "boost" }; +}; \ No newline at end of file diff --git a/unit_tests/tests/actuators/boost/test_closed_loop_adders.cpp b/unit_tests/tests/actuators/boost/test_closed_loop_adders.cpp new file mode 100644 index 0000000000..6d9f826b3a --- /dev/null +++ b/unit_tests/tests/actuators/boost/test_closed_loop_adders.cpp @@ -0,0 +1,202 @@ +// +// Created by kifir on 7/31/24. +// + +#include "pch.h" + +#include "boost_test_base.h" + +namespace { + class ClosedLoopAddersTest : public BoostTestBase { + protected: + static constexpr float TEST_BOOST_CONTROL_TARGET = 14.0f; + static constexpr float TEST_CLT_BOOST_ADDER_BINS[BOOST_CURVE_SIZE] = { 4.8f, 9.7f, 19.6f, 39.5f, 79.4f }; + static constexpr float TEST_CLT_BOOST_ADDER[BOOST_CURVE_SIZE] = { 1.8f, 1.3f, 0.9f, 0.6f, 0.4f }; + static constexpr float TEST_IAT_BOOST_ADDER_BINS[BOOST_CURVE_SIZE] = { 2.7f, 7.5f, 17.4f, 37.3f, 77.2f }; + static constexpr float TEST_IAT_BOOST_ADDER[BOOST_CURVE_SIZE] = { 0.5f, 0.4f, 0.6f, 0.9f, 1.3f }; + + virtual void SetUp() override; + + void initTestCltBoostAdder(); + void initTestIatBoostAdder(); + void initLuaTargetCorrections(const float luaTargetMult, const int luaTargetAdd); + static std::optional getTestCltBoostBin(const int index); + static std::optional getTestIatBoostBin(const int index); + + void checkClosedLoopSetPoint( + std::function(int)> cltExtractorByIndex, + std::function(int)> iatExtractorByIndex, + std::function expectedClosedLoopExtractorByIndex + ); + + void checkClosedLoopSetPoint( + const std::optional clt, + const std::optional iat, + const float expectedClosedLoop + ); + }; + + void ClosedLoopAddersTest::SetUp() { + BoostTestBase::SetUp(); + + engineConfiguration->boostType = CLOSED_LOOP; + + setTable(config->boostTableClosedLoop, TEST_BOOST_CONTROL_TARGET); + + Sensor::setMockValue(SensorType::DriverThrottleIntent, 11.2f); + } + + void ClosedLoopAddersTest::initTestCltBoostAdder() { + initTestBoostCurve( + TEST_CLT_BOOST_ADDER_BINS, + config->cltBoostAdderBins, + TEST_CLT_BOOST_ADDER, + config->cltBoostAdder + ); + } + + void ClosedLoopAddersTest::initTestIatBoostAdder() { + initTestBoostCurve( + TEST_IAT_BOOST_ADDER_BINS, + config->iatBoostAdderBins, + TEST_IAT_BOOST_ADDER, + config->iatBoostAdder + ); + } + + void ClosedLoopAddersTest::initLuaTargetCorrections(const float luaTargetMult, const int luaTargetAdd) { + bc->luaTargetMult = luaTargetMult; + bc->luaTargetAdd = luaTargetAdd; + } + + std::optional ClosedLoopAddersTest::getTestCltBoostBin(const int index) { + return { TEST_CLT_BOOST_ADDER_BINS[index] }; + } + + std::optional ClosedLoopAddersTest::getTestIatBoostBin(const int index) { + return { TEST_IAT_BOOST_ADDER_BINS[index] }; + } + + void ClosedLoopAddersTest::checkClosedLoopSetPoint( + std::function(int)> cltExtractorByIndex, + std::function(int)> iatExtractorByIndex, + std::function expectedClosedLoopExtractorByIndex + ) { + for (int i = 0; i< BOOST_CURVE_SIZE; i++) { + checkClosedLoopSetPoint( + cltExtractorByIndex(i), + iatExtractorByIndex(i), + expectedClosedLoopExtractorByIndex(i) + ); + } + } + + void ClosedLoopAddersTest::checkClosedLoopSetPoint( + const std::optional clt, + const std::optional iat, + const float expectedSetPoint + ) { + if (clt.has_value()) { + Sensor::setMockValue(SensorType::Clt, clt.value()); + } + if (iat.has_value()) { + Sensor::setMockValue(SensorType::Iat, iat.value()); + } + const expected setPoint = bc->getSetpoint(); + EXPECT_TRUE(setPoint.Valid) << "clt: " << clt.value_or(-1) << ", iat: " << iat.value_or(-1) ; + ASSERT_NEAR(setPoint.Value, expectedSetPoint, EPS5D) + << "clt: " << clt.value_or(-1) << ", iat: " << iat.value_or(-1) ; + } + + TEST_F(ClosedLoopAddersTest, closedLoopWithDefaultCurves) { + for (int i = 0; i < BOOST_CURVE_SIZE; i++) { + EXPECT_EQ(config->cltBoostAdder[i], 0.0f) << "index: " << i; // check default adder + EXPECT_EQ(config->iatBoostAdder[i], 0.0f) << "index: " << i; // check default adder + } + + checkClosedLoopSetPoint({}, {}, TEST_BOOST_CONTROL_TARGET); + } + + TEST_F(ClosedLoopAddersTest, closedLoopWithUninitializedCurves) { + // Emulate configuration created with old version of TunerStudio, that doesn't support CLT and IAT boost curves: + setArrayValues(config->cltBoostAdder, 0.0f); + setArrayValues(config->cltBoostAdderBins, 0.0f); + setArrayValues(config->iatBoostAdder, 0.0f); + setArrayValues(config->iatBoostAdderBins, 0.0f); + + checkClosedLoopSetPoint({}, {}, TEST_BOOST_CONTROL_TARGET); + } + + TEST_F(ClosedLoopAddersTest, closedLoopWithCltAdder) { + initTestCltBoostAdder(); + + checkClosedLoopSetPoint( + ClosedLoopAddersTest::getTestCltBoostBin, + ClosedLoopAddersTest::getTestIatBoostBin, + [](const int i) -> float { return TEST_BOOST_CONTROL_TARGET + TEST_CLT_BOOST_ADDER[i]; } + ); + } + + TEST_F(ClosedLoopAddersTest, closedLoopWithIatAdder) { + initTestIatBoostAdder(); + + checkClosedLoopSetPoint( + ClosedLoopAddersTest::getTestCltBoostBin, + ClosedLoopAddersTest::getTestIatBoostBin, + [](const int i) -> float { return TEST_BOOST_CONTROL_TARGET + TEST_IAT_BOOST_ADDER[i]; } + ); + } + + TEST_F(ClosedLoopAddersTest, closedLoopWithBothCltAndIatAdders) { + initTestCltBoostAdder(); + initTestIatBoostAdder(); + + checkClosedLoopSetPoint( + ClosedLoopAddersTest::getTestCltBoostBin, + ClosedLoopAddersTest::getTestIatBoostBin, + [](const int i) -> float { + return TEST_BOOST_CONTROL_TARGET + TEST_CLT_BOOST_ADDER[i] + TEST_IAT_BOOST_ADDER[i]; + } + ); + } + + TEST_F(ClosedLoopAddersTest, closedLoopWithBothCltAndIatCorrectionWithMissedIatSensor) { + initTestCltBoostAdder(); + initTestIatBoostAdder(); + + checkClosedLoopSetPoint( + ClosedLoopAddersTest::getTestCltBoostBin, + emptyValue, + [](const int i) -> float { return TEST_BOOST_CONTROL_TARGET + TEST_CLT_BOOST_ADDER[i]; } + ); + } + + TEST_F(ClosedLoopAddersTest, closedLoopWithBothCltAndIatCorrectionWithMissedCltSensor) { + initTestCltBoostAdder(); + initTestIatBoostAdder(); + + checkClosedLoopSetPoint( + emptyValue, + ClosedLoopAddersTest::getTestIatBoostBin, + [](const int i) -> float { return TEST_BOOST_CONTROL_TARGET + TEST_IAT_BOOST_ADDER[i]; } + ); + } + + TEST_F(ClosedLoopAddersTest, closeLoopWithBothCltAndIatCorrectionAndLuaCorrections) { + initTestCltBoostAdder(); + initTestIatBoostAdder(); + + constexpr float TEST_LUA_TARGET_MULT = 1.2f; + constexpr int TEST_LUA_TARGET_ADD = 3; + initLuaTargetCorrections(TEST_LUA_TARGET_MULT, TEST_LUA_TARGET_ADD); + + checkClosedLoopSetPoint( + getTestCltBoostBin, + getTestIatBoostBin, + [](const int i) -> float { + return TEST_BOOST_CONTROL_TARGET * TEST_LUA_TARGET_MULT + static_cast(TEST_LUA_TARGET_ADD) + + TEST_CLT_BOOST_ADDER[i] + TEST_IAT_BOOST_ADDER[i]; + } + ); + } +} \ No newline at end of file diff --git a/unit_tests/tests/actuators/boost/test_open_loop_multipliers.cpp b/unit_tests/tests/actuators/boost/test_open_loop_multipliers.cpp index dd5e1ae9a1..b893ac2f77 100644 --- a/unit_tests/tests/actuators/boost/test_open_loop_multipliers.cpp +++ b/unit_tests/tests/actuators/boost/test_open_loop_multipliers.cpp @@ -4,10 +4,10 @@ #include "pch.h" -#include "util/test_base.h" +#include "boost_test_base.h" namespace { - class OpenLoopMultipliersTest : public TestBase { + class OpenLoopMultipliersTest : public BoostTestBase { protected: static constexpr float TEST_BOOST_CONTROL_DUTY_CYCLE = 17.0f; static constexpr float TEST_CLT_BOOST_CORR_BINS[BOOST_CURVE_SIZE] = { 5.9f, 10.8f, 20.7f, 40.6f, 80.5f }; @@ -16,15 +16,16 @@ namespace { static constexpr float TEST_IAT_BOOST_CORR[BOOST_CURVE_SIZE] = { 0.4f, 0.5f, 0.7f, 1.0f, 1.4f }; virtual void SetUp() override; - virtual void TearDown() override; void initTestCltBoostCorr(); void initTestIatBoostCorr(); void initLuaOpenLoopAdd(const float value); + static std::optional getTestCltBoostBin(const int index); + static std::optional getTestIatBoostBin(const int index); void checkOpenLoop( - std::function(int)> cltExtractorByIndex, - std::function(int)> iatExtractorByIndex, + ValueByIndexRetriever cltExtractorByIndex, + ValueByIndexRetriever iatExtractorByIndex, std::function expectedOpenLoopExtractorByIndex ); @@ -33,59 +34,39 @@ namespace { const std::optional iat, const float expectedOpenLoop ); - private: - std::unique_ptr bc; - - void initBoostControllerTables(); - void initDefaultConfiguration(); - - Map3D boostMapOpen{ "bo" }; - Map3D boostMapClosed{ "bc" }; - Map2D boostCltCorr { "clt" }; - Map2D boostIatCorr { "iat" }; - SimplePwm boostPwmControl { "boost" }; }; void OpenLoopMultipliersTest::SetUp() { - TestBase::SetUp(); + BoostTestBase::SetUp(); - bc = std::make_unique(); - initBoostControllerTables(); + setTable(config->boostTableOpenLoop, TEST_BOOST_CONTROL_DUTY_CYCLE); - Sensor::resetAllMocks(); - initDefaultConfiguration(); - } - - void OpenLoopMultipliersTest::TearDown() { - bc.reset(); - TestBase::TearDown(); + Sensor::setMockValue(SensorType::Tps1, 42.1f); } void OpenLoopMultipliersTest::initTestCltBoostCorr() { - std::copy( - std::begin(TEST_CLT_BOOST_CORR_BINS), - std::end(TEST_CLT_BOOST_CORR_BINS), - std::begin(config->cltBoostCorrBins) - ); - std::copy(std::begin(TEST_CLT_BOOST_CORR), std::end(TEST_CLT_BOOST_CORR), std::begin(config->cltBoostCorr)); + initTestBoostCurve(TEST_CLT_BOOST_CORR_BINS, config->cltBoostCorrBins, TEST_CLT_BOOST_CORR, config->cltBoostCorr); } void OpenLoopMultipliersTest::initTestIatBoostCorr() { - std::copy( - std::begin(TEST_IAT_BOOST_CORR_BINS), - std::end(TEST_IAT_BOOST_CORR_BINS), - std::begin(config->iatBoostCorrBins) - ); - std::copy(std::begin(TEST_IAT_BOOST_CORR), std::end(TEST_IAT_BOOST_CORR), std::begin(config->iatBoostCorr)); + initTestBoostCurve(TEST_IAT_BOOST_CORR_BINS, config->iatBoostCorrBins, TEST_IAT_BOOST_CORR, config->iatBoostCorr); } void OpenLoopMultipliersTest::initLuaOpenLoopAdd(const float value) { bc->luaOpenLoopAdd = value; } + std::optional OpenLoopMultipliersTest::getTestCltBoostBin(const int index) { + return {TEST_CLT_BOOST_CORR_BINS[index] }; + } + + std::optional OpenLoopMultipliersTest::getTestIatBoostBin(const int index) { + return {TEST_IAT_BOOST_CORR_BINS[index] }; + } + void OpenLoopMultipliersTest::checkOpenLoop( - std::function(int)> cltExtractorByIndex, - std::function(int)> iatExtractorByIndex, + ValueByIndexRetriever cltExtractorByIndex, + ValueByIndexRetriever iatExtractorByIndex, std::function expectedOpenLoopExtractorByIndex ) { for (int i = 0; i< BOOST_CURVE_SIZE; i++) { @@ -109,33 +90,6 @@ namespace { EXPECT_EQ(openLoop.Value, expectedOpenLoop) << "clt: " << clt.value_or(-1) << ", iat: " << iat.value_or(-1) ; } - void OpenLoopMultipliersTest::initBoostControllerTables() { - // The code below is very similar to code in file boost_control.cpp - // TODO: think how we can get rid of duplicated code - - // Set up open & closed loop tables - boostMapOpen.initTable(config->boostTableOpenLoop, config->boostRpmBins, config->boostTpsBins); - boostMapClosed.initTable(config->boostTableClosedLoop, config->boostRpmBins, config->boostTpsBins); - boostCltCorr.initTable(config->cltBoostCorr, config->cltBoostCorrBins); - boostIatCorr.initTable(config->iatBoostCorr, config->iatBoostCorrBins); - - // Set up boost controller instance - bc->init( - &boostPwmControl, - &boostMapOpen, - &boostMapClosed, - boostCltCorr, - boostIatCorr, - &engineConfiguration->boostPid - ); - } - - void OpenLoopMultipliersTest::initDefaultConfiguration() { - setTable(config->boostTableOpenLoop, TEST_BOOST_CONTROL_DUTY_CYCLE); - - Sensor::setMockValue(SensorType::Tps1, 42.1f); - } - TEST_F(OpenLoopMultipliersTest, openLoopWithDefaultCurves) { for (int i = 0; i < BOOST_CURVE_SIZE; i++) { EXPECT_EQ(config->cltBoostCorr[i], 1.0f) << "index: " << i; // check default multiplier @@ -159,8 +113,8 @@ namespace { initTestCltBoostCorr(); checkOpenLoop( - [](const int i) -> std::optional { return { TEST_CLT_BOOST_CORR_BINS[i] }; }, - [](const int i) -> std::optional { return { TEST_IAT_BOOST_CORR_BINS[i] }; }, + OpenLoopMultipliersTest::getTestCltBoostBin, + OpenLoopMultipliersTest::getTestIatBoostBin, [](const int i) -> float { return TEST_BOOST_CONTROL_DUTY_CYCLE * TEST_CLT_BOOST_CORR[i]; } ); } @@ -169,8 +123,8 @@ namespace { initTestIatBoostCorr(); checkOpenLoop( - [](const int i) -> std::optional { return { TEST_CLT_BOOST_CORR_BINS[i] }; }, - [](const int i) -> std::optional { return { TEST_IAT_BOOST_CORR_BINS[i] }; }, + OpenLoopMultipliersTest::getTestCltBoostBin, + OpenLoopMultipliersTest::getTestIatBoostBin, [](const int i) -> float { return TEST_BOOST_CONTROL_DUTY_CYCLE * TEST_IAT_BOOST_CORR[i]; } ); } @@ -180,8 +134,8 @@ namespace { initTestIatBoostCorr(); checkOpenLoop( - [](const int i) -> std::optional { return { TEST_CLT_BOOST_CORR_BINS[i] }; }, - [](const int i) -> std::optional { return { TEST_IAT_BOOST_CORR_BINS[i] }; }, + OpenLoopMultipliersTest::getTestCltBoostBin, + OpenLoopMultipliersTest::getTestIatBoostBin, [](const int i) -> float { return TEST_BOOST_CONTROL_DUTY_CYCLE * TEST_CLT_BOOST_CORR[i] * TEST_IAT_BOOST_CORR[i]; } @@ -193,8 +147,8 @@ namespace { initTestIatBoostCorr(); checkOpenLoop( - [](const int i) -> std::optional { return { TEST_CLT_BOOST_CORR_BINS[i] }; }, - [](const int i) -> std::optional { return {}; }, + OpenLoopMultipliersTest::getTestCltBoostBin, + emptyValue, [](const int i) -> float { return TEST_BOOST_CONTROL_DUTY_CYCLE * TEST_CLT_BOOST_CORR[i]; } ); } @@ -204,8 +158,8 @@ namespace { initTestIatBoostCorr(); checkOpenLoop( - [](const int i) -> std::optional { return {}; }, - [](const int i) -> std::optional { return { TEST_IAT_BOOST_CORR_BINS[i] }; }, + emptyValue, + OpenLoopMultipliersTest::getTestIatBoostBin, [](const int i) -> float { return TEST_BOOST_CONTROL_DUTY_CYCLE * TEST_IAT_BOOST_CORR[i]; } ); } @@ -218,8 +172,8 @@ namespace { initLuaOpenLoopAdd(TEST_LUA_OPEN_LOOP_ADD); checkOpenLoop( - [](const int i) -> std::optional { return { TEST_CLT_BOOST_CORR_BINS[i] }; }, - [](const int i) -> std::optional { return { TEST_IAT_BOOST_CORR_BINS[i] }; }, + OpenLoopMultipliersTest::getTestCltBoostBin, + OpenLoopMultipliersTest::getTestIatBoostBin, [](const int i) -> float { return TEST_LUA_OPEN_LOOP_ADD + TEST_BOOST_CONTROL_DUTY_CYCLE * TEST_CLT_BOOST_CORR[i] * TEST_IAT_BOOST_CORR[i]; diff --git a/unit_tests/tests/actuators/test_boost.cpp b/unit_tests/tests/actuators/test_boost.cpp index bc787e134c..15016cb3b4 100644 --- a/unit_tests/tests/actuators/test_boost.cpp +++ b/unit_tests/tests/actuators/test_boost.cpp @@ -7,6 +7,8 @@ using ::testing::StrictMock; static Map2D testBoostCltCorr { "clt" }; static Map2D testBoostIatCorr { "iat" }; +static Map2D testBoostCltAdder { "clt (adder)" }; +static Map2D testBoostIatAdder { "iat (adder)" }; TEST(BoostControl, Setpoint) { MockVp3d targetMap; @@ -23,8 +25,13 @@ TEST(BoostControl, Setpoint) { // Should return unexpected without a pedal map cfg'd EXPECT_EQ(bc.getSetpoint(), unexpected); - // Now init with mock target map - bc.init(nullptr, nullptr, &targetMap, testBoostCltCorr, testBoostIatCorr, nullptr); + testBoostCltCorr.initTable(config->cltBoostCorr, config->cltBoostCorrBins); + testBoostIatCorr.initTable(config->iatBoostCorr, config->iatBoostCorrBins); + testBoostCltAdder.initTable(config->cltBoostAdder, config->cltBoostAdderBins); + testBoostIatAdder.initTable(config->iatBoostAdder, config->iatBoostAdderBins); + + // Now init with mock target map + bc.init(nullptr, nullptr, &targetMap, testBoostCltCorr, testBoostIatCorr, testBoostCltAdder, testBoostIatAdder, nullptr); // Should still return unxepected since TPS is invalid EXPECT_EQ(bc.getSetpoint(), unexpected); @@ -67,8 +74,19 @@ TEST(BoostControl, OpenLoop) { testBoostCltCorr.initTable(config->cltBoostCorr, config->cltBoostCorrBins); testBoostIatCorr.initTable(config->iatBoostCorr, config->iatBoostCorrBins); - - bc.init(nullptr, &openMap, nullptr, testBoostCltCorr, testBoostIatCorr, nullptr); + testBoostCltAdder.initTable(config->cltBoostAdder, config->cltBoostAdderBins); + testBoostIatAdder.initTable(config->iatBoostAdder, config->iatBoostAdderBins); + + bc.init( + nullptr, + &openMap, + nullptr, + testBoostCltCorr, + testBoostIatCorr, + testBoostCltAdder, + testBoostIatAdder, + nullptr + ); // Should pass TPS value thru Sensor::setMockValue(SensorType::Tps1, 47.0f); @@ -87,8 +105,19 @@ TEST(BoostControl, BoostOpenLoopYAxis) testBoostCltCorr.initTable(config->cltBoostCorr, config->cltBoostCorrBins); testBoostIatCorr.initTable(config->iatBoostCorr, config->iatBoostCorrBins); + testBoostCltAdder.initTable(config->cltBoostAdder, config->cltBoostAdderBins); + testBoostIatAdder.initTable(config->iatBoostAdder, config->iatBoostAdderBins); - bc.init(nullptr, &openMap, nullptr, testBoostCltCorr, testBoostIatCorr, nullptr); + bc.init( + nullptr, + &openMap, + nullptr, + testBoostCltCorr, + testBoostIatCorr, + testBoostCltAdder, + testBoostIatAdder, + nullptr + ); constexpr float RPM_TEST_VALUE = 42.0f; Sensor::setMockValue(SensorType::Rpm, RPM_TEST_VALUE); @@ -243,7 +272,16 @@ TEST(BoostControl, TestClosedLoop) { -100, 100 // min/max output }; - bc.init(nullptr, nullptr, nullptr, testBoostCltCorr, testBoostIatCorr, &pidCfg); + bc.init( + nullptr, + nullptr, + nullptr, + testBoostCltCorr, + testBoostIatCorr, + testBoostCltAdder, + testBoostIatAdder, + &pidCfg + ); // Enable closed loop engineConfiguration->boostType = CLOSED_LOOP; @@ -287,7 +325,7 @@ TEST(BoostControl, SetOutput) { EXPECT_NO_THROW(bc.setOutput(25.0f)); // Init with mock PWM device and ETB - bc.init(&pwm, nullptr, nullptr, testBoostCltCorr, testBoostIatCorr, nullptr); + bc.init(&pwm, nullptr, nullptr, testBoostCltCorr, testBoostIatCorr, testBoostCltAdder, testBoostIatAdder, nullptr); engine->etbControllers[0] = &etb; bc.setOutput(25.0f); diff --git a/unit_tests/tests/tests.mk b/unit_tests/tests/tests.mk index bc8980f101..3027dbb7ba 100644 --- a/unit_tests/tests/tests.mk +++ b/unit_tests/tests/tests.mk @@ -142,4 +142,6 @@ TESTS_SRC_CPP = \ tests/actuators/test_vvt.cpp \ tests/actuators/test_alternator.cpp \ tests/actuators/test_alternator_voltage_target_set_point.cpp \ + tests/actuators/boost/boost_test_base.cpp \ tests/actuators/boost/test_open_loop_multipliers.cpp \ + tests/actuators/boost/test_closed_loop_adders.cpp \