diff --git a/firmware/controllers/algo/algo.mk b/firmware/controllers/algo/algo.mk index e9ed7484b1..45a14ecd2b 100644 --- a/firmware/controllers/algo/algo.mk +++ b/firmware/controllers/algo/algo.mk @@ -16,3 +16,4 @@ CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/advance_map.cpp \ $(PROJECT_DIR)/controllers/algo/airmass/maf_airmass.cpp \ $(PROJECT_DIR)/controllers/algo/airmass/speed_density_airmass.cpp \ $(PROJECT_DIR)/controllers/algo/airmass/speed_density_base.cpp \ + $(PROJECT_DIR)/controllers/algo/fuel/fuel_computer.cpp \ diff --git a/firmware/controllers/algo/fuel/fuel_computer.cpp b/firmware/controllers/algo/fuel/fuel_computer.cpp new file mode 100644 index 0000000000..98d4153722 --- /dev/null +++ b/firmware/controllers/algo/fuel/fuel_computer.cpp @@ -0,0 +1,27 @@ +#include "fuel_computer.h" + +EXTERN_ENGINE; + +mass_t FuelComputerBase::getCycleFuel(mass_t airmass, int rpm, float load) const { + float stoich = getStoichiometricRatio(); + float lambda = getTargetLambda(rpm, load); + float afr = stoich * lambda; + + ENGINE(engineState.targetAFR) = afr; + + return airmass / afr; +} + +FuelComputer::FuelComputer(const ValueProvider3D& afrTable) : m_afrTable(&afrTable) {} + +float FuelComputer::getStoichiometricRatio() const { + // TODO: vary this with ethanol content/configured setting/whatever + return 14.7f; +} + +float FuelComputer::getTargetLambda(int rpm, float load) const { + efiAssert(OBD_PCM_Processor_Fault, m_afrTable != nullptr, "AFR table null", 0); + + // TODO: set the table value in lambda instead of afr + return m_afrTable->getValue(rpm, load) / getStoichiometricRatio(); +}; diff --git a/firmware/controllers/algo/fuel/fuel_computer.h b/firmware/controllers/algo/fuel/fuel_computer.h new file mode 100644 index 0000000000..44864f9a27 --- /dev/null +++ b/firmware/controllers/algo/fuel/fuel_computer.h @@ -0,0 +1,36 @@ +#pragma once + +#include "engine.h" + +class ValueProvider3D; + +using mass_t = float; + +struct IFuelComputer { + virtual mass_t getCycleFuel(mass_t airmass, int rpm, float load) const = 0; +}; + +// This contains the math of the fuel model, but doesn't actually read any configuration +class FuelComputerBase : public IFuelComputer { +public: + mass_t getCycleFuel(mass_t airmass, int rpm, float load) const override; + +protected: + virtual float getStoichiometricRatio() const = 0; + virtual float getTargetLambda(int rpm, float load) const = 0; +}; + +// This class is a usable implemenation of a fuel model that reads real configuration +class FuelComputer final : public FuelComputerBase { + DECLARE_ENGINE_PTR; + +public: + FuelComputer(const ValueProvider3D& afrTable); + +protected: + float getStoichiometricRatio() const override; + float getTargetLambda(int rpm, float load) const override; + +private: + const ValueProvider3D* const m_afrTable; +}; diff --git a/firmware/controllers/controllers.mk b/firmware/controllers/controllers.mk index 4fb3a605ee..73a5cac59e 100644 --- a/firmware/controllers/controllers.mk +++ b/firmware/controllers/controllers.mk @@ -56,6 +56,7 @@ CONTROLLERS_INC=\ $(CONTROLLERS_DIR)/system/timer \ $(CONTROLLERS_DIR)/algo \ $(CONTROLLERS_DIR)/algo/airmass \ + $(CONTROLLERS_DIR)/algo/fuel \ $(CONTROLLERS_DIR)/engine_cycle \ $(CONTROLLERS_DIR)/trigger/decoders \ $(CONTROLLERS_DIR)/trigger \