trigger refactoring: instance RPM #4740

This commit is contained in:
Andrey 2022-11-06 10:58:04 -05:00
parent 0d74e201ee
commit b5796c121d
3 changed files with 70 additions and 57 deletions

View File

@ -240,12 +240,12 @@ void RpmCalculator::setSpinningUp(efitick_t nowNt) {
// Only a completely stopped and non-spinning engine can enter the spinning-up state.
if (isStopped() && !isSpinning) {
state = SPINNING_UP;
engine->triggerCentral.triggerState.spinningEventIndex = 0;
engine->triggerCentral.triggerState.instantRpm.spinningEventIndex = 0;
isSpinning = true;
}
// update variables needed by early instant RPM calc.
if (isSpinningUp()) {
engine->triggerCentral.triggerState.setLastEventTimeForInstantRpm(nowNt);
if (isSpinningUp() && !engine->triggerCentral.triggerState.getShaftSynchronized()) {
engine->triggerCentral.triggerState.instantRpm.setLastEventTimeForInstantRpm(nowNt);
}
}
@ -298,7 +298,7 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType,
} else {
// we are here only once trigger is synchronized for the first time
// while transitioning from 'spinning' to 'running'
engine->triggerCentral.triggerState.movePreSynchTimestamps();
engine->triggerCentral.triggerState.instantRpm.movePreSynchTimestamps();
}
rpmState->onNewEngineCycle();
@ -315,7 +315,7 @@ void rpmShaftPositionCallback(trigger_event_e ckpSignalType,
#endif /* EFI_SENSOR_CHART */
// Always update instant RPM even when not spinning up
engine->triggerCentral.triggerState.updateInstantRpm(
engine->triggerCentral.triggerState.instantRpm.updateInstantRpm(
engine->triggerCentral.triggerShape, &engine->triggerCentral.triggerFormDetails,
trgEventIndex, nowNt);

View File

@ -109,11 +109,15 @@ void TriggerDecoderBase::resetCurrentCycleState() {
#if EFI_SHAFT_POSITION_INPUT
InstantRpmCalculator::InstantRpmCalculator() :
//https://en.cppreference.com/w/cpp/language/zero_initialization
timeOfLastEvent()
, instantRpmValue()
{
}
PrimaryTriggerDecoder::PrimaryTriggerDecoder(const char* name)
: TriggerDecoderBase(name)
//https://en.cppreference.com/w/cpp/language/zero_initialization
, timeOfLastEvent()
, instantRpmValue()
{
}
@ -198,20 +202,14 @@ int TriggerDecoderBase::getCrankSynchronizationCounter() const {
void PrimaryTriggerDecoder::resetState() {
TriggerDecoderBase::resetState();
prevInstantRpmValue = 0;
m_instantRpm = 0;
resetHasFullSync();
resetInstantRpm();
instantRpm.prevInstantRpmValue = 0;
instantRpm.m_instantRpm = 0;
instantRpm.resetInstantRpm();
}
void PrimaryTriggerDecoder::resetInstantRpm() {
memset(timeOfLastEvent, 0, sizeof(timeOfLastEvent));
memset(spinningEvents, 0, sizeof(spinningEvents));
spinningEventIndex = 0;
}
void PrimaryTriggerDecoder::movePreSynchTimestamps() {
void InstantRpmCalculator::movePreSynchTimestamps() {
// here we take timestamps of events which happened prior to synchronization and place them
// at appropriate locations
auto triggerSize = getTriggerCentral()->triggerShape.getLength();
@ -234,7 +232,7 @@ void PrimaryTriggerDecoder::movePreSynchTimestamps() {
memcpy(timeOfLastEvent + firstDst, spinningEvents + firstSrc, eventsToCopy * sizeof(timeOfLastEvent[0]));
}
float PrimaryTriggerDecoder::calculateInstantRpm(
float InstantRpmCalculator::calculateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t current_index, efitick_t nowNt) {
@ -291,10 +289,7 @@ float PrimaryTriggerDecoder::calculateInstantRpm(
return instantRpm;
}
void PrimaryTriggerDecoder::setLastEventTimeForInstantRpm(efitick_t nowNt) {
if (getShaftSynchronized()) {
return;
}
void InstantRpmCalculator::setLastEventTimeForInstantRpm(efitick_t nowNt) {
// here we remember tooth timestamps which happen prior to synchronization
if (spinningEventIndex >= efi::size(spinningEvents)) {
// too many events while trying to find synchronization point
@ -310,7 +305,7 @@ void PrimaryTriggerDecoder::setLastEventTimeForInstantRpm(efitick_t nowNt) {
spinningEventIndex += engineConfiguration->useOnlyRisingEdgeForTrigger ? 2 : 1;
}
void PrimaryTriggerDecoder::updateInstantRpm(
void InstantRpmCalculator::updateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t index, efitick_t nowNt) {
@ -377,7 +372,7 @@ angle_t PrimaryTriggerDecoder::syncEnginePhase(int divider, int remainder, angle
// Reset instant RPM, since the engine phase has now changed, invalidating the tooth history buffer
// maybe TODO: could/should we rotate the buffer around to re-align it instead? Is that worth it?
resetInstantRpm();
instantRpm.resetInstantRpm();
}
return totalShift;

View File

@ -182,25 +182,32 @@ private:
Timer m_timeSinceDecodeError;
};
/**
* the reason for sub-class is simply to save RAM but not having statistics in the trigger initialization instance
*/
class PrimaryTriggerDecoder : public TriggerDecoderBase, public trigger_state_primary_s {
class InstantRpmCalculator {
public:
PrimaryTriggerDecoder(const char* name);
void resetState() override;
void resetHasFullSync() {
// If this trigger doesn't need disambiguation, we already have phase sync
m_hasSynchronizedPhase = !m_needsDisambiguation;
}
angle_t syncEnginePhase(int divider, int remainder, angle_t engineCycle);
InstantRpmCalculator();
float getInstantRpm() const {
return m_instantRpm;
}
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
void updateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t index, efitick_t nowNt);
#endif
/**
* Update timeOfLastEvent[] on every trigger event - even without synchronization
* Needed for early spin-up RPM detection.
*/
void setLastEventTimeForInstantRpm(efitick_t nowNt);
void movePreSynchTimestamps();
void resetInstantRpm() {
memset(timeOfLastEvent, 0, sizeof(timeOfLastEvent));
memset(spinningEvents, 0, sizeof(spinningEvents));
spinningEventIndex = 0;
}
/**
* timestamp of each trigger wheel tooth
*/
@ -219,18 +226,37 @@ public:
* Stores last non-zero instant RPM value to fix early instability
*/
float prevInstantRpmValue = 0;
void movePreSynchTimestamps();
#if EFI_ENGINE_CONTROL && EFI_SHAFT_POSITION_INPUT
void updateInstantRpm(
float m_instantRpm = 0;
private:
float calculateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t index, efitick_t nowNt);
#endif
/**
* Update timeOfLastEvent[] on every trigger event - even without synchronization
* Needed for early spin-up RPM detection.
*/
void setLastEventTimeForInstantRpm(efitick_t nowNt);
float m_instantRpmRatio = 0;
};
/**
* the reason for sub-class is simply to save RAM but not having statistics in the trigger initialization instance
*/
class PrimaryTriggerDecoder : public TriggerDecoderBase, public trigger_state_primary_s {
public:
PrimaryTriggerDecoder(const char* name);
void resetState() override;
void resetHasFullSync() {
// If this trigger doesn't need disambiguation, we already have phase sync
m_hasSynchronizedPhase = !m_needsDisambiguation;
}
angle_t syncEnginePhase(int divider, int remainder, angle_t engineCycle);
InstantRpmCalculator instantRpm;
float getInstantRpm() const {
return instantRpm.getInstantRpm();
}
// Returns true if syncEnginePhase has been called,
// i.e. if we have enough VVT information to have full sync on
@ -251,14 +277,6 @@ public:
void onTooManyTeeth(int actual, int expected) override;
private:
float calculateInstantRpm(
TriggerWaveform const & triggerShape, TriggerFormDetails *triggerFormDetails,
uint32_t index, efitick_t nowNt);
void resetInstantRpm();
float m_instantRpm = 0;
float m_instantRpmRatio = 0;
bool m_needsDisambiguation = false;
};