parent
b2b05659dc
commit
542cb6a420
|
@ -201,6 +201,31 @@ int IdleController::getTargetRpm(float clt) const {
|
||||||
return fsioBump + interpolate2d("cltRpm", clt, CONFIG(cltIdleRpmBins), CONFIG(cltIdleRpm));
|
return fsioBump + interpolate2d("cltRpm", clt, CONFIG(cltIdleRpmBins), CONFIG(cltIdleRpm));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IIdleController::Phase IdleController::determinePhase(int rpm, int targetRpm, SensorResult tps) const {
|
||||||
|
if (!engine->rpmCalculator.isRunning()) {
|
||||||
|
return Phase::Cranking;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tps) {
|
||||||
|
// If the TPS has failed, assume the engine is running
|
||||||
|
return Phase::Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if throttle pressed, we're out of the idle corner
|
||||||
|
if (tps.Value > CONFIG(idlePidDeactivationTpsThreshold)) {
|
||||||
|
return Phase::Running;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If rpm too high (but throttle not pressed), we're coasting
|
||||||
|
int maximumIdleRpm = targetRpm + CONFIG(idlePidRpmUpperLimit);
|
||||||
|
if (rpm > maximumIdleRpm) {
|
||||||
|
return Phase::Coasting;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No other conditions met, we are idling!
|
||||||
|
return Phase::Idling;
|
||||||
|
}
|
||||||
|
|
||||||
static percent_t manualIdleController(float cltCorrection DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
static percent_t manualIdleController(float cltCorrection DECLARE_ENGINE_PARAMETER_SUFFIX) {
|
||||||
|
|
||||||
percent_t correctedPosition = cltCorrection * CONFIG(manIdlePosition);
|
percent_t correctedPosition = cltCorrection * CONFIG(manIdlePosition);
|
||||||
|
|
|
@ -13,6 +13,14 @@
|
||||||
#include "periodic_task.h"
|
#include "periodic_task.h"
|
||||||
|
|
||||||
struct IIdleController {
|
struct IIdleController {
|
||||||
|
enum class Phase : uint8_t {
|
||||||
|
Cranking, // Below cranking threshold
|
||||||
|
Idling, // Below idle RPM, off throttle
|
||||||
|
Coasting, // Off throttle but above idle RPM
|
||||||
|
Running, // On throttle
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual Phase determinePhase(int rpm, int targetRpm, SensorResult tps) const;
|
||||||
virtual int getTargetRpm(float clt) const = 0;
|
virtual int getTargetRpm(float clt) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,6 +37,9 @@ public:
|
||||||
|
|
||||||
// TARGET DETERMINATION
|
// TARGET DETERMINATION
|
||||||
int getTargetRpm(float clt) const override;
|
int getTargetRpm(float clt) const override;
|
||||||
|
|
||||||
|
// PHASE DETERMINATION: what is the driver trying to do right now?
|
||||||
|
Phase determinePhase(int rpm, int targetRpm, SensorResult tps) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
void updateIdleControl();
|
void updateIdleControl();
|
||||||
|
|
|
@ -144,3 +144,43 @@ TEST(idle_v2, testTargetRpm) {
|
||||||
EXPECT_FLOAT_EQ(100, dut.getTargetRpm(10));
|
EXPECT_FLOAT_EQ(100, dut.getTargetRpm(10));
|
||||||
EXPECT_FLOAT_EQ(500, dut.getTargetRpm(50));
|
EXPECT_FLOAT_EQ(500, dut.getTargetRpm(50));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using ICP = IIdleController::Phase;
|
||||||
|
|
||||||
|
TEST(idle_v2, testDeterminePhase) {
|
||||||
|
WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
|
||||||
|
IdleController dut;
|
||||||
|
INJECT_ENGINE_REFERENCE(&dut);
|
||||||
|
|
||||||
|
// TPS threshold 5% for easy test
|
||||||
|
CONFIG(idlePidDeactivationTpsThreshold) = 5;
|
||||||
|
// RPM window is 100 RPM above target
|
||||||
|
CONFIG(idlePidRpmUpperLimit) = 100;
|
||||||
|
|
||||||
|
// First test stopped engine
|
||||||
|
engine->rpmCalculator.setRpmValue(0);
|
||||||
|
EXPECT_EQ(ICP::Cranking, dut.determinePhase(0, 1000, unexpected));
|
||||||
|
|
||||||
|
// Now engine is running!
|
||||||
|
// Controller doesn't need this other than for isCranking()
|
||||||
|
engine->rpmCalculator.setRpmValue(1000);
|
||||||
|
|
||||||
|
// Test invalid TPS, but inside the idle window
|
||||||
|
EXPECT_EQ(ICP::Running, dut.determinePhase(1000, 1000, unexpected));
|
||||||
|
|
||||||
|
// Valid TPS should now be inside the zone
|
||||||
|
EXPECT_EQ(ICP::Idling, dut.determinePhase(1000, 1000, 0));
|
||||||
|
|
||||||
|
// Above TPS threshold should be outside the zone
|
||||||
|
EXPECT_EQ(ICP::Running, dut.determinePhase(1000, 1000, 10));
|
||||||
|
|
||||||
|
// Above target, below (target + upperLimit) should be in idle zone
|
||||||
|
EXPECT_EQ(ICP::Idling, dut.determinePhase(1099, 1000, 0));
|
||||||
|
|
||||||
|
// above upper limit and on throttle should be out of idle zone
|
||||||
|
EXPECT_EQ(ICP::Running, dut.determinePhase(1101, 1000, 10));
|
||||||
|
|
||||||
|
// Below TPS but above RPM should be outside the zone
|
||||||
|
EXPECT_EQ(ICP::Coasting, dut.determinePhase(1101, 1000, 0));
|
||||||
|
EXPECT_EQ(ICP::Coasting, dut.determinePhase(5000, 1000, 0));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue