Now we use `Coolant Temperature Boost Adder` and `Intake Air Temperature Boost Adder` in close loop target calculation #6424

This commit is contained in:
kifir 2024-07-31 15:10:09 +03:00 committed by Andrey
parent cf3479d45d
commit 4c349de3d1
9 changed files with 433 additions and 99 deletions

View File

@ -23,6 +23,8 @@ namespace {
static Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t, uint8_t> boostMapClosed{"bc"};
Map2D<BOOST_CURVE_SIZE, float, float> boostCltCorr { "clt" };
Map2D<BOOST_CURVE_SIZE, float, float> boostIatCorr { "iat" };
Map2D<BOOST_CURVE_SIZE, float, float> boostCltAdder { "clt (adder)" };
Map2D<BOOST_CURVE_SIZE, float, float> 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<float> BoostController::getSetpoint() {
}
#endif //EFI_ENGINE_CONTROL
return target * luaTargetMult + luaTargetAdd;
target *= luaTargetMult;
target += luaTargetAdd;
const std::optional<float> temperatureAdder = getBoostControlTargetTemperatureAdder();
if (temperatureAdder.has_value()) {
target += temperatureAdder.value();
}
return target;
}
expected<percent_t> BoostController::getOpenLoop(float target) {
@ -185,26 +197,39 @@ float BoostController::getBoostControlDutyCycleWithTemperatureCorrections(
const float driverIntent
) const {
float result = m_openLoopMap->getValue(rpm, driverIntent);
std::optional<float> cltBoostMultiplier = getBoostMultiplier(SensorType::Clt, *m_cltBoostCorrMap);
std::optional<float> cltBoostMultiplier = getBoostTemperatureCorrection(SensorType::Clt, *m_cltBoostCorrMap);
if (cltBoostMultiplier.has_value()) {
result *= cltBoostMultiplier.value();
}
std::optional<float> iatBoostMultiplier = getBoostMultiplier(SensorType::Iat, *m_iatBoostCorrMap);
std::optional<float> iatBoostMultiplier = getBoostTemperatureCorrection(SensorType::Iat, *m_iatBoostCorrMap);
if (iatBoostMultiplier.has_value()) {
result *= iatBoostMultiplier.value();
}
return result;
}
std::optional<float> BoostController::getBoostMultiplier(
std::optional<float> BoostController::getBoostControlTargetTemperatureAdder() const {
std::optional<float> result = getBoostTemperatureCorrection(SensorType::Clt, *m_cltBoostAdderMap);
const std::optional<float> 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<float> BoostController::getBoostTemperatureCorrection(
const SensorType sensorType,
const ValueProvider2D& multiplierCurve
const ValueProvider2D& correctionCurve
) const {
const SensorResult temperature = Sensor::get(sensorType);
if (temperature.Valid) {
const std::optional<float> boostMultiplier = multiplierCurve.getValue(temperature.Value);
if (boostMultiplier.has_value()) {
return std::make_optional<float>(boostMultiplier.value());
const std::optional<float> boostCorrection = correctionCurve.getValue(temperature.Value);
if (boostCorrection.has_value()) {
return std::make_optional<float>(boostCorrection.value());
}
}
return {};
@ -344,6 +369,8 @@ void initBoostCtrl() {
&boostMapClosed,
boostCltCorr,
boostIatCorr,
boostCltAdder,
boostIatAdder,
&engineConfiguration->boostPid
);

View File

@ -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<float> getBoostMultiplier(const SensorType sensorType, const ValueProvider2D& multiplierCurve) const;
std::optional<float> getBoostControlTargetTemperatureAdder() const;
std::optional<float> 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;
};

View File

@ -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;

View File

@ -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<float> {
return {};
};
void BoostTestBase::SetUp() {
TestBase::SetUp();
bc = std::make_unique<BoostController>();
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
);
}

View File

@ -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<std::optional<float>(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<BoostController> bc;
private:
void initBoostCurveArray(const float (&src)[BOOST_CURVE_SIZE], float (&dst)[BOOST_CURVE_SIZE]);
void initBoostControllerTables();
Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t, uint8_t> boostMapOpen{ "bo" };
Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t, uint8_t> boostMapClosed{ "bc" };
Map2D<BOOST_CURVE_SIZE, float, float> boostCltCorr { "clt" };
Map2D<BOOST_CURVE_SIZE, float, float> boostIatCorr { "iat" };
Map2D<BOOST_CURVE_SIZE, float, float> boostCltAdder { "clt (adder)" };
Map2D<BOOST_CURVE_SIZE, float, float> boostIatAdder { "iat (adder)" };
SimplePwm boostPwmControl { "boost" };
};

View File

@ -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<float> getTestCltBoostBin(const int index);
static std::optional<float> getTestIatBoostBin(const int index);
void checkClosedLoopSetPoint(
std::function<std::optional<float>(int)> cltExtractorByIndex,
std::function<std::optional<float>(int)> iatExtractorByIndex,
std::function<float(int)> expectedClosedLoopExtractorByIndex
);
void checkClosedLoopSetPoint(
const std::optional<float> clt,
const std::optional<float> 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<float> ClosedLoopAddersTest::getTestCltBoostBin(const int index) {
return { TEST_CLT_BOOST_ADDER_BINS[index] };
}
std::optional<float> ClosedLoopAddersTest::getTestIatBoostBin(const int index) {
return { TEST_IAT_BOOST_ADDER_BINS[index] };
}
void ClosedLoopAddersTest::checkClosedLoopSetPoint(
std::function<std::optional<float>(int)> cltExtractorByIndex,
std::function<std::optional<float>(int)> iatExtractorByIndex,
std::function<float(int)> expectedClosedLoopExtractorByIndex
) {
for (int i = 0; i< BOOST_CURVE_SIZE; i++) {
checkClosedLoopSetPoint(
cltExtractorByIndex(i),
iatExtractorByIndex(i),
expectedClosedLoopExtractorByIndex(i)
);
}
}
void ClosedLoopAddersTest::checkClosedLoopSetPoint(
const std::optional<float> clt,
const std::optional<float> 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<percent_t> 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<float>(TEST_LUA_TARGET_ADD)
+ TEST_CLT_BOOST_ADDER[i] + TEST_IAT_BOOST_ADDER[i];
}
);
}
}

View File

@ -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<float> getTestCltBoostBin(const int index);
static std::optional<float> getTestIatBoostBin(const int index);
void checkOpenLoop(
std::function<std::optional<float>(int)> cltExtractorByIndex,
std::function<std::optional<float>(int)> iatExtractorByIndex,
ValueByIndexRetriever cltExtractorByIndex,
ValueByIndexRetriever iatExtractorByIndex,
std::function<float(int)> expectedOpenLoopExtractorByIndex
);
@ -33,59 +34,39 @@ namespace {
const std::optional<float> iat,
const float expectedOpenLoop
);
private:
std::unique_ptr<BoostController> bc;
void initBoostControllerTables();
void initDefaultConfiguration();
Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t, uint8_t> boostMapOpen{ "bo" };
Map3D<BOOST_RPM_COUNT, BOOST_LOAD_COUNT, uint8_t, uint8_t, uint8_t> boostMapClosed{ "bc" };
Map2D<BOOST_CURVE_SIZE, float, float> boostCltCorr { "clt" };
Map2D<BOOST_CURVE_SIZE, float, float> boostIatCorr { "iat" };
SimplePwm boostPwmControl { "boost" };
};
void OpenLoopMultipliersTest::SetUp() {
TestBase::SetUp();
BoostTestBase::SetUp();
bc = std::make_unique<BoostController>();
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<float> OpenLoopMultipliersTest::getTestCltBoostBin(const int index) {
return {TEST_CLT_BOOST_CORR_BINS[index] };
}
std::optional<float> OpenLoopMultipliersTest::getTestIatBoostBin(const int index) {
return {TEST_IAT_BOOST_CORR_BINS[index] };
}
void OpenLoopMultipliersTest::checkOpenLoop(
std::function<std::optional<float>(int)> cltExtractorByIndex,
std::function<std::optional<float>(int)> iatExtractorByIndex,
ValueByIndexRetriever cltExtractorByIndex,
ValueByIndexRetriever iatExtractorByIndex,
std::function<float(int)> 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<float> { return { TEST_CLT_BOOST_CORR_BINS[i] }; },
[](const int i) -> std::optional<float> { 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<float> { return { TEST_CLT_BOOST_CORR_BINS[i] }; },
[](const int i) -> std::optional<float> { 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<float> { return { TEST_CLT_BOOST_CORR_BINS[i] }; },
[](const int i) -> std::optional<float> { 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<float> { return { TEST_CLT_BOOST_CORR_BINS[i] }; },
[](const int i) -> std::optional<float> { 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<float> { return {}; },
[](const int i) -> std::optional<float> { 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<float> { return { TEST_CLT_BOOST_CORR_BINS[i] }; },
[](const int i) -> std::optional<float> { 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];

View File

@ -7,6 +7,8 @@ using ::testing::StrictMock;
static Map2D<BOOST_CURVE_SIZE, float, float> testBoostCltCorr { "clt" };
static Map2D<BOOST_CURVE_SIZE, float, float> testBoostIatCorr { "iat" };
static Map2D<BOOST_CURVE_SIZE, float, float> testBoostCltAdder { "clt (adder)" };
static Map2D<BOOST_CURVE_SIZE, float, float> 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);
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
);
// 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);

View File

@ -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 \