mirror of https://github.com/rusefi/rusefi-1.git
test dc_motor.cpp (#2890)
* use ipwm where possible * mock ipwm * initialize * test
This commit is contained in:
parent
35ad1b7d89
commit
1bca4843fe
|
@ -31,7 +31,7 @@ static boostOpenLoop_Map3D_t boostMapOpen;
|
||||||
static boostOpenLoop_Map3D_t boostMapClosed;
|
static boostOpenLoop_Map3D_t boostMapClosed;
|
||||||
static SimplePwm boostPwmControl("boost");
|
static SimplePwm boostPwmControl("boost");
|
||||||
|
|
||||||
void BoostController::init(SimplePwm* pwm, const ValueProvider3D* openLoopMap, const ValueProvider3D* closedLoopTargetMap, pid_s* pidParams) {
|
void BoostController::init(IPwm* pwm, const ValueProvider3D* openLoopMap, const ValueProvider3D* closedLoopTargetMap, pid_s* pidParams) {
|
||||||
m_pwm = pwm;
|
m_pwm = pwm;
|
||||||
m_openLoopMap = openLoopMap;
|
m_openLoopMap = openLoopMap;
|
||||||
m_closedLoopTargetMap = closedLoopTargetMap;
|
m_closedLoopTargetMap = closedLoopTargetMap;
|
||||||
|
|
|
@ -11,13 +11,13 @@
|
||||||
#include "closed_loop_controller.h"
|
#include "closed_loop_controller.h"
|
||||||
#include "pid.h"
|
#include "pid.h"
|
||||||
|
|
||||||
class SimplePwm;
|
class IPwm;
|
||||||
|
|
||||||
class BoostController : public ClosedLoopController<float, percent_t> {
|
class BoostController : public ClosedLoopController<float, percent_t> {
|
||||||
public:
|
public:
|
||||||
DECLARE_ENGINE_PTR;
|
DECLARE_ENGINE_PTR;
|
||||||
|
|
||||||
void init(SimplePwm* pmw, const ValueProvider3D* openLoopMap, const ValueProvider3D* closedLoopTargetMap, pid_s* pidParams);
|
void init(IPwm* pmw, const ValueProvider3D* openLoopMap, const ValueProvider3D* closedLoopTargetMap, pid_s* pidParams);
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
// Called when the configuration may have changed. Controller will
|
// Called when the configuration may have changed. Controller will
|
||||||
|
@ -39,7 +39,7 @@ private:
|
||||||
|
|
||||||
const ValueProvider3D* m_openLoopMap = nullptr;
|
const ValueProvider3D* m_openLoopMap = nullptr;
|
||||||
const ValueProvider3D* m_closedLoopTargetMap = nullptr;
|
const ValueProvider3D* m_closedLoopTargetMap = nullptr;
|
||||||
SimplePwm* m_pwm = nullptr;
|
IPwm* m_pwm = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void startBoostPin();
|
void startBoostPin();
|
||||||
|
|
|
@ -59,7 +59,7 @@ void GppwmChannel::setOutput(float result) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GppwmChannel::init(bool usePwm, SimplePwm* pwm, OutputPin* outputPin, const ValueProvider3D* table, const gppwm_channel* config) {
|
void GppwmChannel::init(bool usePwm, IPwm* pwm, OutputPin* outputPin, const ValueProvider3D* table, const gppwm_channel* config) {
|
||||||
m_usePwm = usePwm;
|
m_usePwm = usePwm;
|
||||||
m_pwm = pwm;
|
m_pwm = pwm;
|
||||||
m_output = outputPin;
|
m_output = outputPin;
|
||||||
|
|
|
@ -6,14 +6,14 @@
|
||||||
|
|
||||||
struct gppwm_channel;
|
struct gppwm_channel;
|
||||||
class OutputPin;
|
class OutputPin;
|
||||||
class SimplePwm;
|
class IPwm;
|
||||||
class ValueProvider3D;
|
class ValueProvider3D;
|
||||||
|
|
||||||
class GppwmChannel {
|
class GppwmChannel {
|
||||||
public:
|
public:
|
||||||
DECLARE_ENGINE_PTR;
|
DECLARE_ENGINE_PTR;
|
||||||
|
|
||||||
void init(bool usePwm, SimplePwm* pwm, OutputPin* outputPin, const ValueProvider3D* table, const gppwm_channel* config);
|
void init(bool usePwm, IPwm* pwm, OutputPin* outputPin, const ValueProvider3D* table, const gppwm_channel* config);
|
||||||
float update();
|
float update();
|
||||||
percent_t getOutput() const;
|
percent_t getOutput() const;
|
||||||
void setOutput(float result);
|
void setOutput(float result);
|
||||||
|
@ -25,7 +25,7 @@ private:
|
||||||
// Configuration fields
|
// Configuration fields
|
||||||
const gppwm_channel* m_config = nullptr;
|
const gppwm_channel* m_config = nullptr;
|
||||||
bool m_usePwm = false;
|
bool m_usePwm = false;
|
||||||
SimplePwm* m_pwm = nullptr;
|
IPwm* m_pwm = nullptr;
|
||||||
OutputPin* m_output = nullptr;
|
OutputPin* m_output = nullptr;
|
||||||
const ValueProvider3D* m_table = nullptr;
|
const ValueProvider3D* m_table = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,9 +71,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IPwm* m_enable;
|
IPwm* m_enable = nullptr;
|
||||||
IPwm* m_dir1;
|
IPwm* m_dir1 = nullptr;
|
||||||
IPwm* m_dir2;
|
IPwm* m_dir2 = nullptr;
|
||||||
OutputPin* const m_disable;
|
OutputPin* const m_disable;
|
||||||
float m_value = 0;
|
float m_value = 0;
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
MOCK_METHOD(float, getValue, (float xColumn, float yRow), (const, override));
|
MOCK_METHOD(float, getValue, (float xColumn, float yRow), (const, override));
|
||||||
};
|
};
|
||||||
|
|
||||||
class MockPwm : public SimplePwm {
|
class MockPwm : public IPwm {
|
||||||
public:
|
public:
|
||||||
MOCK_METHOD(void, setSimplePwmDutyCycle, (float dutyCycle), (override));
|
MOCK_METHOD(void, setSimplePwmDutyCycle, (float dutyCycle), (override));
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
#include "dc_motor.h"
|
||||||
|
|
||||||
|
#include "mocks.h"
|
||||||
|
|
||||||
|
using ::testing::InSequence;
|
||||||
|
using ::testing::NiceMock;
|
||||||
|
using ::testing::StrictMock;
|
||||||
|
|
||||||
|
TEST(DcMotor, Disable) {
|
||||||
|
StrictMock<MockOutputPin> dpin;
|
||||||
|
|
||||||
|
EXPECT_CALL(dpin, setValue(1))
|
||||||
|
.Times(2); // happens twice - once for initial disable, once for set(0)
|
||||||
|
|
||||||
|
TwoPinDcMotor dut(dpin);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DcMotor, Disable2) {
|
||||||
|
StrictMock<MockOutputPin> dpin;
|
||||||
|
|
||||||
|
EXPECT_CALL(dpin, setValue(1)).Times(4);
|
||||||
|
|
||||||
|
TwoPinDcMotor dut(dpin);
|
||||||
|
|
||||||
|
dut.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DcMotor, Enable) {
|
||||||
|
StrictMock<MockOutputPin> dpin;
|
||||||
|
|
||||||
|
{
|
||||||
|
InSequence is;
|
||||||
|
|
||||||
|
// Construction disables
|
||||||
|
EXPECT_CALL(dpin, setValue(1)).Times(2);
|
||||||
|
|
||||||
|
// Then enable
|
||||||
|
EXPECT_CALL(dpin, setValue(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TwoPinDcMotor dut(dpin);
|
||||||
|
dut.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DcMotor, SetUnconfigured) {
|
||||||
|
StrictMock<MockOutputPin> dpin;
|
||||||
|
EXPECT_CALL(dpin, setValue(1)).Times(3);
|
||||||
|
|
||||||
|
TwoPinDcMotor dut(dpin);
|
||||||
|
EXPECT_FLOAT_EQ(dut.get(), 0);
|
||||||
|
EXPECT_NO_THROW(dut.set(0.5f));
|
||||||
|
|
||||||
|
// Readback should work even without configuration
|
||||||
|
EXPECT_FLOAT_EQ(dut.get(), 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DcMotor, PwmEnablePinModePositive) {
|
||||||
|
NiceMock<MockOutputPin> dpin;
|
||||||
|
TwoPinDcMotor dut(dpin);
|
||||||
|
dut.setType(TwoPinDcMotor::ControlType::PwmEnablePin);
|
||||||
|
|
||||||
|
MockPwm enable;
|
||||||
|
MockPwm dir1;
|
||||||
|
MockPwm dir2;
|
||||||
|
|
||||||
|
EXPECT_CALL(enable, setSimplePwmDutyCycle(0.5f));
|
||||||
|
EXPECT_CALL(dir1, setSimplePwmDutyCycle(1));
|
||||||
|
EXPECT_CALL(dir2, setSimplePwmDutyCycle(0));
|
||||||
|
|
||||||
|
dut.configure(enable, dir1, dir2);
|
||||||
|
dut.set(0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DcMotor, PwmEnablePinModeNegative) {
|
||||||
|
NiceMock<MockOutputPin> dpin;
|
||||||
|
TwoPinDcMotor dut(dpin);
|
||||||
|
dut.setType(TwoPinDcMotor::ControlType::PwmEnablePin);
|
||||||
|
|
||||||
|
MockPwm enable;
|
||||||
|
MockPwm dir1;
|
||||||
|
MockPwm dir2;
|
||||||
|
|
||||||
|
|
||||||
|
EXPECT_CALL(enable, setSimplePwmDutyCycle(0.5f));
|
||||||
|
EXPECT_CALL(dir1, setSimplePwmDutyCycle(0));
|
||||||
|
EXPECT_CALL(dir2, setSimplePwmDutyCycle(1));
|
||||||
|
|
||||||
|
dut.configure(enable, dir1, dir2);
|
||||||
|
dut.set(-0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DcMotor, PwmDirectionPinsModePositive) {
|
||||||
|
NiceMock<MockOutputPin> dpin;
|
||||||
|
TwoPinDcMotor dut(dpin);
|
||||||
|
dut.setType(TwoPinDcMotor::ControlType::PwmDirectionPins);
|
||||||
|
|
||||||
|
MockPwm enable;
|
||||||
|
MockPwm dir1;
|
||||||
|
MockPwm dir2;
|
||||||
|
|
||||||
|
|
||||||
|
EXPECT_CALL(enable, setSimplePwmDutyCycle(1));
|
||||||
|
EXPECT_CALL(dir1, setSimplePwmDutyCycle(0.5f));
|
||||||
|
EXPECT_CALL(dir2, setSimplePwmDutyCycle(0));
|
||||||
|
|
||||||
|
dut.configure(enable, dir1, dir2);
|
||||||
|
dut.set(0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DcMotor, PwmDirectionPinsModeNegative) {
|
||||||
|
NiceMock<MockOutputPin> dpin;
|
||||||
|
TwoPinDcMotor dut(dpin);
|
||||||
|
dut.setType(TwoPinDcMotor::ControlType::PwmDirectionPins);
|
||||||
|
|
||||||
|
MockPwm enable;
|
||||||
|
MockPwm dir1;
|
||||||
|
MockPwm dir2;
|
||||||
|
|
||||||
|
|
||||||
|
EXPECT_CALL(enable, setSimplePwmDutyCycle(1));
|
||||||
|
EXPECT_CALL(dir1, setSimplePwmDutyCycle(0));
|
||||||
|
EXPECT_CALL(dir2, setSimplePwmDutyCycle(0.5f));
|
||||||
|
|
||||||
|
dut.configure(enable, dir1, dir2);
|
||||||
|
dut.set(-0.5f);
|
||||||
|
}
|
|
@ -7,13 +7,14 @@
|
||||||
#include "mocks.h"
|
#include "mocks.h"
|
||||||
|
|
||||||
using ::testing::InSequence;
|
using ::testing::InSequence;
|
||||||
|
using ::testing::StrictMock;
|
||||||
|
|
||||||
TEST(GpPwm, OutputWithPwm) {
|
TEST(GpPwm, OutputWithPwm) {
|
||||||
GppwmChannel ch;
|
GppwmChannel ch;
|
||||||
|
|
||||||
gppwm_channel cfg;
|
gppwm_channel cfg;
|
||||||
|
|
||||||
MockPwm pwm;
|
StrictMock<MockPwm> pwm;
|
||||||
|
|
||||||
// Shouldn't throw with no config
|
// Shouldn't throw with no config
|
||||||
EXPECT_NO_THROW(ch.setOutput(10));
|
EXPECT_NO_THROW(ch.setOutput(10));
|
||||||
|
|
|
@ -38,6 +38,7 @@ TESTS_SRC_CPP = \
|
||||||
tests/test_idle_controller.cpp \
|
tests/test_idle_controller.cpp \
|
||||||
tests/test_issue_898.cpp \
|
tests/test_issue_898.cpp \
|
||||||
tests/test_etb.cpp \
|
tests/test_etb.cpp \
|
||||||
|
tests/test_dc_motor.cpp \
|
||||||
tests/test_fan_control.cpp \
|
tests/test_fan_control.cpp \
|
||||||
tests/test_vvt.cpp \
|
tests/test_vvt.cpp \
|
||||||
tests/test_launch.cpp \
|
tests/test_launch.cpp \
|
||||||
|
|
Loading…
Reference in New Issue