[DRAFT] Fix cranking->idling taper phase for useSeparate*ForIdle tables (#3168)
* Rename Phase::CrankToRunTaper -> CrankToIdleTaper * Change isIdling() to isIdlingOrTaper() * test_idle_controller.cpp * useSeparateIdleTablesForCrankingTaper setting Co-authored-by: Andrei <andreikagit@users.noreply.github.com>
This commit is contained in:
parent
a8f0187b5a
commit
d917cc8cc2
|
@ -187,7 +187,7 @@ IIdleController::Phase IdleController::determinePhase(int rpm, int targetRpm, Se
|
||||||
|
|
||||||
// If still in the cranking taper, disable closed loop idle
|
// If still in the cranking taper, disable closed loop idle
|
||||||
if (crankingTaperFraction < 1) {
|
if (crankingTaperFraction < 1) {
|
||||||
return Phase::CrankToRunTaper;
|
return Phase::CrankToIdleTaper;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No other conditions met, we are idling!
|
// No other conditions met, we are idling!
|
||||||
|
@ -506,8 +506,8 @@ float getIdleTimingAdjustment(int rpm) {
|
||||||
return idleControllerInstance.getIdleTimingAdjustment(rpm);
|
return idleControllerInstance.getIdleTimingAdjustment(rpm);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isIdling() {
|
bool isIdlingOrTaper() {
|
||||||
return idleControllerInstance.isIdling();
|
return idleControllerInstance.isIdlingOrTaper();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void applyPidSettings(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
static void applyPidSettings(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct IIdleController {
|
||||||
Cranking, // Below cranking threshold
|
Cranking, // Below cranking threshold
|
||||||
Idling, // Below idle RPM, off throttle
|
Idling, // Below idle RPM, off throttle
|
||||||
Coasting, // Off throttle but above idle RPM
|
Coasting, // Off throttle but above idle RPM
|
||||||
CrankToRunTaper, // Taper between cranking and running
|
CrankToIdleTaper, // Taper between cranking and idling
|
||||||
Running, // On throttle
|
Running, // On throttle
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,8 +59,8 @@ public:
|
||||||
float getClosedLoop(IIdleController::Phase phase, float tpsPos, int rpm, int targetRpm) override;
|
float getClosedLoop(IIdleController::Phase phase, float tpsPos, int rpm, int targetRpm) override;
|
||||||
|
|
||||||
// Allow querying state from outside
|
// Allow querying state from outside
|
||||||
bool isIdling() {
|
bool isIdlingOrTaper() {
|
||||||
return m_lastPhase == Phase::Idling;
|
return m_lastPhase == Phase::Idling || (CONFIG(useSeparateIdleTablesForCrankingTaper) && m_lastPhase == Phase::CrankToIdleTaper);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -79,7 +79,7 @@ percent_t getIdlePosition();
|
||||||
|
|
||||||
float getIdleTimingAdjustment(int rpm);
|
float getIdleTimingAdjustment(int rpm);
|
||||||
|
|
||||||
bool isIdling();
|
bool isIdlingOrTaper();
|
||||||
|
|
||||||
void applyIACposition(percent_t position DECLARE_ENGINE_PARAMETER_SUFFIX);
|
void applyIACposition(percent_t position DECLARE_ENGINE_PARAMETER_SUFFIX);
|
||||||
void setManualIdleValvePosition(int positionPercent);
|
void setManualIdleValvePosition(int positionPercent);
|
||||||
|
|
|
@ -50,7 +50,7 @@ static angle_t getRunningAdvance(int rpm, float engineLoad DECLARE_ENGINE_PARAME
|
||||||
float advanceAngle = advanceMap.getValue((float) rpm, engineLoad);
|
float advanceAngle = advanceMap.getValue((float) rpm, engineLoad);
|
||||||
|
|
||||||
// get advance from the separate table for Idle
|
// get advance from the separate table for Idle
|
||||||
if (CONFIG(useSeparateAdvanceForIdle) && isIdling()) {
|
if (CONFIG(useSeparateAdvanceForIdle) && isIdlingOrTaper()) {
|
||||||
float idleAdvance = interpolate2d(rpm, config->idleAdvanceBins, config->idleAdvance);
|
float idleAdvance = interpolate2d(rpm, config->idleAdvanceBins, config->idleAdvance);
|
||||||
|
|
||||||
auto [valid, tps] = Sensor::get(SensorType::DriverThrottleIntent);
|
auto [valid, tps] = Sensor::get(SensorType::DriverThrottleIntent);
|
||||||
|
|
|
@ -24,7 +24,7 @@ float AirmassVeModelBase::getVe(int rpm, float load) const {
|
||||||
|
|
||||||
auto tps = Sensor::get(SensorType::Tps1);
|
auto tps = Sensor::get(SensorType::Tps1);
|
||||||
// get VE from the separate table for Idle if idling
|
// get VE from the separate table for Idle if idling
|
||||||
if (isIdling() && tps && CONFIG(useSeparateVeForIdle)) {
|
if (isIdlingOrTaper() && tps && CONFIG(useSeparateVeForIdle)) {
|
||||||
float idleVe = interpolate2d(rpm, config->idleVeBins, config->idleVe);
|
float idleVe = interpolate2d(rpm, config->idleVeBins, config->idleVe);
|
||||||
// interpolate between idle table and normal (running) table using TPS threshold
|
// interpolate between idle table and normal (running) table using TPS threshold
|
||||||
ve = interpolateClamped(0.0f, idleVe, CONFIG(idlePidDeactivationTpsThreshold), ve, tps.Value);
|
ve = interpolateClamped(0.0f, idleVe, CONFIG(idlePidDeactivationTpsThreshold), ve, tps.Value);
|
||||||
|
|
|
@ -587,7 +587,7 @@ bit cj125isUrDivided;+Is your UR CJ125 output wired to MCU via resistor divider?
|
||||||
bit useCicPidForIdle;+Switch between Industrial and Cic PID implementation
|
bit useCicPidForIdle;+Switch between Industrial and Cic PID implementation
|
||||||
bit useTLE8888_cranking_hack;
|
bit useTLE8888_cranking_hack;
|
||||||
bit useInstantRpmForIdle;
|
bit useInstantRpmForIdle;
|
||||||
bit unused76b19;
|
bit useSeparateIdleTablesForCrankingTaper;+This uses separate ignition timing and VE tables not only for idle conditions, also during the postcranking-to-idle taper transition (See also afterCrankingIACtaperDuration).
|
||||||
bit launchControlEnabled;
|
bit launchControlEnabled;
|
||||||
bit rollingLaunchEnabled;
|
bit rollingLaunchEnabled;
|
||||||
bit antiLagEnabled;
|
bit antiLagEnabled;
|
||||||
|
|
|
@ -2708,6 +2708,7 @@ cmd_set_engine_type_default = "@@TS_IO_TEST_COMMAND_char@@\x00\x31\x00\x00"
|
||||||
dialog = idleExtra, "Extra Idle Features"
|
dialog = idleExtra, "Extra Idle Features"
|
||||||
field = "Use idle ignition table", useSeparateAdvanceForIdle
|
field = "Use idle ignition table", useSeparateAdvanceForIdle
|
||||||
field = "Use idle VE table", useSeparateVeForIdle
|
field = "Use idle VE table", useSeparateVeForIdle
|
||||||
|
field = "Use idle tables for cranking taper", useSeparateIdleTablesForCrankingTaper
|
||||||
field = "Use coasting idle table", useIacTableForCoasting, {idleMode == 0}
|
field = "Use coasting idle table", useIacTableForCoasting, {idleMode == 0}
|
||||||
field = useInstantRpmForIdle, useInstantRpmForIdle
|
field = useInstantRpmForIdle, useInstantRpmForIdle
|
||||||
field = "Detailed status in console", isVerboseIAC
|
field = "Detailed status in console", isVerboseIAC
|
||||||
|
|
|
@ -98,7 +98,7 @@ TEST(idle_v2, testDeterminePhase) {
|
||||||
EXPECT_EQ(ICP::Running, dut.determinePhase(1000, 1000, 0, 25, 10));
|
EXPECT_EQ(ICP::Running, dut.determinePhase(1000, 1000, 0, 25, 10));
|
||||||
|
|
||||||
// Check that shortly after cranking, the cranking taper inhibits closed loop idle
|
// Check that shortly after cranking, the cranking taper inhibits closed loop idle
|
||||||
EXPECT_EQ(ICP::CrankToRunTaper, dut.determinePhase(1000, 1000, 0, 0, 0.5f));
|
EXPECT_EQ(ICP::CrankToIdleTaper, dut.determinePhase(1000, 1000, 0, 0, 0.5f));
|
||||||
|
|
||||||
// Above TPS threshold should be outside the zone
|
// Above TPS threshold should be outside the zone
|
||||||
EXPECT_EQ(ICP::Running, dut.determinePhase(1000, 1000, 10, 0, 10));
|
EXPECT_EQ(ICP::Running, dut.determinePhase(1000, 1000, 10, 0, 10));
|
||||||
|
@ -246,19 +246,19 @@ TEST(idle_v2, openLoopRunningTaper) {
|
||||||
|
|
||||||
// 0 cycles - no taper yet, pure cranking value
|
// 0 cycles - no taper yet, pure cranking value
|
||||||
EXPECT_FLOAT_EQ(75, dut.getOpenLoop(ICP::Running, 30, 0, 0));
|
EXPECT_FLOAT_EQ(75, dut.getOpenLoop(ICP::Running, 30, 0, 0));
|
||||||
EXPECT_FLOAT_EQ(75, dut.getOpenLoop(ICP::CrankToRunTaper, 30, 0, 0));
|
EXPECT_FLOAT_EQ(75, dut.getOpenLoop(ICP::CrankToIdleTaper, 30, 0, 0));
|
||||||
|
|
||||||
// 1/2 taper - half way, 50% each value -> outputs 50
|
// 1/2 taper - half way, 50% each value -> outputs 50
|
||||||
EXPECT_FLOAT_EQ(50, dut.getOpenLoop(ICP::Running, 30, 0, 0.5f));
|
EXPECT_FLOAT_EQ(50, dut.getOpenLoop(ICP::Running, 30, 0, 0.5f));
|
||||||
EXPECT_FLOAT_EQ(50, dut.getOpenLoop(ICP::CrankToRunTaper, 30, 0, 0.5f));
|
EXPECT_FLOAT_EQ(50, dut.getOpenLoop(ICP::CrankToIdleTaper, 30, 0, 0.5f));
|
||||||
|
|
||||||
// 1x taper - fully tapered, should be running value
|
// 1x taper - fully tapered, should be running value
|
||||||
EXPECT_FLOAT_EQ(25, dut.getOpenLoop(ICP::Running, 30, 0, 1.0f));
|
EXPECT_FLOAT_EQ(25, dut.getOpenLoop(ICP::Running, 30, 0, 1.0f));
|
||||||
EXPECT_FLOAT_EQ(25, dut.getOpenLoop(ICP::CrankToRunTaper, 30, 0, 1.0f));
|
EXPECT_FLOAT_EQ(25, dut.getOpenLoop(ICP::CrankToIdleTaper, 30, 0, 1.0f));
|
||||||
|
|
||||||
// 2x taper - still fully tapered, should be running value
|
// 2x taper - still fully tapered, should be running value
|
||||||
EXPECT_FLOAT_EQ(25, dut.getOpenLoop(ICP::Running, 30, 0, 2.0f));
|
EXPECT_FLOAT_EQ(25, dut.getOpenLoop(ICP::Running, 30, 0, 2.0f));
|
||||||
EXPECT_FLOAT_EQ(25, dut.getOpenLoop(ICP::CrankToRunTaper, 30, 0, 2.0f));
|
EXPECT_FLOAT_EQ(25, dut.getOpenLoop(ICP::CrankToIdleTaper, 30, 0, 2.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(idle_v2, getCrankingTaperFraction) {
|
TEST(idle_v2, getCrankingTaperFraction) {
|
||||||
|
|
Loading…
Reference in New Issue