improve maf output channels and logging (#3743)

* maf channels

* s

* binary log

* if only I could type

* can

* instant RPM too

* s

* test

* graceful zero rpm

* test works

* float near
This commit is contained in:
Matthew Kennedy 2022-01-12 12:41:35 -08:00 committed by GitHub
parent 7fbd1b338f
commit 7d341cfc9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 39 additions and 27 deletions

View File

@ -55,9 +55,9 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 0, 0
int16_t autoscale throttlePedalPosition;@@GAUGE_NAME_THROTTLE_PEDAL@@;"%",{1/@@PACK_MULT_PERCENT@@}, 0, 0, 0, 0
uint16_t tpsADC;;"ADC", 1, 0, 0, 0, 0
uint16_t autoscale MAFValue;@@GAUGE_NAME_MAF@@;"V",{1/@@PACK_MULT_VOLTAGE@@}, 0, 0, 0, 0
uint16_t autoscale rawMaf;;"V",{1/@@PACK_MULT_VOLTAGE@@}, 0, 0, 0, 0
uint16_t autoscale massAirFlowValue;@@GAUGE_NAME_AIR_FLOW@@;"Kg/h",{1/@@PACK_MULT_MASS_FLOW@@}, 0, 0, 0, 0
uint16_t autoscale mafMeasured;@@GAUGE_NAME_AIR_FLOW_MEASURED@@;"kg/h",{1/@@PACK_MULT_MASS_FLOW@@}, 0, 0, 0, 0
uint16_t autoscale MAPValue;@@GAUGE_NAME_MAP@@;"kPa",{1/@@PACK_MULT_PRESSURE@@}, 0, 0, 0, 0
uint16_t autoscale baroPressure;;"kPa",{1/@@PACK_MULT_PRESSURE@@}, 0, 0, 0, 0
@ -268,9 +268,11 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 0, 0
float m_I_sum_percent;"DI: m_I_sum_percent";"v", 1, 0, 0, 100, 0
float m_pressureTarget_kPa;"DI: m_pressureTarget_kPa";"v", 1, 0, 0, 100, 0
uint16_t autoscale mafEstimate;@@GAUGE_NAME_AIR_FLOW_ESTIMATE@@;"kg/h",{1/@@PACK_MULT_MASS_FLOW@@}, 0, 0, 0, 0
uint16_t instantRpm;;"rpm", 1, 0, 0, 0, 0
! we have some unused bytes to allow compatible TS changes
int[28 iterate] unusedAtTheEnd;;"",1, 0, 0, 0, 0
uint8_t[108 iterate] unusedAtTheEnd;;"",1, 0, 0, 0, 0
bit launchSpeedCondition
bit launchRpmCondition

View File

@ -97,7 +97,8 @@ static constexpr LogField fields[] = {
{engine->outputChannels.fuelTankLevel, GAUGE_NAME_FUEL_LEVEL, "%", 0},
{engine->outputChannels.fuelingLoad, GAUGE_NAME_FUEL_LOAD, "%", 1},
{engine->outputChannels.ignitionLoad, GAUGE_NAME_IGNITION_LOAD, "%", 1},
{engine->outputChannels.massAirFlowValue, GAUGE_NAME_AIR_FLOW, "kg/h", 1},
{engine->outputChannels.mafMeasured, GAUGE_NAME_AIR_FLOW_MEASURED, "kg/h", 1},
{engine->outputChannels.mafEstimate, GAUGE_NAME_AIR_FLOW_ESTIMATE, "kg/h", 1},
{engine->outputChannels.tcuDesiredGear, GAUGE_NAME_DESIRED_GEAR, "gear", 0},
{engine->outputChannels.tcuCurrentGear, GAUGE_NAME_CURRENT_GEAR, "gear", 0},
{engine->outputChannels.flexPercent, GAUGE_NAME_FLEX, "%", 1},

View File

@ -157,10 +157,6 @@ static int packEngineMode() {
engineConfiguration->ignitionMode;
}
static float getAirFlowGauge() {
return Sensor::get(SensorType::Maf).value_or(engine->engineState.airFlow);
}
static int prevCkpEventCounter = -1;
/**
@ -555,7 +551,7 @@ static void updateRawSensors() {
engine->outputChannels.rawOilPressure = Sensor::getRaw(SensorType::OilPressure);
engine->outputChannels.rawLowFuelPressure = Sensor::getRaw(SensorType::FuelPressureLow);
engine->outputChannels.rawHighFuelPressure = Sensor::getRaw(SensorType::FuelPressureHigh);
engine->outputChannels.MAFValue = Sensor::getRaw(SensorType::Maf);
engine->outputChannels.rawMaf = Sensor::getRaw(SensorType::Maf);
engine->outputChannels.rawWastegatePosition = Sensor::getRaw(SensorType::WastegatePosition);
engine->outputChannels.rawIdlePositionSensor = Sensor::getRaw(SensorType::IdlePosition);
}
@ -701,6 +697,8 @@ void updateTunerStudioState() {
// offset 0
tsOutputChannels->RPMValue = rpm;
auto instantRpm = engine->triggerCentral.triggerState.getInstantRpm();
tsOutputChannels->instantRpm = instantRpm;
updateSensors(rpm);
updateFuelInfo();
@ -709,9 +707,11 @@ void updateTunerStudioState() {
// 104
tsOutputChannels->rpmAcceleration = engine->rpmCalculator.getRpmAcceleration();
// offset 108
// For air-interpolated tCharge mode, we calculate a decent massAirFlow approximation, so we can show it to users even without MAF sensor!
tsOutputChannels->massAirFlowValue = getAirFlowGauge();
// Output both the estimated air flow, and measured air flow (if available)
tsOutputChannels->mafMeasured = Sensor::getOrZero(SensorType::Maf);
tsOutputChannels->mafEstimate = engine->engineState.airflowEstimate;
// offset 116
// TPS acceleration
tsOutputChannels->deltaTps = engine->tpsAccelEnrichment.getMaxDelta();
@ -851,8 +851,6 @@ void updateTunerStudioState() {
break;
case DBG_INSTANT_RPM:
{
float instantRpm = engine->triggerCentral.triggerState.getInstantRpm();
tsOutputChannels->debugFloatField1 = instantRpm;
tsOutputChannels->debugFloatField2 = instantRpm / GET_RPM();
tsOutputChannels->mostRecentTimeBetweenSparkEvents = engine->mostRecentTimeBetweenSparkEvents;

View File

@ -37,10 +37,8 @@ public:
WarningCodeState warnings;
/**
* speed-density logic, calculated air flow in kg/h for tCharge Air-Interp. method
*/
float airFlow = 0;
// Estimated airflow based on whatever airmass model is active
float airflowEstimate = 0;
float knockThreshold = 0;

View File

@ -156,6 +156,12 @@ static float getBaseFuelMass(int rpm) {
engine->engineState.sd.airMassInOneCylinder = airmass.CylinderAirmass;
engine->engineState.fuelingLoad = airmass.EngineLoadPercent;
engine->engineState.ignitionLoad = getLoadOverride(airmass.EngineLoadPercent, engineConfiguration->ignOverrideMode);
auto gramPerCycle = airmass.CylinderAirmass * engineConfiguration->specs.cylindersCount;
auto gramPerMs = rpm == 0 ? 0 : gramPerCycle / getEngineCycleDuration(rpm);
// convert g/s -> kg/h
engine->engineState.airflowEstimate = gramPerMs * 3600000 /* milliseconds per hour */ / 1000 /* grams per kg */;;
float baseFuelMass = engine->fuelComputer->getCycleFuel(airmass.CylinderAirmass, rpm, airmass.EngineLoadPercent);

View File

@ -125,7 +125,7 @@ struct Fueling {
static void populateFrame(Fueling& msg) {
msg.cylAirmass = engine->engineState.sd.airMassInOneCylinder;
msg.estAirflow = engine->engineState.airFlow;
msg.estAirflow = engine->engineState.airflowEstimate;
msg.fuel_pulse = engine->actualLastInjection[0];
}

View File

@ -55,7 +55,6 @@ temperature_t getTCharge(int rpm, float tps) {
// 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.airFlow = airFlow;
engine->engineState.sd.Tcharge_coff = interpolateClamped(0.0,
engineConfiguration->tChargeAirCoefMin,
engineConfiguration->tChargeAirFlowMax,

View File

@ -1709,7 +1709,8 @@ end_struct
#define INDICATOR_NAME_BRAKE_DOWN "brake: down"
#define INDICATOR_NAME_AC_SWITCH "AC switch"
#define GAUGE_NAME_AIR_FLOW "MAF air flow"
#define GAUGE_NAME_AIR_FLOW_MEASURED "MAF sensor"
#define GAUGE_NAME_AIR_FLOW_ESTIMATE "MAF estimate"
#define GAUGE_NAME_AIR_MASS "air mass"
#define GAUGE_NAME_WARNING_LAST "warning: last"

View File

@ -462,9 +462,9 @@ enable2ndByteCanID = false
columnLabel = "Voltage", "kg/hour"
xAxis = -1, 6, 10
yAxis = -30, 1300, 10
xBins = mafDecodingBins, MAFValue
xBins = mafDecodingBins, rawMaf
yBins = mafDecoding
gauge = MAFGauge
gauge = rawMafGauge
curve = iatFuelCorrCurve, "Intake air temperature fuel Multiplier"
columnLabel = "Air Temp", "Multiplier"
@ -1030,10 +1030,9 @@ gaugeCategory = Sensors - Basic
afr2Gauge = AFRValue2, @@GAUGE_NAME_AFR2@@, "", 10, 19.4, 12, 13, 15, 16, 2, 2
lambda1Gauge = lambdaValue, @@GAUGE_NAME_LAMBDA@@, "", 0.65, 1.2, 0.7, 0.75, 1.1, 1.15, 3, 2
lambda2Gauge = lambdaValue2, @@GAUGE_NAME_LAMBDA2@@, "", 0.65, 1.2, 0.7, 0.75, 1.1, 1.15, 3, 2
MAFGauge = MAFValue, "Mass air flow", "V", 0, 5, 0, 1, 3, 4, 1, 1
VBattGauge = VBatt, "Battery", "V", 8, 21, 9, 10, 17, 19, 1, 1
MAPGauge = MAPValue, "MAP", "kPa", 0, 300, 10, 10, 200, 200, 0, 0
massAirFlowValueGa = massAirFlowValue,"Mass air flow", "kg/hr", 0, 50, -999, -999, 999, 999, 1, 1
massAirFlowValueGa = mafMeasured, @@GAUGE_NAME_AIR_FLOW_MEASURED@@, "kg/h", 0, 50, -999, -999, 999, 999, 1, 1
gaugeCategory = Sensors - Extra 1
@ -1123,6 +1122,8 @@ gaugeCategory = Sensors - Raw
rawWastegatePositionGauge = rawWastegatePosition,"Raw Wastegate Position","V", 0, 5, 0, 0, 5, 5, 3, 0
rawLowFuelPressureGauge = rawLowFuelPressure,"Raw fuel pressure (low) voltage","V", 0, 5, 0, 0, 5, 5, 3, 0
rawHighFuelPressureGauge = rawHighFuelPressure,"Raw fuel pressure (high) voltage","V", 0, 5, 0, 0, 5, 5, 3, 0
rawMafGauge = rawMaf , "Raw MAF", "V", 0, 5, 0, 0, 5, 5, 3, 0
gaugeCategory = Transmission
desiredGearGauge = tcuDesiredGear, @@GAUGE_NAME_DESIRED_GEAR@@, "gear", -1, 10, -1, -1, 10, 10, 0, 0

View File

@ -38,6 +38,7 @@ TEST(misc, testEngineMath) {
EngineTestHelper eth(FORD_ESCORT_GT);
engineConfiguration->ambiguousOperationMode = FOUR_STROKE_CAM_SENSOR;
engineConfiguration->fuelAlgorithm = LM_SPEED_DENSITY;
ASSERT_NEAR( 50, getOneDegreeTimeMs(600) * 180, EPS4D) << "600 RPM";
ASSERT_EQ( 5, getOneDegreeTimeMs(6000) * 180) << "6000 RPM";
@ -64,9 +65,14 @@ TEST(misc, testEngineMath) {
Sensor::setMockValue(SensorType::Clt, 90);
Sensor::setMockValue(SensorType::Iat, 20);
Sensor::setMockValue(SensorType::Map, 100);
Sensor::setMockValue(SensorType::Tps1, 0);
engine->rpmCalculator.mockRpm = 1000;
// calc. airFlow using airMass, and find tCharge
ASSERT_FLOAT_EQ(59.1175f, getTCharge(/*RPM*/1000, /*TPS*/0));
ASSERT_FLOAT_EQ(65.5625f/*kg/h*/, engine->engineState.airFlow);
engine->periodicFastCallback();
ASSERT_NEAR(59.1175f, engine->engineState.sd.tCharge, EPS4D);
ASSERT_NEAR(56.9762f/*kg/h*/, engine->engineState.airflowEstimate, EPS4D);
}
TEST(misc, testIgnitionMapGenerator) {