rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
gear_detector.cpp
Go to the documentation of this file.
1#include "pch.h"
2#include "gear_detector.h"
3
4static constexpr float geometricMean(float x, float y) {
5 return sqrtf(x * y);
6}
7
12
16
18 // Compute gear thresholds between gears
19
20 uint8_t gearCount = engineConfiguration->totalGearsCount;
21
22 if (gearCount == 0) {
23 // No gears, nothing to do here.
24 return;
25 }
26
27 if (gearCount > TCU_GEAR_COUNT) {
28 criticalError("too many gears");
29 return;
30 }
31
32 // validate gears
33 for (size_t i = 0; i < gearCount; i++) {
34 if (engineConfiguration->gearRatio[i] <= 0) {
35 criticalError("Expecting positive gear ratio for #%d", i + 1);
36 return;
37 }
38 }
39
40 for (int i = 0; i < gearCount - 1; i++) {
41 // Threshold i is the threshold between gears i and i+1
42 float gearI = engineConfiguration->gearRatio[i];
43 float gearIplusOne = engineConfiguration->gearRatio[i + 1];
44
45 if (gearI <= gearIplusOne) {
46 criticalError("Invalid gear ordering near gear #%d", i + 1);
47 }
48
49 m_gearThresholds[i] = geometricMean(gearI, gearIplusOne);
50 }
51
52 Register();
53}
54
58
60 if (!isInitialized) {
62 isInitialized = true;
63 }
64
65 float ratio = computeGearboxRatio();
66 m_gearboxRatio = ratio;
67
69}
70
71size_t GearDetector::determineGearFromRatio(float ratio) const {
72 auto gearCount = engineConfiguration->totalGearsCount;
73 if (gearCount == 0) {
74 // No gears, we only have neutral.
75 return 0;
76 }
77
78 // 1.5x first gear is neutral or clutch slip or something
79 if (ratio > engineConfiguration->gearRatio[0] * 1.5f) {
80 return 0;
81 }
82
83 // 0.66x top gear is coasting with engine off or something
84 if (ratio < engineConfiguration->gearRatio[gearCount - 1] * 0.66f) {
85 return 0;
86 }
87
88 size_t currentGear = gearCount;
89
90 while (currentGear > 1) {
91 if (ratio < m_gearThresholds[currentGear - 2]) {
92 break;
93 }
94
95 currentGear--;
96 }
97
98 return currentGear;
99}
100
103
104 if (vssKph < 3) {
105 // Vehicle too slow to determine gearbox ratio, avoid div/0
106 return 0;
107 }
108
109 // Convert to wheel RPM
110 // km rev 1 hr
111 // ------ * ------------ * __________
112 // hr km 60 min
113 float wheelRpm = vssKph * engineConfiguration->driveWheelRevPerKm * (1 / 60.0f);
114
115 // Convert to driveshaft RPM
116 return wheelRpm * engineConfiguration->finalGearRatio;
117}
118
120 float driveshaftRpm = getDriveshaftRpm();
121
122 if (driveshaftRpm == 0) {
123 return 0;
124 }
125
126 float engineRpm;
129 } else {
131 }
132
133 return engineRpm / driveshaftRpm;
134}
135
136float GearDetector::getRpmInGear(size_t gear) const {
137 if (gear <= 0 || gear > engineConfiguration->totalGearsCount) {
138 return 0;
139 }
140
141 // Ideal engine RPM is driveshaft speed times gear
142 return getDriveshaftRpm() * engineConfiguration->gearRatio[gear - 1];
143}
144
146 return m_gearboxRatio;
147}
148
152
153void GearDetector::showInfo(const char* sensorName) const {
154 efiPrintf("Sensor \"%s\" is gear detector.", sensorName);
155 efiPrintf(" Gearbox ratio: %.3f", m_gearboxRatio);
156 efiPrintf(" Detected gear: %d", m_currentGear);
157}
size_t m_currentGear
SensorResult get() const override
void onConfigurationChange(engine_configuration_s const *) override
float m_gearboxRatio
float computeGearboxRatio() const
size_t determineGearFromRatio(float ratio) const
void onSlowCallback() override
void initGearDetector()
float getRpmInGear(size_t gear) const
void showInfo(const char *sensorName) const override
float getDriveshaftRpm() const
float getGearboxRatio() const
float m_gearThresholds[TCU_GEAR_COUNT - 1]
bool Register()
Definition sensor.cpp:131
virtual bool hasSensor() const
Definition sensor.h:141
static float getOrZero(SensorType type)
Definition sensor.h:83
void unregister()
Definition sensor.cpp:135
static constexpr engine_configuration_s * engineConfiguration
static constexpr float geometricMean(float x, float y)
expected< float > SensorResult
Definition sensor.h:46
SensorType
Definition sensor_type.h:18
scaled_channel< uint16_t, 100, 1 > gearRatio[TCU_GEAR_COUNT]