Line |
Branch |
Decision |
Exec |
Source |
1 |
|
|
|
/** |
2 |
|
|
|
* @file rpm_calculator.h |
3 |
|
|
|
* @brief Shaft position sensor(s) decoder header |
4 |
|
|
|
* |
5 |
|
|
|
* @date Jan 1, 2013 |
6 |
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020 |
7 |
|
|
|
*/ |
8 |
|
|
|
|
9 |
|
|
|
#pragma once |
10 |
|
|
|
|
11 |
|
|
|
#include "scheduler.h" |
12 |
|
|
|
#include "stored_value_sensor.h" |
13 |
|
|
|
#include <rusefi/timer.h> |
14 |
|
|
|
#include "rpm_calculator_api.h" |
15 |
|
|
|
#include "trigger_decoder.h" |
16 |
|
|
|
|
17 |
|
|
|
#define MAX_ALLOWED_RPM 30000 |
18 |
|
|
|
|
19 |
|
|
|
typedef enum { |
20 |
|
|
|
/** |
21 |
|
|
|
* The engine is not spinning, RPM=0 |
22 |
|
|
|
*/ |
23 |
|
|
|
STOPPED, |
24 |
|
|
|
/** |
25 |
|
|
|
* The engine is spinning up (reliable RPM is not detected yet). |
26 |
|
|
|
* In this state, rpmValue is >= 0 (can be zero). |
27 |
|
|
|
*/ |
28 |
|
|
|
SPINNING_UP, |
29 |
|
|
|
/** |
30 |
|
|
|
* The engine is cranking (0 < RPM < cranking.rpm) |
31 |
|
|
|
*/ |
32 |
|
|
|
CRANKING, |
33 |
|
|
|
/** |
34 |
|
|
|
* The engine is running (RPM >= cranking.rpm) |
35 |
|
|
|
*/ |
36 |
|
|
|
RUNNING, |
37 |
|
|
|
} spinning_state_e; |
38 |
|
|
|
|
39 |
|
|
|
/** |
40 |
|
|
|
* Most consumers should access value via Sensor framework by SensorType::Rpm key |
41 |
|
|
|
*/ |
42 |
|
|
|
class RpmCalculator : public StoredValueSensor, public EngineRotationState { |
43 |
|
|
|
public: |
44 |
|
|
|
RpmCalculator(); |
45 |
|
|
|
|
46 |
|
|
|
operation_mode_e getOperationMode() const override; |
47 |
|
|
|
|
48 |
|
|
|
void onSlowCallback(); |
49 |
|
|
|
|
50 |
|
|
|
/** |
51 |
|
|
|
* Returns true if the engine is not spinning (RPM==0) |
52 |
|
|
|
*/ |
53 |
|
|
|
bool isStopped() const override; |
54 |
|
|
|
/** |
55 |
|
|
|
* Returns true if the engine is spinning up |
56 |
|
|
|
*/ |
57 |
|
|
|
bool isSpinningUp() const; |
58 |
|
|
|
/** |
59 |
|
|
|
* Returns true if the engine is cranking OR spinning up |
60 |
|
|
|
*/ |
61 |
|
|
|
bool isCranking() const override; |
62 |
|
|
|
/** |
63 |
|
|
|
* Returns true if the engine is running and not cranking |
64 |
|
|
|
*/ |
65 |
|
|
|
bool isRunning() const; |
66 |
|
|
|
|
67 |
|
|
|
bool checkIfSpinning(efitick_t nowNt) const; |
68 |
|
|
|
|
69 |
|
|
|
/** |
70 |
|
|
|
* This accessor is used in unit-tests. |
71 |
|
|
|
*/ |
72 |
|
|
|
spinning_state_e getState() const; |
73 |
|
|
|
|
74 |
|
|
|
/** |
75 |
|
|
|
* Should be called on every trigger event when the engine is just starting to spin up. |
76 |
|
|
|
*/ |
77 |
|
|
|
void setSpinningUp(efitick_t nowNt ); |
78 |
|
|
|
/** |
79 |
|
|
|
* Called if the synchronization is lost due to a trigger timeout. |
80 |
|
|
|
*/ |
81 |
|
|
|
void setStopSpinning(); |
82 |
|
|
|
|
83 |
|
|
|
/** |
84 |
|
|
|
* Just a quick getter for rpmValue |
85 |
|
|
|
* Should be same exact value as Sensor::get(SensorType::Rpm).Value just quicker. |
86 |
|
|
|
* Open question if we have any cases where this opimization is needed. |
87 |
|
|
|
*/ |
88 |
|
|
|
float getCachedRpm() const; |
89 |
|
|
|
/** |
90 |
|
|
|
* This method is invoked once per engine cycle right after we calculate new RPM value |
91 |
|
|
|
*/ |
92 |
|
|
|
void onNewEngineCycle(); |
93 |
|
|
|
uint32_t getRevolutionCounterM(void) const; |
94 |
|
|
|
void setRpmValue(float value); |
95 |
|
|
|
/** |
96 |
|
|
|
* The same as setRpmValue() but without state change. |
97 |
|
|
|
* We need this to be public because of calling rpmState->assignRpmValue() from rpmShaftPositionCallback() |
98 |
|
|
|
*/ |
99 |
|
|
|
void assignRpmValue(float value); |
100 |
|
|
|
uint32_t getRevolutionCounterSinceStart(void) const; |
101 |
|
|
|
/** |
102 |
|
|
|
* RPM rate of change between current RPM and RPM measured during previous engine cycle |
103 |
|
|
|
* see also SC_RPM_ACCEL |
104 |
|
|
|
*/ |
105 |
|
|
|
float getRpmAcceleration() const; |
106 |
|
|
|
|
107 |
|
|
|
// Get elapsed time since the engine transitioned to the running state. |
108 |
|
|
|
float getSecondsSinceEngineStart(efitick_t nowNt) const; |
109 |
|
|
|
|
110 |
|
|
|
/** |
111 |
|
|
|
* this is RPM on previous engine cycle. |
112 |
|
|
|
*/ |
113 |
|
|
|
float previousRpmValue = 0; |
114 |
|
|
|
|
115 |
|
|
|
/** |
116 |
|
|
|
* This is a performance optimization: let's pre-calculate this each time RPM changes |
117 |
|
|
|
* NaN while engine is not spinning |
118 |
|
|
|
*/ |
119 |
|
|
|
floatus_t oneDegreeUs = NAN; |
120 |
|
|
|
|
121 |
|
|
3152 |
floatus_t getOneDegreeUs() override { |
122 |
|
|
3152 |
return oneDegreeUs; |
123 |
|
|
|
} |
124 |
|
|
|
|
125 |
|
|
|
Timer lastTdcTimer; |
126 |
|
|
|
|
127 |
|
|
|
// RPM rate of change, in RPM per second |
128 |
|
|
|
float rpmRate = 0; |
129 |
|
|
|
|
130 |
|
|
|
protected: |
131 |
|
|
|
// Print sensor info - current RPM state |
132 |
|
|
|
void showInfo(const char* sensorName) const override; |
133 |
|
|
|
|
134 |
|
|
|
private: |
135 |
|
|
|
/** |
136 |
|
|
|
* At this point this value is same exact value as in private m_value variable |
137 |
|
|
|
* At this point all this is performance optimization? |
138 |
|
|
|
* Open question is when do we need it for performance reasons. |
139 |
|
|
|
*/ |
140 |
|
|
|
float cachedRpmValue = 0; |
141 |
|
|
|
|
142 |
|
|
|
/** |
143 |
|
|
|
* This counter is incremented with each revolution of one of the shafts. Could be |
144 |
|
|
|
* crankshaft could be camshaft. |
145 |
|
|
|
*/ |
146 |
|
|
|
uint32_t revolutionCounterSinceBoot = 0; |
147 |
|
|
|
/** |
148 |
|
|
|
* Same as the above, but since the engine started spinning |
149 |
|
|
|
*/ |
150 |
|
|
|
uint32_t revolutionCounterSinceStart = 0; |
151 |
|
|
|
|
152 |
|
|
|
spinning_state_e state = STOPPED; |
153 |
|
|
|
|
154 |
|
|
|
/** |
155 |
|
|
|
* True if the engine is spinning (regardless of its state), i.e. if shaft position changes. |
156 |
|
|
|
* Needed by spinning-up logic. |
157 |
|
|
|
*/ |
158 |
|
|
|
bool isSpinning = false; |
159 |
|
|
|
|
160 |
|
|
|
Timer engineStartTimer; |
161 |
|
|
|
}; |
162 |
|
|
|
|
163 |
|
|
|
void rpmShaftPositionCallback(trigger_event_e ckpSignalType, uint32_t trgEventIndex, efitick_t edgeTimestamp); |
164 |
|
|
|
|
165 |
|
|
|
void tdcMarkCallback( |
166 |
|
|
|
uint32_t trgEventIndex, efitick_t edgeTimestamp); |
167 |
|
|
|
|
168 |
|
|
|
operation_mode_e lookupOperationMode(); |
169 |
|
|
|
|
170 |
|
|
|
#define getRevolutionCounter() (engine->rpmCalculator.getRevolutionCounterM()) |
171 |
|
|
|
|
172 |
|
|
|
/** |
173 |
|
|
|
* @return tick time of scheduled action |
174 |
|
|
|
*/ |
175 |
|
|
|
efitick_t scheduleByAngle(scheduling_s *timer, efitick_t nowNt, angle_t angle, action_s const& action); |
176 |
|
|
|
|