diff --git a/firmware/console/binary/tunerstudio.cpp b/firmware/console/binary/tunerstudio.cpp index 032761840f..d027ddb5c5 100644 --- a/firmware/console/binary/tunerstudio.cpp +++ b/firmware/console/binary/tunerstudio.cpp @@ -262,7 +262,7 @@ static const void * getStructAddr(int structId) { return static_cast(&engine->triggerCentral.triggerState); #if EFI_ELECTRONIC_THROTTLE_BODY case LDS_ETB_PID_STATE_INDEX: - return engine->etbControllers[0]->getPidState(); + return static_cast(engine->etbControllers[0])->getPidState(); #endif /* EFI_ELECTRONIC_THROTTLE_BODY */ #ifndef EFI_IDLE_CONTROL diff --git a/firmware/controllers/actuators/electronic_throttle.cpp b/firmware/controllers/actuators/electronic_throttle.cpp index 6835628012..63d2f4170c 100644 --- a/firmware/controllers/actuators/electronic_throttle.cpp +++ b/firmware/controllers/actuators/electronic_throttle.cpp @@ -75,8 +75,7 @@ #if EFI_ELECTRONIC_THROTTLE_BODY -#include "electronic_throttle_impl.h" -#include "engine.h" +#include "electronic_throttle.h" #include "tps.h" #include "sensor.h" #include "dc_motor.h" diff --git a/firmware/controllers/actuators/electronic_throttle.h b/firmware/controllers/actuators/electronic_throttle.h index 746a8e9f1f..6afbd8a5b7 100644 --- a/firmware/controllers/actuators/electronic_throttle.h +++ b/firmware/controllers/actuators/electronic_throttle.h @@ -7,9 +7,108 @@ #pragma once -#include "engine_ptr.h" +/** + * Hard code ETB update speed. + * Since this is a safety critical system with no real reason for a user to ever need to change the update rate, + * it's locked to 500hz, along with the ADC. + * https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem + */ +#define ETB_LOOP_FREQUENCY 500 +#define DEFAULT_ETB_PWM_FREQUENCY 800 + +#include "engine.h" #include "closed_loop_controller.h" -#include "rusefi_types.h" +#include "expected.h" +#include "sensor.h" + +class DcMotor; +class Logging; + +class IEtbController : public ClosedLoopController { +public: + DECLARE_ENGINE_PTR; + + // Initialize the throttle. + // returns true if the throttle was initialized, false otherwise. + virtual bool init(etb_function_e function, DcMotor *motor, pid_s *pidParameters, const ValueProvider3D* pedalMap) = 0; + virtual void reset() = 0; + virtual void setIdlePosition(percent_t pos) = 0; + virtual void setWastegatePosition(percent_t pos) = 0; + virtual void update() = 0; + virtual void autoCalibrateTps() = 0; +}; + +class EtbController : public IEtbController { +public: + bool init(etb_function_e function, DcMotor *motor, pid_s *pidParameters, const ValueProvider3D* pedalMap) override; + void setIdlePosition(percent_t pos) override; + void setWastegatePosition(percent_t pos) override; + void reset() override; + + // Update the controller's state: read sensors, send output, etc + void update(); + + // Called when the configuration may have changed. Controller will + // reset if necessary. + void onConfigurationChange(pid_s* previousConfiguration); + + // Print this throttle's status. + void showStatus(Logging* logger); + + // Helpers for individual parts of throttle control + expected observePlant() const override; + + expected getSetpoint() const override; + expected getSetpointEtb() const; + expected getSetpointWastegate() const; + expected getSetpointIdleValve() const; + + expected getOpenLoop(percent_t target) const override; + expected getClosedLoop(percent_t setpoint, percent_t observation) override; + expected getClosedLoopAutotune(percent_t actualThrottlePosition); + + void setOutput(expected outputValue) override; + + // Used to inspect the internal PID controller's state + const pid_state_s* getPidState() const { return &m_pid; }; + + // Use the throttle to automatically calibrate the relevant throttle position sensor(s). + void autoCalibrateTps() override; + +protected: + // This is set if an automatic TPS calibration should be run + bool m_isAutocal = false; + + etb_function_e getFunction() const { return m_function; } + DcMotor* getMotor() { return m_motor; } + +private: + etb_function_e m_function = ETB_None; + SensorType m_positionSensor = SensorType::Invalid; + DcMotor *m_motor = nullptr; + Pid m_pid; + bool m_shouldResetPid = false; + + // Pedal -> target map + const ValueProvider3D* m_pedalMap = nullptr; + + float m_idlePosition = 0; + float m_wastegatePosition = 0; + + // Autotune helpers + bool m_lastIsPositive = false; + efitick_t m_cycleStartTime = 0; + float m_minCycleTps = 0; + float m_maxCycleTps = 0; + // Autotune measured parameters: gain and ultimate period + // These are set to correct order of magnitude starting points + // so we converge more quickly on the correct values + float m_a = 8; + float m_tu = 0.1f; + + uint8_t m_autotuneCounter = 0; + uint8_t m_autotuneCurrentParam = 0; +}; void initElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE); void doInitElectronicThrottle(DECLARE_ENGINE_PARAMETER_SIGNATURE); @@ -29,24 +128,3 @@ void onConfigurationChangeElectronicThrottleCallback(engine_configuration_s *pre void unregisterEtbPins(); void etbAutocal(size_t throttleIndex); - -class DcMotor; -struct pid_s; -class ValueProvider3D; -struct pid_state_s; - -class IEtbController : public ClosedLoopController { -public: - DECLARE_ENGINE_PTR; - - // Initialize the throttle. - // returns true if the throttle was initialized, false otherwise. - virtual bool init(etb_function_e function, DcMotor *motor, pid_s *pidParameters, const ValueProvider3D* pedalMap) = 0; - virtual void reset() = 0; - virtual void setIdlePosition(percent_t pos) = 0; - virtual void setWastegatePosition(percent_t pos) = 0; - virtual void update() = 0; - virtual void autoCalibrateTps() = 0; - - virtual const pid_state_s* getPidState() const = 0; -}; diff --git a/firmware/controllers/actuators/electronic_throttle_impl.h b/firmware/controllers/actuators/electronic_throttle_impl.h deleted file mode 100644 index 3914cbcda7..0000000000 --- a/firmware/controllers/actuators/electronic_throttle_impl.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file electronic_throttle_impl.h - * - * @date Dec 7, 2013 - * @author Andrey Belomutskiy, (c) 2012-2020 - */ - -#pragma once - -// include the "public" ETB interface -#include "electronic_throttle.h" - -#include "sensor.h" -#include "pid.h" - -/** - * Hard code ETB update speed. - * Since this is a safety critical system with no real reason for a user to ever need to change the update rate, - * it's locked to 500hz, along with the ADC. - * https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem - */ -#define ETB_LOOP_FREQUENCY 500 -#define DEFAULT_ETB_PWM_FREQUENCY 800 - -class Logging; - -class EtbController : public IEtbController { -public: - bool init(etb_function_e function, DcMotor *motor, pid_s *pidParameters, const ValueProvider3D* pedalMap) override; - void setIdlePosition(percent_t pos) override; - void setWastegatePosition(percent_t pos) override; - void reset() override; - - // Update the controller's state: read sensors, send output, etc - void update(); - - // Called when the configuration may have changed. Controller will - // reset if necessary. - void onConfigurationChange(pid_s* previousConfiguration); - - // Print this throttle's status. - void showStatus(Logging* logger); - - // Helpers for individual parts of throttle control - expected observePlant() const override; - - expected getSetpoint() const override; - expected getSetpointEtb() const; - expected getSetpointWastegate() const; - expected getSetpointIdleValve() const; - - expected getOpenLoop(percent_t target) const override; - expected getClosedLoop(percent_t setpoint, percent_t observation) override; - expected getClosedLoopAutotune(percent_t actualThrottlePosition); - - void setOutput(expected outputValue) override; - - // Used to inspect the internal PID controller's state - const pid_state_s* getPidState() const override { return &m_pid; }; - - // Use the throttle to automatically calibrate the relevant throttle position sensor(s). - void autoCalibrateTps() override; - -protected: - // This is set if an automatic TPS calibration should be run - bool m_isAutocal = false; - - etb_function_e getFunction() const { return m_function; } - DcMotor* getMotor() { return m_motor; } - -private: - etb_function_e m_function = ETB_None; - SensorType m_positionSensor = SensorType::Invalid; - DcMotor *m_motor = nullptr; - Pid m_pid; - bool m_shouldResetPid = false; - - // Pedal -> target map - const ValueProvider3D* m_pedalMap = nullptr; - - float m_idlePosition = 0; - float m_wastegatePosition = 0; - - // Autotune helpers - bool m_lastIsPositive = false; - efitick_t m_cycleStartTime = 0; - float m_minCycleTps = 0; - float m_maxCycleTps = 0; - // Autotune measured parameters: gain and ultimate period - // These are set to correct order of magnitude starting points - // so we converge more quickly on the correct values - float m_a = 8; - float m_tu = 0.1f; - - uint8_t m_autotuneCounter = 0; - uint8_t m_autotuneCurrentParam = 0; -}; diff --git a/unit_tests/mocks.h b/unit_tests/mocks.h index 9bb2c86bf9..09f1d6e527 100644 --- a/unit_tests/mocks.h +++ b/unit_tests/mocks.h @@ -17,7 +17,6 @@ public: MOCK_METHOD(void, setIdlePosition, (percent_t pos), (override)); MOCK_METHOD(void, setWastegatePosition, (percent_t pos), (override)); MOCK_METHOD(void, autoCalibrateTps, (), (override)); - MOCK_METHOD(const pid_state_s*, getPidState, (), (const, override)); // ClosedLoopController mocks MOCK_METHOD(expected, getSetpoint, (), (const, override)); diff --git a/unit_tests/tests/test_etb.cpp b/unit_tests/tests/test_etb.cpp index 7bff71266b..48c12f8ac1 100644 --- a/unit_tests/tests/test_etb.cpp +++ b/unit_tests/tests/test_etb.cpp @@ -6,7 +6,7 @@ */ #include "engine_test_helper.h" -#include "electronic_throttle_impl.h" +#include "electronic_throttle.h" #include "dc_motor.h" #include "engine_controller.h" #include "sensor.h" @@ -313,9 +313,6 @@ TEST(etb, setpointIdle) { TEST(etb, setpointNoPedalMap) { EtbController etb; - // Must have TPS initialized for ETB setup - Sensor::setMockValue(SensorType::Tps1, 0.0f, true); - // Don't pass a pedal map etb.init(ETB_Throttle1, nullptr, nullptr, nullptr);