compensate injector flow based on fuel pressure (#1931)

* injector compensation

* fix

* ui

* testability & comments

* hella testing

* debug channels

* enum value

* auto generated enums

* update comment

* oops too much

* update config fields

* handle failed pressure sensor

* build

* fix

* add some todos for the future

Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
Matthew Kennedy 2020-11-10 20:11:22 -08:00 committed by GitHub
parent cd55e04085
commit 02c4d630f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 214 additions and 27 deletions

View File

@ -677,8 +677,6 @@ case DBG_16:
return "DBG_16";
case DBG_34:
return "DBG_34";
case DBG_43:
return "DBG_43";
case DBG_44:
return "DBG_44";
case DBG_ALTERNATOR_PID:
@ -733,6 +731,8 @@ case DBG_IDLE_CONTROL:
return "DBG_IDLE_CONTROL";
case DBG_IGNITION_TIMING:
return "DBG_IGNITION_TIMING";
case DBG_INJECTOR_COMPENSATION:
return "DBG_INJECTOR_COMPENSATION";
case DBG_INSTANT_RPM:
return "DBG_INSTANT_RPM";
case DBG_ION:

View File

@ -473,8 +473,6 @@ case DBG_16:
return "DBG_16";
case DBG_34:
return "DBG_34";
case DBG_43:
return "DBG_43";
case DBG_44:
return "DBG_44";
case DBG_ALTERNATOR_PID:
@ -529,6 +527,8 @@ case DBG_IDLE_CONTROL:
return "DBG_IDLE_CONTROL";
case DBG_IGNITION_TIMING:
return "DBG_IGNITION_TIMING";
case DBG_INJECTOR_COMPENSATION:
return "DBG_INJECTOR_COMPENSATION";
case DBG_INSTANT_RPM:
return "DBG_INSTANT_RPM";
case DBG_ION:

View File

@ -619,8 +619,6 @@ case DBG_16:
return "DBG_16";
case DBG_34:
return "DBG_34";
case DBG_43:
return "DBG_43";
case DBG_44:
return "DBG_44";
case DBG_ALTERNATOR_PID:
@ -675,6 +673,8 @@ case DBG_IDLE_CONTROL:
return "DBG_IDLE_CONTROL";
case DBG_IGNITION_TIMING:
return "DBG_IGNITION_TIMING";
case DBG_INJECTOR_COMPENSATION:
return "DBG_INJECTOR_COMPENSATION";
case DBG_INSTANT_RPM:
return "DBG_INSTANT_RPM";
case DBG_ION:

View File

@ -1,4 +1,6 @@
#include "injector_model.h"
#include "tunerstudio_outputs.h"
#include "map.h"
EXTERN_ENGINE;
@ -15,10 +17,58 @@ constexpr float convertToGramsPerSecond(float ccPerMinute) {
return ccPerSecond * 0.72f; // 0.72g/cc fuel density
}
expected<float> InjectorModel::getAbsoluteRailPressure() const {
switch (CONFIG(injectorCompensationMode)) {
case ICM_FixedRailPressure:
// TODO: should this add baro pressure instead of 1atm?
return (CONFIG(fuelReferencePressure) + 101.325f);
case ICM_SensedRailPressure:
// TODO: what happens when the sensor fails?
return Sensor::get(SensorType::FuelPressureInjector);
default: return unexpected;
}
}
float InjectorModel::getInjectorFlowRatio() const {
// Compensation disabled, use reference flow.
if (CONFIG(injectorCompensationMode) == ICM_None) {
return 1.0f;
}
float referencePressure = CONFIG(fuelReferencePressure);
expected<float> absRailPressure = getAbsoluteRailPressure();
// If sensor failed, best we can do is disable correction
if (!absRailPressure) {
return 1.0f;
}
float map = getMap(PASS_ENGINE_PARAMETER_SIGNATURE);
// TODO: what to do when pressureDelta is less than 0?
float pressureDelta = absRailPressure.Value - map;
float pressureRatio = pressureDelta / referencePressure;
float flowRatio = sqrtf(pressureRatio);
#if EFI_TUNER_STUDIO
if (CONFIG(debugMode) == DBG_INJECTOR_COMPENSATION) {
tsOutputChannels.debugFloatField1 = pressureDelta;
tsOutputChannels.debugFloatField2 = pressureRatio;
tsOutputChannels.debugFloatField3 = flowRatio;
}
#endif // EFI_TUNER_STUDIO
// TODO: should the flow ratio be clamped?
return flowRatio;
}
float InjectorModel::getInjectorMassFlowRate() const {
// TODO: injector flow dependent upon rail pressure (and temperature/ethanol content?)
// TODO: injector flow dependent upon temperature/ethanol content?
auto injectorVolumeFlow = CONFIG(injector.flow);
return convertToGramsPerSecond(injectorVolumeFlow);
float flowRatio = getInjectorFlowRatio();
return flowRatio * convertToGramsPerSecond(injectorVolumeFlow);
}
float InjectorModel::getDeadtime() const {

View File

@ -1,6 +1,7 @@
#pragma once
#include "engine.h"
#include "expected.h"
struct IInjectorModel {
virtual void prepare() = 0;
@ -14,6 +15,8 @@ public:
virtual floatms_t getDeadtime() const = 0;
virtual float getInjectorMassFlowRate() const = 0;
virtual float getInjectorFlowRatio() const = 0;
virtual expected<float> getAbsoluteRailPressure() const = 0;
virtual void postState(float deadTime) const { (void)deadTime; };
@ -22,11 +25,13 @@ private:
float m_massFlowRate = 0;
};
class InjectorModel final : public InjectorModelBase {
class InjectorModel : public InjectorModelBase {
public:
DECLARE_ENGINE_PTR;
void postState(float deadtime) const override;
floatms_t getDeadtime() const override;
float getInjectorMassFlowRate() const override;
float getInjectorFlowRatio() const override;
expected<float> getAbsoluteRailPressure() const override;
};

View File

@ -758,7 +758,7 @@ typedef enum {
DBG_COMPOSITE_LOG = 40,
DBG_FSIO_EXPRESSION_8_14 = 41,
DBG_FSIO_SPECIAL = 42,
DBG_43 = 43,
DBG_INJECTOR_COMPENSATION = 43,
DBG_44 = 44,
Force_4_bytes_size_debug_mode_e = ENUM_32_BITS,
@ -1016,3 +1016,9 @@ typedef enum __attribute__ ((__packed__)) {
IPT_Low = 0,
IPT_High = 1,
} injector_pressure_type_e;
typedef enum __attribute__ ((__packed__)) {
ICM_None = 0,
ICM_FixedRailPressure = 1,
ICM_SensedRailPressure = 2,
} injector_compensation_mode_e;

View File

@ -273,7 +273,7 @@ float baseFuel;+Base mass of the per-cylinder fuel injected during cranking. Th
int16_t rpm;+This sets the RPM limit below which the ECU will use cranking fuel and ignition logic, typically this is around 350-450rpm. \nset cranking_rpm X;"RPM", 1, 0, 0, 3000, 0
end_struct
#define debug_mode_e_enum "Alternator PID", "TPS acceleration enrichment", "GPPWM", "Idle Control", "Engine Load accl enrich", "Trigger Counters", "FSIO_ADC", "AUX_PID_1", "VVT input", "Cranking", "Timing", "Closed-loop fuel corr PID", "VSS", "SD card", "sr5", "Knock", "mode16", "Electronic Throttle", "Executor", "Bench Test / TS commands", "Aux Valves", "Analog inputs #1", "INSTANT_RPM", "FSIO_EXPRESSION_1_7", "Status", "CJ125", "CAN", "MAP", "Metrics", "ETB#2", "Ion Sense", "TLE8888", "Analog inputs #2", "Dwell Metric", "INVALID", "ETB Logic", "Boost Control", "Start/Stop", "Launch", "ETB Autotune", "FSIO_COMPOSITE_LOG", "FSIO_EXPRESSION_8_14", "FSIO_SPECIAL", "Mode43", "Mode44"
#define debug_mode_e_enum "Alternator PID", "TPS acceleration enrichment", "GPPWM", "Idle Control", "Engine Load accl enrich", "Trigger Counters", "FSIO_ADC", "AUX_PID_1", "VVT input", "Cranking", "Timing", "Closed-loop fuel corr PID", "VSS", "SD card", "sr5", "Knock", "mode16", "Electronic Throttle", "Executor", "Bench Test / TS commands", "Aux Valves", "Analog inputs #1", "INSTANT_RPM", "FSIO_EXPRESSION_1_7", "Status", "CJ125", "CAN", "MAP", "Metrics", "ETB#2", "Ion Sense", "TLE8888", "Analog inputs #2", "Dwell Metric", "INVALID", "ETB Logic", "Boost Control", "Start/Stop", "Launch", "ETB Autotune", "FSIO_COMPOSITE_LOG", "FSIO_EXPRESSION_8_14", "FSIO_SPECIAL", "Injector Compensation", "Mode44"
custom debug_mode_e 4 bits, U32, @OFFSET@, [0:5], @@debug_mode_e_enum@@
#define vvt_mode_e_enum "Inactive", "Single Tooth Second Half", "2GZ", "Miata NB2", "Single Tooth First Half", "Bosch Quick Start", "4/1", "mode7"
@ -1245,8 +1245,12 @@ custom tle8888_mode_e 1 bits, U08, @OFFSET@, [0:1], "Auto", "SemiAuto", "Manual"
tle8888_mode_e tle8888mode;
pin_output_mode_e LIS302DLCsPinMode;
uint8_t[2] unusedSomethingWasHere;;"units", 1, 0, -20, 100, 0
float unused244_1;;"units", 1, 0, -20, 100, 0
custom injector_compensation_mode_e 1 bits, U08, @OFFSET@, [0:1], "None", "Fixed rail pressure", "Sensed Rail Pressure"
injector_compensation_mode_e injectorCompensationMode;
uint8_t unused2419;;"units", 1, 0, -20, 100, 0
float fuelReferencePressure;+This is the pressure at which your injector flow is known.\nFor example if your injectors flow 400cc/min at 3.5 bar, enter 350kpa here.;"kPa", 1, 0, 0, 700000, 0
float unused244_2;;"units", 1, 0, -20, 100, 0
float unused244_3;;"units", 1, 0, -20, 100, 0
float unused2432;;"units", 1, 0, -20, 100, 0

View File

@ -413,22 +413,22 @@ enable2ndByteCanID = false
; wall of debug mode :)
; https://rusefi.com/wiki/index.php?title=Manual:Debug_fields
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
; Alternator TPS Acceleration GPPWM Idle Engine Load Acc Trigger Counters VVT Cranking Ignition Timing ETB PID FSIO_1_7 CJ125 CAN TLE8888 Analog inputs 2 Boost Start Launcher ETB Autotune FSIO_8_14 FSIO_SPECIAL
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
; Alternator TPS Acceleration GPPWM Idle Engine Load Acc Trigger Counters VVT Cranking Ignition Timing ETB PID FSIO_1_7 CJ125 CAN TLE8888 Analog inputs 2 Boost Start Launcher ETB Autotune FSIO_8_14 FSIO_SPECIAL Injector flow compensation
; DBG_ALTERNATOR_PID DBG_TPS_ACCEL DBG_GPPWM DBG_IDLE_CONTROL
debugFieldF1List = bits, U08, [0:7], "Controller Output", "From TPS", "GPPWM 1", "Controller Output", "Idle output", "Channel 1 Rise Counter", "", "", "VVT Event Position","", "Ign IAT Corr", "", "", "", "", "", "", "ETB Controller Output", "", "", "df1", "df1", "22df1", "fsio 1", "24:df1", "CJ125: output", "", "", "", "", "", "", "TPS1 Pri/Sec Diff", "", "", "", "Boost Open Loop Duty", "S unused" "", "Osc Amplitude", "", "fsio 8", "idle offset",""
debugFieldF2List = bits, U08, [0:7], "I-Term", "To TPS", "GPPWM 2", "I-Term", "Idle df2", "Channel 2 Rise Counter", "", "", "VVT Ratio", "", "Ign CLT Corr", "", "", "", "", "", "", "ETB I-Term", "", "", "df2", "df2", "22df2", "fsio 2", "24:df2", "CJ125: i-term", "", "", "", "", "", "", "TPS2 Pri/Sec Diff", "", "", "", "Boost Closed Loop Duty","S unused" "", "Duty Amplitude", "", "fsio 9", "idle min", ""
debugFieldF3List = bits, U08, [0:7], "Previous Error", "Current TPS<>TPS", "GPPWM 3", "prev error", "Idle df3", "ICU sum", "", "", "", "", "Ign FSIO Adj", "", "", "", "", "", "", "ETB err", "", "", "df3", "df3", "22df3", "fsio 3", "24:df3", "CJ125: err", "", "", "", "", "", "", "TPS1/2 Diff", "", "", "", "", "S unused" "", "Tu", "", "fsio 10", "", ""
debugFieldF4List = bits, U08, [0:7], "I Gain", "Extra Fuel", "GPPWM 4", "I Gain", "Idle df4", "VVT rise", "", "", "", "", "Ign PID Adj", "", "", "", "", "", "", "ETB I setting", "", "", "df4", "df4", "22df4", "fsio 4", "24:df4", "CJ125: UA", "", "", "", "", "", "", "Acc Pedal Pri/Sec Diff","", "", "", "", "S unused" "", "Ku", "", "fsio 11", "", ""
debugFieldF5List = bits, U08, [0:7], "D Gain", "df5", "df5", "D Gain", "Idle df5", "VVT fall", "df5", "", "", "", "", "", "", "", "", "", "", "ETB D setting", "df5", "df5", "df5", "df5", "22df5", "fsio 5", "24:df5", "CJ125: UR", "", "", "", "", "", "", "", "", "", "", "", "S unused" "", "Kp", "", "fsio 12", "", ""
debugFieldF6List = bits, U08, [0:7], "D Term", "", "", "D Term", "Idle df6", "Current Gap", "", "", "", "", "", "", "", "", "", "", "", "ETB df6", "", "", "df6", "df6", "22df6", "fsio 6", "24:df6", "cj: f7", "", "", "", "", "", "", "", "", "", "", "", "S unused" "", "Ki", "", "fsio 13", "", ""
debugFieldF7List = bits, U08, [0:7], "Max-Value", "", "", "Max-Value", "Idle df7", "", "", "", "", "", "", "", "", "", "", "", "", "ETB df7", "", "", "df7", "df7", "22df7", "fsio 7", "24:df7", "cj: f7", "", "", "", "", "", "", "", "", "", "", "", "S unused" "", "Kd", "", "fsio 14", "", ""
debugFieldF1List = bits, U08, [0:7], "Controller Output", "From TPS", "GPPWM 1", "Controller Output", "Idle output", "Channel 1 Rise Counter", "", "", "VVT Event Position","", "Ign IAT Corr", "", "", "", "", "", "", "ETB Controller Output", "", "", "df1", "df1", "22df1", "fsio 1", "24:df1", "CJ125: output", "", "", "", "", "", "", "TPS1 Pri/Sec Diff", "", "", "", "Boost Open Loop Duty", "S unused" "", "Osc Amplitude", "", "fsio 8", "idle offset", "Pressure across injector(kpa)", ""
debugFieldF2List = bits, U08, [0:7], "I-Term", "To TPS", "GPPWM 2", "I-Term", "Idle df2", "Channel 2 Rise Counter", "", "", "VVT Ratio", "", "Ign CLT Corr", "", "", "", "", "", "", "ETB I-Term", "", "", "df2", "df2", "22df2", "fsio 2", "24:df2", "CJ125: i-term", "", "", "", "", "", "", "TPS2 Pri/Sec Diff", "", "", "", "Boost Closed Loop Duty","S unused" "", "Duty Amplitude", "", "fsio 9", "idle min", "Pressure ratio vs. nominal", ""
debugFieldF3List = bits, U08, [0:7], "Previous Error", "Current TPS<>TPS", "GPPWM 3", "prev error", "Idle df3", "ICU sum", "", "", "", "", "Ign FSIO Adj", "", "", "", "", "", "", "ETB err", "", "", "df3", "df3", "22df3", "fsio 3", "24:df3", "CJ125: err", "", "", "", "", "", "", "TPS1/2 Diff", "", "", "", "", "S unused" "", "Tu", "", "fsio 10", "", "Flow ratio vs. configured", ""
debugFieldF4List = bits, U08, [0:7], "I Gain", "Extra Fuel", "GPPWM 4", "I Gain", "Idle df4", "VVT rise", "", "", "", "", "Ign PID Adj", "", "", "", "", "", "", "ETB I setting", "", "", "df4", "df4", "22df4", "fsio 4", "24:df4", "CJ125: UA", "", "", "", "", "", "", "Acc Pedal Pri/Sec Diff","", "", "", "", "S unused" "", "Ku", "", "fsio 11", "", "", ""
debugFieldF5List = bits, U08, [0:7], "D Gain", "df5", "df5", "D Gain", "Idle df5", "VVT fall", "df5", "", "", "", "", "", "", "", "", "", "", "ETB D setting", "df5", "df5", "df5", "df5", "22df5", "fsio 5", "24:df5", "CJ125: UR", "", "", "", "", "", "", "", "", "", "", "", "S unused" "", "Kp", "", "fsio 12", "", "", ""
debugFieldF6List = bits, U08, [0:7], "D Term", "", "", "D Term", "Idle df6", "Current Gap", "", "", "", "", "", "", "", "", "", "", "", "ETB df6", "", "", "df6", "df6", "22df6", "fsio 6", "24:df6", "cj: f7", "", "", "", "", "", "", "", "", "", "", "", "S unused" "", "Ki", "", "fsio 13", "", "", ""
debugFieldF7List = bits, U08, [0:7], "Max-Value", "", "", "Max-Value", "Idle df7", "", "", "", "", "", "", "", "", "", "", "", "", "ETB df7", "", "", "df7", "df7", "22df7", "fsio 7", "24:df7", "cj: f7", "", "", "", "", "", "", "", "", "", "", "", "S unused" "", "Kd", "", "fsio 14", "", "", ""
debugFieldI1List = bits, U08, [0:7], "P-Gain", "", "", "P-Gain", "Idle di1", "Channel 1 Fall Counter", "", "", "VVT Sync Counter", "", "Multispark Count", "", "", "", "", "", "", "ETB P-Gain", "", "", "di1", "di1", "22di1", "", "24:di1", "CJ125: state", "read count","", "", "", "", "SPI Counter", "", "", "", "", "", "Start Count" "", "", "", "", "", ""
debugFieldI2List = bits, U08, [0:7], "Offset", "", "", "Offset", "Idle di2", "Channel 2 Fall Counter", "", "", "", "", "", "", "", "", "", "", "", "ETB di2", "", "", "di2", "di2", "22di2", "", "24:di2", "", "write count","", "", "", "", "Latest Transmit","", "", "", "", "", "S unused" "", "", "", "", "", ""
debugFieldI3List = bits, U08, [0:7], "Reset Cnt", "", "", "Reset Cnt", "Idle di3", "Cycle Index", "", "", "", "", "", "", "", "", "", "", "", "ETB di3", "", "", "di3", "di3", "22di3", "", "24:di3", "", "write err", "", "", "", "", "Latest Received","", "", "", "", "", "S unused" "", "", "", "", "", ""
debugFieldI4List = bits, U08, [0:7], "Period", "", "", "State", "Idle di4", "Cycle Cnt 1", "", "", "", "", "", "", "", "", "", "", "", "ETB di4", "", "", "di4", "di4", "22di4", "", "24:di4", "", "", "", "", "", "", "Init Count", "", "", "", "", "", "S unused" "", "", "", "", "", ""
debugFieldI5List = bits, U08, [0:7], "", "", "", "", "Idle di5", "Cycle Cnt 2", "", "", "", "", "", "", "", "", "", "di5", "di5", "ETB di5", "di5", "di5", "di5", "di5", "22di5", "di5", "di5", "di5", "di5", "di5", "di5", "di5", "di5", "di5", "", "di5", "di5", "di5", "di5", "S di5" "", "", "", "", "", ""
debugFieldI1List = bits, U08, [0:7], "P-Gain", "", "", "P-Gain", "Idle di1", "Channel 1 Fall Counter", "", "", "VVT Sync Counter", "", "Multispark Count", "", "", "", "", "", "", "ETB P-Gain", "", "", "di1", "di1", "22di1", "", "24:di1", "CJ125: state", "read count","", "", "", "", "SPI Counter", "", "", "", "", "", "Start Count" "", "", "", "", "", "", ""
debugFieldI2List = bits, U08, [0:7], "Offset", "", "", "Offset", "Idle di2", "Channel 2 Fall Counter", "", "", "", "", "", "", "", "", "", "", "", "ETB di2", "", "", "di2", "di2", "22di2", "", "24:di2", "", "write count","", "", "", "", "Latest Transmit","", "", "", "", "", "S unused" "", "", "", "", "", "", ""
debugFieldI3List = bits, U08, [0:7], "Reset Cnt", "", "", "Reset Cnt", "Idle di3", "Cycle Index", "", "", "", "", "", "", "", "", "", "", "", "ETB di3", "", "", "di3", "di3", "22di3", "", "24:di3", "", "write err", "", "", "", "", "Latest Received","", "", "", "", "", "S unused" "", "", "", "", "", "", ""
debugFieldI4List = bits, U08, [0:7], "Period", "", "", "State", "Idle di4", "Cycle Cnt 1", "", "", "", "", "", "", "", "", "", "", "", "ETB di4", "", "", "di4", "di4", "22di4", "", "24:di4", "", "", "", "", "", "", "Init Count", "", "", "", "", "", "S unused" "", "", "", "", "", "", ""
debugFieldI5List = bits, U08, [0:7], "", "", "", "", "Idle di5", "Cycle Cnt 2", "", "", "", "", "", "", "", "", "", "di5", "di5", "ETB di5", "di5", "di5", "di5", "di5", "22di5", "di5", "di5", "di5", "di5", "di5", "di5", "di5", "di5", "di5", "", "di5", "di5", "di5", "di5", "S di5" "", "", "", "", "", "", ""
[ConstantsExtensions]
; defaultValue is used to provide TunerStudio with a value to use in the case of
@ -1754,6 +1754,8 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00"
dialog = injChars, "Injector Settings", yAxis
field = "Injector Flow", injector_flow, {isInjectionEnabled == 1}
field = "Fuel rail pressure sensor", injectorPressureType, { isInjectionEnabled && (highPressureFuel_hwChannel || lowPressureFuel_hwChannel) }
field = "Injector flow compensation mode", injectorCompensationMode, { isInjectionEnabled }
field = "Injector reference pressure", fuelReferencePressure, { isInjectionEnabled && injectorCompensationMode != 0 }
dialog = fuelParams, "Fuel characteristics", yAxis
field = "Stoichiometric ratio", stoichRatioPrimary, {isInjectionEnabled == 1}

View File

@ -10,6 +10,8 @@ class MockInjectorModel : public InjectorModelBase {
public:
MOCK_METHOD(floatms_t, getDeadtime, (), (const, override));
MOCK_METHOD(float, getInjectorMassFlowRate, (), (const, override));
MOCK_METHOD(float, getInjectorFlowRatio, (), (const, override));
MOCK_METHOD(expected<float>, getAbsoluteRailPressure, (), (const, override));
};
TEST(InjectorModel, Prepare) {
@ -53,3 +55,121 @@ TEST(InjectorModel, Deadtime) {
engine->sensors.vBatt = 7;
EXPECT_EQ(dut.getDeadtime(), 14);
}
struct TesterGetFlowRate : public InjectorModel {
MOCK_METHOD(float, getInjectorFlowRatio, (), (const, override));
};
struct TesterGetRailPressure : public InjectorModel {
MOCK_METHOD(expected<float>, getAbsoluteRailPressure, (), (const, override));
};
class FlowRateFixture : public ::testing::TestWithParam<float> {
};
INSTANTIATE_TEST_SUITE_P(
InjectorModel,
FlowRateFixture,
::testing::Values(0.1f, 0.5f, 1.0f, 2.0f, 10.0f)
);
TEST_P(FlowRateFixture, FlowRateRatio) {
float flowRatio = GetParam();
StrictMock<TesterGetFlowRate> dut;
EXPECT_CALL(dut, getInjectorFlowRatio()).WillOnce(Return(flowRatio));
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
INJECT_ENGINE_REFERENCE(&dut);
engineConfiguration->injector.flow = 500;
// 500 cc/min = 6g/s
float expectedFlow = flowRatio * 6.0f;
// Check that flow is adjusted correctly
EXPECT_FLOAT_EQ(expectedFlow, dut.getInjectorMassFlowRate());
}
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));
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
INJECT_ENGINE_REFERENCE(&dut);
// Use injector compensation
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
// Reference pressure is 400kPa
engineConfiguration->fuelReferencePressure = 400.0f;
// MAP sensor always reads 35 kpa
engine->mockMapValue = fakeMap;
// Should return the expected ratio
EXPECT_FLOAT_EQ(expectedFlowRatio, dut.getInjectorFlowRatio());
}
TEST(InjectorModel, VariableInjectorFlowModeNone) {
StrictMock<TesterGetRailPressure> dut;
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
INJECT_ENGINE_REFERENCE(&dut);
engineConfiguration->injectorCompensationMode = ICM_None;
// This shoudn't call getAbsoluteRailPressure, it should just return 1.0
EXPECT_FLOAT_EQ(1, dut.getInjectorFlowRatio());
}
TEST(InjectorModel, RailPressureFixed) {
InjectorModel dut;
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
INJECT_ENGINE_REFERENCE(&dut);
// Reference pressure is 350kpa
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));
}
TEST(InjectorModel, RailPressureSensed) {
InjectorModel dut;
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
INJECT_ENGINE_REFERENCE(&dut);
// Reference pressure is 350kpa
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
// Should just return rail sensor value
Sensor::setMockValue(SensorType::FuelPressureInjector, 100);
EXPECT_FLOAT_EQ(100, dut.getAbsoluteRailPressure().value_or(-1));
Sensor::setMockValue(SensorType::FuelPressureInjector, 200);
EXPECT_FLOAT_EQ(200, dut.getAbsoluteRailPressure().value_or(-1));
Sensor::setMockValue(SensorType::FuelPressureInjector, 300);
EXPECT_FLOAT_EQ(300, dut.getAbsoluteRailPressure().value_or(-1));
}
TEST(InjectorModel, FailedPressureSensor) {
InjectorModel dut;
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
INJECT_ENGINE_REFERENCE(&dut);
// Reference pressure is 350kpa
engineConfiguration->injectorCompensationMode = ICM_SensedRailPressure;
// Sensor is broken!
Sensor::resetMockValue(SensorType::FuelPressureInjector);
EXPECT_EQ(1.0f, dut.getInjectorFlowRatio());
}