2021-08-03 19:05:01 -07:00
|
|
|
#include "pch.h"
|
2020-05-06 05:40:42 -07:00
|
|
|
|
2021-08-03 19:05:01 -07:00
|
|
|
#include "boost_control.h"
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
using ::testing::_;
|
|
|
|
using ::testing::StrictMock;
|
|
|
|
|
|
|
|
TEST(BoostControl, Setpoint) {
|
|
|
|
MockVp3d targetMap;
|
|
|
|
|
|
|
|
// Just pass TPS input to output
|
|
|
|
EXPECT_CALL(targetMap, getValue(_, _))
|
2021-12-22 05:09:41 -08:00
|
|
|
.WillRepeatedly([](float xRpm, float tps) { return tps; });
|
2020-05-06 05:40:42 -07:00
|
|
|
|
2023-05-31 22:31:28 -07:00
|
|
|
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
2020-11-25 04:27:24 -08:00
|
|
|
engineConfiguration->boostType = CLOSED_LOOP;
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
BoostController bc;
|
|
|
|
|
|
|
|
// Should return unexpected without a pedal map cfg'd
|
|
|
|
EXPECT_EQ(bc.getSetpoint(), unexpected);
|
|
|
|
|
|
|
|
// Now init with mock target map
|
|
|
|
bc.init(nullptr, nullptr, &targetMap, nullptr);
|
|
|
|
|
|
|
|
// Should still return unxepected since TPS is invalid
|
|
|
|
EXPECT_EQ(bc.getSetpoint(), unexpected);
|
|
|
|
|
|
|
|
// Configure TPS, should get passthru of tps value
|
|
|
|
Sensor::setMockValue(SensorType::DriverThrottleIntent, 35.0f);
|
|
|
|
EXPECT_FLOAT_EQ(bc.getSetpoint().value_or(-1), 35.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BoostControl, ObservePlant) {
|
2023-05-31 22:31:28 -07:00
|
|
|
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
2023-10-19 18:22:59 -07:00
|
|
|
engineConfiguration->boostType = CLOSED_LOOP;
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
BoostController bc;
|
|
|
|
|
2020-12-30 05:43:49 -08:00
|
|
|
Sensor::resetMockValue(SensorType::Map);
|
2020-05-06 05:40:42 -07:00
|
|
|
// Check that invalid MAP returns unexpected
|
|
|
|
EXPECT_EQ(bc.observePlant(), unexpected);
|
|
|
|
|
|
|
|
// Test valid MAP value
|
2020-12-30 05:43:49 -08:00
|
|
|
Sensor::setMockValue(SensorType::Map, 150);
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
EXPECT_FLOAT_EQ(bc.observePlant().value_or(0), 150.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BoostControl, OpenLoop) {
|
|
|
|
MockVp3d openMap;
|
|
|
|
|
|
|
|
// Just pass MAP input to output
|
|
|
|
EXPECT_CALL(openMap, getValue(_, _))
|
2021-12-22 05:09:41 -08:00
|
|
|
.WillRepeatedly([](float xRpm, float tps) { return tps; });
|
2020-05-06 05:40:42 -07:00
|
|
|
|
2023-05-31 22:31:28 -07:00
|
|
|
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
BoostController bc;
|
|
|
|
|
|
|
|
// Without table set, should return unexpected
|
|
|
|
EXPECT_EQ(bc.getOpenLoop(0), unexpected);
|
|
|
|
|
|
|
|
bc.init(nullptr, &openMap, nullptr, nullptr);
|
|
|
|
|
|
|
|
// Should pass TPS value thru
|
|
|
|
Sensor::setMockValue(SensorType::DriverThrottleIntent, 47.0f);
|
|
|
|
EXPECT_FLOAT_EQ(bc.getOpenLoop(0).value_or(-1), 47.0f);
|
|
|
|
}
|
|
|
|
|
2022-01-20 19:22:52 -08:00
|
|
|
TEST(BoostControl, TestClosedLoop) {
|
2023-05-31 22:31:28 -07:00
|
|
|
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
BoostController bc;
|
|
|
|
|
|
|
|
pid_s pidCfg = {
|
|
|
|
1, 0, 0, // P controller, easier to test
|
|
|
|
0, // no offset
|
|
|
|
5, // 5ms period
|
|
|
|
-100, 100 // min/max output
|
|
|
|
};
|
|
|
|
|
|
|
|
bc.init(nullptr, nullptr, nullptr, &pidCfg);
|
|
|
|
|
|
|
|
// Enable closed loop
|
2021-11-17 00:54:21 -08:00
|
|
|
engineConfiguration->boostType = CLOSED_LOOP;
|
2021-08-27 14:54:08 -07:00
|
|
|
// Minimum 75kpa
|
2021-11-17 00:54:21 -08:00
|
|
|
engineConfiguration->minimumBoostClosedLoopMap = 75;
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
// At 0 RPM, closed loop is disabled
|
2022-01-20 19:22:52 -08:00
|
|
|
Sensor::setMockValue(SensorType::Rpm, 0);
|
2020-05-06 05:40:42 -07:00
|
|
|
EXPECT_EQ(0, bc.getClosedLoop(150, 100).value_or(-1000));
|
2021-08-27 14:54:08 -07:00
|
|
|
|
|
|
|
// too low MAP, disable closed loop
|
2022-01-20 19:22:52 -08:00
|
|
|
Sensor::setMockValue(SensorType::Rpm, 0);
|
2021-08-27 14:54:08 -07:00
|
|
|
EXPECT_EQ(0, bc.getClosedLoop(150, 50).value_or(-1000));
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
// With RPM, we should get an output
|
2022-01-20 19:22:52 -08:00
|
|
|
Sensor::setMockValue(SensorType::Rpm, 1000);
|
2020-05-06 05:40:42 -07:00
|
|
|
// Actual is below target -> positive output
|
|
|
|
EXPECT_FLOAT_EQ(50, bc.getClosedLoop(150, 100).value_or(-1000));
|
|
|
|
// Actual is above target -> negative output
|
|
|
|
EXPECT_FLOAT_EQ(-25.0f, bc.getClosedLoop(150, 175).value_or(-1000));
|
|
|
|
|
|
|
|
// Disabling closed loop should return 0
|
2021-11-17 00:54:21 -08:00
|
|
|
engineConfiguration->boostType = OPEN_LOOP;
|
2020-05-06 05:40:42 -07:00
|
|
|
EXPECT_FLOAT_EQ(0, bc.getClosedLoop(150, 175).value_or(-1000));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(BoostControl, SetOutput) {
|
2023-05-31 22:31:28 -07:00
|
|
|
EngineTestHelper eth(engine_type_e::TEST_ENGINE);
|
2020-10-18 18:57:04 -07:00
|
|
|
|
2022-01-11 17:47:50 -08:00
|
|
|
engineConfiguration->isBoostControlEnabled = true;
|
|
|
|
|
2020-05-06 05:40:42 -07:00
|
|
|
StrictMock<MockPwm> pwm;
|
2020-10-18 18:57:04 -07:00
|
|
|
StrictMock<MockEtb> etb;
|
2020-05-06 05:40:42 -07:00
|
|
|
BoostController bc;
|
|
|
|
|
2020-10-18 18:57:04 -07:00
|
|
|
// ETB wastegate position & PWM should both be set
|
2020-11-25 18:14:06 -08:00
|
|
|
EXPECT_CALL(etb, setWastegatePosition(25.0f));
|
2020-05-06 05:40:42 -07:00
|
|
|
EXPECT_CALL(pwm, setSimplePwmDutyCycle(0.25f));
|
|
|
|
|
|
|
|
// Don't crash if not init'd (don't deref null ptr m_pwm)
|
|
|
|
EXPECT_NO_THROW(bc.setOutput(25.0f));
|
|
|
|
|
2020-10-18 18:57:04 -07:00
|
|
|
// Init with mock PWM device and ETB
|
2020-05-06 05:40:42 -07:00
|
|
|
bc.init(&pwm, nullptr, nullptr, nullptr);
|
2020-10-18 18:57:04 -07:00
|
|
|
engine->etbControllers[0] = &etb;
|
2020-05-06 05:40:42 -07:00
|
|
|
|
|
|
|
bc.setOutput(25.0f);
|
|
|
|
}
|