table for tcharge interpolation (#3855)
* extract getTChargeCoefficient * new table
This commit is contained in:
parent
e612423e48
commit
40e96a03d5
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue