From bdacda558c3498a7f2d621101c9da621d30a7742 Mon Sep 17 00:00:00 2001 From: Matthew Kennedy Date: Thu, 14 Jan 2021 17:45:55 -0800 Subject: [PATCH] fix instant rpm (#2180) * consumers * impl * instant rpm in idle timing --- firmware/console/status_loop.cpp | 2 +- .../controllers/actuators/idle_thread.cpp | 7 +++-- firmware/controllers/algo/engine.cpp | 4 --- .../engine_cycle/rpm_calculator.cpp | 11 +++++-- .../controllers/trigger/trigger_decoder.cpp | 30 ++++++++----------- .../controllers/trigger/trigger_decoder.h | 17 +++++++++-- 6 files changed, 41 insertions(+), 30 deletions(-) diff --git a/firmware/console/status_loop.cpp b/firmware/console/status_loop.cpp index ef91b33dff..0911ab6870 100644 --- a/firmware/console/status_loop.cpp +++ b/firmware/console/status_loop.cpp @@ -851,7 +851,7 @@ void updateTunerStudioState(TunerStudioOutputChannels *tsOutputChannels DECLARE_ break; case DBG_INSTANT_RPM: { - float instantRpm = engine->triggerCentral.triggerState.instantRpm; + float instantRpm = engine->triggerCentral.triggerState.getInstantRpm(); tsOutputChannels->debugFloatField1 = instantRpm; tsOutputChannels->debugFloatField2 = instantRpm / GET_RPM(); } diff --git a/firmware/controllers/actuators/idle_thread.cpp b/firmware/controllers/actuators/idle_thread.cpp index 7f0fc4cdb6..dd8746aef2 100644 --- a/firmware/controllers/actuators/idle_thread.cpp +++ b/firmware/controllers/actuators/idle_thread.cpp @@ -289,6 +289,10 @@ float IdleController::getIdleTimingAdjustment(int rpm, int targetRpm, Phase phas return 0; } + if (CONFIG(useInstantRpmForIdle)) { + rpm = engine->triggerCentral.triggerState.getInstantRpm(); + } + // If inside the deadzone, do nothing if (absI(rpm - targetRpm) < CONFIG(idleTimingPidDeadZone)) { m_timingPid.reset(); @@ -454,8 +458,7 @@ static percent_t automaticIdleController(float tpsPos, float rpm, int targetRpm, float rpm; if (CONFIG(useInstantRpmForIdle)) { - efitick_t nowNt = getTimeNowNt(); - rpm = engine->triggerCentral.triggerState.calculateInstantRpm(&engine->triggerCentral.triggerFormDetails, NULL, nowNt PASS_ENGINE_PARAMETER_SUFFIX); + rpm = engine->triggerCentral.triggerState.getInstantRpm(); } else { rpm = GET_RPM(); } diff --git a/firmware/controllers/algo/engine.cpp b/firmware/controllers/algo/engine.cpp index 0b2a2eba98..2d3bd8a71c 100644 --- a/firmware/controllers/algo/engine.cpp +++ b/firmware/controllers/algo/engine.cpp @@ -397,10 +397,6 @@ void Engine::OnTriggerStateProperState(efitick_t nowNt) { Engine *engine = this; EXPAND_Engine; -#if EFI_SHAFT_POSITION_INPUT - triggerCentral.triggerState.runtimeStatistics(&triggerCentral.triggerFormDetails, nowNt PASS_ENGINE_PARAMETER_SUFFIX); -#endif /* EFI_SHAFT_POSITION_INPUT */ - rpmCalculator.setSpinningUp(nowNt); } diff --git a/firmware/controllers/engine_cycle/rpm_calculator.cpp b/firmware/controllers/engine_cycle/rpm_calculator.cpp index dd91898133..2f2d23771e 100644 --- a/firmware/controllers/engine_cycle/rpm_calculator.cpp +++ b/firmware/controllers/engine_cycle/rpm_calculator.cpp @@ -295,9 +295,14 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType, // while transitioning from 'spinning' to 'running' // Replace 'normal' RPM with instant RPM for the initial spin-up period engine->triggerCentral.triggerState.movePreSynchTimestamps(PASS_ENGINE_PARAMETER_SIGNATURE); - int prevIndex; - float instantRpm = engine->triggerCentral.triggerState.calculateInstantRpm(&engine->triggerCentral.triggerFormDetails, - &prevIndex, nowNt PASS_ENGINE_PARAMETER_SUFFIX); + } + + // Always update instant RPM even when not spinning up + engine->triggerCentral.triggerState.updateInstantRpm(&engine->triggerCentral.triggerFormDetails, nowNt PASS_ENGINE_PARAMETER_SUFFIX); + + if (rpmState->isSpinningUp()) { + float instantRpm = engine->triggerCentral.triggerState.getInstantRpm(); + // validate instant RPM - we shouldn't skip the cranking state instantRpm = minF(instantRpm, CONFIG(cranking.rpm) - 1); rpmState->assignRpmValue(instantRpm); diff --git a/firmware/controllers/trigger/trigger_decoder.cpp b/firmware/controllers/trigger/trigger_decoder.cpp index 8756559660..cd5f74361e 100644 --- a/firmware/controllers/trigger/trigger_decoder.cpp +++ b/firmware/controllers/trigger/trigger_decoder.cpp @@ -211,8 +211,7 @@ void TriggerStateWithRunningStatistics::movePreSynchTimestamps(DECLARE_ENGINE_PA } } -float TriggerStateWithRunningStatistics::calculateInstantRpm(TriggerFormDetails *triggerFormDetails, - int *prevIndexOut, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { +float TriggerStateWithRunningStatistics::calculateInstantRpm(TriggerFormDetails *triggerFormDetails, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { int current_index = currentCycle.current_index; // local copy so that noone changes the value on us assertIsInBoundsWithResult(current_index, timeOfLastEvent, "calc timeOfLastEvent", 0); timeOfLastEvent[current_index] = nowNt; @@ -229,10 +228,6 @@ float TriggerStateWithRunningStatistics::calculateInstantRpm(TriggerFormDetails // todo: prevIndex should be pre-calculated int prevIndex = triggerFormDetails->triggerIndexByAngle[(int)previousAngle]; - if (prevIndexOut) { - *prevIndexOut = prevIndex; - } - // now let's get precise angle for that event angle_t prevIndexAngle = triggerFormDetails->eventAngles[prevIndex]; efitick_t time90ago = timeOfLastEvent[prevIndex]; @@ -255,10 +250,14 @@ float TriggerStateWithRunningStatistics::calculateInstantRpm(TriggerFormDetails instantRpmValue[current_index] = instantRpm; // This fixes early RPM instability based on incomplete data - if (instantRpm < RPM_LOW_THRESHOLD) + if (instantRpm < RPM_LOW_THRESHOLD) { return prevInstantRpmValue; + } + prevInstantRpmValue = instantRpm; + m_instantRpmRatio = instantRpm / instantRpmValue[prevIndex]; + return instantRpm; } @@ -276,23 +275,20 @@ void TriggerStateWithRunningStatistics::setLastEventTimeForInstantRpm(efitick_t spinningEvents[spinningEventIndex++] = nowNt; } -void TriggerStateWithRunningStatistics::runtimeStatistics(TriggerFormDetails *triggerFormDetails, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { - if (engineConfiguration->debugMode == DBG_INSTANT_RPM) { - instantRpm = calculateInstantRpm(triggerFormDetails, NULL, nowNt PASS_ENGINE_PARAMETER_SUFFIX); - } - if (ENGINE(sensorChartMode) == SC_RPM_ACCEL || ENGINE(sensorChartMode) == SC_DETAILED_RPM) { - int prevIndex; - instantRpm = calculateInstantRpm(triggerFormDetails, &prevIndex, nowNt PASS_ENGINE_PARAMETER_SUFFIX); +void TriggerStateWithRunningStatistics::updateInstantRpm(TriggerFormDetails *triggerFormDetails, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX) { + m_instantRpm = calculateInstantRpm(triggerFormDetails, nowNt PASS_ENGINE_PARAMETER_SUFFIX); + #if EFI_SENSOR_CHART + if (ENGINE(sensorChartMode) == SC_RPM_ACCEL || ENGINE(sensorChartMode) == SC_DETAILED_RPM) { angle_t currentAngle = triggerFormDetails->eventAngles[currentCycle.current_index]; if (CONFIG(sensorChartMode) == SC_DETAILED_RPM) { - scAddData(currentAngle, instantRpm); + scAddData(currentAngle, m_instantRpm); } else { - scAddData(currentAngle, instantRpm / instantRpmValue[prevIndex]); + scAddData(currentAngle, m_instantRpmRatio); } -#endif /* EFI_SENSOR_CHART */ } +#endif /* EFI_SENSOR_CHART */ } bool TriggerState::isValidIndex(const TriggerWaveform& triggerShape) const { diff --git a/firmware/controllers/trigger/trigger_decoder.h b/firmware/controllers/trigger/trigger_decoder.h index 925f2046a4..eb90689e89 100644 --- a/firmware/controllers/trigger/trigger_decoder.h +++ b/firmware/controllers/trigger/trigger_decoder.h @@ -169,7 +169,11 @@ private: class TriggerStateWithRunningStatistics : public TriggerState { public: TriggerStateWithRunningStatistics(); - float instantRpm = 0; + + float getInstantRpm() const { + return m_instantRpm; + } + /** * timestamp of each trigger wheel tooth */ @@ -187,15 +191,22 @@ public: */ float prevInstantRpmValue = 0; void movePreSynchTimestamps(DECLARE_ENGINE_PARAMETER_SIGNATURE); - float calculateInstantRpm(TriggerFormDetails *triggerFormDetails, int *prevIndex, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX); + #if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT - void runtimeStatistics(TriggerFormDetails *triggerFormDetails, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX); + void updateInstantRpm(TriggerFormDetails *triggerFormDetails, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX); #endif /** * Update timeOfLastEvent[] on every trigger event - even without synchronization * Needed for early spin-up RPM detection. */ void setLastEventTimeForInstantRpm(efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX); + +private: + float calculateInstantRpm(TriggerFormDetails *triggerFormDetails, efitick_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX); + + float m_instantRpm = 0; + float m_instantRpmRatio = 0; + }; angle_t getEngineCycle(operation_mode_e operationMode);