diff --git a/firmware/controllers/algo/engine_configuration_defaults.h b/firmware/controllers/algo/engine_configuration_defaults.h index b4136387e2..ffa93851eb 100644 --- a/firmware/controllers/algo/engine_configuration_defaults.h +++ b/firmware/controllers/algo/engine_configuration_defaults.h @@ -16,6 +16,7 @@ namespace engine_configuration_defaults { constexpr torqueReductionActivationMode_e TORQUE_REDUCTION_ACTIVATION_MODE = TORQUE_REDUCTION_BUTTON; constexpr switch_input_pin_e TORQUE_REDUCTION_TRIGGER_PIN = Gpio::Unassigned; constexpr bool TORQUE_REDUCTION_TRIGGER_PIN_INVERTED = false; + constexpr float TORQUE_REDUCTION_TIME = 0.0f; /* Launch Control: */ constexpr switch_input_pin_e LAUNCH_ACTIVATE_PIN = Gpio::Unassigned; diff --git a/firmware/controllers/algo/shift_torque_reduction_controller.cpp b/firmware/controllers/algo/shift_torque_reduction_controller.cpp index 9b82b7a112..90266a2217 100644 --- a/firmware/controllers/algo/shift_torque_reduction_controller.cpp +++ b/firmware/controllers/algo/shift_torque_reduction_controller.cpp @@ -16,6 +16,7 @@ void ShiftTorqueReductionController::update() { if (engineConfiguration->torqueReductionEnabled) { updateTriggerPinState(); + updateTimeConditionSatisfied(); } } @@ -45,11 +46,22 @@ void ShiftTorqueReductionController::updateTriggerPinState(const switch_input_pi #if !EFI_SIMULATOR isTorqueReductionTriggerPinValid = isBrainPinValid(pin); if (isTorqueReductionTriggerPinValid) { + const bool previousTorqueReductionTriggerPinState = torqueReductionTriggerPinState; torqueReductionTriggerPinState = isPinInverted ^ efiReadPin(pin); + if (!previousTorqueReductionTriggerPinState && torqueReductionTriggerPinState) { + m_pinTriggeredTimer.reset(); + } } else { torqueReductionTriggerPinState = false; } #endif // !EFI_SIMULATOR } +void ShiftTorqueReductionController::updateTimeConditionSatisfied() { + isTimeConditionSatisfied = torqueReductionTriggerPinState + ? (0.0f < engineConfiguration->torqueReductionTime) + && !m_pinTriggeredTimer.hasElapsedMs(engineConfiguration->torqueReductionTime) + : false; +} + #endif // EFI_LAUNCH_CONTROL \ No newline at end of file diff --git a/firmware/controllers/algo/shift_torque_reduction_controller.h b/firmware/controllers/algo/shift_torque_reduction_controller.h index ff65b87886..141b41b0e2 100644 --- a/firmware/controllers/algo/shift_torque_reduction_controller.h +++ b/firmware/controllers/algo/shift_torque_reduction_controller.h @@ -12,4 +12,8 @@ public: private: void updateTriggerPinState(); void updateTriggerPinState(switch_input_pin_e pin, bool isPinInverted); + + void updateTimeConditionSatisfied(); + + Timer m_pinTriggeredTimer; }; diff --git a/firmware/controllers/algo/shift_torque_reduction_state.txt b/firmware/controllers/algo/shift_torque_reduction_state.txt index 3a1725da1d..dc441a7087 100644 --- a/firmware/controllers/algo/shift_torque_reduction_state.txt +++ b/firmware/controllers/algo/shift_torque_reduction_state.txt @@ -2,5 +2,6 @@ struct_no_prefix shift_torque_reduction_state_s bit isTorqueReductionTriggerPinValid bit torqueReductionTriggerPinState +bit isTimeConditionSatisfied end_struct diff --git a/unit_tests/tests/shift_torque_reduction/shift_torque_reduction_test_base.cpp b/unit_tests/tests/shift_torque_reduction/shift_torque_reduction_test_base.cpp index 29f520db2c..f408ef5fd9 100644 --- a/unit_tests/tests/shift_torque_reduction/shift_torque_reduction_test_base.cpp +++ b/unit_tests/tests/shift_torque_reduction/shift_torque_reduction_test_base.cpp @@ -47,6 +47,13 @@ ShiftTorqueReductionTestConfig ShiftTorqueReductionTestConfig::setLaunchActivate return *this; } +ShiftTorqueReductionTestConfig ShiftTorqueReductionTestConfig::setTorqueReductionTime( + const std::optional value +) { + m_torqueReductionTime = value; + return *this; +} + void ShiftTorqueReductionTestBase::setUpTestConfig(const ShiftTorqueReductionTestConfig& config) { configureTorqueReductionEnabled(config.getTorqueReductionEnabled()); configureTorqueReductionActivationMode(config.getTorqueReductionActivationMode()); @@ -54,6 +61,7 @@ void ShiftTorqueReductionTestBase::setUpTestConfig(const ShiftTorqueReductionTes configureTorqueReductionButtonInverted(config.getPinInverted()); configureLaunchActivatePin(config.getLaunchActivatePin()); configureLaunchActivateInverted(config.getLaunchActivateInverted()); + configureTorqueReductionTime(config.getTorqueReductionTime()); } void ShiftTorqueReductionTestBase::configureTorqueReductionEnabled(const std::optional torqueReductionEnabled) { @@ -122,4 +130,15 @@ void ShiftTorqueReductionTestBase::configureLaunchActivateInverted(const std::op engine_configuration_defaults::LAUNCH_ACTIVATE_PIN_INVERTED ); // check default value } +} + +void ShiftTorqueReductionTestBase::configureTorqueReductionTime(std::optional timeout) { + if (timeout.has_value()) { + engineConfiguration->torqueReductionTime = timeout.value(); + } else { + ASSERT_EQ( + engineConfiguration->torqueReductionTime, + engine_configuration_defaults::TORQUE_REDUCTION_TIME + ); // check default value + } } \ No newline at end of file diff --git a/unit_tests/tests/shift_torque_reduction/shift_torque_reduction_test_base.h b/unit_tests/tests/shift_torque_reduction/shift_torque_reduction_test_base.h index 45bff165cb..7b17dda9ec 100644 --- a/unit_tests/tests/shift_torque_reduction/shift_torque_reduction_test_base.h +++ b/unit_tests/tests/shift_torque_reduction/shift_torque_reduction_test_base.h @@ -16,6 +16,7 @@ public: std::optional getPinInverted() const { return m_pinInverted; } std::optional getLaunchActivatePin() const { return m_launchActivatePin; } std::optional getLaunchActivateInverted() const { return m_launchActivateInverted; } + std::optional getTorqueReductionTime() const { return m_torqueReductionTime; } // We do not core about performance in tests, but we want to use builder-like style, so setters return new instance // of configuration: @@ -27,6 +28,7 @@ public: ShiftTorqueReductionTestConfig setPinInverted(std::optional value); ShiftTorqueReductionTestConfig setLaunchActivatePin(std::optional value); ShiftTorqueReductionTestConfig setLaunchActivateInverted(std::optional value); + ShiftTorqueReductionTestConfig setTorqueReductionTime(std::optional value); private: std::optional m_isTorqueReductionEnabled; std::optional m_torqueReductionActivationMode; @@ -34,6 +36,7 @@ private: std::optional m_pinInverted; std::optional m_launchActivatePin; std::optional m_launchActivateInverted; + std::optional m_torqueReductionTime; }; class ShiftTorqueReductionTestBase : public TestBase { @@ -46,4 +49,5 @@ private: void configureTorqueReductionButtonInverted(std::optional pinInverted); void configureLaunchActivatePin(std::optional pin); void configureLaunchActivateInverted(std::optional pinInverted); + void configureTorqueReductionTime(std::optional timeout); }; diff --git a/unit_tests/tests/shift_torque_reduction/test_shift_torque_reduction_time_condition.cpp b/unit_tests/tests/shift_torque_reduction/test_shift_torque_reduction_time_condition.cpp new file mode 100644 index 0000000000..453240436f --- /dev/null +++ b/unit_tests/tests/shift_torque_reduction/test_shift_torque_reduction_time_condition.cpp @@ -0,0 +1,126 @@ +// +// Created by kifir on 10/2/24. +// + +#include "pch.h" + +#include "shift_torque_reduction_test_base.h" + +namespace { + constexpr switch_input_pin_e TEST_TORQUE_REDUCTION_BUTTON_PIN = Gpio::F13; + constexpr float TEST_TORQUE_REDUCTION_TIME = 239.17; + constexpr float IMMEDIATELY = 0.0f; + + class ShiftTorqueReductionTimeConditionTest : public ShiftTorqueReductionTestBase { + protected: + void waitAndCheckTimeCondition( + float timeoutInMs, + bool expectedTriggerPinState, + bool expectedTimeCondition, + const char* context + ); + }; + + void ShiftTorqueReductionTimeConditionTest::waitAndCheckTimeCondition( + const float timeoutInMs, + const bool expectedTriggerPinState, + const bool expectedTimeCondition, + const char* const context + ) { + if (timeoutInMs > IMMEDIATELY) { + advanceTimeUs(MS2US(timeoutInMs)); + } + periodicFastCallback(); + EXPECT_EQ( + engine->shiftTorqueReductionController.torqueReductionTriggerPinState, + expectedTriggerPinState + ) << context; + EXPECT_EQ( + engine->shiftTorqueReductionController.isTimeConditionSatisfied, + expectedTimeCondition + ) << context; + } + + TEST_F(ShiftTorqueReductionTimeConditionTest, checkExpiration) { + setUpTestConfig(ShiftTorqueReductionTestConfig() + .setTorqueReductionEnabled(true) + .setTorqueReductionActivationMode(torqueReductionActivationMode_e::TORQUE_REDUCTION_BUTTON) + .setTriggerPin(TEST_TORQUE_REDUCTION_BUTTON_PIN) + .setTorqueReductionTime(TEST_TORQUE_REDUCTION_TIME) + ); + + waitAndCheckTimeCondition(IMMEDIATELY, false, false, "Initial state"); + + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, true); + waitAndCheckTimeCondition(IMMEDIATELY, true, true, "Pin has just been actvated"); + + waitAndCheckTimeCondition(TEST_TORQUE_REDUCTION_TIME, true, true, "Before timeout exriration"); + + waitAndCheckTimeCondition(EPS3D, true, false, "After timeout expiration"); + } + + TEST_F(ShiftTorqueReductionTimeConditionTest, checkDeactivation) { + setUpTestConfig(ShiftTorqueReductionTestConfig() + .setTorqueReductionEnabled(true) + .setTorqueReductionActivationMode(torqueReductionActivationMode_e::TORQUE_REDUCTION_BUTTON) + .setTriggerPin(TEST_TORQUE_REDUCTION_BUTTON_PIN) + .setTorqueReductionTime(TEST_TORQUE_REDUCTION_TIME) + ); + + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, true); + waitAndCheckTimeCondition(IMMEDIATELY, true, true, "Pin has just been actvated"); + + waitAndCheckTimeCondition(TEST_TORQUE_REDUCTION_TIME / 2, true, true, "Before pin deactivation"); + + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, false); + waitAndCheckTimeCondition(IMMEDIATELY, false, false, "Pin has just been deactvated"); + } + + TEST_F(ShiftTorqueReductionTimeConditionTest, checkReactivation) { + setUpTestConfig(ShiftTorqueReductionTestConfig() + .setTorqueReductionEnabled(true) + .setTorqueReductionActivationMode(torqueReductionActivationMode_e::TORQUE_REDUCTION_BUTTON) + .setTriggerPin(TEST_TORQUE_REDUCTION_BUTTON_PIN) + .setTorqueReductionTime(TEST_TORQUE_REDUCTION_TIME) + ); + + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, true); + waitAndCheckTimeCondition(IMMEDIATELY, true, true, "Pin has just been actvated"); + + waitAndCheckTimeCondition(TEST_TORQUE_REDUCTION_TIME / 3, true, true, "Before pin deactivation"); + + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, false); + waitAndCheckTimeCondition(IMMEDIATELY, false, false, "Pin has just been deactvated"); + + waitAndCheckTimeCondition(TEST_TORQUE_REDUCTION_TIME / 3, false, false, "Pin is still deactvated"); + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, true); + waitAndCheckTimeCondition(IMMEDIATELY, true, true, "Pin has just been reactivated"); + + waitAndCheckTimeCondition(TEST_TORQUE_REDUCTION_TIME, true, true, "Before timeout expiration"); + waitAndCheckTimeCondition(EPS3D, true, false, "After timeout expiration"); + } + + TEST_F(ShiftTorqueReductionTimeConditionTest, checkTimeConditionIsNeverSatisfiedWithZeroTorqueReductionTime) { + setUpTestConfig(ShiftTorqueReductionTestConfig() + .setTorqueReductionEnabled(true) + .setTorqueReductionActivationMode(torqueReductionActivationMode_e::TORQUE_REDUCTION_BUTTON) + .setTriggerPin(TEST_TORQUE_REDUCTION_BUTTON_PIN) + .setTorqueReductionTime(IMMEDIATELY) + ); + + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, true); + waitAndCheckTimeCondition(IMMEDIATELY, true, false, "Pin has just been actvated"); + + waitAndCheckTimeCondition(TEST_TORQUE_REDUCTION_TIME / 3, true, false, "Before pin deactivation"); + + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, false); + waitAndCheckTimeCondition(IMMEDIATELY, false, false, "Pin has just been deactvated"); + + waitAndCheckTimeCondition(TEST_TORQUE_REDUCTION_TIME / 3, false, false, "Pin is still deactvated"); + setMockState(TEST_TORQUE_REDUCTION_BUTTON_PIN, true); + waitAndCheckTimeCondition(IMMEDIATELY, true, false, "Pin has just been reactivated"); + + waitAndCheckTimeCondition(TEST_TORQUE_REDUCTION_TIME, true, false, "Before timeout expiration"); + waitAndCheckTimeCondition(EPS3D, true, false, "After timeout expiration"); + } +} \ No newline at end of file diff --git a/unit_tests/tests/tests.mk b/unit_tests/tests/tests.mk index ecfe446ba4..e9084cce89 100644 --- a/unit_tests/tests/tests.mk +++ b/unit_tests/tests/tests.mk @@ -59,6 +59,7 @@ TESTS_SRC_CPP = \ tests/launch/test_spark_skip_ratio.cpp \ tests/shift_torque_reduction/shift_torque_reduction_test_base.cpp \ tests/shift_torque_reduction/test_shift_torque_reduction_trigger_pin_state.cpp \ + tests/shift_torque_reduction/test_shift_torque_reduction_time_condition.cpp \ tests/lua/test_lua_basic.cpp \ tests/lua/test_lookup.cpp \ tests/lua/test_lua_e38.cpp \