2021-10-16 17:16:40 -07:00
|
|
|
/*
|
|
|
|
* @file wall_fuel.cpp
|
|
|
|
*
|
|
|
|
* @author Matthew Kennedy
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "pch.h"
|
|
|
|
#include "wall_fuel.h"
|
|
|
|
|
|
|
|
void WallFuel::resetWF() {
|
|
|
|
wallFuel = 0;
|
|
|
|
}
|
|
|
|
|
2021-11-25 15:45:44 -08:00
|
|
|
float WallFuel::adjust(float desiredMassGrams) {
|
2021-10-16 17:16:40 -07:00
|
|
|
invocationCounter++;
|
2021-11-25 15:45:44 -08:00
|
|
|
if (cisnan(desiredMassGrams)) {
|
|
|
|
return desiredMassGrams;
|
2021-10-16 17:16:40 -07:00
|
|
|
}
|
2021-11-25 15:45:44 -08:00
|
|
|
|
2021-10-16 17:16:40 -07:00
|
|
|
// disable this correction for cranking
|
2021-11-17 00:54:21 -08:00
|
|
|
if (engine->rpmCalculator.isCranking()) {
|
2021-11-25 15:45:44 -08:00
|
|
|
return desiredMassGrams;
|
2021-10-16 17:16:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2021-11-25 15:45:44 -08:00
|
|
|
desiredMassGrams = desired fuel mass (input to this function)
|
2021-10-16 17:16:40 -07:00
|
|
|
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.
|
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2021-11-25 15:45:44 -08:00
|
|
|
// if tau or beta is really small, we get div/0.
|
2021-10-16 17:16:40 -07:00
|
|
|
// you probably meant to disable wwae.
|
2021-11-17 00:54:21 -08:00
|
|
|
float tau = engineConfiguration->wwaeTau;
|
2021-11-25 15:45:44 -08:00
|
|
|
float beta = engineConfiguration->wwaeBeta;
|
|
|
|
|
|
|
|
if (tau < 0.01f || beta < 0.01f) {
|
|
|
|
return desiredMassGrams;
|
2021-10-16 17:16:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ignore really slow RPM
|
2022-01-20 20:32:59 -08:00
|
|
|
int rpm = Sensor::getOrZero(SensorType::Rpm);
|
2021-10-16 17:16:40 -07:00
|
|
|
if (rpm < 100) {
|
2021-11-25 15:45:44 -08:00
|
|
|
return desiredMassGrams;
|
2021-10-16 17:16:40 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
float alpha = expf_taylor(-120 / (rpm * tau));
|
|
|
|
|
|
|
|
#if EFI_TUNER_STUDIO
|
|
|
|
if (engineConfiguration->debugMode == DBG_KNOCK) {
|
2021-12-07 17:18:47 -08:00
|
|
|
engine->outputChannels.debugFloatField1 = alpha;
|
|
|
|
engine->outputChannels.debugFloatField2 = beta;
|
2021-10-16 17:16:40 -07:00
|
|
|
}
|
|
|
|
#endif // EFI_TUNER_STUDIO
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
float fuelFilmMass = wallFuel;
|
2021-11-25 15:45:44 -08:00
|
|
|
float M_cmd = (desiredMassGrams - (1 - alpha) * fuelFilmMass) / (1 - beta);
|
2021-10-16 17:16:40 -07:00
|
|
|
|
|
|
|
#if EFI_TUNER_STUDIO
|
|
|
|
if (engineConfiguration->debugMode == DBG_KNOCK) {
|
2021-12-07 17:18:47 -08:00
|
|
|
engine->outputChannels.debugFloatField3 = fuelFilmMass;
|
|
|
|
engine->outputChannels.debugFloatField4 = M_cmd;
|
2021-10-16 17:16:40 -07:00
|
|
|
}
|
|
|
|
#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) {
|
2021-12-07 17:18:47 -08:00
|
|
|
engine->outputChannels.debugFloatField5 = fuelFilmMassNext;
|
2021-10-16 17:16:40 -07:00
|
|
|
}
|
|
|
|
#endif // EFI_TUNER_STUDIO
|
|
|
|
|
|
|
|
wallFuel = fuelFilmMassNext;
|
2021-11-25 15:45:44 -08:00
|
|
|
wallFuelCorrection = M_cmd - desiredMassGrams;
|
2021-10-16 17:16:40 -07:00
|
|
|
return M_cmd;
|
|
|
|
}
|
|
|
|
|
2021-11-25 15:45:44 -08:00
|
|
|
float WallFuel::getWallFuel() const {
|
2021-10-16 17:16:40 -07:00
|
|
|
return wallFuel;
|
|
|
|
}
|