support abs+gauge+diff fuel pressure #32

This commit is contained in:
Matthew Kennedy 2023-03-25 13:53:16 -07:00
parent 5834164d62
commit cb0e81b062
3 changed files with 100 additions and 36 deletions

View File

@ -50,20 +50,49 @@ InjectorNonlinearMode InjectorModel::getNonlinearMode() const {
return engineConfiguration->injectorNonlinearMode; return engineConfiguration->injectorNonlinearMode;
} }
expected<float> InjectorModel::getAbsoluteRailPressure() const { expected<float> InjectorModel::getFuelDifferentialPressure() const {
auto map = Sensor::get(SensorType::Map);
float baro = Sensor::get(SensorType::BarometricPressure).value_or(101.325f);
switch (engineConfiguration->injectorCompensationMode) { switch (engineConfiguration->injectorCompensationMode) {
case ICM_FixedRailPressure: case ICM_FixedRailPressure:
// Add barometric pressure, as "fixed" really means "fixed pressure above atmosphere" // Add barometric pressure, as "fixed" really means "fixed pressure above atmosphere"
return engineConfiguration->fuelReferencePressure + Sensor::get(SensorType::BarometricPressure).value_or(101.325f); return
case ICM_SensedRailPressure: engineConfiguration->fuelReferencePressure
+ baro
- map.value_or(101.325);
case ICM_SensedRailPressure: {
if (!Sensor::hasSensor(SensorType::FuelPressureInjector)) { if (!Sensor::hasSensor(SensorType::FuelPressureInjector)) {
firmwareError(OBD_PCM_Processor_Fault, "Fuel pressure compensation is set to use a pressure sensor, but none is configured."); firmwareError(OBD_PCM_Processor_Fault, "Fuel pressure compensation is set to use a pressure sensor, but none is configured.");
return unexpected; return unexpected;
} }
auto fps = Sensor::get(SensorType::FuelPressureInjector);
// TODO: what happens when the sensor fails? // TODO: what happens when the sensor fails?
return Sensor::get(SensorType::FuelPressureInjector); if (!fps) {
default: return unexpected; return unexpected;
}
switch (engineConfiguration->fuelPressureSensorMode) {
case FPM_Differential:
// This sensor directly measures delta-P, no math needed!
return fps.Value;
case FPM_Gauge:
if (!map) {
return unexpected;
}
return fps.Value + baro - map.Value;
case FPM_Absolute:
default:
if (!map) {
return unexpected;
}
return fps.Value - map.Value;
}
} default: return unexpected;
} }
} }
@ -82,21 +111,14 @@ float InjectorModel::getInjectorFlowRatio() {
return 1.0f; return 1.0f;
} }
expected<float> absRailPressure = getAbsoluteRailPressure(); expected<float> diffPressure = getFuelDifferentialPressure();
// If sensor failed, best we can do is disable correction // If sensor failed, best we can do is disable correction
if (!absRailPressure) { if (!diffPressure) {
return 1.0f; return 1.0f;
} }
auto map = Sensor::get(SensorType::Map); pressureDelta = diffPressure.Value;
// Map has failed, assume nominal pressure
if (!map) {
return 1.0f;
}
pressureDelta = absRailPressure.Value - map.Value;
// Somehow pressure delta is less than 0, assume failed sensor and return default flow // Somehow pressure delta is less than 0, assume failed sensor and return default flow
if (pressureDelta <= 0) { if (pressureDelta <= 0) {

View File

@ -18,7 +18,7 @@ public:
float getFuelMassForDuration(floatms_t duration) const override; float getFuelMassForDuration(floatms_t duration) const override;
virtual float getInjectorFlowRatio() = 0; virtual float getInjectorFlowRatio() = 0;
virtual expected<float> getAbsoluteRailPressure() const = 0; virtual expected<float> getFuelDifferentialPressure() const = 0;
virtual float getBaseFlowRate() const = 0; virtual float getBaseFlowRate() const = 0;
@ -50,7 +50,7 @@ public:
floatms_t getDeadtime() const override; floatms_t getDeadtime() const override;
float getBaseFlowRate() const override; float getBaseFlowRate() const override;
float getInjectorFlowRatio() override; float getInjectorFlowRatio() override;
expected<float> getAbsoluteRailPressure() const override; expected<float> getFuelDifferentialPressure() const override;
InjectorNonlinearMode getNonlinearMode() const override; InjectorNonlinearMode getNonlinearMode() const override;

View File

@ -9,7 +9,7 @@ public:
MOCK_METHOD(floatms_t, getDeadtime, (), (const, override)); MOCK_METHOD(floatms_t, getDeadtime, (), (const, override));
MOCK_METHOD(float, getBaseFlowRate, (), (const, override)); MOCK_METHOD(float, getBaseFlowRate, (), (const, override));
MOCK_METHOD(float, getInjectorFlowRatio, (), (override)); MOCK_METHOD(float, getInjectorFlowRatio, (), (override));
MOCK_METHOD(expected<float>, getAbsoluteRailPressure, (), (const, override)); MOCK_METHOD(expected<float>, getFuelDifferentialPressure, (), (const, override));
MOCK_METHOD(float, getSmallPulseFlowRate, (), (const, override)); MOCK_METHOD(float, getSmallPulseFlowRate, (), (const, override));
MOCK_METHOD(float, getSmallPulseBreakPoint, (), (const, override)); MOCK_METHOD(float, getSmallPulseBreakPoint, (), (const, override));
MOCK_METHOD(InjectorNonlinearMode, getNonlinearMode, (), (const, override)); MOCK_METHOD(InjectorNonlinearMode, getNonlinearMode, (), (const, override));
@ -152,7 +152,7 @@ struct TesterGetFlowRate : public InjectorModel {
}; };
struct TesterGetRailPressure : public InjectorModel { struct TesterGetRailPressure : public InjectorModel {
MOCK_METHOD(expected<float>, getAbsoluteRailPressure, (), (const, override)); MOCK_METHOD(expected<float>, getFuelDifferentialPressure, (), (const, override));
}; };
class FlowRateFixture : public ::testing::TestWithParam<float> { class FlowRateFixture : public ::testing::TestWithParam<float> {
@ -168,22 +168,18 @@ TEST_P(FlowRateFixture, PressureRatio) {
float pressureRatio = GetParam(); float pressureRatio = GetParam();
// Flow ratio should be the sqrt of pressure ratio // Flow ratio should be the sqrt of pressure ratio
float expectedFlowRatio = sqrtf(pressureRatio); float expectedFlowRatio = sqrtf(pressureRatio);
float fakeMap = 35.0f;
StrictMock<TesterGetRailPressure> dut; StrictMock<TesterGetRailPressure> dut;
EXPECT_CALL(dut, getAbsoluteRailPressure()).WillOnce(Return(400 * pressureRatio + fakeMap)); EXPECT_CALL(dut, getFuelDifferentialPressure()).WillOnce(Return(400 * pressureRatio));
EngineTestHelper eth(TEST_ENGINE); EngineTestHelper eth(TEST_ENGINE);
// Use injector compensation // Use injector compensation
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure; engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
// Reference pressure is 400kPa // Reference pressure is 400kPa
engineConfiguration->fuelReferencePressure = 400.0f; engineConfiguration->fuelReferencePressure = 400.0f;
// MAP sensor always reads 35 kpa
Sensor::setMockValue(SensorType::Map, fakeMap);
// Should return the expected ratio // Should return the expected ratio
EXPECT_FLOAT_EQ(expectedFlowRatio, dut.getInjectorFlowRatio()); EXPECT_FLOAT_EQ(expectedFlowRatio, dut.getInjectorFlowRatio());
} }
@ -196,12 +192,10 @@ TEST(InjectorModel, NegativePressureDelta) {
// Use injector compensation // Use injector compensation
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure; engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
// Reference pressure is 400kPa // Reference pressure is 400kPa
engineConfiguration->fuelReferencePressure = 400.0f; engineConfiguration->fuelReferencePressure = 400.0f;
EXPECT_CALL(dut, getAbsoluteRailPressure()).WillOnce(Return(50)); EXPECT_CALL(dut, getFuelDifferentialPressure()).WillOnce(Return(-50));
// MAP sensor reads more pressure than fuel rail
Sensor::setMockValue(SensorType::Map, 100);
// Flow ratio defaults to 1.0 in this case // Flow ratio defaults to 1.0 in this case
EXPECT_FLOAT_EQ(1.0f, dut.getInjectorFlowRatio()); EXPECT_FLOAT_EQ(1.0f, dut.getInjectorFlowRatio());
@ -214,7 +208,7 @@ TEST(InjectorModel, VariableInjectorFlowModeNone) {
engineConfiguration->injectorCompensationMode = ICM_None; engineConfiguration->injectorCompensationMode = ICM_None;
// This shoudn't call getAbsoluteRailPressure, it should just return 1.0 // This shoudn't call getFuelDifferentialPressure, it should just return 1.0
EXPECT_FLOAT_EQ(1, dut.getInjectorFlowRatio()); EXPECT_FLOAT_EQ(1, dut.getInjectorFlowRatio());
} }
@ -227,25 +221,73 @@ TEST(InjectorModel, RailPressureFixed) {
engineConfiguration->fuelReferencePressure = 350; engineConfiguration->fuelReferencePressure = 350;
engineConfiguration->injectorCompensationMode = ICM_FixedRailPressure; engineConfiguration->injectorCompensationMode = ICM_FixedRailPressure;
// Should be reference pressure + 1 atm // MAP is 75kPa
EXPECT_FLOAT_EQ(101.325f + 350.0f, dut.getAbsoluteRailPressure().value_or(0)); Sensor::setMockValue(SensorType::Map, 75);
// Baro is 100kpa
Sensor::setMockValue(SensorType::BarometricPressure, 100);
// Should be reference pressure + 1 atm - 75kpa -> 375kPa
EXPECT_FLOAT_EQ(375.0f, dut.getFuelDifferentialPressure().value_or(0));
} }
TEST(InjectorModel, RailPressureSensed) { TEST(InjectorModel, RailPressureSensedAbsolute) {
InjectorModel dut; InjectorModel dut;
EngineTestHelper eth(TEST_ENGINE); EngineTestHelper eth(TEST_ENGINE);
// Reference pressure is 350kpa // Reference pressure is 350kpa
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure; engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
engineConfiguration->fuelPressureSensorMode = FPM_Absolute;
Sensor::setMockValue(SensorType::Map, 50);
// Should just return rail sensor value - MAP
Sensor::setMockValue(SensorType::FuelPressureInjector, 100);
EXPECT_FLOAT_EQ(100 - 50, dut.getFuelDifferentialPressure().value_or(-1));
Sensor::setMockValue(SensorType::FuelPressureInjector, 200);
EXPECT_FLOAT_EQ(200 - 50, dut.getFuelDifferentialPressure().value_or(-1));
Sensor::setMockValue(SensorType::FuelPressureInjector, 300);
EXPECT_FLOAT_EQ(300 - 50, dut.getFuelDifferentialPressure().value_or(-1));
}
TEST(InjectorModel, RailPressureSensedGauge) {
InjectorModel dut;
EngineTestHelper eth(TEST_ENGINE);
// Reference pressure is 350kpa
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
engineConfiguration->fuelPressureSensorMode = FPM_Gauge;
Sensor::setMockValue(SensorType::BarometricPressure, 110);
Sensor::setMockValue(SensorType::Map, 50);
// Should just return rail sensor value + baro - MAP
Sensor::setMockValue(SensorType::FuelPressureInjector, 100);
EXPECT_FLOAT_EQ(100 + 110 - 50, dut.getFuelDifferentialPressure().value_or(-1));
Sensor::setMockValue(SensorType::FuelPressureInjector, 200);
EXPECT_FLOAT_EQ(200 + 110 - 50, dut.getFuelDifferentialPressure().value_or(-1));
Sensor::setMockValue(SensorType::FuelPressureInjector, 300);
EXPECT_FLOAT_EQ(300 + 110 - 50, dut.getFuelDifferentialPressure().value_or(-1));
}
TEST(InjectorModel, RailPressureSensedDifferential) {
InjectorModel dut;
EngineTestHelper eth(TEST_ENGINE);
// Reference pressure is 350kpa
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
engineConfiguration->fuelPressureSensorMode = FPM_Differential;
// Should just return rail sensor value // Should just return rail sensor value
Sensor::setMockValue(SensorType::FuelPressureInjector, 100); Sensor::setMockValue(SensorType::FuelPressureInjector, 100);
EXPECT_FLOAT_EQ(100, dut.getAbsoluteRailPressure().value_or(-1)); EXPECT_FLOAT_EQ(100, dut.getFuelDifferentialPressure().value_or(-1));
Sensor::setMockValue(SensorType::FuelPressureInjector, 200); Sensor::setMockValue(SensorType::FuelPressureInjector, 200);
EXPECT_FLOAT_EQ(200, dut.getAbsoluteRailPressure().value_or(-1)); EXPECT_FLOAT_EQ(200, dut.getFuelDifferentialPressure().value_or(-1));
Sensor::setMockValue(SensorType::FuelPressureInjector, 300); Sensor::setMockValue(SensorType::FuelPressureInjector, 300);
EXPECT_FLOAT_EQ(300, dut.getAbsoluteRailPressure().value_or(-1)); EXPECT_FLOAT_EQ(300, dut.getFuelDifferentialPressure().value_or(-1));
} }
TEST(InjectorModel, FailedPressureSensor) { TEST(InjectorModel, FailedPressureSensor) {