Knock fuel trim and deacceleration (#7024)
* - knock fuel trim - knock disable suppression then deceleration * - knock disable suppression then deceleration syntax fix * - knock disable suppression for test reapply * - knock disable suppression for test reapply fix * - knock fuel trim tests --------- Co-authored-by: 3er0.1ive <3er0.1ive@veeroute.com>
This commit is contained in:
parent
1829e1cec6
commit
691fb3f3db
|
@ -66,20 +66,23 @@ void KnockControllerBase::onKnockSenseCompleted(uint8_t cylinderNumber, float db
|
|||
auto retardFraction = engineConfiguration->knockRetardAggression * 0.01f;
|
||||
auto retardAmount = distToMinimum * retardFraction;
|
||||
|
||||
// TODO: remove magic 30% m_maximumFuelTrim?
|
||||
auto maximumFuelTrim = 0.3f;
|
||||
|
||||
auto trimFuelFraction = engineConfiguration->knockFuelTrimAggression * 0.01f;
|
||||
float trimFuelPersent = clampF(0.0, (float)engineConfiguration->knockFuelTrim, 30.0);
|
||||
float trimFuelCoeff = (trimFuelPersent / 100.f);
|
||||
float trimFuelAmount = trimFuelCoeff * trimFuelFraction;
|
||||
float trimFuelPercent = clampF(0.f, (float)engineConfiguration->knockFuelTrim, maximumFuelTrim * 100.f);
|
||||
float trimFuelAmountPercent = trimFuelPercent * trimFuelFraction;
|
||||
float trimFuelAmount = trimFuelAmountPercent / 100.f;
|
||||
|
||||
{
|
||||
// Adjust knock retard under lock
|
||||
chibios_rt::CriticalSectionLocker csl;
|
||||
|
||||
auto newRetard = m_knockRetard + retardAmount;
|
||||
m_knockRetard = clampF(0, newRetard, m_maximumRetard);
|
||||
m_knockRetard = clampF(0.f, newRetard, m_maximumRetard);
|
||||
|
||||
auto newFuelTrim = m_knockFuelTrimMultiplier + trimFuelAmount;
|
||||
m_knockFuelTrimMultiplier = clampF(0.0, newFuelTrim, 0.3); // TODO: remove magic 30%
|
||||
m_knockFuelTrimMultiplier = clampF(0.f, newFuelTrim, maximumFuelTrim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +106,7 @@ void KnockControllerBase::onFastCallback() {
|
|||
constexpr auto callbackPeriodSeconds = FAST_CALLBACK_PERIOD_MS / 1000.0f;
|
||||
|
||||
auto applyRetardAmount = engineConfiguration->knockRetardReapplyRate * callbackPeriodSeconds;
|
||||
auto applyFuelAmount = engineConfiguration->knockFuelTrimReapplyRate * callbackPeriodSeconds;
|
||||
auto applyFuelAmount = engineConfiguration->knockFuelTrimReapplyRate * 0.01f * callbackPeriodSeconds;
|
||||
|
||||
// disable knock suppression then deceleration
|
||||
auto TPSValue = Sensor::getOrZero(SensorType::Tps1);
|
||||
|
@ -132,7 +135,7 @@ void KnockControllerBase::onFastCallback() {
|
|||
// Reduce fuel trim at the requested rate
|
||||
float newTrim = m_knockFuelTrimMultiplier - applyFuelAmount;
|
||||
|
||||
// don't allow retard to go negative
|
||||
// don't allow trim to go negative
|
||||
if (newTrim < 0) {
|
||||
m_knockFuelTrimMultiplier = 0;
|
||||
} else {
|
||||
|
|
|
@ -1723,7 +1723,7 @@ linear_sensor_s auxLinear4
|
|||
|
||||
uint8_t autoscale knockSuppressMinTps;Below TPS value all knock suppression will be disabled.;"%", 1, 0, 0, 100, 1
|
||||
uint8_t autoscale knockFuelTrimAggression;Fuel to odd when a knock event occurs. Advice: 5% (mild), 10% (turbo/high comp.), 15% (high knock, e.g. GDI), 20% (spicy lump),;"%", 0.1, 0, 0, 20, 1
|
||||
uint8_t autoscale knockFuelTrimReapplyRate;After a knock event, reapply fuel at this rate.;"deg/s", 0.1, 0, 0, 10, 1
|
||||
uint8_t autoscale knockFuelTrimReapplyRate;After a knock event, reapply fuel at this rate.;"1%/s", 0.1, 0, 0, 10, 1
|
||||
uint8_t autoscale knockFuelTrim;Fuel trim when knock, max 30%;"%", 1, 0, 0, 30, 1
|
||||
|
||||
float knockSpectrumSensitivity;;"sense", 1, 0, 0, 1, 2
|
||||
|
|
|
@ -92,3 +92,84 @@ TEST(Knock, Reapply) {
|
|||
// Should have no knock retard
|
||||
EXPECT_FLOAT_EQ(dut.getKnockRetard(), 0);
|
||||
}
|
||||
|
||||
TEST(Knock, FuelTrim) {
|
||||
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
||||
|
||||
// Aggression of 10%
|
||||
engineConfiguration->knockFuelTrimAggression = 10;
|
||||
engineConfiguration->knockFuelTrim = 30;
|
||||
|
||||
MockKnockController dut;
|
||||
dut.onFastCallback();
|
||||
|
||||
// No trim unless we knock
|
||||
ASSERT_FLOAT_EQ(dut.getFuelTrimMultiplier(), 1.0);
|
||||
|
||||
// Send some weak knocks, should yield no response
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
dut.onKnockSenseCompleted(0, 10, 0);
|
||||
}
|
||||
|
||||
EXPECT_FLOAT_EQ(dut.getFuelTrimMultiplier(), 1.0);
|
||||
|
||||
// Send a strong knock!
|
||||
dut.onKnockSenseCompleted(0, 30, 0);
|
||||
|
||||
// Should retard 10% of the distance between current timing and "maximum"
|
||||
EXPECT_FLOAT_EQ(dut.getFuelTrimMultiplier(), 1.03);
|
||||
|
||||
// Send tons of strong knocks, make sure we don't go over the configured limit
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
dut.onKnockSenseCompleted(0, 30, 0);
|
||||
}
|
||||
|
||||
EXPECT_FLOAT_EQ(dut.getFuelTrimMultiplier(), 1.3);
|
||||
}
|
||||
|
||||
TEST(Knock, FuelTrimReapply) {
|
||||
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
||||
|
||||
MockKnockController dut;
|
||||
dut.onFastCallback();
|
||||
|
||||
// Aggression of 100%
|
||||
engineConfiguration->knockFuelTrimAggression = 10;
|
||||
// Apply 1%/second
|
||||
engineConfiguration->knockFuelTrimReapplyRate = 1;
|
||||
|
||||
// fuel trim 30%
|
||||
engineConfiguration->knockFuelTrim = 30;
|
||||
|
||||
// disable suppress for test
|
||||
engineConfiguration->knockSuppressMinTps = 0;
|
||||
|
||||
// Send a strong knock!
|
||||
dut.onKnockSenseCompleted(0, 30, 0);
|
||||
|
||||
// 100% trim
|
||||
float trim = 1.03;
|
||||
|
||||
// Should retard 100% of the distance between current timing and "maximum"
|
||||
EXPECT_FLOAT_EQ(dut.getFuelTrimMultiplier(), trim);
|
||||
|
||||
constexpr auto fastPeriodSec = FAST_CALLBACK_PERIOD_MS / 1000.0f;
|
||||
|
||||
// call the fast callback, should reapply 1% trim * callback period
|
||||
dut.onFastCallback();
|
||||
EXPECT_FLOAT_EQ(dut.getFuelTrimMultiplier(), trim - 0.01f * fastPeriodSec);
|
||||
|
||||
// 10 updates total
|
||||
for (size_t i = 0; i < 9; i++) {
|
||||
dut.onFastCallback();
|
||||
}
|
||||
EXPECT_FLOAT_EQ(dut.getFuelTrimMultiplier(), trim - 10 * 0.01f * fastPeriodSec);
|
||||
|
||||
// Spend a long time without knock
|
||||
for (size_t i = 0; i < 2000; i++) {
|
||||
dut.onFastCallback();
|
||||
}
|
||||
|
||||
// Should have no knock retard
|
||||
EXPECT_FLOAT_EQ(dut.getFuelTrimMultiplier(), 1.0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue