mirror of https://github.com/rusefi/rusefi.git
Dashpot for return-to-idle from coasting
This commit is contained in:
parent
ad29882308
commit
1a8cacf7c1
|
@ -111,12 +111,28 @@ if (engine->antilagController.isAntilagCondition) {
|
|||
}
|
||||
#endif /* EFI_ANTILAG_SYSTEM */
|
||||
|
||||
// 'dashpot' (hold+decay) logic for coasting->idle
|
||||
float tpsForTaper = tps.value_or(0);
|
||||
efitimeus_t nowUs = getTimeNowUs();
|
||||
if (phase == Phase::Running) {
|
||||
lastTimeRunningUs = nowUs;
|
||||
}
|
||||
// imitate a slow pedal release for TPS taper (to avoid engine stalls)
|
||||
if (tpsForTaper <= engineConfiguration->idlePidDeactivationTpsThreshold) {
|
||||
// make sure the time is not zero
|
||||
float timeSinceRunningPhaseSecs = (float)(nowUs - lastTimeRunningUs + 1) / US_PER_SECOND_F;
|
||||
// we shift the time to implement the hold correction (time can be negative)
|
||||
float timeSinceRunningAfterHoldSecs = timeSinceRunningPhaseSecs - engineConfiguration->iacByTpsHoldTime;
|
||||
// implement the decay correction (from tpsForTaper to 0)
|
||||
tpsForTaper = interpolateClamped(0, engineConfiguration->idlePidDeactivationTpsThreshold, engineConfiguration->iacByTpsDecayTime, tpsForTaper, timeSinceRunningAfterHoldSecs);
|
||||
}
|
||||
|
||||
// Now bump it by the specified amount when the throttle is opened (if configured)
|
||||
// nb: invalid tps will make no change, no explicit check required
|
||||
iacByTpsTaper = interpolateClamped(
|
||||
0, 0,
|
||||
engineConfiguration->idlePidDeactivationTpsThreshold, engineConfiguration->iacByTpsTaper,
|
||||
tps.value_or(0));
|
||||
tpsForTaper);
|
||||
|
||||
running += iacByTpsTaper;
|
||||
|
||||
|
|
|
@ -93,6 +93,8 @@ private:
|
|||
Phase m_lastPhase = Phase::Cranking;
|
||||
int m_lastTargetRpm = 0;
|
||||
efitimeus_t restoreAfterPidResetTimeUs = 0;
|
||||
// used by 'dashpot' (hold+decay) logic for iacByTpsTaper
|
||||
efitimeus_t lastTimeRunningUs = 0;
|
||||
|
||||
// This is stored by getClosedLoop and used in case we want to "do nothing"
|
||||
float m_lastAutomaticPosition = 0;
|
||||
|
|
|
@ -207,6 +207,46 @@ TEST(idle_v2, runningOpenLoopTpsTaper) {
|
|||
EXPECT_FLOAT_EQ(50, dut.getRunningOpenLoop(IIdleController::Phase::Cranking, 0, 0, 20));
|
||||
}
|
||||
|
||||
extern int timeNowUs;
|
||||
|
||||
TEST(idle_v2, runningOpenLoopTpsTaperWithDashpot) {
|
||||
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
||||
IdleController dut;
|
||||
|
||||
// Zero out base tempco table
|
||||
setArrayValues(config->cltIdleCorr, 0.0f);
|
||||
|
||||
// Add 50% idle position
|
||||
engineConfiguration->iacByTpsTaper = 50;
|
||||
// At 10% TPS
|
||||
engineConfiguration->idlePidDeactivationTpsThreshold = 10;
|
||||
|
||||
// set hold and decay time
|
||||
engineConfiguration->iacByTpsHoldTime = 10; // 10 secs
|
||||
engineConfiguration->iacByTpsDecayTime = 10; // 10 secs
|
||||
|
||||
// save the lastTimeRunningUs time - let it be the start of the hold phase
|
||||
timeNowUs += 5'000'000;
|
||||
// full throttle = max.iac
|
||||
EXPECT_FLOAT_EQ(50, dut.getRunningOpenLoop(ICP::Running, 0, 0, 100));
|
||||
|
||||
// jump to the end of the 'hold' phase of dashpot
|
||||
timeNowUs += 10'000'000;
|
||||
|
||||
// change the state to idle (release the pedal) - but still 100% max.iac!
|
||||
EXPECT_FLOAT_EQ(50, dut.getRunningOpenLoop(ICP::Idling, 0, 0, 0));
|
||||
// now we're in the middle of decay
|
||||
timeNowUs += 5'000'000;
|
||||
// 50% decay (50% of 50 is 25)
|
||||
EXPECT_FLOAT_EQ(25, dut.getRunningOpenLoop(ICP::Idling, 0, 0, 0));
|
||||
// now the decay is finished
|
||||
timeNowUs += 5'000'000;
|
||||
// no correction
|
||||
EXPECT_FLOAT_EQ(0, dut.getRunningOpenLoop(ICP::Idling, 0, 0, 0));
|
||||
// still react to the pedal
|
||||
EXPECT_FLOAT_EQ(50, dut.getRunningOpenLoop(ICP::Idling, 0, 0, 10));
|
||||
}
|
||||
|
||||
TEST(idle_v2, runningOpenLoopRpmTaper) {
|
||||
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
||||
IdleController dut;
|
||||
|
@ -251,8 +291,8 @@ TEST(idle_v2, openLoopRunningTaper) {
|
|||
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
||||
StrictMock<MockOpenLoopIdler> dut;
|
||||
|
||||
EXPECT_CALL(dut, getRunningOpenLoop(IIdleController::Phase::CrankToIdleTaper, 0, 30, SensorResult(0))).WillRepeatedly(Return(25));
|
||||
EXPECT_CALL(dut, getRunningOpenLoop(IIdleController::Phase::Running, 0, 30, SensorResult(0))).WillRepeatedly(Return(25));
|
||||
EXPECT_CALL(dut, getRunningOpenLoop(ICP::CrankToIdleTaper, 0, 30, SensorResult(0))).WillRepeatedly(Return(25));
|
||||
EXPECT_CALL(dut, getRunningOpenLoop(ICP::Running, 0, 30, SensorResult(0))).WillRepeatedly(Return(25));
|
||||
EXPECT_CALL(dut, getCrankingOpenLoop(30)).WillRepeatedly(Return(75));
|
||||
|
||||
// 0 cycles - no taper yet, pure cranking value
|
||||
|
|
Loading…
Reference in New Issue