Gear detection implementation (#4052)
* gear detect improvements * ui * ui for gear ratios * ui * output channel * output channels etc * implement gear detection * name * s * status loop * missing function * ui tweaking * s
This commit is contained in:
parent
c32742db0f
commit
88ff526764
|
@ -324,7 +324,7 @@ uint16_t rpmAcceleration;dRPM;"RPM/s",1, 0, 0, 0, 0
|
||||||
uint16_t autoscale fallbackMap;;"kPa", 0.1, 0, 0, 1000, 1
|
uint16_t autoscale fallbackMap;;"kPa", 0.1, 0, 0, 1000, 1
|
||||||
|
|
||||||
int8_t autoscale boostControllerClosedLoopPart;@@GAUGE_NAME_BOOST_CLOSED_LOOP@@;"%", 0.5, 0, -50, 50, 1
|
int8_t autoscale boostControllerClosedLoopPart;@@GAUGE_NAME_BOOST_CLOSED_LOOP@@;"%", 0.5, 0, -50, 50, 1
|
||||||
uint8_t unused503;;"", 1, 0, 0, 0, 0
|
uint8_t detectedGear;@@GAUGE_NAME_DETECTED_GEAR@@;"", 1, 0, 0, @@GEARS_COUNT@@, 0
|
||||||
|
|
||||||
int16_t autoscale timingCltCorrection;;"deg",{1/@@PACK_MULT_PERCENT@@}, 0, -20, 20, 2
|
int16_t autoscale timingCltCorrection;;"deg",{1/@@PACK_MULT_PERCENT@@}, 0, -20, 20, 2
|
||||||
int16_t autoscale timingIatCorrection;;"deg",{1/@@PACK_MULT_PERCENT@@}, 0, -20, 20, 2
|
int16_t autoscale timingIatCorrection;;"deg",{1/@@PACK_MULT_PERCENT@@}, 0, -20, 20, 2
|
||||||
|
|
|
@ -546,10 +546,11 @@ static void updateVvtSensors() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateVehicleSpeed(int rpm) {
|
static void updateVehicleSpeed() {
|
||||||
#if EFI_VEHICLE_SPEED
|
#if EFI_VEHICLE_SPEED
|
||||||
engine->outputChannels.vehicleSpeedKph = Sensor::getOrZero(SensorType::VehicleSpeed);
|
engine->outputChannels.vehicleSpeedKph = Sensor::getOrZero(SensorType::VehicleSpeed);
|
||||||
engine->outputChannels.speedToRpmRatio = engine->module<GearDetector>()->getGearboxRatio();
|
engine->outputChannels.speedToRpmRatio = engine->module<GearDetector>()->getGearboxRatio();
|
||||||
|
engine->outputChannels.detectedGear = engine->module<GearDetector>()->getCurrentGear();
|
||||||
#endif /* EFI_VEHICLE_SPEED */
|
#endif /* EFI_VEHICLE_SPEED */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,14 +595,14 @@ static void updateMiscSensors() {
|
||||||
engine->outputChannels.tCharge = engine->engineState.sd.tCharge;
|
engine->outputChannels.tCharge = engine->engineState.sd.tCharge;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateSensors(int rpm) {
|
static void updateSensors() {
|
||||||
updateTempSensors();
|
updateTempSensors();
|
||||||
updateThrottles();
|
updateThrottles();
|
||||||
updateRawSensors();
|
updateRawSensors();
|
||||||
updateLambda();
|
updateLambda();
|
||||||
updateFuelSensors();
|
updateFuelSensors();
|
||||||
updateVvtSensors();
|
updateVvtSensors();
|
||||||
updateVehicleSpeed(rpm);
|
updateVehicleSpeed();
|
||||||
updatePressures();
|
updatePressures();
|
||||||
updateMiscSensors();
|
updateMiscSensors();
|
||||||
}
|
}
|
||||||
|
@ -724,7 +725,7 @@ void updateTunerStudioState() {
|
||||||
auto instantRpm = engine->triggerCentral.triggerState.getInstantRpm();
|
auto instantRpm = engine->triggerCentral.triggerState.getInstantRpm();
|
||||||
tsOutputChannels->instantRpm = instantRpm;
|
tsOutputChannels->instantRpm = instantRpm;
|
||||||
|
|
||||||
updateSensors(rpm);
|
updateSensors();
|
||||||
updateFuelInfo();
|
updateFuelInfo();
|
||||||
updateIgnition(rpm);
|
updateIgnition(rpm);
|
||||||
updateFlags();
|
updateFlags();
|
||||||
|
|
|
@ -1,9 +1,55 @@
|
||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
void GearDetector::onSlowCallback() {
|
static constexpr float geometricMean(float x, float y) {
|
||||||
m_gearboxRatio = computeGearboxRatio();
|
return sqrtf(x * y);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: solve for which gear this is
|
void GearDetector::onConfigurationChange(engine_configuration_s const * /*previousConfig*/) {
|
||||||
|
// Compute gear thresholds between gears
|
||||||
|
|
||||||
|
for (size_t i = 0; i < efi::size(m_gearThresholds); i++) {
|
||||||
|
// Threshold i is the threshold between gears i and i+1
|
||||||
|
|
||||||
|
m_gearThresholds[i] = geometricMean(
|
||||||
|
engineConfiguration->gearRatio[i],
|
||||||
|
engineConfiguration->gearRatio[i + 1]
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: validate gears are in correct order
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GearDetector::onSlowCallback() {
|
||||||
|
float ratio = computeGearboxRatio();
|
||||||
|
m_gearboxRatio = ratio;
|
||||||
|
|
||||||
|
m_currentGear = determineGearFromRatio(ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GearDetector::determineGearFromRatio(float ratio) const {
|
||||||
|
// 1.5x first gear is neutral or clutch slip or something
|
||||||
|
if (ratio > engineConfiguration->gearRatio[0] * 1.5f) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto gearCount = engineConfiguration->totalGearsCount;
|
||||||
|
|
||||||
|
// 0.66x top gear is coasting with engine off or something
|
||||||
|
if (ratio < engineConfiguration->gearRatio[gearCount - 1] * 0.66f) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t currentGear = gearCount;
|
||||||
|
|
||||||
|
while (currentGear > 1) {
|
||||||
|
if (ratio < m_gearThresholds[currentGear - 2]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentGear--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentGear;
|
||||||
}
|
}
|
||||||
|
|
||||||
float GearDetector::computeGearboxRatio() const {
|
float GearDetector::computeGearboxRatio() const {
|
||||||
|
@ -31,3 +77,7 @@ float GearDetector::computeGearboxRatio() const {
|
||||||
float GearDetector::getGearboxRatio() const {
|
float GearDetector::getGearboxRatio() const {
|
||||||
return m_gearboxRatio;
|
return m_gearboxRatio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t GearDetector::getCurrentGear() const {
|
||||||
|
return m_currentGear;
|
||||||
|
}
|
||||||
|
|
|
@ -2,11 +2,20 @@
|
||||||
class GearDetector : public EngineModule {
|
class GearDetector : public EngineModule {
|
||||||
public:
|
public:
|
||||||
void onSlowCallback() override;
|
void onSlowCallback() override;
|
||||||
|
void onConfigurationChange(engine_configuration_s const * /*previousConfig*/) override;
|
||||||
|
|
||||||
float getGearboxRatio() const;
|
float getGearboxRatio() const;
|
||||||
|
|
||||||
|
// Returns 0 for neutral, 1 for 1st, 5 for 5th, etc.
|
||||||
|
size_t getCurrentGear() const;
|
||||||
|
|
||||||
|
size_t determineGearFromRatio(float ratio) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float computeGearboxRatio() const;
|
float computeGearboxRatio() const;
|
||||||
|
|
||||||
float m_gearboxRatio = 0;
|
float m_gearboxRatio = 0;
|
||||||
|
size_t m_currentGear = 0;
|
||||||
|
|
||||||
|
float m_gearThresholds[GEARS_COUNT - 1];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1695,6 +1695,7 @@ end_struct
|
||||||
#define GAUGE_NAME_TIMING_ADVANCE "timing"
|
#define GAUGE_NAME_TIMING_ADVANCE "timing"
|
||||||
#define GAUGE_NAME_VVS "Vehicle Speed"
|
#define GAUGE_NAME_VVS "Vehicle Speed"
|
||||||
#define GAUGE_NAME_GEAR_RATIO "Gearbox Ratio"
|
#define GAUGE_NAME_GEAR_RATIO "Gearbox Ratio"
|
||||||
|
#define GAUGE_NAME_DETECTED_GEAR "Detected Gear"
|
||||||
#define GAUGE_NAME_TURBO_SPEED "Turbocharger Speed"
|
#define GAUGE_NAME_TURBO_SPEED "Turbocharger Speed"
|
||||||
#define GAUGE_NAME_VBAT "VBatt"
|
#define GAUGE_NAME_VBAT "VBatt"
|
||||||
#define GAUGE_NAME_TIME "Time"
|
#define GAUGE_NAME_TIME "Time"
|
||||||
|
|
|
@ -1037,7 +1037,6 @@ gaugeCategory = Sensors - Extra 2
|
||||||
knockLevelGauge = knockLevel,"Knock level", "V", 0, 7, 10, 10, 100, 100, 1, 2
|
knockLevelGauge = knockLevel,"Knock level", "V", 0, 7, 10, 10, 100, 100, 1, 2
|
||||||
knockCountGauge = knockCount, "Knock count", "count", 0, 10000, 0, 0, 10000, 10000, 0, 0
|
knockCountGauge = knockCount, "Knock count", "count", 0, 10000, 0, 0, 10000, 10000, 0, 0
|
||||||
fuelTankLevelGauge = fuelTankLevel,"Fuel level", "%", 0, 100, 10, 20, 100, 100, 1, 1
|
fuelTankLevelGauge = fuelTankLevel,"Fuel level", "%", 0, 100, 10, 20, 100, 100, 1, 1
|
||||||
speedToRpmRatioGauge = speedToRpmRatio, @@GAUGE_NAME_GEAR_RATIO@@, "", 0, 100, 0, 0, 100, 100, 4, 4
|
|
||||||
wastegatePosGauge = wastegatePositionSensor, @@GAUGE_NAME_WG_POSITION@@, "%", 0, 100, 0, 0, 100, 100, 1, 1
|
wastegatePosGauge = wastegatePositionSensor, @@GAUGE_NAME_WG_POSITION@@, "%", 0, 100, 0, 0, 100, 100, 1, 1
|
||||||
idlePosSensGauge = idlePositionSensor, @@GAUGE_NAME_IDLE_POSITION@@, "%", 0, 100, 0, 0, 100, 100, 1, 1
|
idlePosSensGauge = idlePositionSensor, @@GAUGE_NAME_IDLE_POSITION@@, "%", 0, 100, 0, 0, 100, 100, 1, 1
|
||||||
currentEnginePhaseGauge = currentEnginePhase, "Engine Phase", "deg", 0, 720, 0, 0, 720, 720, 0, 0
|
currentEnginePhaseGauge = currentEnginePhase, "Engine Phase", "deg", 0, 720, 0, 0, 720, 720, 0, 0
|
||||||
|
@ -1184,6 +1183,8 @@ gaugeCategory = Sensors - Raw
|
||||||
gaugeCategory = Transmission
|
gaugeCategory = Transmission
|
||||||
desiredGearGauge = tcuDesiredGear, @@GAUGE_NAME_DESIRED_GEAR@@, "gear", -1, 10, -1, -1, 10, 10, 0, 0
|
desiredGearGauge = tcuDesiredGear, @@GAUGE_NAME_DESIRED_GEAR@@, "gear", -1, 10, -1, -1, 10, 10, 0, 0
|
||||||
currentGearGauge = tcuCurrentGear, @@GAUGE_NAME_CURRENT_GEAR@@, "gear", -1, 10, -1, -1, 10, 10, 0, 0
|
currentGearGauge = tcuCurrentGear, @@GAUGE_NAME_CURRENT_GEAR@@, "gear", -1, 10, -1, -1, 10, 10, 0, 0
|
||||||
|
detectedGearGauge = detectedGear, @@GAUGE_NAME_DETECTED_GEAR@@, "gear", 0, @@GEARS_COUNT@@, 0, 0, @@GEARS_COUNT@@, @@GEARS_COUNT@@, 0, 0
|
||||||
|
speedToRpmRatioGauge = speedToRpmRatio, @@GAUGE_NAME_GEAR_RATIO@@, "", 0, 100, 0, 0, 100, 100, 4, 4
|
||||||
|
|
||||||
gaugeCategory = Knock
|
gaugeCategory = Knock
|
||||||
knock1Gauge = knock1, "Knock Cyl 1", "dBv", -60, 10, -60, -60, 10, 10, 0, 0
|
knock1Gauge = knock1, "Knock Cyl 1", "dBv", -60, 10, -60, -60, 10, 10, 0, 0
|
||||||
|
@ -1466,10 +1467,10 @@ menuDialog = main
|
||||||
subMenu = gearDetection, "Gear detection", 0
|
subMenu = gearDetection, "Gear detection", 0
|
||||||
|
|
||||||
subMenu = std_separator
|
subMenu = std_separator
|
||||||
subMenu = boostDialog, "Boost Control"
|
subMenu = boostDialog, "Boost control"
|
||||||
subMenu = boostOpenLoopDialog, "Boost Control Open Loop", { isBoostControlEnabled && boostType == 0 }
|
subMenu = boostOpenLoopDialog, "Boost control open loop", { isBoostControlEnabled }
|
||||||
subMenu = boostPidDialog, "Boost Control Closed Loop PID", { isBoostControlEnabled && boostType == 1 }
|
subMenu = boostPidDialog, "Boost control PID", { isBoostControlEnabled && boostType == 1 }
|
||||||
subMenu = boostTargetDialog, "Boost Control Closed Loop Target", { isBoostControlEnabled && boostType == 1 }
|
subMenu = boostTargetDialog, "Boost control target", { isBoostControlEnabled && boostType == 1 }
|
||||||
subMenu = boostEtbPid, "ETB-style Wastegate Actuator", { etbFunctions1 == @@etb_function_e_ETB_Wastegate@@ || etbFunctions2 == @@etb_function_e_ETB_Wastegate@@ }
|
subMenu = boostEtbPid, "ETB-style Wastegate Actuator", { etbFunctions1 == @@etb_function_e_ETB_Wastegate@@ || etbFunctions2 == @@etb_function_e_ETB_Wastegate@@ }
|
||||||
|
|
||||||
subMenu = std_separator
|
subMenu = std_separator
|
||||||
|
@ -3122,7 +3123,6 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00"
|
||||||
dialog = speedSensorLeft, "", yAxis
|
dialog = speedSensorLeft, "", yAxis
|
||||||
panel = speedSensorAnalog, { enableCanVss == 0 }
|
panel = speedSensorAnalog, { enableCanVss == 0 }
|
||||||
panel = speedSensorCan
|
panel = speedSensorCan
|
||||||
panel = vssFilter
|
|
||||||
|
|
||||||
dialog = gearDetection, "Gear Detection"
|
dialog = gearDetection, "Gear Detection"
|
||||||
field = "Wheel revolutions per kilometer", driveWheelRevPerKm
|
field = "Wheel revolutions per kilometer", driveWheelRevPerKm
|
||||||
|
|
|
@ -26,3 +26,110 @@ TEST(GearDetector, ComputeGearRatio) {
|
||||||
// Idling, car stopped, check no div/0
|
// Idling, car stopped, check no div/0
|
||||||
EXPECT_EQ(0, GetGearRatioFor(507, 4.1, 0, 800));
|
EXPECT_EQ(0, GetGearRatioFor(507, 4.1, 0, 800));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(GearDetector, DetermineGearSingleSpeed) {
|
||||||
|
EngineTestHelper eth(TEST_ENGINE);
|
||||||
|
GearDetector dut;
|
||||||
|
|
||||||
|
engineConfiguration->totalGearsCount = 1;
|
||||||
|
engineConfiguration->gearRatio[0] = 2;
|
||||||
|
|
||||||
|
dut.onConfigurationChange(nullptr);
|
||||||
|
|
||||||
|
// Super high ratios indicate clutch slip or idling in neutral or something
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(100));
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(4));
|
||||||
|
|
||||||
|
// Check exactly on the gear
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(2));
|
||||||
|
|
||||||
|
// Check near the gear
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(2.1));
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(1.9));
|
||||||
|
|
||||||
|
// Extremely low ratio suggests stopped engine at speed?
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GearDetector, DetermineGear5Speed) {
|
||||||
|
EngineTestHelper eth(TEST_ENGINE);
|
||||||
|
GearDetector dut;
|
||||||
|
|
||||||
|
engineConfiguration->totalGearsCount = 5;
|
||||||
|
engineConfiguration->gearRatio[0] = 3.35;
|
||||||
|
engineConfiguration->gearRatio[1] = 1.99;
|
||||||
|
engineConfiguration->gearRatio[2] = 1.33;
|
||||||
|
engineConfiguration->gearRatio[3] = 1.00;
|
||||||
|
engineConfiguration->gearRatio[4] = 0.72;
|
||||||
|
|
||||||
|
dut.onConfigurationChange(nullptr);
|
||||||
|
|
||||||
|
// Super high ratios indicate clutch slip or idling in neutral or something
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(100));
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(6));
|
||||||
|
|
||||||
|
// Check exactly on gears
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(3.35));
|
||||||
|
EXPECT_EQ(2, dut.determineGearFromRatio(1.99));
|
||||||
|
EXPECT_EQ(3, dut.determineGearFromRatio(1.33));
|
||||||
|
EXPECT_EQ(4, dut.determineGearFromRatio(1.00));
|
||||||
|
EXPECT_EQ(5, dut.determineGearFromRatio(0.72));
|
||||||
|
|
||||||
|
// Check near each gear
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(3.45));
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(3.25));
|
||||||
|
|
||||||
|
EXPECT_EQ(2, dut.determineGearFromRatio(2.2));
|
||||||
|
EXPECT_EQ(2, dut.determineGearFromRatio(1.8));
|
||||||
|
|
||||||
|
EXPECT_EQ(3, dut.determineGearFromRatio(1.45));
|
||||||
|
EXPECT_EQ(3, dut.determineGearFromRatio(1.25));
|
||||||
|
|
||||||
|
EXPECT_EQ(4, dut.determineGearFromRatio(1.1));
|
||||||
|
EXPECT_EQ(4, dut.determineGearFromRatio(0.9));
|
||||||
|
|
||||||
|
EXPECT_EQ(5, dut.determineGearFromRatio(0.8));
|
||||||
|
EXPECT_EQ(5, dut.determineGearFromRatio(0.6));
|
||||||
|
|
||||||
|
// Extremely low ratio suggests stopped engine at speed?
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(0.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(GearDetector, DetermineGear8Speed) {
|
||||||
|
EngineTestHelper eth(TEST_ENGINE);
|
||||||
|
GearDetector dut;
|
||||||
|
|
||||||
|
// ZF 8HP 70
|
||||||
|
engineConfiguration->totalGearsCount = 8;
|
||||||
|
engineConfiguration->gearRatio[0] = 4.69;
|
||||||
|
engineConfiguration->gearRatio[1] = 3.13;
|
||||||
|
engineConfiguration->gearRatio[2] = 2.10;
|
||||||
|
engineConfiguration->gearRatio[3] = 1.67;
|
||||||
|
engineConfiguration->gearRatio[4] = 1.28;
|
||||||
|
engineConfiguration->gearRatio[5] = 1;
|
||||||
|
engineConfiguration->gearRatio[6] = 0.84;
|
||||||
|
engineConfiguration->gearRatio[7] = 0.67;
|
||||||
|
|
||||||
|
dut.onConfigurationChange(nullptr);
|
||||||
|
|
||||||
|
// Super high ratios indicate clutch slip or idling in neutral or something
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(100));
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(8));
|
||||||
|
|
||||||
|
// Check exactly on gears - only test the ends, the middle works
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(4.69));
|
||||||
|
EXPECT_EQ(2, dut.determineGearFromRatio(3.13));
|
||||||
|
|
||||||
|
EXPECT_EQ(7, dut.determineGearFromRatio(0.84));
|
||||||
|
EXPECT_EQ(8, dut.determineGearFromRatio(0.67));
|
||||||
|
|
||||||
|
// Check near each gear - only test the ends, the middle works
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(4.75));
|
||||||
|
EXPECT_EQ(1, dut.determineGearFromRatio(4.3));
|
||||||
|
|
||||||
|
EXPECT_EQ(8, dut.determineGearFromRatio(0.71));
|
||||||
|
EXPECT_EQ(8, dut.determineGearFromRatio(0.6));
|
||||||
|
|
||||||
|
// Extremely low ratio suggests stopped engine at speed?
|
||||||
|
EXPECT_EQ(0, dut.determineGearFromRatio(0.1));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue