flex fuel AFR interpolation (#2190)
* config * implement flex * secondary fuel default * test * test works * rename Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
parent
cb1637411c
commit
8608df5450
|
@ -792,6 +792,7 @@ static void setDefaultEngineConfiguration(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
|||
|
||||
setLambdaMap(config->lambdaTable, 1.0f);
|
||||
engineConfiguration->stoichRatioPrimary = 14.7f * PACK_MULT_AFR_CFG;
|
||||
engineConfiguration->stoichRatioSecondary = 9.0f * PACK_MULT_AFR_CFG;
|
||||
|
||||
setDefaultVETable(PASS_ENGINE_PARAMETER_SIGNATURE);
|
||||
|
||||
|
|
|
@ -22,14 +22,33 @@ FuelComputer::FuelComputer(const ValueProvider3D& lambdaTable) : m_lambdaTable(&
|
|||
|
||||
float FuelComputer::getStoichiometricRatio() const {
|
||||
// TODO: vary this with ethanol content/configured setting/whatever
|
||||
float rawConfig = (float)CONFIG(stoichRatioPrimary) / PACK_MULT_AFR_CFG;
|
||||
float primary = (float)CONFIG(stoichRatioPrimary) / PACK_MULT_AFR_CFG;
|
||||
|
||||
// Config compatibility: this field may be zero on ECUs with old defaults
|
||||
if (rawConfig < 5) {
|
||||
return 14.7f;
|
||||
if (primary < 5) {
|
||||
// 14.7 = E0 gasoline AFR
|
||||
primary = 14.7f;
|
||||
}
|
||||
|
||||
return rawConfig;
|
||||
// Without an ethanol/flex sensor, return primary configured stoich ratio
|
||||
if (!Sensor::hasSensor(SensorType::FuelEthanolPercent)) {
|
||||
return primary;
|
||||
}
|
||||
|
||||
float secondary = (float)CONFIG(stoichRatioSecondary) / PACK_MULT_AFR_CFG;
|
||||
|
||||
// Config compatibility: this field may be zero on ECUs with old defaults
|
||||
if (secondary < 5) {
|
||||
// 9.0 = E100 ethanol AFR
|
||||
secondary = 9.0f;
|
||||
}
|
||||
|
||||
auto flex = Sensor::get(SensorType::FuelEthanolPercent);
|
||||
|
||||
// TODO: what do do if flex sensor fails?
|
||||
|
||||
// Linear interpolate between primary and secondary stoich ratios
|
||||
return interpolateClamped(0, primary, 100, secondary, flex.Value);
|
||||
}
|
||||
|
||||
float FuelComputer::getTargetLambda(int rpm, float load) const {
|
||||
|
|
|
@ -1421,11 +1421,12 @@ tChargeMode_e tChargeMode;
|
|||
int16_t idlerpmpid_iTermMin;iTerm min value;"", 1, 0, -30000, 30000.0, 0
|
||||
|
||||
spi_device_e tle6240spiDevice;
|
||||
uint8_t stoichRatioPrimary;+Stoichiometric ratio for your primary fuel.;":1", {1/@@PACK_MULT_AFR_CFG@@},0, 5, 25.0, 1
|
||||
uint8_t stoichRatioPrimary;+Stoichiometric ratio for your primary fuel. When Flex Fuel is enabled, this value is used when the Flex Fuel sensor indicates E0.;":1", {1/@@PACK_MULT_AFR_CFG@@},0, 5, 25.0, 1
|
||||
int16_t idlerpmpid_iTermMax;iTerm max value;"", 1, 0, -30000, 30000.0, 0
|
||||
|
||||
spi_device_e mc33972spiDevice;
|
||||
uint8_t[3] unusedSpiPadding8;;"units", 1, 0, -20, 100, 0
|
||||
uint8_t stoichRatioSecondary;+Stoichiometric ratio for your secondary fuel. This value is used when the Flex Fuel sensor indicates E100.;":1", {1/@@PACK_MULT_AFR_CFG@@},0, 5, 25.0, 1
|
||||
uint8_t[2] unusedSpiPadding8;;"units", 1, 0, -20, 100, 0
|
||||
|
||||
|
||||
float etbIdleThrottleRange; ETB idle authority; "%", 1, 0, 0, 15, 0
|
||||
|
|
|
@ -1807,7 +1807,8 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00"
|
|||
field = "Injector reference pressure", fuelReferencePressure, { isInjectionEnabled && injectorCompensationMode != 0 }
|
||||
|
||||
dialog = fuelParams, "Fuel characteristics", yAxis
|
||||
field = "Stoichiometric ratio", stoichRatioPrimary, {isInjectionEnabled == 1}
|
||||
field = "Stoichiometric ratio", stoichRatioPrimary, {isInjectionEnabled == 1}
|
||||
field = "E100 stoichiometric ratio", stoichRatioSecondary, {isInjectionEnabled == 1 && flexSensorPin != 0 }
|
||||
|
||||
dialog = injectorOutputSettings, "Injector Outputs", yAxis
|
||||
field = "Use only first half of pins for batch mode"
|
||||
|
|
|
@ -42,3 +42,39 @@ TEST(FuelComputer, LambdaLookup) {
|
|||
|
||||
EXPECT_FLOAT_EQ(dut.getTargetLambda(1500, 0.7f), 0.85f);
|
||||
}
|
||||
|
||||
TEST(FuelComputer, FlexFuel) {
|
||||
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||
|
||||
MockVp3d lambdaTable;
|
||||
FuelComputer dut(lambdaTable);
|
||||
INJECT_ENGINE_REFERENCE(&dut);
|
||||
|
||||
// easier values for testing
|
||||
engineConfiguration->stoichRatioPrimary = 150;
|
||||
engineConfiguration->stoichRatioSecondary = 100;
|
||||
|
||||
// No sensor -> returns primary
|
||||
Sensor::resetMockValue(SensorType::FuelEthanolPercent);
|
||||
EXPECT_FLOAT_EQ(15.0f, dut.getStoichiometricRatio());
|
||||
|
||||
// E0 -> primary afr
|
||||
Sensor::setMockValue(SensorType::FuelEthanolPercent, 0);
|
||||
EXPECT_FLOAT_EQ(15.0f, dut.getStoichiometricRatio());
|
||||
|
||||
// E50 -> half way between
|
||||
Sensor::setMockValue(SensorType::FuelEthanolPercent, 50);
|
||||
EXPECT_FLOAT_EQ(12.5f, dut.getStoichiometricRatio());
|
||||
|
||||
// E100 -> secondary afr
|
||||
Sensor::setMockValue(SensorType::FuelEthanolPercent, 100);
|
||||
EXPECT_FLOAT_EQ(10.0f, dut.getStoichiometricRatio());
|
||||
|
||||
// E(-10) -> clamp to primary
|
||||
Sensor::setMockValue(SensorType::FuelEthanolPercent, -10);
|
||||
EXPECT_FLOAT_EQ(15.0f, dut.getStoichiometricRatio());
|
||||
|
||||
// E110 -> clamp to secondary
|
||||
Sensor::setMockValue(SensorType::FuelEthanolPercent, 110);
|
||||
EXPECT_FLOAT_EQ(10.0f, dut.getStoichiometricRatio());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue