diff --git a/firmware/controllers/algo/engine_configuration_defaults.h b/firmware/controllers/algo/engine_configuration_defaults.h index 8bc7d861c0..4306b7f736 100644 --- a/firmware/controllers/algo/engine_configuration_defaults.h +++ b/firmware/controllers/algo/engine_configuration_defaults.h @@ -60,4 +60,5 @@ namespace engine_configuration_defaults { constexpr float NITROUS_LUA_GAUGE_ARMING_VALUE = 0.0f; constexpr int NITROUS_MINIMUM_TPS = 0; + constexpr uint8_t NITROUS_MINIMUM_CLT = 0; } diff --git a/firmware/controllers/algo/nitrous_control_state.txt b/firmware/controllers/algo/nitrous_control_state.txt index fa131e26bc..6ec09ee350 100644 --- a/firmware/controllers/algo/nitrous_control_state.txt +++ b/firmware/controllers/algo/nitrous_control_state.txt @@ -2,5 +2,6 @@ struct_no_prefix nitrous_control_state_s bit isArmed bit isTpsConditionSatisfied +bit isCltConditionSatisfied end_struct \ No newline at end of file diff --git a/firmware/controllers/algo/nitrous_controller.cpp b/firmware/controllers/algo/nitrous_controller.cpp index 7d331bfe3e..9911d88a50 100644 --- a/firmware/controllers/algo/nitrous_controller.cpp +++ b/firmware/controllers/algo/nitrous_controller.cpp @@ -11,6 +11,7 @@ void NitrousController::update() { if (engineConfiguration->nitrousControlEnabled) { updateArmingState(); updateTpsConditionSatisfied(); + updateCltConditionSatisfied(); } } @@ -40,6 +41,15 @@ void NitrousController::updateTpsConditionSatisfied() { } } +void NitrousController::updateCltConditionSatisfied() { + const expected clt = Sensor::get(SensorType::Clt); + if (engineConfiguration->nitrousMinimumClt != 0) { + isCltConditionSatisfied = clt.Valid && (engineConfiguration->nitrousMinimumClt <= clt.Value); + } else { + isCltConditionSatisfied = true; + } +} + bool NitrousController::checkTriggerPinState() const { bool result = false; #if !EFI_SIMULATOR diff --git a/firmware/controllers/algo/nitrous_controller.h b/firmware/controllers/algo/nitrous_controller.h index b90f2674c9..bb8f88f2a3 100644 --- a/firmware/controllers/algo/nitrous_controller.h +++ b/firmware/controllers/algo/nitrous_controller.h @@ -12,6 +12,7 @@ public: private: void updateArmingState(); void updateTpsConditionSatisfied(); + void updateCltConditionSatisfied(); bool checkTriggerPinState() const; bool checkLuaGauge() const; diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 07d470f375..b05602ea1d 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -1785,8 +1785,9 @@ uint8_t autoscale knockFuelTrim;Fuel trim when knock, max 30%;"%", 1, 0, 0, 30, float nitrousLuaGaugeArmingValue;;"", 1, 0, -30000, 30000, 3 int nitrousMinimumTps;;"", 1, 0, 0, 20000, 0 + uint8_t nitrousMinimumClt;;"deg C", 1, 0, 0, @@CLT_UPPER_LIMIT@@, 0 -#define END_OF_CALIBRATION_PADDING 90 +#define END_OF_CALIBRATION_PADDING 89 uint8_t[END_OF_CALIBRATION_PADDING] unusedOftenChangesDuringFirmwareUpdate;;"units", 1, 0, 0, 1, 0 ! end of engine_configuration_s diff --git a/firmware/tunerstudio/tunerstudio.template.ini b/firmware/tunerstudio/tunerstudio.template.ini index 4352654434..a682e5061a 100644 --- a/firmware/tunerstudio/tunerstudio.template.ini +++ b/firmware/tunerstudio/tunerstudio.template.ini @@ -4991,6 +4991,7 @@ dialog = tcuControls, "Transmission Settings" dialog = NitrousControlSettings, "Settings" field = "Minimum TPS", nitrousMinimumTps + field = "Minimum CLT", nitrousMinimumClt dialog = NitrousControlSettingsDialog, "", yAxis field = "Enable Nitrous Control", nitrousControlEnabled diff --git a/unit_tests/tests/nitrous_control/test_nitrous_clt_condition.cpp b/unit_tests/tests/nitrous_control/test_nitrous_clt_condition.cpp new file mode 100644 index 0000000000..9ccfb112bb --- /dev/null +++ b/unit_tests/tests/nitrous_control/test_nitrous_clt_condition.cpp @@ -0,0 +1,91 @@ +// +// Created by kifir on 11/28/24. +// + +#include "pch.h" + +#include "util/test_base.h" + +namespace { + struct CltConditionTestData { + const std::optional clt; + const bool expectedCltCondition; + const char* const context; + }; + + class NitrousCltConditionTest : public TestBase { + protected: + static constexpr uint8_t TEST_CLT = 51; + + void checkCltCondition(const std::vector& testData); + }; + + void NitrousCltConditionTest::checkCltCondition(const std::vector& testData) { + for (const CltConditionTestData& item: testData) { + updateClt(item.clt); + EXPECT_EQ(engine->nitrousController.isCltConditionSatisfied, item.expectedCltCondition) << item.context; + } + } + + TEST_F(NitrousCltConditionTest, checkDefault) { + checkCltCondition({ + { {}, false, "default" }, + { { 0 }, false, "0.0" }, + { { TEST_CLT - EPS5D }, false, "TEST_CLT - EPS5D" }, + { { TEST_CLT }, false, "TEST_CLT" }, + { { TEST_CLT + EPS5D }, false, "TEST_CLT + EPS5D" }, + }); + } + + TEST_F(NitrousCltConditionTest, checkDefaultWithDisabledNitrousControl) { + setUpEngineConfiguration(EngineConfig().setNitrousControlEnabled({ false })); + checkCltCondition({ + { {}, false, "default" }, + { { 0.0f }, false, "0.0" }, + { { TEST_CLT - EPS5D }, false, "TEST_CLT - EPS5D" }, + { { TEST_CLT }, false, "TEST_CLT" }, + { { TEST_CLT + EPS5D }, false, "TEST_CLT + EPS5D" }, + }); + } + + TEST_F(NitrousCltConditionTest, checkDefaultWithEnabledNitrousControl) { + setUpEngineConfiguration(EngineConfig().setNitrousControlEnabled({ true })); + checkCltCondition({ + { {}, true, "default" }, + { { 0.0f }, true, "0.0" }, + { { TEST_CLT - EPS5D }, true, "TEST_CLT - EPS5D" }, + { { TEST_CLT }, true, "TEST_CLT" }, + { { TEST_CLT + EPS5D }, true, "TEST_CLT + EPS5D" }, + }); + } + + TEST_F(NitrousCltConditionTest, checkZeroMinimumClt) { + setUpEngineConfiguration( + EngineConfig() + .setNitrousControlEnabled({ true }) + .setNitrousMinimumClt(0) + ); + checkCltCondition({ + { {}, true, "default" }, + { { 0.0f }, true, "0.0" }, + { { TEST_CLT - EPS5D }, true, "TEST_CLT - EPS5D" }, + { { TEST_CLT }, true, "TEST_CLT" }, + { { TEST_CLT + EPS5D }, true, "TEST_CLT + EPS5D" }, + }); + } + + TEST_F(NitrousCltConditionTest, checkMinimumClt) { + setUpEngineConfiguration( + EngineConfig() + .setNitrousControlEnabled({ true }) + .setNitrousMinimumClt({ TEST_CLT }) + ); + checkCltCondition({ + { {}, false, "default" }, + { { 0.0f }, false, "0.0" }, + { { TEST_CLT - EPS5D }, false, "TEST_CLT - EPS5D" }, + { { TEST_CLT }, true, "TEST_CLT" }, + { { TEST_CLT + EPS5D }, true, "TEST_CLT + EPS5D" }, + }); + } +} \ No newline at end of file diff --git a/unit_tests/tests/tests.mk b/unit_tests/tests/tests.mk index 5084906c2a..49a3a32f8a 100644 --- a/unit_tests/tests/tests.mk +++ b/unit_tests/tests/tests.mk @@ -73,6 +73,7 @@ TESTS_SRC_CPP = \ tests/shift_torque_reduction/test_shift_torque_reduction_angle_advance.cpp \ tests/nitrous_control/test_nitrous_arming.cpp \ tests/nitrous_control/test_nitrous_tps_condition.cpp \ + tests/nitrous_control/test_nitrous_clt_condition.cpp \ tests/test_fft.cpp \ tests/lua/test_lua_basic.cpp \ tests/lua/test_bit_range_msb.cpp \ diff --git a/unit_tests/tests/util/engine_config.cpp b/unit_tests/tests/util/engine_config.cpp index 8ab898b55f..4d89d3289d 100644 --- a/unit_tests/tests/util/engine_config.cpp +++ b/unit_tests/tests/util/engine_config.cpp @@ -223,3 +223,8 @@ EngineConfig EngineConfig::setNitrousMinimumTps(const std::optional value) m_nitrousMinimumTps = value; return *this; } + +EngineConfig EngineConfig::setNitrousMinimumClt(const std::optional value) { + m_nitrousMinimumClt = value; + return *this; +} \ No newline at end of file diff --git a/unit_tests/tests/util/engine_config.h b/unit_tests/tests/util/engine_config.h index 448db4ec8e..5cdd74ad00 100644 --- a/unit_tests/tests/util/engine_config.h +++ b/unit_tests/tests/util/engine_config.h @@ -70,6 +70,7 @@ public: std::optional getNitrousLuaGaugeArmingValue() const { return m_nitrousLuaGaugeArmingValue; } std::optional getNitrousMinimumTps() const { return m_nitrousMinimumTps; } + std::optional getNitrousMinimumClt() const { return m_nitrousMinimumClt; } // We do not core about performance in tests, but we want to use builder-like style, so setters return new instance // of configuration: @@ -129,6 +130,7 @@ public: EngineConfig setNitrousLuaGaugeArmingValue(std::optional value); EngineConfig setNitrousMinimumTps(std::optional value); + EngineConfig setNitrousMinimumClt(std::optional value); private: // Launch Control std::optional m_launchActivatePin; @@ -184,6 +186,6 @@ private: std::optional m_nitrousLuaGaugeMeaning; std::optional m_nitrousLuaGaugeArmingValue; - std::optional m_nitrousMinimumTps; + std::optional m_nitrousMinimumTps; std::optional m_nitrousMinimumClt; }; \ No newline at end of file diff --git a/unit_tests/tests/util/test_base.cpp b/unit_tests/tests/util/test_base.cpp index 68ec887526..ceabe7c135 100644 --- a/unit_tests/tests/util/test_base.cpp +++ b/unit_tests/tests/util/test_base.cpp @@ -88,6 +88,7 @@ void TestBase::setUpEngineConfiguration(const EngineConfig& config) { getTestEngineConfiguration().configureNitrousLuaGaugeArmingValue(config.getNitrousLuaGaugeArmingValue()); getTestEngineConfiguration().configureNitrousMinimumTps(config.getNitrousMinimumTps()); + getTestEngineConfiguration().configureNitrousMinimumClt(config.getNitrousMinimumClt()); } void TestBase::periodicFastCallback() { @@ -108,6 +109,10 @@ void TestBase::updateApp(const std::optional app) { updateSensor(SensorType::DriverThrottleIntent, app); } +void TestBase::updateClt(const std::optional clt) { + updateSensor(SensorType::Clt, clt); +} + void TestBase::updateSensor(const SensorType sensor, const std::optional sensorReading) { if (sensorReading.has_value()) { Sensor::setMockValue(sensor, sensorReading.value()); diff --git a/unit_tests/tests/util/test_base.h b/unit_tests/tests/util/test_base.h index e17c371cc5..d57a8c80d2 100644 --- a/unit_tests/tests/util/test_base.h +++ b/unit_tests/tests/util/test_base.h @@ -25,6 +25,7 @@ protected: void updateRpm(float rpm); void updateApp(std::optional app); + void updateClt(std::optional clt); template ModuleType& getModule(); private: diff --git a/unit_tests/tests/util/test_engine_configuration.cpp b/unit_tests/tests/util/test_engine_configuration.cpp index 3f926eec8f..cba19fca51 100644 --- a/unit_tests/tests/util/test_engine_configuration.cpp +++ b/unit_tests/tests/util/test_engine_configuration.cpp @@ -488,6 +488,17 @@ void TestEngineConfiguration::configureNitrousMinimumTps(const std::optional nitrousMinimumClt) { + if (nitrousMinimumClt.has_value()) { + engineConfiguration->nitrousMinimumClt = nitrousMinimumClt.value(); + } else { + ASSERT_EQ( + engineConfiguration->nitrousMinimumClt, + engine_configuration_defaults::NITROUS_MINIMUM_CLT + ); // check default value + } +} + TestEngineConfiguration::TestEngineConfiguration() { } diff --git a/unit_tests/tests/util/test_engine_configuration.h b/unit_tests/tests/util/test_engine_configuration.h index 61c936e469..e86b3a88a0 100644 --- a/unit_tests/tests/util/test_engine_configuration.h +++ b/unit_tests/tests/util/test_engine_configuration.h @@ -73,6 +73,7 @@ public: void configureNitrousLuaGaugeArmingValue(std::optional luaGaugeArmingValue); void configureNitrousMinimumTps(std::optional nitrousMinimumTps); + void configureNitrousMinimumClt(std::optional nitrousMinimumClt); private: TestEngineConfiguration(); static TestEngineConfiguration instance;