rusefi-1/firmware/controllers/algo/engine2.cpp

226 lines
6.7 KiB
C++
Raw Normal View History

2019-01-04 21:32:56 -08:00
/*
* engine2.cpp
*
* @date Jan 5, 2019
2020-01-07 21:02:40 -08:00
* @author Andrey Belomutskiy, (c) 2012-2020
2019-01-04 21:32:56 -08:00
*/
// todo: move this code to more proper locations
#include "pch.h"
#include "os_access.h"
2019-01-04 21:32:56 -08:00
#include "speed_density.h"
#include "fuel_math.h"
#include "advance_map.h"
#include "aux_valves.h"
#include "closed_loop_fuel.h"
#include "launch_control.h"
#include "injector_model.h"
2019-01-11 16:08:15 -08:00
#if EFI_PROD_CODE
#include "svnversion.h"
#endif
#if ! EFI_UNIT_TEST
#include "status_loop.h"
#endif
2019-01-04 21:32:56 -08:00
WarningCodeState::WarningCodeState() {
clear();
}
void WarningCodeState::clear() {
warningCounter = 0;
lastErrorCode = 0;
timeOfPreviousWarning = DEEP_IN_THE_PAST_SECONDS;
recentWarnings.clear();
}
void WarningCodeState::addWarningCode(obd_code_e code) {
warningCounter++;
lastErrorCode = code;
if (!recentWarnings.contains(code)) {
chibios_rt::CriticalSectionLocker csl;
// We don't bother double checking
recentWarnings.add((int)code);
2019-01-12 11:19:21 -08:00
}
}
/**
* @param forIndicator if we want to retrieving value for TS indicator, this case a minimal period is applued
*/
bool WarningCodeState::isWarningNow(efitimesec_t now, bool forIndicator) const {
int period = forIndicator ? maxI(3, engineConfiguration->warningPeriod) : engineConfiguration->warningPeriod;
return absI(now - timeOfPreviousWarning) < period;
}
2019-01-04 21:32:56 -08:00
void FuelConsumptionState::consumeFuel(float grams, efitick_t nowNt) {
m_consumedGrams += grams;
2019-01-04 21:32:56 -08:00
float elapsedSecond = m_timer.getElapsedSecondsAndReset(nowNt);
2019-01-04 21:32:56 -08:00
// If it's been a long time since last injection, ignore this pulse
if (elapsedSecond > 0.2f) {
m_rate = 0;
} else {
m_rate = grams / elapsedSecond;
2019-01-04 21:32:56 -08:00
}
}
2019-01-04 21:32:56 -08:00
float FuelConsumptionState::getConsumedGrams() const {
return m_consumedGrams;
2019-01-04 21:32:56 -08:00
}
float FuelConsumptionState::getConsumptionGramPerSecond() const {
return m_rate;
2019-01-04 21:32:56 -08:00
}
EngineState::EngineState() {
timeSinceLastTChargeK = getTimeNowNt();
}
void EngineState::updateSlowSensors() {
2019-01-04 21:32:56 -08:00
}
void EngineState::periodicFastCallback() {
2019-10-11 17:43:21 -07:00
ScopePerf perf(PE::EngineStatePeriodicFastCallback);
2019-04-12 19:07:03 -07:00
#if EFI_ENGINE_CONTROL
if (!engine->slowCallBackWasInvoked) {
2019-12-02 17:16:41 -08:00
warning(CUSTOM_SLOW_NOT_INVOKED, "Slow not invoked yet");
}
2019-01-04 21:32:56 -08:00
efitick_t nowNt = getTimeNowNt();
if (engine->rpmCalculator.isCranking()) {
2019-01-04 21:32:56 -08:00
crankingTime = nowNt;
timeSinceCranking = 0.0f;
} else {
timeSinceCranking = nowNt - crankingTime;
}
recalculateAuxValveTiming();
2019-01-04 21:32:56 -08:00
2022-01-20 19:12:04 -08:00
int rpm = Sensor::getOrZero(SensorType::Rpm);
2022-04-13 13:39:59 -07:00
sparkDwell = engine->ignitionState.getSparkDwell(rpm);
2019-01-04 21:32:56 -08:00
dwellAngle = cisnan(rpm) ? NAN : sparkDwell / getOneDegreeTimeMs(rpm);
// todo: move this into slow callback, no reason for IAT corr to be here
running.intakeTemperatureCoefficient = getIatFuelCorrection();
2019-01-04 21:32:56 -08:00
// todo: move this into slow callback, no reason for CLT corr to be here
running.coolantTemperatureCoefficient = getCltFuelCorrection();
2019-01-04 21:32:56 -08:00
engine->module<DfcoController>()->update();
2019-01-04 21:32:56 -08:00
// post-cranking fuel enrichment.
// for compatibility reasons, apply only if the factor is greater than unity (only allow adding fuel)
if (engineConfiguration->postCrankingFactor > 1.0f) {
2019-01-04 21:32:56 -08:00
// convert to microsecs and then to seconds
2021-08-09 13:33:06 -07:00
running.timeSinceCrankingInSecs = NT2US(timeSinceCranking) / US_PER_SECOND_F;
2019-01-04 21:32:56 -08:00
// use interpolation for correction taper
2019-08-26 20:41:04 -07:00
running.postCrankingFuelCorrection = interpolateClamped(0.0f, engineConfiguration->postCrankingFactor,
engineConfiguration->postCrankingDurationSec, 1.0f, running.timeSinceCrankingInSecs);
2019-01-04 21:32:56 -08:00
} else {
2019-08-26 20:41:04 -07:00
running.postCrankingFuelCorrection = 1.0f;
2019-01-04 21:32:56 -08:00
}
cltTimingCorrection = getCltTimingCorrection();
2019-01-04 21:32:56 -08:00
baroCorrection = getBaroCorrection();
2019-01-04 21:32:56 -08:00
auto tps = Sensor::get(SensorType::Tps1);
updateTChargeK(rpm, tps.value_or(0));
float injectionMass = getInjectionMass(rpm);
auto clResult = fuelClosedLoopCorrection();
// Store the pre-wall wetting injection duration for scheduling purposes only, not the actual injection duration
engine->injectionDuration = engine->module<InjectorModel>()->getInjectionDuration(injectionMass);
2020-07-20 23:11:48 -07:00
float fuelLoad = getFuelingLoad();
injectionOffset = getInjectionOffset(rpm, fuelLoad);
2020-07-20 23:11:48 -07:00
float ignitionLoad = getIgnitionLoad();
float advance = getAdvance(rpm, ignitionLoad) * engine->ignitionState.luaTimingMult + engine->ignitionState.luaTimingAdd;
// compute per-bank fueling
for (size_t i = 0; i < STFT_BANK_COUNT; i++) {
float corr = clResult.banks[i];
engine->stftCorrection[i] = corr;
}
// Now apply that to per-cylinder fueling and timing
for (size_t i = 0; i < engineConfiguration->specs.cylindersCount; i++) {
uint8_t bankIndex = engineConfiguration->cylinderBankSelect[i];
auto bankTrim =engine->stftCorrection[bankIndex];
auto cylinderTrim = getCylinderFuelTrim(i, rpm, fuelLoad);
// Apply both per-bank and per-cylinder trims
engine->injectionMass[i] = injectionMass * bankTrim * cylinderTrim;
timingAdvance[i] = advance + getCylinderIgnitionTrim(i, rpm, ignitionLoad);
}
// TODO: calculate me from a table!
trailingSparkAngle = engineConfiguration->trailingSparkAngle;
multispark.count = getMultiSparkCount(rpm);
#if EFI_LAUNCH_CONTROL
2021-11-15 15:57:12 -08:00
engine->launchController.update();
#endif //EFI_LAUNCH_CONTROL
engine->limpManager.updateState(rpm, nowNt);
#endif // EFI_ENGINE_CONTROL
2019-01-04 21:32:56 -08:00
}
void EngineState::updateTChargeK(int rpm, float tps) {
2019-04-12 19:07:03 -07:00
#if EFI_ENGINE_CONTROL
float newTCharge = getTCharge(rpm, tps);
2019-01-04 21:32:56 -08:00
// convert to microsecs and then to seconds
efitick_t curTime = getTimeNowNt();
2021-08-09 13:33:06 -07:00
float secsPassed = (float)NT2US(curTime - timeSinceLastTChargeK) / US_PER_SECOND_F;
2019-01-04 21:32:56 -08:00
if (!cisnan(newTCharge)) {
// control the rate of change or just fill with the initial value
sd.tCharge = (sd.tChargeK == 0) ? newTCharge : limitRateOfChange(newTCharge, sd.tCharge, engineConfiguration->tChargeAirIncrLimit, engineConfiguration->tChargeAirDecrLimit, secsPassed);
sd.tChargeK = convertCelsiusToKelvin(sd.tCharge);
2019-01-04 21:32:56 -08:00
timeSinceLastTChargeK = curTime;
}
2019-01-31 08:57:15 -08:00
#endif
2019-01-04 21:32:56 -08:00
}
2019-01-11 16:08:15 -08:00
#if EFI_SIMULATOR
#define VCS_VERSION "123"
#endif
void TriggerConfiguration::update() {
UseOnlyRisingEdgeForTrigger = isUseOnlyRisingEdgeForTrigger();
VerboseTriggerSynchDetails = isVerboseTriggerSynchDetails();
TriggerType = getType();
}
2020-08-23 23:01:50 -07:00
bool PrimaryTriggerConfiguration::isUseOnlyRisingEdgeForTrigger() const {
return engineConfiguration->useOnlyRisingEdgeForTrigger;
2020-08-23 22:21:42 -07:00
}
2020-08-23 23:01:50 -07:00
trigger_type_e PrimaryTriggerConfiguration::getType() const {
return engineConfiguration->trigger.type;
2020-08-23 22:21:42 -07:00
}
2020-08-23 23:01:50 -07:00
bool PrimaryTriggerConfiguration::isVerboseTriggerSynchDetails() const {
return engineConfiguration->verboseTriggerSynchDetails;
2020-08-26 20:35:11 -07:00
}
bool VvtTriggerConfiguration::isUseOnlyRisingEdgeForTrigger() const {
return engineConfiguration->vvtCamSensorUseRise;
2020-08-26 20:35:11 -07:00
}
trigger_type_e VvtTriggerConfiguration::getType() const {
// Convert from VVT type to trigger type
return getVvtTriggerType(engineConfiguration->vvtMode[index]);
2020-08-26 20:35:11 -07:00
}
bool VvtTriggerConfiguration::isVerboseTriggerSynchDetails() const {
return engineConfiguration->verboseVVTDecoding;
2020-08-26 20:35:11 -07:00
}