From 6b432ffef505b06f10adcda5da190771fbf40036 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Tue, 16 Jan 2024 23:11:01 -0800 Subject: [PATCH] Actually separate injector model for second stage --- .../controllers/algo/fuel/injector_model.cpp | 53 +++++++++++++++---- .../controllers/algo/fuel/injector_model.h | 28 +++++++--- .../test_injector_model.cpp | 20 +++---- 3 files changed, 72 insertions(+), 29 deletions(-) diff --git a/firmware/controllers/algo/fuel/injector_model.cpp b/firmware/controllers/algo/fuel/injector_model.cpp index 486b8c1794..9691a837d6 100644 --- a/firmware/controllers/algo/fuel/injector_model.cpp +++ b/firmware/controllers/algo/fuel/injector_model.cpp @@ -29,28 +29,43 @@ constexpr float convertToGramsPerSecond(float ccPerMinute) { return ccPerMinute * (fuelDensity / 60.f); } -float InjectorModel::getBaseFlowRate() const { +float InjectorModelWithConfig::getBaseFlowRate() const { if (engineConfiguration->injectorFlowAsMassFlow) { - return engineConfiguration->injector.flow; + return m_cfg->flow; } else { - return convertToGramsPerSecond(engineConfiguration->injector.flow); + return convertToGramsPerSecond(m_cfg->flow); } } -float InjectorModel::getSmallPulseFlowRate() const { +float InjectorModelPrimary::getSmallPulseFlowRate() const { return engineConfiguration->fordInjectorSmallPulseSlope; } -float InjectorModel::getSmallPulseBreakPoint() const { +float InjectorModelPrimary::getSmallPulseBreakPoint() const { // convert milligrams -> grams return 0.001f * engineConfiguration->fordInjectorSmallPulseBreakPoint; } -InjectorNonlinearMode InjectorModel::getNonlinearMode() const { +InjectorNonlinearMode InjectorModelPrimary::getNonlinearMode() const { return engineConfiguration->injectorNonlinearMode; } -expected InjectorModel::getFuelDifferentialPressure() const { +float InjectorModelSecondary::getSmallPulseFlowRate() const { + // not supported on second bank + return 0; +} + +float InjectorModelSecondary::getSmallPulseBreakPoint() const { + // not supported on second bank + return 0; +} + +InjectorNonlinearMode InjectorModelSecondary::getNonlinearMode() const { + // nonlinear not supported on second bank + return InjectorNonlinearMode::INJ_None; +} + +expected InjectorModelWithConfig::getFuelDifferentialPressure() const { auto map = Sensor::get(SensorType::Map); auto baro = Sensor::get(SensorType::BarometricPressure); @@ -101,7 +116,7 @@ expected InjectorModel::getFuelDifferentialPressure() const { } } -float InjectorModel::getInjectorFlowRatio() { +float InjectorModelWithConfig::getInjectorFlowRatio() { // Compensation disabled, use reference flow. if (engineConfiguration->injectorCompensationMode == ICM_None) { return 1.0f; @@ -138,11 +153,11 @@ float InjectorModel::getInjectorFlowRatio() { return flowRatio; } -float InjectorModel::getDeadtime() const { +float InjectorModelWithConfig::getDeadtime() const { return interpolate2d( Sensor::get(SensorType::BatteryVoltage).value_or(VBAT_FALLBACK_VALUE), - engineConfiguration->injector.battLagCorrBins, - engineConfiguration->injector.battLagCorr + m_cfg->battLagCorrBins, + m_cfg->battLagCorr ); } @@ -203,3 +218,19 @@ float InjectorModelBase::correctInjectionPolynomial(float baseDuration) const { return baseDuration + adder; } + +InjectorModelWithConfig::InjectorModelWithConfig(const injector_s* const cfg) + : m_cfg(cfg) +{ +} + +InjectorModelPrimary::InjectorModelPrimary() + : InjectorModelWithConfig(&engineConfiguration->injector) +{ +} + +// TODO: actual separate config for second bank! +InjectorModelSecondary::InjectorModelSecondary() + : InjectorModelWithConfig(&engineConfiguration->injector) +{ +} diff --git a/firmware/controllers/algo/fuel/injector_model.h b/firmware/controllers/algo/fuel/injector_model.h index 16996a0d74..f8899832ec 100644 --- a/firmware/controllers/algo/fuel/injector_model.h +++ b/firmware/controllers/algo/fuel/injector_model.h @@ -44,25 +44,37 @@ private: float m_smallPulseOffset = 0; }; -class InjectorModel : public InjectorModelBase { +class InjectorModelWithConfig : public InjectorModelBase { public: + InjectorModelWithConfig(const injector_s* const cfg); floatms_t getDeadtime() const override; float getBaseFlowRate() const override; float getInjectorFlowRatio() override; expected getFuelDifferentialPressure() const override; + using interface_t = IInjectorModel; // Mock interface + +private: + const injector_s* const m_cfg; +}; + +struct InjectorModelPrimary : public InjectorModelWithConfig { + InjectorModelPrimary(); + InjectorNonlinearMode getNonlinearMode() const override; // Ford small pulse model float getSmallPulseFlowRate() const override; float getSmallPulseBreakPoint() const override; - - // Small pulse correction logic - - using interface_t = IInjectorModel; // Mock interface }; -// TODO: differentiate primary vs. secondary injector configuration -struct InjectorModelPrimary : public InjectorModel { }; -struct InjectorModelSecondary : public InjectorModel { }; +struct InjectorModelSecondary : public InjectorModelWithConfig { + InjectorModelSecondary(); + + InjectorNonlinearMode getNonlinearMode() const override; + + // Ford small pulse model + float getSmallPulseFlowRate() const override; + float getSmallPulseBreakPoint() const override; +}; diff --git a/unit_tests/tests/ignition_injection/test_injector_model.cpp b/unit_tests/tests/ignition_injection/test_injector_model.cpp index b74497b6eb..d567e6265d 100644 --- a/unit_tests/tests/ignition_injection/test_injector_model.cpp +++ b/unit_tests/tests/ignition_injection/test_injector_model.cpp @@ -107,7 +107,7 @@ TEST(InjectorModel, nonLinearFordMode) { TEST(InjectorModel, nonlinearPolynomial) { EngineTestHelper eth(engine_type_e::TEST_ENGINE); - InjectorModel dut; + InjectorModelPrimary dut; engineConfiguration->applyNonlinearBelowPulse = 10; @@ -138,7 +138,7 @@ TEST(InjectorModel, Deadtime) { engineConfiguration->injector.battLagCorrBins[i] = i; } - InjectorModel dut; + InjectorModelPrimary dut; Sensor::setMockValue(SensorType::BatteryVoltage, 3); EXPECT_EQ(dut.getDeadtime(), 6); @@ -147,11 +147,11 @@ TEST(InjectorModel, Deadtime) { EXPECT_EQ(dut.getDeadtime(), 14); } -struct TesterGetFlowRate : public InjectorModel { +struct TesterGetFlowRate : public InjectorModelPrimary { MOCK_METHOD(float, getInjectorFlowRatio, (), (override)); }; -struct TesterGetRailPressure : public InjectorModel { +struct TesterGetRailPressure : public InjectorModelPrimary { MOCK_METHOD(expected, getFuelDifferentialPressure, (), (const, override)); }; @@ -213,7 +213,7 @@ TEST(InjectorModel, VariableInjectorFlowModeNone) { } TEST(InjectorModel, RailPressureFixed) { - InjectorModel dut; + InjectorModelPrimary dut; EngineTestHelper eth(engine_type_e::TEST_ENGINE); @@ -232,7 +232,7 @@ TEST(InjectorModel, RailPressureFixed) { } TEST(InjectorModel, RailPressureSensedAbsolute) { - InjectorModel dut; + InjectorModelPrimary dut; EngineTestHelper eth(engine_type_e::TEST_ENGINE); @@ -252,7 +252,7 @@ TEST(InjectorModel, RailPressureSensedAbsolute) { } TEST(InjectorModel, RailPressureSensedGauge) { - InjectorModel dut; + InjectorModelPrimary dut; EngineTestHelper eth(engine_type_e::TEST_ENGINE); @@ -273,7 +273,7 @@ TEST(InjectorModel, RailPressureSensedGauge) { } TEST(InjectorModel, RailPressureSensedDifferential) { - InjectorModel dut; + InjectorModelPrimary dut; EngineTestHelper eth(engine_type_e::TEST_ENGINE); @@ -291,7 +291,7 @@ TEST(InjectorModel, RailPressureSensedDifferential) { } TEST(InjectorModel, FailedPressureSensor) { - InjectorModel dut; + InjectorModelPrimary dut; EngineTestHelper eth(engine_type_e::TEST_ENGINE); @@ -309,7 +309,7 @@ TEST(InjectorModel, FailedPressureSensor) { } TEST(InjectorModel, MissingPressureSensor) { - InjectorModel dut; + InjectorModelPrimary dut; EngineTestHelper eth(engine_type_e::TEST_ENGINE);