rusEFI
The most advanced open source ECU
Public Member Functions | Data Fields | Private Member Functions | Private Attributes
InstantRpmCalculator Class Reference

#include <instant_rpm_calculator.h>

Collaboration diagram for InstantRpmCalculator:
Collaboration graph
[legend]

Public Member Functions

 InstantRpmCalculator ()
 
float getInstantRpm () const
 
void updateInstantRpm (uint32_t current_index, TriggerWaveform const &triggerShape, TriggerFormDetails *triggerFormDetails, uint32_t index, efitick_t nowNt)
 
void setLastEventTimeForInstantRpm (efitick_t nowNt)
 
void movePreSynchTimestamps ()
 
void resetInstantRpm ()
 

Data Fields

uint32_t timeOfLastEvent [PWM_PHASE_MAX_COUNT]
 
size_t spinningEventIndex = 0
 
uint32_t spinningEvents [120]
 
float instantRpmValue [PWM_PHASE_MAX_COUNT]
 
float prevInstantRpmValue = 0
 
float m_instantRpm = 0
 

Private Member Functions

float calculateInstantRpm (TriggerWaveform const &triggerShape, TriggerFormDetails *triggerFormDetails, uint32_t index, efitick_t nowNt)
 

Private Attributes

float m_instantRpmRatio = 0
 

Detailed Description

instant_rpm_calculator.h

Definition at line 8 of file instant_rpm_calculator.h.

Constructor & Destructor Documentation

◆ InstantRpmCalculator()

InstantRpmCalculator::InstantRpmCalculator ( )

Definition at line 20 of file instant_rpm_calculator.cpp.

20  :
21  //https://en.cppreference.com/w/cpp/language/zero_initialization
23  , instantRpmValue()
24  {
25 }
float instantRpmValue[PWM_PHASE_MAX_COUNT]
uint32_t timeOfLastEvent[PWM_PHASE_MAX_COUNT]

Member Function Documentation

◆ calculateInstantRpm()

float InstantRpmCalculator::calculateInstantRpm ( TriggerWaveform const &  triggerShape,
TriggerFormDetails triggerFormDetails,
uint32_t  index,
efitick_t  nowNt 
)
private

Definition at line 50 of file instant_rpm_calculator.cpp.

52  {
53 
54  // It's OK to truncate from 64b to 32b, ARM with single precision FPU uses an expensive
55  // software function to convert 64b int -> float, while 32b int -> float is very cheap hardware conversion
56  // The difference is guaranteed to be short (it's 90 degrees of engine rotation!), so it won't overflow.
57  uint32_t nowNt32 = nowNt;
58 
59  assertIsInBoundsWithResult(current_index, timeOfLastEvent, "calc timeOfLastEvent", 0);
60 
61  // Record the time of this event so we can calculate RPM from it later
62  timeOfLastEvent[current_index] = nowNt32;
63 
64  // Determine where we currently are in the revolution
65  angle_t currentAngle = triggerFormDetails->eventAngles[current_index];
66  efiAssert(ObdCode::OBD_PCM_Processor_Fault, !cisnan(currentAngle), "eventAngles", 0);
67 
68  // Hunt for a tooth ~90 degrees ago to compare to the current time
69  angle_t previousAngle = currentAngle - 90;
70  wrapAngle(previousAngle, "prevAngle", ObdCode::CUSTOM_ERR_TRIGGER_ANGLE_RANGE);
71  int prevIndex = triggerShape.findAngleIndex(triggerFormDetails, previousAngle);
72 
73  // now let's get precise angle for that event
74  angle_t prevIndexAngle = triggerFormDetails->eventAngles[prevIndex];
75  auto time90ago = timeOfLastEvent[prevIndex];
76 
77  // No previous timestamp, instant RPM isn't ready yet
78  if (time90ago == 0) {
79  return prevInstantRpmValue;
80  }
81 
82  uint32_t time = nowNt32 - time90ago;
83  angle_t angleDiff = currentAngle - prevIndexAngle;
84 
85  // Wrap the angle in to the correct range (ie, could be -630 when we want +90)
86  wrapAngle(angleDiff, "angleDiff", ObdCode::CUSTOM_ERR_6561);
87 
88  // just for safety, avoid divide-by-0
89  if (time == 0) {
90  return prevInstantRpmValue;
91  }
92 
93  float instantRpm = (60000000.0 / 360 * US_TO_NT_MULTIPLIER) * angleDiff / time;
94  assertIsInBoundsWithResult(current_index, instantRpmValue, "instantRpmValue", 0);
95  instantRpmValue[current_index] = instantRpm;
96 
97  // This fixes early RPM instability based on incomplete data
98  if (instantRpm < RPM_LOW_THRESHOLD) {
99  return prevInstantRpmValue;
100  }
101 
103 
105 
106  return instantRpm;
107 }
angle_t eventAngles[2 *PWM_PHASE_MAX_COUNT]
@ CUSTOM_ERR_TRIGGER_ANGLE_RANGE
@ CUSTOM_ERR_6561
@ OBD_PCM_Processor_Fault
float angle_t
Definition: rusefi_types.h:58
instantRpm("sync: instant RPM", SensorCategory.SENSOR_INPUTS, FieldType.INT16, 316, 1.0, 0.0, 0.0, "rpm")
void wrapAngle(angle_t &angle, const char *msg, ObdCode code)

Referenced by updateInstantRpm().

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

◆ getInstantRpm()

float InstantRpmCalculator::getInstantRpm ( ) const
inline

Definition at line 11 of file instant_rpm_calculator.h.

11  {
12  return m_instantRpm;
13  }

Referenced by getAdvanceCorrections(), IdleController::onSlowCallback(), rpmShaftPositionCallback(), and updateTunerStudioState().

Here is the caller graph for this function:

◆ movePreSynchTimestamps()

void InstantRpmCalculator::movePreSynchTimestamps ( )

Definition at line 27 of file instant_rpm_calculator.cpp.

27  {
28  // here we take timestamps of events which happened prior to synchronization and place them
29  // at appropriate locations
30  auto triggerSize = getTriggerCentral()->triggerShape.getLength();
31 
32  size_t eventsToCopy = minI(spinningEventIndex, triggerSize);
33 
34  size_t firstSrc;
35  size_t firstDst;
36 
37  if (eventsToCopy >= triggerSize) {
38  // Only copy one trigger length worth of events, filling the whole buffer
39  firstSrc = spinningEventIndex - triggerSize;
40  firstDst = 0;
41  } else {
42  // There is less than one full cycle, copy to the end of the buffer
43  firstSrc = 0;
44  firstDst = triggerSize - spinningEventIndex;
45  }
46 
47  memcpy(timeOfLastEvent + firstDst, spinningEvents + firstSrc, eventsToCopy * sizeof(timeOfLastEvent[0]));
48 }
TriggerWaveform triggerShape
size_t getLength() const
TriggerCentral * getTriggerCentral()
Definition: engine.cpp:589

Referenced by rpmShaftPositionCallback().

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

◆ resetInstantRpm()

void InstantRpmCalculator::resetInstantRpm ( )
inline

Definition at line 29 of file instant_rpm_calculator.h.

29  {
30  memset(timeOfLastEvent, 0, sizeof(timeOfLastEvent));
31  memset(spinningEvents, 0, sizeof(spinningEvents));
34  m_instantRpm = 0;
35  }

Referenced by PrimaryTriggerDecoder::onTriggerError(), Engine::OnTriggerSynchronizationLost(), and TriggerCentral::syncAndReport().

Here is the caller graph for this function:

◆ setLastEventTimeForInstantRpm()

void InstantRpmCalculator::setLastEventTimeForInstantRpm ( efitick_t  nowNt)

Update timeOfLastEvent[] on every trigger event - even without synchronization Needed for early spin-up RPM detection.

Definition at line 109 of file instant_rpm_calculator.cpp.

109  {
110  // here we remember tooth timestamps which happen prior to synchronization
112  // too many events while trying to find synchronization point
113  // todo: better implementation would be to shift here or use cyclic buffer so that we keep last
114  // 'PRE_SYNC_EVENTS' events
115  return;
116  }
117 
118  uint32_t nowNt32 = nowNt;
120 
121  // If we are using only rising edges, we never write in to the odd-index slots that
122  // would be used by falling edges
123  // TODO: don't reach across to trigger central to get this info
125 }
composite packet size

Referenced by RpmCalculator::setSpinningUp().

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

◆ updateInstantRpm()

void InstantRpmCalculator::updateInstantRpm ( uint32_t  current_index,
TriggerWaveform const &  triggerShape,
TriggerFormDetails triggerFormDetails,
uint32_t  index,
efitick_t  nowNt 
)

Definition at line 127 of file instant_rpm_calculator.cpp.

130  {
131 
132  m_instantRpm = calculateInstantRpm(triggerShape, triggerFormDetails, index,
133  nowNt);
134 #if EFI_UNIT_TEST
135  if (printTriggerDebug) {
136  printf("instantRpm = %f\n", m_instantRpm);
137  }
138 #endif
139 
140 #if EFI_SENSOR_CHART
141  if (getEngineState()->sensorChartMode == SC_RPM_ACCEL || getEngineState()->sensorChartMode == SC_DETAILED_RPM) {
142  angle_t currentAngle = triggerFormDetails->eventAngles[current_index];
143  if (engineConfiguration->sensorChartMode == SC_DETAILED_RPM) {
144  scAddData(currentAngle, m_instantRpm);
145  } else {
146  scAddData(currentAngle, m_instantRpmRatio);
147  }
148  }
149 #endif /* EFI_SENSOR_CHART */
150 }
float calculateInstantRpm(TriggerWaveform const &triggerShape, TriggerFormDetails *triggerFormDetails, uint32_t index, efitick_t nowNt)
EngineState * getEngineState()
Definition: engine.cpp:576
bool printTriggerDebug
engine_configuration_s * engineConfiguration
void scAddData(float angle, float value)
printf("\n")

Referenced by rpmShaftPositionCallback().

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

Field Documentation

◆ instantRpmValue

float InstantRpmCalculator::instantRpmValue[PWM_PHASE_MAX_COUNT]

instant RPM calculated at this trigger wheel tooth

Definition at line 50 of file instant_rpm_calculator.h.

Referenced by calculateInstantRpm().

◆ m_instantRpm

float InstantRpmCalculator::m_instantRpm = 0

Definition at line 57 of file instant_rpm_calculator.h.

Referenced by getInstantRpm(), resetInstantRpm(), and updateInstantRpm().

◆ m_instantRpmRatio

float InstantRpmCalculator::m_instantRpmRatio = 0
private

Definition at line 63 of file instant_rpm_calculator.h.

Referenced by calculateInstantRpm(), and updateInstantRpm().

◆ prevInstantRpmValue

float InstantRpmCalculator::prevInstantRpmValue = 0

Stores last non-zero instant RPM value to fix early instability

Definition at line 54 of file instant_rpm_calculator.h.

Referenced by calculateInstantRpm(), and resetInstantRpm().

◆ spinningEventIndex

size_t InstantRpmCalculator::spinningEventIndex = 0

◆ spinningEvents

uint32_t InstantRpmCalculator::spinningEvents[120]

◆ timeOfLastEvent

uint32_t InstantRpmCalculator::timeOfLastEvent[PWM_PHASE_MAX_COUNT]

timestamp of each trigger wheel tooth

Definition at line 40 of file instant_rpm_calculator.h.

Referenced by calculateInstantRpm(), movePreSynchTimestamps(), and resetInstantRpm().


The documentation for this class was generated from the following files: