table for tcharge interpolation (#3855)

* extract getTChargeCoefficient

* new table
This commit is contained in:
Matthew Kennedy 2022-01-30 05:45:11 -08:00 committed by GitHub
parent e612423e48
commit 40e96a03d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 29 deletions

View File

@ -534,6 +534,7 @@ typedef enum {
typedef enum {
TCHARGE_MODE_RPM_TPS = 0,
TCHARGE_MODE_AIR_INTERP = 1,
TCHARGE_MODE_AIR_INTERP_TABLE = 2,
Force_4bytes_size_tChargeMode_e = ENUM_32_BITS,
} tChargeMode_e;

View File

@ -23,6 +23,48 @@ lambda_Map3D_t lambdaMap;
#define tpMin 0
#define tpMax 100
static float getTChargeCoefficient(int rpm, float tps) {
engine->engineState.sd.isTChargeAirModel = engineConfiguration->tChargeMode == TCHARGE_MODE_AIR_INTERP;
// First, do TPS mode since it doesn't need any of the airflow math.
if (engineConfiguration->tChargeMode == TCHARGE_MODE_RPM_TPS) {
float minRpmKcurrentTPS = interpolateMsg("minRpm", tpMin,
engineConfiguration->tChargeMinRpmMinTps, tpMax,
engineConfiguration->tChargeMinRpmMaxTps, tps);
float maxRpmKcurrentTPS = interpolateMsg("maxRpm", tpMin,
engineConfiguration->tChargeMaxRpmMinTps, tpMax,
engineConfiguration->tChargeMaxRpmMaxTps, tps);
return interpolateMsg("Kcurr", rpmMin, minRpmKcurrentTPS, rpmMax, maxRpmKcurrentTPS, rpm);
}
constexpr 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
floatms_t airMassForEngine = engine->engineState.sd.airMassInOneCylinder * engineConfiguration->specs.cylindersCount;
// 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)
floatms_t airFlow = (rpm == 0) ? 0 : airMassForEngine * gramsPerMsToKgPerHour / getEngineCycleDuration(rpm);
if (engineConfiguration->tChargeMode == TCHARGE_MODE_AIR_INTERP) {
// just interpolate between user-specified min and max coefs, based on the max airFlow value
return interpolateClamped(
0.0, engineConfiguration->tChargeAirCoefMin,
engineConfiguration->tChargeAirFlowMax, engineConfiguration->tChargeAirCoefMax,
airFlow
);
} else if (engineConfiguration->tChargeMode == TCHARGE_MODE_AIR_INTERP_TABLE) {
return interpolate2d(
airFlow,
engineConfiguration->tchargeBins,
engineConfiguration->tchargeValues
);
} else {
firmwareError(OBD_PCM_Processor_Fault, "Unexpected tChargeMode: %d", engineConfiguration->tChargeMode);
return 0;
}
}
// http://rusefi.com/math/t_charge.html
/***panel:Charge Temperature*/
temperature_t getTCharge(int rpm, float tps) {
@ -47,37 +89,18 @@ temperature_t getTCharge(int rpm, float tps) {
float coolantTemp = clt.Value;
if ((engine->engineState.sd.isTChargeAirModel = (engineConfiguration->tChargeMode == TCHARGE_MODE_AIR_INTERP))) {
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
floatms_t airMassForEngine = engine->engineState.sd.airMassInOneCylinder * engineConfiguration->specs.cylindersCount;
// 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)
floatms_t airFlow = (rpm == 0) ? 0 : airMassForEngine * gramsPerMsToKgPerHour / getEngineCycleDuration(rpm);
// just interpolate between user-specified min and max coefs, based on the max airFlow value
engine->engineState.sd.Tcharge_coff = interpolateClamped(0.0,
engineConfiguration->tChargeAirCoefMin,
engineConfiguration->tChargeAirFlowMax,
engineConfiguration->tChargeAirCoefMax, airFlow);
// save it for console output (instead of MAF massAirFlow)
} else {
float minRpmKcurrentTPS = interpolateMsg("minRpm", tpMin,
engineConfiguration->tChargeMinRpmMinTps, tpMax,
engineConfiguration->tChargeMinRpmMaxTps, tps);
float maxRpmKcurrentTPS = interpolateMsg("maxRpm", tpMin,
engineConfiguration->tChargeMaxRpmMinTps, tpMax,
engineConfiguration->tChargeMaxRpmMaxTps, tps);
auto coefficient = getTChargeCoefficient(rpm, tps);
engine->engineState.sd.Tcharge_coff = coefficient;
engine->engineState.sd.Tcharge_coff = interpolateMsg("Kcurr", rpmMin, minRpmKcurrentTPS, rpmMax, maxRpmKcurrentTPS, rpm);
}
if (cisnan(engine->engineState.sd.Tcharge_coff)) {
if (cisnan(coefficient)) {
warning(CUSTOM_ERR_T2_CHARGE, "t2-getTCharge NaN");
return coolantTemp;
}
// We use a robust interp. function for proper tcharge_coff clamping.
float Tcharge = interpolateClamped(0.0f, coolantTemp, 1.0f, airTemp, engine->engineState.sd.Tcharge_coff);
// Interpolate between CLT and IAT:
// 0.0 coefficient -> use CLT (full heat transfer)
// 1.0 coefficient -> use IAT (no heat transfer)
float Tcharge = interpolateClamped(0.0f, coolantTemp, 1.0f, airTemp, coefficient);
if (cisnan(Tcharge)) {
// we can probably end up here while resetting engine state - interpolation would fail

View File

@ -1237,7 +1237,10 @@ int16_t tps2Max;Full throttle#2. tpsMax value as 10 bit ADC value. Not Voltage!\
float boostCutPressure;+MAP value above which fuel is cut in case of overboost.\nSet to 0 to disable overboost cut.;"kPa (absolute)", 1, 0, 0, 500, 0
float[16] unusedMapAccelTaperBins;;"counter", 1, 0, 0, 300, 0
uint8_t[16] tchargeBins;;"kg/h", 5, 0, 0, 1200, 0
uint8_t[16] tchargeValues;;"ratio", 0.01, 0, 0, 1, 2
float[8] unusedMapAccelTaperBins;;"counter", 1, 0, 0, 300, 0
float fixedTiming;Fixed timing, useful for TDC testing;"deg", 1, 0, -720, 720, 2
float mapLowValueVoltage;MAP voltage for low point;"v", 1, 0, 0, 10, 2
@ -1388,8 +1391,8 @@ float tChargeAirFlowMax;High flow point for heat transfer estimation.\nSet this
float tChargeAirIncrLimit;Maximum allowed rate of increase allowed for the estimated charge temperature;"deg/sec", 1, 0, 0, 100, 1
float tChargeAirDecrLimit;Maximum allowed rate of decrease allowed for the estimated charge temperature;"deg/sec", 1, 0, 0, 100, 1
#define tChargeMode_e_enum "RPM+TPS (Default)", "Air Mass Interpolation"
custom tChargeMode_e 4 bits, U32, @OFFSET@, [0:0], @@tChargeMode_e_enum@@
#define tChargeMode_e_enum "RPM+TPS (Default)", "Air Mass Interpolation", "Table"
custom tChargeMode_e 4 bits, U32, @OFFSET@, [0:1], @@tChargeMode_e_enum@@
tChargeMode_e tChargeMode;
float[ETB_BIAS_CURVE_LENGTH] etbBiasBins;target TPS value, 0 to 100%\nTODO: use int8 data date once we template interpolation method;"target TPS position", 1, 0, 0, 100, 0

View File

@ -644,6 +644,14 @@ enable2ndByteCanID = false
yBins = wwBetaMapValues
gauge = MAPGauge
curve = tchargeCurve, "Charge temperature estimation coefficient"
columnLabel = "flow", "coefficient"
xAxis = 0, 500, 6
yAxis = 0, 100, 5
xBins = tchargeBins, mafEstimate
yBins = tchargeValues
gauge = tChargeGauge
[TableEditor]
; table_id, map3d_id, "title", page
@ -1829,6 +1837,7 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00"
panel = tChargeGeneralSettings
panel = tChargeRpmTpsSettings, { tChargeMode == 0}
panel = tChargeAirInterpSettings, { tChargeMode == 1}
panel = tchargeCurve, { tChargeMode == 2 }
dialog = baseInjection, "General"
field = "Enabled", isInjectionEnabled