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;
}
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) {
case ICM_FixedRailPressure:
// Add barometric pressure, as "fixed" really means "fixed pressure above atmosphere"
return engineConfiguration->fuelReferencePressure + Sensor::get(SensorType::BarometricPressure).value_or(101.325f);
case ICM_SensedRailPressure:
return
engineConfiguration->fuelReferencePressure
+ baro
- map.value_or(101.325);
case ICM_SensedRailPressure: {
if (!Sensor::hasSensor(SensorType::FuelPressureInjector)) {
firmwareError(OBD_PCM_Processor_Fault, "Fuel pressure compensation is set to use a pressure sensor, but none is configured.");
return unexpected;
}
auto fps = Sensor::get(SensorType::FuelPressureInjector);
// TODO: what happens when the sensor fails?
return Sensor::get(SensorType::FuelPressureInjector);
default: return unexpected;
if (!fps) {
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;
}
expected<float> absRailPressure = getAbsoluteRailPressure();
expected<float> diffPressure = getFuelDifferentialPressure();
// If sensor failed, best we can do is disable correction
if (!absRailPressure) {
if (!diffPressure) {
return 1.0f;
}
auto map = Sensor::get(SensorType::Map);
// Map has failed, assume nominal pressure
if (!map) {
return 1.0f;
}
pressureDelta = absRailPressure.Value - map.Value;
pressureDelta = diffPressure.Value;
// Somehow pressure delta is less than 0, assume failed sensor and return default flow
if (pressureDelta <= 0) {

View File

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

View File

@ -9,7 +9,7 @@ public:
MOCK_METHOD(floatms_t, getDeadtime, (), (const, override));
MOCK_METHOD(float, getBaseFlowRate, (), (const, 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, getSmallPulseBreakPoint, (), (const, override));
MOCK_METHOD(InjectorNonlinearMode, getNonlinearMode, (), (const, override));
@ -152,7 +152,7 @@ struct TesterGetFlowRate : 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> {
@ -168,22 +168,18 @@ TEST_P(FlowRateFixture, PressureRatio) {
float pressureRatio = GetParam();
// Flow ratio should be the sqrt of pressure ratio
float expectedFlowRatio = sqrtf(pressureRatio);
float fakeMap = 35.0f;
StrictMock<TesterGetRailPressure> dut;
EXPECT_CALL(dut, getAbsoluteRailPressure()).WillOnce(Return(400 * pressureRatio + fakeMap));
EXPECT_CALL(dut, getFuelDifferentialPressure()).WillOnce(Return(400 * pressureRatio));
EngineTestHelper eth(TEST_ENGINE);
// Use injector compensation
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
// Reference pressure is 400kPa
// Reference pressure is 400kPa
engineConfiguration->fuelReferencePressure = 400.0f;
// MAP sensor always reads 35 kpa
Sensor::setMockValue(SensorType::Map, fakeMap);
// Should return the expected ratio
EXPECT_FLOAT_EQ(expectedFlowRatio, dut.getInjectorFlowRatio());
}
@ -196,12 +192,10 @@ TEST(InjectorModel, NegativePressureDelta) {
// Use injector compensation
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
// Reference pressure is 400kPa
// Reference pressure is 400kPa
engineConfiguration->fuelReferencePressure = 400.0f;
EXPECT_CALL(dut, getAbsoluteRailPressure()).WillOnce(Return(50));
// MAP sensor reads more pressure than fuel rail
Sensor::setMockValue(SensorType::Map, 100);
EXPECT_CALL(dut, getFuelDifferentialPressure()).WillOnce(Return(-50));
// Flow ratio defaults to 1.0 in this case
EXPECT_FLOAT_EQ(1.0f, dut.getInjectorFlowRatio());
@ -214,7 +208,7 @@ TEST(InjectorModel, VariableInjectorFlowModeNone) {
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());
}
@ -227,25 +221,73 @@ TEST(InjectorModel, RailPressureFixed) {
engineConfiguration->fuelReferencePressure = 350;
engineConfiguration->injectorCompensationMode = ICM_FixedRailPressure;
// Should be reference pressure + 1 atm
EXPECT_FLOAT_EQ(101.325f + 350.0f, dut.getAbsoluteRailPressure().value_or(0));
// MAP is 75kPa
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;
EngineTestHelper eth(TEST_ENGINE);
// Reference pressure is 350kpa
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
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);
EXPECT_FLOAT_EQ(200, dut.getAbsoluteRailPressure().value_or(-1));
EXPECT_FLOAT_EQ(200, dut.getFuelDifferentialPressure().value_or(-1));
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) {