splitting accelerations
This commit is contained in:
parent
48f9c25dad
commit
d84cf5eea8
|
@ -22,128 +22,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "trigger_central.h"
|
|
||||||
#include "accel_enrichment.h"
|
#include "accel_enrichment.h"
|
||||||
|
|
||||||
static tps_tps_Map3D_t tpsTpsMap;
|
static tps_tps_Map3D_t tpsTpsMap;
|
||||||
|
|
||||||
void WallFuel::resetWF() {
|
|
||||||
wallFuel = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
floatms_t WallFuel::adjust(floatms_t desiredFuel DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
|
||||||
invocationCounter++;
|
|
||||||
if (cisnan(desiredFuel)) {
|
|
||||||
return desiredFuel;
|
|
||||||
}
|
|
||||||
// disable this correction for cranking
|
|
||||||
if (ENGINE(rpmCalculator).isCranking()) {
|
|
||||||
return desiredFuel;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
desiredFuel = 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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// if tau is really small, we get div/0.
|
|
||||||
// you probably meant to disable wwae.
|
|
||||||
float tau = CONFIG(wwaeTau);
|
|
||||||
if (tau < 0.01f) {
|
|
||||||
return desiredFuel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore really slow RPM
|
|
||||||
int rpm = GET_RPM();
|
|
||||||
if (rpm < 100) {
|
|
||||||
return desiredFuel;
|
|
||||||
}
|
|
||||||
|
|
||||||
float alpha = expf_taylor(-120 / (rpm * tau));
|
|
||||||
float beta = CONFIG(wwaeBeta);
|
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO
|
|
||||||
if (engineConfiguration->debugMode == DBG_KNOCK) {
|
|
||||||
tsOutputChannels.debugFloatField1 = alpha;
|
|
||||||
tsOutputChannels.debugFloatField2 = beta;
|
|
||||||
}
|
|
||||||
#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;
|
|
||||||
float M_cmd = (desiredFuel - (1 - alpha) * fuelFilmMass) / (1 - beta);
|
|
||||||
|
|
||||||
#if EFI_TUNER_STUDIO
|
|
||||||
if (engineConfiguration->debugMode == DBG_KNOCK) {
|
|
||||||
tsOutputChannels.debugFloatField3 = fuelFilmMass;
|
|
||||||
tsOutputChannels.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) {
|
|
||||||
tsOutputChannels.debugFloatField5 = fuelFilmMassNext;
|
|
||||||
}
|
|
||||||
#endif // EFI_TUNER_STUDIO
|
|
||||||
|
|
||||||
wallFuel = fuelFilmMassNext;
|
|
||||||
wallFuelCorrection = M_cmd - desiredFuel;
|
|
||||||
return M_cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
floatms_t WallFuel::getWallFuel() const {
|
|
||||||
return wallFuel;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AccelEnrichment::getMaxDeltaIndex(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
int AccelEnrichment::getMaxDeltaIndex(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||||
|
|
||||||
int len = minI(cb.getSize(), cb.getCount());
|
int len = minI(cb.getSize(), cb.getCount());
|
||||||
|
|
|
@ -60,22 +60,6 @@ private:
|
||||||
int cycleCnt = 0;
|
int cycleCnt = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Wall wetting, also known as fuel film
|
|
||||||
* See https://github.com/rusefi/rusefi/issues/151 for the theory
|
|
||||||
*/
|
|
||||||
class WallFuel : public wall_fuel_state {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @param target desired squirt duration
|
|
||||||
* @return total adjusted fuel squirt duration once wall wetting is taken into effect
|
|
||||||
*/
|
|
||||||
floatms_t adjust(floatms_t target DECLARE_ENGINE_PARAMETER_SUFFIX);
|
|
||||||
floatms_t getWallFuel() const;
|
|
||||||
void resetWF();
|
|
||||||
int invocationCounter = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
void initAccelEnrichment(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
void initAccelEnrichment(DECLARE_ENGINE_PARAMETER_SIGNATURE);
|
||||||
|
|
||||||
void setEngineLoadAccelLen(int len);
|
void setEngineLoadAccelLen(int len);
|
||||||
|
|
|
@ -6,6 +6,7 @@ CONTROLLERS_ALGO_SRC_CPP = $(PROJECT_DIR)/controllers/algo/advance_map.cpp \
|
||||||
$(GENERATED_ENUMS_DIR)/auto_generated_commonenum.cpp \
|
$(GENERATED_ENUMS_DIR)/auto_generated_commonenum.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/fuel_math.cpp \
|
$(PROJECT_DIR)/controllers/algo/fuel_math.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/accel_enrichment.cpp \
|
$(PROJECT_DIR)/controllers/algo/accel_enrichment.cpp \
|
||||||
|
$(PROJECT_DIR)/controllers/algo/wall_fuel.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/launch_control.cpp \
|
$(PROJECT_DIR)/controllers/algo/launch_control.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/dynoview.cpp \
|
$(PROJECT_DIR)/controllers/algo/dynoview.cpp \
|
||||||
$(PROJECT_DIR)/controllers/algo/runtime_state.cpp \
|
$(PROJECT_DIR)/controllers/algo/runtime_state.cpp \
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "fl_stack.h"
|
#include "fl_stack.h"
|
||||||
#include "trigger_structure.h"
|
#include "trigger_structure.h"
|
||||||
#include "accel_enrichment.h"
|
#include "accel_enrichment.h"
|
||||||
|
#include "wall_fuel.h"
|
||||||
|
|
||||||
#define MAX_WIRES_COUNT 2
|
#define MAX_WIRES_COUNT 2
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* @file wall_fuel.cpp
|
||||||
|
*
|
||||||
|
* @author Matthew Kennedy
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "wall_fuel.h"
|
||||||
|
|
||||||
|
void WallFuel::resetWF() {
|
||||||
|
wallFuel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
floatms_t WallFuel::adjust(floatms_t desiredFuel DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||||
|
invocationCounter++;
|
||||||
|
if (cisnan(desiredFuel)) {
|
||||||
|
return desiredFuel;
|
||||||
|
}
|
||||||
|
// disable this correction for cranking
|
||||||
|
if (ENGINE(rpmCalculator).isCranking()) {
|
||||||
|
return desiredFuel;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
desiredFuel = 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// if tau is really small, we get div/0.
|
||||||
|
// you probably meant to disable wwae.
|
||||||
|
float tau = CONFIG(wwaeTau);
|
||||||
|
if (tau < 0.01f) {
|
||||||
|
return desiredFuel;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore really slow RPM
|
||||||
|
int rpm = GET_RPM();
|
||||||
|
if (rpm < 100) {
|
||||||
|
return desiredFuel;
|
||||||
|
}
|
||||||
|
|
||||||
|
float alpha = expf_taylor(-120 / (rpm * tau));
|
||||||
|
float beta = CONFIG(wwaeBeta);
|
||||||
|
|
||||||
|
#if EFI_TUNER_STUDIO
|
||||||
|
if (engineConfiguration->debugMode == DBG_KNOCK) {
|
||||||
|
tsOutputChannels.debugFloatField1 = alpha;
|
||||||
|
tsOutputChannels.debugFloatField2 = beta;
|
||||||
|
}
|
||||||
|
#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;
|
||||||
|
float M_cmd = (desiredFuel - (1 - alpha) * fuelFilmMass) / (1 - beta);
|
||||||
|
|
||||||
|
#if EFI_TUNER_STUDIO
|
||||||
|
if (engineConfiguration->debugMode == DBG_KNOCK) {
|
||||||
|
tsOutputChannels.debugFloatField3 = fuelFilmMass;
|
||||||
|
tsOutputChannels.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) {
|
||||||
|
tsOutputChannels.debugFloatField5 = fuelFilmMassNext;
|
||||||
|
}
|
||||||
|
#endif // EFI_TUNER_STUDIO
|
||||||
|
|
||||||
|
wallFuel = fuelFilmMassNext;
|
||||||
|
wallFuelCorrection = M_cmd - desiredFuel;
|
||||||
|
return M_cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
floatms_t WallFuel::getWallFuel() const {
|
||||||
|
return wallFuel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* @file wall_fuel.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wall wetting, also known as fuel film
|
||||||
|
* See https://github.com/rusefi/rusefi/issues/151 for the theory
|
||||||
|
*/
|
||||||
|
class WallFuel : public wall_fuel_state {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @param target desired squirt duration
|
||||||
|
* @return total adjusted fuel squirt duration once wall wetting is taken into effect
|
||||||
|
*/
|
||||||
|
floatms_t adjust(floatms_t target DECLARE_ENGINE_PARAMETER_SUFFIX);
|
||||||
|
floatms_t getWallFuel() const;
|
||||||
|
void resetWF();
|
||||||
|
int invocationCounter = 0;
|
||||||
|
};
|
|
@ -51,7 +51,7 @@ temperature_t getTCharge(int rpm, float tps DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||||
if ((engine->engineState.sd.isTChargeAirModel = (CONFIG(tChargeMode) == TCHARGE_MODE_AIR_INTERP))) {
|
if ((engine->engineState.sd.isTChargeAirModel = (CONFIG(tChargeMode) == TCHARGE_MODE_AIR_INTERP))) {
|
||||||
const floatms_t gramsPerMsToKgPerHour = (3600.0f * 1000.0f) / 1000.0f;
|
const floatms_t gramsPerMsToKgPerHour = (3600.0f * 1000.0f) / 1000.0f;
|
||||||
// We're actually using an 'old' airMass calculated for the previous cycle, but it's ok, we're not having any self-excitaton issues
|
// We're actually using an 'old' airMass calculated for the previous cycle, but it's ok, we're not having any self-excitaton issues
|
||||||
floatms_t airMassForEngine = engine->engineState.sd./***display*/airMassInOneCylinder * CONFIG(specs.cylindersCount);
|
floatms_t airMassForEngine = engine->engineState.sd.airMassInOneCylinder * CONFIG(specs.cylindersCount);
|
||||||
// airMass is in grams per 1 cycle for 1 cyl. Convert it to airFlow in kg/h for the engine.
|
// airMass is in grams per 1 cycle for 1 cyl. Convert it to airFlow in kg/h for the engine.
|
||||||
// And if the engine is stopped (0 rpm), then airFlow is also zero (avoiding NaN division)
|
// And if the engine is stopped (0 rpm), then airFlow is also zero (avoiding NaN division)
|
||||||
floatms_t airFlow = (rpm == 0) ? 0 : airMassForEngine * gramsPerMsToKgPerHour / getEngineCycleDuration(rpm PASS_ENGINE_PARAMETER_SUFFIX);
|
floatms_t airFlow = (rpm == 0) ? 0 : airMassForEngine * gramsPerMsToKgPerHour / getEngineCycleDuration(rpm PASS_ENGINE_PARAMETER_SUFFIX);
|
||||||
|
|
Loading…
Reference in New Issue