74 lines
2.3 KiB
C++
74 lines
2.3 KiB
C++
#include "pch.h"
|
|
|
|
#include "airmass.h"
|
|
#include "idle_thread.h"
|
|
|
|
AirmassVeModelBase::AirmassVeModelBase(const ValueProvider3D& veTable) : m_veTable(&veTable) {}
|
|
|
|
static float getVeLoadAxis(ve_override_e mode, float passedLoad) {
|
|
switch(mode) {
|
|
case VE_None: return passedLoad;
|
|
case VE_MAP: return Sensor::getOrZero(SensorType::Map);
|
|
case VE_TPS: return Sensor::getOrZero(SensorType::Tps1);
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
float AirmassVeModelBase::getVe(float rpm, float load, bool postState) const {
|
|
efiAssert(ObdCode::OBD_PCM_Processor_Fault, m_veTable != nullptr, "VE table null", 0);
|
|
|
|
// Override the load value if necessary
|
|
load = getVeLoadAxis(engineConfiguration->veOverrideMode, load);
|
|
|
|
percent_t ve = m_veTable->getValue(rpm, load);
|
|
|
|
#if EFI_IDLE_CONTROL
|
|
auto tps = Sensor::get(SensorType::Tps1);
|
|
// get VE from the separate table for Idle if idling
|
|
if (engine->module<IdleController>()->isIdlingOrTaper() &&
|
|
tps && engineConfiguration->useSeparateVeForIdle) {
|
|
float idleVeLoad = getVeLoadAxis(engineConfiguration->idleVeOverrideMode, load);
|
|
|
|
percent_t idleVe = interpolate3d(
|
|
config->idleVeTable,
|
|
config->idleVeLoadBins, idleVeLoad,
|
|
config->idleVeRpmBins, rpm
|
|
);
|
|
|
|
// interpolate between idle table and normal (running) table using TPS threshold
|
|
// 0 TPS -> idle table
|
|
// 1/2 threshold -> idle table
|
|
// idle threshold -> normal table
|
|
float idleThreshold = engineConfiguration->idlePidDeactivationTpsThreshold;
|
|
ve = interpolateClamped(idleThreshold / 2, idleVe, idleThreshold, ve, tps.Value);
|
|
}
|
|
#endif // EFI_IDLE_CONTROL
|
|
|
|
// Add any adjustments if configured
|
|
for (size_t i = 0; i < efi::size(config->veBlends); i++) {
|
|
auto result = calculateBlend(config->veBlends[i], rpm, load);
|
|
|
|
if (postState) {
|
|
engine->outputChannels.veBlendParameter[i] = result.BlendParameter;
|
|
engine->outputChannels.veBlendBias[i] = result.Bias;
|
|
engine->outputChannels.veBlendOutput[i] = result.Value;
|
|
}
|
|
|
|
// Skip extra floating point math if we can...
|
|
if (result.Value == 0) {
|
|
continue;
|
|
}
|
|
|
|
// Apply as a multiplier, not as an adder
|
|
// Value of +5 means add 5%, aka multiply by 1.05
|
|
ve *= ((100 + result.Value) * 0.01f);
|
|
}
|
|
|
|
if (postState) {
|
|
engine->engineState.currentVe = ve;
|
|
engine->engineState.veTableYAxis = load;
|
|
}
|
|
|
|
return ve * PERCENT_DIV;
|
|
}
|