implement launch spark skip functionality (#6566)
This commit is contained in:
parent
3e4d1db28b
commit
fdc60e4bff
|
@ -87,7 +87,15 @@ void EngineState::updateSlowSensors() {
|
|||
void EngineState::updateSparkSkip() {
|
||||
#if EFI_LAUNCH_CONTROL
|
||||
engine->softSparkLimiter.updateTargetSkipRatio(luaSoftSparkSkip, tractionControlSparkSkip);
|
||||
engine->hardSparkLimiter.updateTargetSkipRatio(luaHardSparkSkip, tractionControlSparkSkip);
|
||||
engine->hardSparkLimiter.updateTargetSkipRatio(
|
||||
luaHardSparkSkip,
|
||||
tractionControlSparkSkip,
|
||||
/*
|
||||
* We are applying launch controller spark skip ratio only for hard skip limiter (see
|
||||
* https://github.com/rusefi/rusefi/issues/6566#issuecomment-2153149902).
|
||||
*/
|
||||
engine->launchController.getSparkSkipRatio()
|
||||
);
|
||||
#endif // EFI_LAUNCH_CONTROL
|
||||
}
|
||||
|
||||
|
|
|
@ -144,6 +144,8 @@ void LaunchControlBase::update() {
|
|||
// If conditions are met...
|
||||
isLaunchCondition = m_launchTimer.hasElapsedSec(engineConfiguration->launchActivateDelay);
|
||||
}
|
||||
|
||||
sparkSkipRatio = calculateSparkSkipRatio(rpm);
|
||||
}
|
||||
|
||||
bool LaunchControlBase::isLaunchRpmRetardCondition() const {
|
||||
|
@ -158,6 +160,25 @@ bool LaunchControlBase::isLaunchFuelRpmRetardCondition() const {
|
|||
return isLaunchRpmRetardCondition() && engineConfiguration->launchFuelCutEnable;
|
||||
}
|
||||
|
||||
float LaunchControlBase::calculateSparkSkipRatio(const int rpm) const {
|
||||
float result = 0.0f;
|
||||
if (engineConfiguration->launchControlEnabled && engineConfiguration->launchSparkCutEnable) {
|
||||
if (isLaunchCondition) {
|
||||
result = 1.0f;
|
||||
} else {
|
||||
const int launchRpm = engineConfiguration->launchRpm;
|
||||
const int sparkSkipStartRpm = launchRpm - engineConfiguration->launchRpmWindow;
|
||||
if (sparkSkipStartRpm <= rpm) {
|
||||
const float initialIgnitionCutRatio = engineConfiguration->initialIgnitionCutPercent / 100.0f;
|
||||
const int sparkSkipEndRpm = launchRpm - engineConfiguration->launchCorrectionsEndRpm;
|
||||
const float finalIgnitionCutRatio = engineConfiguration->finalIgnitionCutPercentBeforeLaunch / 100.0f;
|
||||
result = interpolateClamped(sparkSkipStartRpm, initialIgnitionCutRatio, sparkSkipEndRpm, finalIgnitionCutRatio, rpm);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SoftSparkLimiter::SoftSparkLimiter(const bool p_allowHardCut)
|
||||
: allowHardCut(p_allowHardCut) {
|
||||
#if EFI_UNIT_TEST
|
||||
|
@ -165,7 +186,11 @@ SoftSparkLimiter::SoftSparkLimiter(const bool p_allowHardCut)
|
|||
#endif // EFI_UNIT_TEST
|
||||
}
|
||||
|
||||
void SoftSparkLimiter::updateTargetSkipRatio(const float luaSparkSkip, const float tractionControlSparkSkip) {
|
||||
void SoftSparkLimiter::updateTargetSkipRatio(
|
||||
const float luaSparkSkip,
|
||||
const float tractionControlSparkSkip,
|
||||
const float launchControllerSparkSkipRatio
|
||||
) {
|
||||
targetSkipRatio = luaSparkSkip;
|
||||
if (engineConfiguration->useHardSkipInTraction) {
|
||||
if (allowHardCut) {
|
||||
|
@ -174,6 +199,14 @@ void SoftSparkLimiter::updateTargetSkipRatio(const float luaSparkSkip, const flo
|
|||
} else if (!allowHardCut) {
|
||||
targetSkipRatio += tractionControlSparkSkip;
|
||||
}
|
||||
|
||||
if (allowHardCut) {
|
||||
/*
|
||||
* We are applying launch controller spark skip ratio only for hard skip limiter (see
|
||||
* https://github.com/rusefi/rusefi/issues/6566#issuecomment-2153149902).
|
||||
*/
|
||||
targetSkipRatio += launchControllerSparkSkipRatio;
|
||||
}
|
||||
}
|
||||
|
||||
static tinymt32_t tinymt;
|
||||
|
|
|
@ -35,10 +35,16 @@ public:
|
|||
bool isLaunchSparkRpmRetardCondition() const;
|
||||
bool isLaunchFuelRpmRetardCondition() const;
|
||||
|
||||
float getSparkSkipRatio() const { return sparkSkipRatio; }
|
||||
|
||||
private:
|
||||
bool isLaunchRpmRetardCondition() const;
|
||||
|
||||
float calculateSparkSkipRatio(int rpm) const;
|
||||
|
||||
|
||||
Timer m_launchTimer;
|
||||
float sparkSkipRatio = 0.0f;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -50,7 +56,11 @@ public:
|
|||
/**
|
||||
* targetSkipRatio of '0' means 'do not skip', would always return false
|
||||
*/
|
||||
void updateTargetSkipRatio(float luaSoftSparkSkip, float tractionControlSparkSkip);
|
||||
void updateTargetSkipRatio(
|
||||
float luaSoftSparkSkip,
|
||||
float tractionControlSparkSkip,
|
||||
float launchControllerSparkSkipRatio = 0.0f
|
||||
);
|
||||
[[nodiscard]] float getTargetSkipRatio() const { return targetSkipRatio; }
|
||||
|
||||
bool shouldSkip();
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// Created by kifir on 6/7/24.
|
||||
//
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
constexpr int TEST_LAUNCH_RPM = 3850;
|
||||
constexpr int TEST_LAUNCH_RPM_WINDOW = 1850;
|
||||
constexpr int TEST_LAUNCH_SPARK_SKIP_END_RPM = 850;
|
||||
constexpr int TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_START = TEST_LAUNCH_RPM - TEST_LAUNCH_RPM_WINDOW;
|
||||
constexpr int TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_END = TEST_LAUNCH_RPM - TEST_LAUNCH_SPARK_SKIP_END_RPM;
|
||||
constexpr int TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW = TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_END - TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_START;
|
||||
|
||||
constexpr int TEST_INITIAL_IGNITION_CUT_PERCENT = 13;
|
||||
constexpr float TEST_INITIAL_IGNITION_CUT_RATIO = 0.13f;
|
||||
|
||||
constexpr int TEST_FINAL_IGNITION_CUT_PERCENT = 42;
|
||||
constexpr float TEST_FINAL_IGNITION_CUT_RATIO = 0.42f;
|
||||
|
||||
static void setUpTestParameters(
|
||||
const std::optional<bool> launchControlEnabled,
|
||||
const std::optional<bool> enableIgnitionCut
|
||||
) {
|
||||
if (launchControlEnabled.has_value()) {
|
||||
engineConfiguration->launchControlEnabled = launchControlEnabled.value();
|
||||
} else {
|
||||
ASSERT_FALSE(engineConfiguration->launchControlEnabled); // check default value
|
||||
}
|
||||
if (enableIgnitionCut.has_value()) {
|
||||
engineConfiguration->launchSparkCutEnable = enableIgnitionCut.value();
|
||||
} else {
|
||||
ASSERT_FALSE(engineConfiguration->launchSparkCutEnable); // check default value
|
||||
}
|
||||
engineConfiguration->launchRpm = TEST_LAUNCH_RPM;
|
||||
engineConfiguration->launchRpmWindow = TEST_LAUNCH_RPM_WINDOW;
|
||||
engineConfiguration->launchCorrectionsEndRpm = TEST_LAUNCH_SPARK_SKIP_END_RPM;
|
||||
|
||||
engineConfiguration->initialIgnitionCutPercent = TEST_INITIAL_IGNITION_CUT_PERCENT;
|
||||
engineConfiguration->finalIgnitionCutPercentBeforeLaunch = TEST_FINAL_IGNITION_CUT_PERCENT;
|
||||
|
||||
engineConfiguration->launchActivationMode = ALWAYS_ACTIVE_LAUNCH; // to satisfy activateSwitchCondition
|
||||
engineConfiguration->launchSpeedThreshold = 0; // to satisfy speedCondition
|
||||
Sensor::setMockValue(SensorType::DriverThrottleIntent, 1.7); // to satisfy tpsCondition
|
||||
}
|
||||
|
||||
static void updateRpm(const int rpm, EngineTestHelper& eth) {
|
||||
Sensor::setMockValue(SensorType::Rpm, rpm);
|
||||
for (int i = 0; i < 2; i++) {\
|
||||
/*
|
||||
* We need to repeat the following code twice because method EngineState::periodicFastCallback updates launch
|
||||
* controller after updating spark skip - can we fix it safely?
|
||||
*/
|
||||
eth.moveTimeForwardSec(1);
|
||||
// run the ignition math
|
||||
engine->periodicFastCallback();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(skipSparkRatio, raisingRpm) {
|
||||
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
||||
setUpTestParameters({ true }, { true });
|
||||
|
||||
updateRpm(TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_START - 1, eth);
|
||||
EXPECT_FALSE(engine->launchController.isLaunchCondition);
|
||||
EXPECT_EQ(engine->hardSparkLimiter.getTargetSkipRatio(), 0.0f);
|
||||
|
||||
updateRpm(TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_START, eth);
|
||||
/* We've entered spark skip RPM window: */
|
||||
EXPECT_FALSE(engine->launchController.isLaunchCondition);
|
||||
EXPECT_EQ(engine->hardSparkLimiter.getTargetSkipRatio(), TEST_INITIAL_IGNITION_CUT_RATIO);
|
||||
|
||||
updateRpm(TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_END, eth);
|
||||
EXPECT_FALSE(engine->launchController.isLaunchCondition);
|
||||
EXPECT_EQ(engine->hardSparkLimiter.getTargetSkipRatio(), TEST_FINAL_IGNITION_CUT_RATIO);
|
||||
|
||||
updateRpm((TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_END - TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_START) / 2, eth);
|
||||
EXPECT_FALSE(engine->launchController.isLaunchCondition);
|
||||
EXPECT_EQ(
|
||||
engine->hardSparkLimiter.getTargetSkipRatio(),
|
||||
(TEST_FINAL_IGNITION_CUT_RATIO - TEST_FINAL_IGNITION_CUT_RATIO) / 2
|
||||
);
|
||||
|
||||
updateRpm(TEST_LAUNCH_SPARK_SKIP_RPM_WINDOW_END + 1, eth);
|
||||
/* We've left spark skip RPM window: */
|
||||
EXPECT_FALSE(engine->launchController.isLaunchCondition);
|
||||
EXPECT_EQ(engine->hardSparkLimiter.getTargetSkipRatio(), TEST_FINAL_IGNITION_CUT_RATIO);
|
||||
|
||||
updateRpm(TEST_LAUNCH_RPM - 1, eth);
|
||||
EXPECT_FALSE(engine->launchController.isLaunchCondition);
|
||||
EXPECT_EQ(engine->hardSparkLimiter.getTargetSkipRatio(), TEST_FINAL_IGNITION_CUT_RATIO);
|
||||
|
||||
/* We've reached TEST_LAUNCH_RPM: */
|
||||
updateRpm(TEST_LAUNCH_RPM, eth);
|
||||
EXPECT_TRUE(engine->launchController.isLaunchCondition);
|
||||
EXPECT_EQ(engine->hardSparkLimiter.getTargetSkipRatio(), 1.0);
|
||||
}
|
|
@ -48,6 +48,7 @@ TESTS_SRC_CPP = \
|
|||
tests/launch/test_rpm_condition.cpp \
|
||||
tests/launch/test_retard_threshold_rpm.cpp \
|
||||
tests/launch/test_ignition_angle_advance.cpp \
|
||||
tests/launch/test_spark_skip_ratio.cpp \
|
||||
tests/lua/test_lua_basic.cpp \
|
||||
tests/lua/test_lookup.cpp \
|
||||
tests/lua/test_lua_e38.cpp \
|
||||
|
|
Loading…
Reference in New Issue