rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Functions | Variables
fuel_math.cpp File Reference

Detailed Description

Fuel amount calculation logic.

Date
May 27, 2013
Author
Andrey Belomutskiy, (c) 2012-2020

This file is part of rusEfi - see http://rusefi.com

rusEfi is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

rusEfi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file fuel_math.cpp.

Functions

float getCrankingFuel3 (float baseFuel, uint32_t revolutionCounterSinceStart)
 
float getRunningFuel (float baseFuel)
 
AirmassModelBasegetAirmassModel (engine_load_mode_e mode)
 
float getMaxAirflowAtMap (float map)
 
static float getBaseFuelMass (float rpm)
 
angle_t getInjectionOffset (float rpm, float load)
 
int getNumberOfInjections (injection_mode_e mode)
 
float getInjectionModeDurationMultiplier ()
 
percent_t getInjectorDutyCycle (float rpm)
 
percent_t getInjectorDutyCycleStage2 (float rpm)
 
float getCycleFuelMass (bool isCranking, float baseFuelMass)
 
float getInjectionMass (float rpm)
 
void initFuelMap ()
 Initialize fuel map data structure.
 
float getCltFuelCorrection ()
 Engine warm-up fuel correction.
 
float getIatFuelCorrection ()
 
float getPostCrankingFuelCorrection ()
 
float getBaroCorrection ()
 
percent_t getFuelALSCorrection (float rpm)
 
float getCrankingFuel (float baseFuel)
 
float getStandardAirCharge ()
 
PUBLIC_API_WEAK_SOMETHING_WEIRD float getCylinderFuelTrim (size_t cylinderNumber, float rpm, float fuelLoad)
 
float getStage2InjectionFraction (float rpm, float load)
 

Variables

ve_Map3D_t veMap
 
static mapEstimate_Map3D_t mapEstimationTable {"mape"}
 
static SpeedDensityAirmass sdAirmass (veMap, mapEstimationTable)
 
static MafAirmass mafAirmass (veMap)
 
static AlphaNAirmass alphaNAirmass (veMap)
 
static Hysteresis stage2Hysteresis
 

Function Documentation

◆ getAirmassModel()

AirmassModelBase * getAirmassModel ( engine_load_mode_e  mode)

Definition at line 156 of file fuel_math.cpp.

156 {
157#if EFI_UNIT_TEST
158 if (mode == engine_load_mode_e::UNSUPPORTED_ENUM_VALUE) {
159 return engine->mockAirmassModel;
160 }
161#endif
162
163 switch (mode) {
164 case engine_load_mode_e::LM_SPEED_DENSITY: return &sdAirmass;
165 case engine_load_mode_e::LM_REAL_MAF: return &mafAirmass;
166 case engine_load_mode_e::LM_ALPHA_N: return &alphaNAirmass;
167#if EFI_LUA
168 case engine_load_mode_e::LM_LUA: return &(getLuaAirmassModel());
169#endif
170 default:
172 return nullptr;
173 }
174}
AirmassModelBase * mockAirmassModel
Definition engine.h:382
static EngineAccessor engine
Definition engine.h:413
static constexpr engine_configuration_s * engineConfiguration
void firmwareError(ObdCode code, const char *fmt,...)
static SpeedDensityAirmass sdAirmass(veMap, mapEstimationTable)
static MafAirmass mafAirmass(veMap)
static AlphaNAirmass alphaNAirmass(veMap)
AirmassModelBase & getLuaAirmassModel()
@ CUSTOM_ERR_ASSERT

Referenced by getBaseFuelMass(), and lua_getAirmass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getBaroCorrection()

float getBaroCorrection ( )

Definition at line 429 of file fuel_math.cpp.

429 {
431 // Default to 1atm if failed
432 float pressure = Sensor::get(SensorType::BarometricPressure).value_or(STD_ATMOSPHERE);
433
434 float correction = interpolate3d(
436 config->baroCorrPressureBins, pressure,
438 );
439
440 if (std::isnan(correction) || correction < 0.01) {
441 warning(ObdCode::OBD_Barometric_Press_Circ_Range_Perf, "Invalid baro correction %f", correction);
442 return 1;
443 }
444
445 return correction;
446 } else {
447 return 1;
448 }
449}
virtual bool hasSensor() const
Definition sensor.h:141
virtual SensorResult get() const =0
static float getOrZero(SensorType type)
Definition sensor.h:83
static constexpr persistent_config_s * config
bool warning(ObdCode code, const char *fmt,...)
@ OBD_Barometric_Press_Circ_Range_Perf
@ BarometricPressure

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getBaseFuelMass()

static float getBaseFuelMass ( float  rpm)
static

Definition at line 183 of file fuel_math.cpp.

183 {
185
186 // airmass modes - get airmass first, then convert to fuel
188 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, model != nullptr, "Invalid airmass mode", 0.0f);
189
190 auto airmass = model->getAirmass(rpm, true);
191
192 // Plop some state for others to read
193 float normalizedCylinderFilling = 100 * airmass.CylinderAirmass / getStandardAirCharge();
194 engine->fuelComputer.sdAirMassInOneCylinder = airmass.CylinderAirmass;
196 engine->engineState.fuelingLoad = airmass.EngineLoadPercent;
198
199 auto gramPerCycle = airmass.CylinderAirmass * engineConfiguration->cylindersCount;
200 auto gramPerMs = rpm == 0 ? 0 : gramPerCycle / getEngineCycleDuration(rpm);
201
202 // convert g/s -> kg/h
203 engine->engineState.airflowEstimate = gramPerMs * 3600000 /* milliseconds per hour */ / 1000 /* grams per kg */;
204
205 float baseFuelMass = engine->fuelComputer.getCycleFuel(airmass.CylinderAirmass, rpm, airmass.EngineLoadPercent);
206
207 engine->engineState.baseFuel = baseFuelMass;
208
209 if (std::isnan(baseFuelMass)) {
210 // todo: we should not have this here but https://github.com/rusefi/rusefi/issues/1690
211 return 0;
212 }
213
214 return baseFuelMass;
215}
FuelComputer fuelComputer
Definition engine.h:139
EngineState engineState
Definition engine.h:344
floatms_t baseFuel
float airflowEstimate
mass_t getCycleFuel(mass_t airmass, float rpm, float load) override
floatms_t getEngineCycleDuration(float rpm)
AirmassModelBase * getAirmassModel(engine_load_mode_e mode)
float getStandardAirCharge()
@ GetBaseFuel
normalizedCylinderFilling("Air: Normalized cyl filling", SensorCategory.SENSOR_INPUTS, FieldType.INT, 928, 1.0, 0.0, 100.0, "%")
float getLoadOverride(float defaultLoad, load_override_e overrideMode) const

Referenced by getInjectionMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCltFuelCorrection()

float getCltFuelCorrection ( )

Engine warm-up fuel correction.

Definition at line 386 of file fuel_math.cpp.

386 {
387 const auto clt = Sensor::get(SensorType::Clt);
388
389 if (!clt)
390 return 1; // this error should be already reported somewhere else, let's just handle it
391
392 return interpolate2d(clt.Value, config->cltFuelCorrBins, config->cltFuelCorr);
393}
static CCM_OPTIONAL FunctionalSensor clt(SensorType::Clt, MS2NT(10))

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCrankingFuel()

float getCrankingFuel ( float  baseFuel)
Returns
Duration of fuel injection while craning

Definition at line 472 of file fuel_math.cpp.

472 {
474}
RpmCalculator rpmCalculator
Definition engine.h:306
uint32_t getRevolutionCounterSinceStart(void) const
float getCrankingFuel3(float baseFuel, uint32_t revolutionCounterSinceStart)
Definition fuel_math.cpp:42

Referenced by getCycleFuelMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCrankingFuel3()

float getCrankingFuel3 ( float  baseFuel,
uint32_t  revolutionCounterSinceStart 
)

Cranking fuel is different depending on engine coolant temperature If the sensor is failed, use 20 deg C

Definition at line 42 of file fuel_math.cpp.

42 {
43
44 float baseCrankingFuel;
46 baseCrankingFuel = baseFuel;
47 } else {
48 // Cranking fuel changes over time
49 baseCrankingFuel = interpolate3d(
53 ) * 0.001f; // parameter is in milligrams, convert to grams
54 }
55
56 engine->engineState.crankingFuel.baseFuel = baseCrankingFuel * 1000; // convert to mg
57
58 /**
59 * Cranking fuel is different depending on engine coolant temperature
60 * If the sensor is failed, use 20 deg C
61 */
62 auto clt = Sensor::get(SensorType::Clt).value_or(20);
63 auto e0Mult = interpolate2d(clt, config->crankingFuelBins, config->crankingFuelCoef);
64
65 bool alreadyWarned = false;
66 if (e0Mult <= 0.1f) {
67 warning(ObdCode::CUSTOM_ERR_ZERO_E0_MULT, "zero e0 multiplier");
68 alreadyWarned = true;
69 }
70
72 auto e85Mult = interpolate2d(clt, config->crankingFuelBins, config->crankingFuelCoefE100);
73
74 if (e85Mult <= 0.1f) {
75 warning(ObdCode::CUSTOM_ERR_ZERO_E85_MULT, "zero e85 multiplier");
76 alreadyWarned = true;
77 }
78
79 // If failed flex sensor, default to 50% E
80 auto flex = Sensor::get(SensorType::FuelEthanolPercent).value_or(50);
81
84 0, e0Mult,
85 85, e85Mult,
86 flex
87 );
88 } else {
90 }
91
94 tps.Valid
95 ? interpolate2d(tps.Value, config->crankingTpsBins, config->crankingTpsCoef)
96 : 1; // in case of failed TPS, don't correct.
97
98 floatms_t crankingFuel = baseCrankingFuel
101
103
104 // don't re-warn for zero fuel when we already warned for a more specific problem
105 if (!alreadyWarned && crankingFuel <= 0) {
107 }
108 return crankingFuel;
109}
float interpolateClamped(float x1, float y1, float x2, float y2, float x)
@ CUSTOM_ERR_ZERO_E85_MULT
@ CUSTOM_ERR_ZERO_CRANKING_FUEL
@ CUSTOM_ERR_ZERO_E0_MULT
float floatms_t
@ FuelEthanolPercent
@ DriverThrottleIntent
revolutionCounterSinceStart("revolutionCounterSinceStart", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 64, 1.0, 0.0, 0.0, "")
crankingFuel("crankingFuel", SensorCategory.SENSOR_INPUTS, FieldType.INT, 1352, 1.0, -1.0, -1.0, "")
scaled_channel< uint16_t, 100, 1 > baseFuel
scaled_channel< uint16_t, 100, 1 > fuel
cranking_fuel_s crankingFuel
float crankingCycleBaseFuel[CRANKING_CYCLE_CLT_SIZE][CRANKING_CURVE_SIZE]
scaled_channel< uint16_t, 100, 1 > crankingFuelCoefE100[CRANKING_CURVE_SIZE]

Referenced by getCrankingFuel().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCycleFuelMass()

float getCycleFuelMass ( bool  isCranking,
float  baseFuelMass 
)

Definition at line 300 of file fuel_math.cpp.

300 {
301 if (isCranking) {
302 return getCrankingFuel(baseFuelMass);
303 } else {
304 return getRunningFuel(baseFuelMass);
305 }
306}
float getRunningFuel(float baseFuel)
float getCrankingFuel(float baseFuel)

Referenced by getInjectionMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCylinderFuelTrim()

PUBLIC_API_WEAK_SOMETHING_WEIRD float getCylinderFuelTrim ( size_t  cylinderNumber,
float  rpm,
float  fuelLoad 
)

Definition at line 491 of file fuel_math.cpp.

491 {
492 auto trimPercent = interpolate3d(
493 config->fuelTrims[cylinderNumber].table,
494 config->fuelTrimLoadBins, fuelLoad,
496 );
497
498 // Convert from percent +- to multiplier
499 // 5% -> 1.05
500 // possible optimization: remove division by moving this scaling to TS level
501 return (100 + trimPercent) / 100;
502}
scaled_channel< int8_t, 5, 1 > table[FUEL_TRIM_SIZE][FUEL_TRIM_SIZE]

Referenced by EngineState::periodicFastCallback().

Here is the caller graph for this function:

◆ getFuelALSCorrection()

percent_t getFuelALSCorrection ( float  rpm)

Definition at line 451 of file fuel_math.cpp.

451 {
452#if EFI_ANTILAG_SYSTEM
455 auto AlsFuelAdd = interpolate3d(
457 config->alsFuelAdjustmentLoadBins, throttleIntent,
459 );
460 return AlsFuelAdd;
461 } else
462#endif /* EFI_ANTILAG_SYSTEM */
463 {
464 return 0;
465 }
466}
AntilagSystemBase antilagController
Definition engine.h:228
scaled_channel< int16_t, 10, 1 > ALSFuelAdjustment[ALS_SIZE][ALS_SIZE]

Referenced by AntilagSystemBase::update().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getIatFuelCorrection()

float getIatFuelCorrection ( )

Definition at line 395 of file fuel_math.cpp.

395 {
396 const auto iat = Sensor::get(SensorType::Iat);
397
398 if (!iat)
399 return 1; // this error should be already reported somewhere else, let's just handle it
400
401 return interpolate2d(iat.Value, config->iatFuelCorrBins, config->iatFuelCorr);
402}
static CCM_OPTIONAL FunctionalSensor iat(SensorType::Iat, MS2NT(10))

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectionMass()

float getInjectionMass ( float  rpm)
Returns
Mass of each individual fuel injection, in grams in case of single point injection mode the amount of fuel into all cylinders, otherwise the amount for one cylinder

Definition at line 312 of file fuel_math.cpp.

312 {
314
315 // Always update base fuel - some cranking modes use it
316 float baseFuelMass = getBaseFuelMass(rpm);
317
318 bool isCranking = engine->rpmCalculator.isCranking();
319 float cycleFuelMass = getCycleFuelMass(isCranking, baseFuelMass);
320 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(cycleFuelMass), "NaN cycleFuelMass", 0);
321
322 if (engine->module<DfcoController>()->cutFuel()) {
323 // If decel fuel cut, zero out fuel
324 cycleFuelMass = 0;
325 }
326
327 float durationMultiplier = getInjectionModeDurationMultiplier();
328 float injectionFuelMass = cycleFuelMass * durationMultiplier;
329
330 // Prepare injector flow rate & deadtime
331 engine->module<InjectorModelPrimary>()->prepare();
332
334 engine->module<InjectorModelSecondary>()->prepare();
335 }
336
337 // This variable will hold the extra fuel mass from legacy AE modes
338 float tpsFuelMass = 0;
339
340 // Get the AE value (it will be 0 if predictive mode is active)
341 float tpsAccelEnrich = engine->module<TpsAccelEnrichment>()->getTpsEnrichment();
342 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(tpsAccelEnrich), "NaN tpsAccelEnrich", 0);
343 engine->engineState.tpsAccelEnrich = tpsAccelEnrich;
344
345 float tpsAccelPerInjection = durationMultiplier * tpsAccelEnrich;
346
347 // Use a switch to handle all AE modes
349 case AE_MODE_PERCENT_ADDER:
350 // Treat the tpsAccelEnrich value as a percentage
351 tpsFuelMass = injectionFuelMass * tpsAccelPerInjection;
352 break;
353
354 case AE_MODE_MS_ADDER:
355 // For legacy reasons, the TPS accel table is in units of milliseconds,
356 // so we have to convert BACK to mass
357 tpsFuelMass = engine->module<InjectorModelPrimary>()->getFuelMassForDuration(tpsAccelPerInjection);
358 break;
359
360 case AE_MODE_PREDICTIVE_MAP:
361 // Do nothing here. Fuel correction has already been handled by providing a
362 // corrected MAP value to the getBaseFuelMass() calculation.
363 break;
364
365 default:
366 criticalError("Invalid accelEnrichmentMode %d", engineConfiguration->accelEnrichmentMode);
367 break;
368 }
369
370 return injectionFuelMass + tpsFuelMass;
371}
bool cutFuel() const
Definition dfco.cpp:81
constexpr auto & module()
Definition engine.h:200
floatms_t tpsAccelEnrich
bool isCranking() const override
static float getBaseFuelMass(float rpm)
float getCycleFuelMass(bool isCranking, float baseFuelMass)
float getInjectionModeDurationMultiplier()
@ GetInjectionDuration
accel_enrichment_mode_e

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectionModeDurationMultiplier()

float getInjectionModeDurationMultiplier ( )

Definition at line 263 of file fuel_math.cpp.

263 {
265
266 switch (mode) {
267 case IM_SIMULTANEOUS: {
268 auto cylCount = engineConfiguration->cylindersCount;
269
270 if (cylCount == 0) {
271 // we can end up here during configuration reset
272 return 0;
273 }
274
275 return 1.0f / cylCount;
276 }
277 case IM_SEQUENTIAL:
278 case IM_SINGLE_POINT:
279 return 1;
280 case IM_BATCH:
281 return 0.5f;
282 default:
283 firmwareError(ObdCode::CUSTOM_ERR_INVALID_INJECTION_MODE, "Unexpected injection_mode_e %d", mode);
284 return 0;
285 }
286}
injection_mode_e getCurrentInjectionMode()
Definition engine.cpp:548
@ CUSTOM_ERR_INVALID_INJECTION_MODE
injection_mode_e

Referenced by getInjectionMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectionOffset()

angle_t getInjectionOffset ( float  rpm,
float  load 
)

Definition at line 217 of file fuel_math.cpp.

217 {
218 if (std::isnan(rpm)) {
219 return 0; // error already reported
220 }
221
222 if (std::isnan(load)) {
223 return 0; // error already reported
224 }
225
226 angle_t value = interpolate3d(
230 );
231
232 if (std::isnan(value)) {
233 // we could be here while resetting configuration for example
234 // huh? what? when do we have RPM while resetting configuration? is that CI edge case? shall we fix CI?
235 warning(ObdCode::CUSTOM_ERR_6569, "phase map not ready");
236 return 0;
237 }
238
239 angle_t result = value;
240 wrapAngle(result, "inj offset#2", ObdCode::CUSTOM_ERR_6553);
241 return result;
242}
@ CUSTOM_ERR_6553
@ CUSTOM_ERR_6569
float angle_t
int16_t injectionPhase[INJ_PHASE_LOAD_COUNT][INJ_PHASE_RPM_COUNT]
void wrapAngle(angle_t &angle, const char *msg, ObdCode code)

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectorDutyCycle()

percent_t getInjectorDutyCycle ( float  rpm)

Definition at line 288 of file fuel_math.cpp.

288 {
290 floatms_t engineCycleDuration = getEngineCycleDuration(rpm);
291 return 100 * totalInjectiorAmountPerCycle / engineCycleDuration;
292}
floatms_t injectionDuration
int getNumberOfInjections(injection_mode_e mode)

Referenced by canDashboardHaltech(), EngineState::periodicFastCallback(), populateFrame(), LimpManager::updateState(), and updateTunerStudioState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getInjectorDutyCycleStage2()

percent_t getInjectorDutyCycleStage2 ( float  rpm)

Definition at line 294 of file fuel_math.cpp.

294 {
296 floatms_t engineCycleDuration = getEngineCycleDuration(rpm);
297 return 100 * totalInjectiorAmountPerCycle / engineCycleDuration;
298}
floatms_t injectionDurationStage2

Referenced by updateTunerStudioState().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getMaxAirflowAtMap()

float getMaxAirflowAtMap ( float  map)

Definition at line 176 of file fuel_math.cpp.

176 {
178}
float getAirflow(float rpm, float map, bool postState)

Referenced by ThrottleModel::maxEngineFlow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getNumberOfInjections()

int getNumberOfInjections ( injection_mode_e  mode)

Number of injections using each injector per engine cycle

See also
getNumberOfSparks

Definition at line 248 of file fuel_math.cpp.

248 {
249 switch (mode) {
250 case IM_SIMULTANEOUS:
251 case IM_SINGLE_POINT:
253 case IM_BATCH:
254 return 2;
255 case IM_SEQUENTIAL:
256 return 1;
257 default:
258 firmwareError(ObdCode::CUSTOM_ERR_INVALID_INJECTION_MODE, "Unexpected injection_mode_e %d", mode);
259 return 1;
260 }
261}

Referenced by getInjectorDutyCycle(), getInjectorDutyCycleStage2(), and InjectionEvent::onTriggerTooth().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getPostCrankingFuelCorrection()

float getPostCrankingFuelCorrection ( )

Definition at line 404 of file fuel_math.cpp.

404 {
405 const auto revolutionCounter = engine->rpmCalculator.getRevolutionCounterSinceStart();
406 // if the engine run time is past the last bin, disable ASE in case the table is filled with values more than 1.0, helps with compatibility
407 if (revolutionCounter > config->postCrankingDurationBins[efi::size(config->postCrankingDurationBins) - 1])
408 return 1;
409
410 // TODO:
411 //const auto clt = Sensor::get(SensorType::Clt);
412 //if (!clt)
413 // return 1; // this error should be already reported somewhere else, let's just handle it
414
415 // post-cranking fuel enrichment.
416 float postCrankingFactor = interpolate3d(
419 config->postCrankingDurationBins, revolutionCounter
420 );
421
422 // for compatibility reasons, apply only if the factor is greater than unity (only allow adding fuel)
423 if (postCrankingFactor < 1.0f)
424 postCrankingFactor = 1.0f;
425
426 return postCrankingFactor;
427}
float postCrankingFactor[CRANKING_ENRICH_CLT_COUNT][CRANKING_ENRICH_COUNT]

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getRunningFuel()

float getRunningFuel ( float  baseFuel)
Returns
baseFuel with CLT and IAT corrections

Definition at line 111 of file fuel_math.cpp.

111 {
113
116 float postCrankingFuelCorrection = engine->fuelComputer.running.postCrankingFuelCorrection;
118
119 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(iatCorrection), "NaN iatCorrection", 0);
120 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(cltCorrection), "NaN cltCorrection", 0);
121 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(postCrankingFuelCorrection), "NaN postCrankingFuelCorrection", 0);
122
123 float correction = baroCorrection * iatCorrection * cltCorrection * postCrankingFuelCorrection;
124
125#if EFI_ANTILAG_SYSTEM
126 correction *= (1 + engine->antilagController.fuelALSCorrection / 100);
127#endif /* EFI_ANTILAG_SYSTEM */
128
129#if EFI_LAUNCH_CONTROL
131 correction *= engine->module<NitrousController>().unmock().getFuelCoefficient();
132#endif
133
134#ifdef MODULE_VVL_CONTROLLER
135 correction *= engine->module<VvlController>().unmock().getFuelCoefficient();
136#endif /* MODULE_VVL_CONTROLLER */
137
138 correction *= getLimpManager()->getLimitingFuelCorrection();
139
140 float runningFuel = baseFuel * correction;
141
142 efiAssert(ObdCode::CUSTOM_ERR_ASSERT, !std::isnan(runningFuel), "NaN runningFuel", 0);
143
144 // Publish output state
145 engine->fuelComputer.running.baseFuel = baseFuel * 1000;
147 engine->fuelComputer.running.fuel = runningFuel * 1000;
148
149 return runningFuel;
150}
LaunchControlBase launchController
Definition engine.h:220
float getFuelCoefficient() const
float getLimitingFuelCorrection() const
float getFuelCoefficient() const
float getFuelCoefficient() const
LimpManager * getLimpManager()
Definition engine.cpp:596
@ GetRunningFuel
baroCorrection("Fuel: Barometric pressure mult", SensorCategory.SENSOR_INPUTS, FieldType.INT, 1364, 1.0, -1.0, -1.0, "")
scaled_channel< uint16_t, 100, 1 > baseFuel
scaled_channel< uint16_t, 100, 1 > fuel

Referenced by getCycleFuelMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getStage2InjectionFraction()

float getStage2InjectionFraction ( float  rpm,
float  load 
)

Definition at line 506 of file fuel_math.cpp.

506 {
508 return 0;
509 }
510
511 float frac = 0.01f * interpolate3d(
515 );
516
517 // don't allow very small fraction, with some hysteresis
518 if (!stage2Hysteresis.test(frac, 0.1, 0.03)) {
519 return 0;
520 }
521
522 // Clamp to 90%
523 if (frac > 0.9) {
524 frac = 0.9;
525 }
526
527 return frac;
528}
bool test(float value, float rising, float falling)
Definition hysteresis.h:31
static Hysteresis stage2Hysteresis
uint8_t injectorStagingTable[INJ_STAGING_COUNT][INJ_STAGING_COUNT]

Referenced by EngineState::periodicFastCallback().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getStandardAirCharge()

float getStandardAirCharge ( )

Standard cylinder air charge - 100% VE at standard temperature, grams per cylinder

Should we bother caching 'getStandardAirCharge' result or can we afford to run the math every time we calculate fuel?

Definition at line 481 of file fuel_math.cpp.

481 {
482 float totalDisplacement = engineConfiguration->displacement;
483 float cylDisplacement = totalDisplacement / engineConfiguration->cylindersCount;
484
485 // Calculation of 100% VE air mass in g/cyl - 1 cylinder filling at 1.204/L
486 // 101.325kpa, 20C
487 return idealGasLaw(cylDisplacement, STD_ATMOSPHERE, C_K_OFFSET + STD_IAT);
488}
mass_t idealGasLaw(float volume, float pressure, float temperature)

Referenced by MafAirmass::getAirmassImpl(), and getBaseFuelMass().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initFuelMap()

void initFuelMap ( )

Initialize fuel map data structure.

Note
this method has nothing to do with fuel map VALUES - it's job is to prepare the fuel map data structure for 3d interpolation

Definition at line 379 of file fuel_math.cpp.

379 {
381}
void initTable(TValueInit(&table)[TRowNum][TColNum], const TXColumnInit(&columnBins)[TColNum], const TRowInit(&rowBins)[TRowNum])
static mapEstimate_Map3D_t mapEstimationTable
Definition fuel_math.cpp:38
scaled_channel< uint16_t, 100, 1 > mapEstimateTpsBins[MAP_EST_LOAD_COUNT]
scaled_channel< uint16_t, 100, 1 > mapEstimateTable[MAP_EST_LOAD_COUNT][MAP_EST_RPM_COUNT]

Referenced by initDataStructures().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ alphaNAirmass

AlphaNAirmass alphaNAirmass(veMap) ( veMap  )
static

Referenced by getAirmassModel().

◆ mafAirmass

MafAirmass mafAirmass(veMap) ( veMap  )
static

Referenced by getAirmassModel().

◆ mapEstimationTable

mapEstimate_Map3D_t mapEstimationTable {"mape"}
static

Definition at line 38 of file fuel_math.cpp.

38{"mape"};

Referenced by initFuelMap().

◆ sdAirmass

◆ stage2Hysteresis

Hysteresis stage2Hysteresis
static

Definition at line 504 of file fuel_math.cpp.

Referenced by getStage2InjectionFraction().

◆ veMap

ve_Map3D_t veMap
extern

Definition at line 19 of file speed_density.cpp.

19{"ve"};

Referenced by initSpeedDensity().

Go to the source code of this file.