Now we use `Coolant Temperature Boost Adder` and `Intake Air Temperature Boost Adder` in close loop target calculation #6424
This commit is contained in:
parent
cf3479d45d
commit
4c349de3d1
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
|
@ -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" };
|
||||
};
|
|
@ -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];
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
Loading…
Reference in New Issue