rusefi/firmware/controllers/algo/wall_fuel.cpp

157 lines
4.2 KiB
C++

/*
* @file wall_fuel.cpp
*
* @author Matthew Kennedy
*/
#include "pch.h"
#include "wall_fuel.h"
void WallFuel::resetWF() {
wallFuel = 0;
}
float WallFuel::adjust(float desiredMassGrams) {
invocationCounter++;
if (cisnan(desiredMassGrams)) {
return desiredMassGrams;
}
ScopePerf perf(PE::WallFuelAdjust);
/*
this math is based on
SAE 810494 by C. F. Aquino
SAE 1999-01-0553 by Peter J Maloney
M_cmd = commanded fuel mass (output of this function)
desiredMassGrams = desired fuel mass (input to this function)
fuelFilmMass = fuel film mass (how much is currently on the wall)
First we compute how much fuel to command, by accounting for
a) how much fuel will evaporate from the walls, entering the air
b) how much fuel from the injector will hit the walls, being deposited
Next, we compute how much fuel will be deposited on the walls. The net
effect of these two steps is computed (some leaves walls, some is deposited)
and stored back in fuelFilmMass.
alpha describes the amount of fuel that REMAINS on the wall per cycle.
It is computed as a function of the evaporation time constant (tau) and
the time the fuel spent on the wall this cycle, (recriprocal RPM).
beta describes the amount of fuel that hits the wall.
*/
// If disabled, pass value through
if (!engine->module<WallFuelController>()->getEnable()) {
return desiredMassGrams;
}
float alpha = engine->module<WallFuelController>()->getAlpha();
float beta = engine->module<WallFuelController>()->getBeta();
float fuelFilmMass = wallFuel;
float M_cmd = (desiredMassGrams - (1 - alpha) * fuelFilmMass) / (1 - beta);
#if EFI_TUNER_STUDIO
if (engineConfiguration->debugMode == DBG_KNOCK) {
engine->outputChannels.debugFloatField3 = fuelFilmMass;
engine->outputChannels.debugFloatField4 = M_cmd;
}
#endif // EFI_TUNER_STUDIO
// We can't inject a negative amount of fuel
// If this goes below zero we will be over-fueling slightly,
// but that's ok.
if (M_cmd <= 0) {
M_cmd = 0;
}
// remainder on walls from last time + new from this time
float fuelFilmMassNext = alpha * fuelFilmMass + beta * M_cmd;
#if EFI_TUNER_STUDIO
if (engineConfiguration->debugMode == DBG_KNOCK) {
engine->outputChannels.debugFloatField5 = fuelFilmMassNext;
}
#endif // EFI_TUNER_STUDIO
wallFuel = fuelFilmMassNext;
wallFuelCorrection = M_cmd - desiredMassGrams;
return M_cmd;
}
float WallFuel::getWallFuel() const {
return wallFuel;
}
/*
TODO: these parameters, tau and beta vary with various engine parameters,
most notably manifold pressure (as a proxy for air speed), and coolant
temperature (as a proxy for the intake valve and runner temperature).
TAU: decreases with increasing temperature.
decreases with decreasing manifold pressure.
BETA: decreases with increasing temperature.
decreases with decreasing manifold pressure.
*/
float WallFuelController::computeTau() const {
return engineConfiguration->wwaeTau;
}
float WallFuelController::computeBeta() const {
return engineConfiguration->wwaeBeta;
}
void WallFuelController::onFastCallback() {
// disable wall wetting cranking
// TODO: is this correct? Why not correct for cranking?
if (engine->rpmCalculator.isCranking()) {
m_enable = false;
return;
}
float tau = computeTau();
float beta = computeBeta();
// if tau or beta is really small, we get div/0.
// you probably meant to disable wwae.
if (tau < 0.01f || beta < 0.01f) {
m_enable = false;
return;
}
auto rpm = Sensor::getOrZero(SensorType::Rpm);
// Ignore low RPM
if (rpm < 100) {
m_enable = false;
return;
}
float alpha = expf_taylor(-120 / (rpm * tau));
// If beta is larger than alpha, the system is underdamped.
// For reasonable values {tau, beta}, this should only be possible
// at extremely low engine speeds (<300rpm ish)
// Clamp beta to less than alpha.
if (beta > alpha) {
beta = alpha;
}
// Store parameters so the model can read them
m_alpha = alpha;
m_beta = beta;
m_enable = true;
#if EFI_TUNER_STUDIO
// TODO: why DBG_KNOCK? That seems wrong.
if (engineConfiguration->debugMode == DBG_KNOCK) {
engine->outputChannels.debugFloatField1 = alpha;
engine->outputChannels.debugFloatField2 = beta;
}
#endif // EFI_TUNER_STUDIO
}