Require redundant tps for ETB (#2037)

* mod sensor api

* require redundancy

* fix tests

* check that it fails

Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
Matthew Kennedy 2020-12-06 23:05:06 -06:00 committed by GitHub
parent efef2bfe4f
commit 4f1085a87a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 10 deletions

View File

@ -168,6 +168,20 @@ bool EtbController::init(etb_function_e function, DcMotor *motor, pid_s *pidPara
m_function = function; m_function = function;
m_positionSensor = functionToPositionSensor(function); m_positionSensor = functionToPositionSensor(function);
// If we are a throttle, require redundant TPS sensor
if (function == ETB_Throttle1 || function == ETB_Throttle2) {
if (!Sensor::isRedundant(m_positionSensor)) {
firmwareError(
OBD_Throttle_Position_Sensor_Circuit_Malfunction,
"Use of electronic throttle requires %s to be redundant.",
Sensor::getSensorName(m_positionSensor)
);
return false;
}
}
m_motor = motor; m_motor = motor;
m_pid.initPidClass(pidParameters); m_pid.initPidClass(pidParameters);
m_pedalMap = pedalMap; m_pedalMap = pedalMap;

View File

@ -50,9 +50,10 @@ public:
return m_sensor; return m_sensor;
} }
void setMockValue(float value) { void setMockValue(float value, bool mockRedundant) {
m_mockValue = value; m_mockValue = value;
m_useMock = true; m_useMock = true;
m_mockRedundant = mockRedundant;
} }
void resetMock() { void resetMock() {
@ -131,11 +132,16 @@ public:
return sensor->isRedundant(); return sensor->isRedundant();
} }
if (m_useMock) {
return m_mockRedundant;
}
return false; return false;
} }
private: private:
bool m_useMock = false; bool m_useMock = false;
bool m_mockRedundant = false;
float m_mockValue; float m_mockValue;
Sensor* m_sensor = nullptr; Sensor* m_sensor = nullptr;
}; };
@ -201,11 +207,11 @@ bool Sensor::Register() {
return entry ? entry->hasSensor() : false; return entry ? entry->hasSensor() : false;
} }
/*static*/ void Sensor::setMockValue(SensorType type, float value) { /*static*/ void Sensor::setMockValue(SensorType type, float value, bool mockRedundant) {
auto entry = getEntryForType(type); auto entry = getEntryForType(type);
if (entry) { if (entry) {
entry->setMockValue(value); entry->setMockValue(value, mockRedundant);
} }
} }

View File

@ -105,7 +105,7 @@ public:
/* /*
* Mock a value for a particular sensor. * Mock a value for a particular sensor.
*/ */
static void setMockValue(SensorType type, float value); static void setMockValue(SensorType type, float value, bool mockRedundant = false);
/* /*
* Mock a value for a particular sensor. * Mock a value for a particular sensor.
@ -127,6 +127,7 @@ public:
* For example, CLT, IAT, Throttle Position 2, etc. * For example, CLT, IAT, Throttle Position 2, etc.
*/ */
const char* getSensorName() { return getSensorName(m_type); } const char* getSensorName() { return getSensorName(m_type); }
static const char* getSensorName(SensorType type);
// Retrieve the current reading from the sensor. // Retrieve the current reading from the sensor.
// //
@ -155,8 +156,6 @@ protected:
explicit Sensor(SensorType type) explicit Sensor(SensorType type)
: m_type(type) {} : m_type(type) {}
static const char* getSensorName(SensorType type);
private: private:
const SensorType m_type; const SensorType m_type;

View File

@ -120,8 +120,8 @@ TEST(etb, initializationDualThrottle) {
Sensor::setMockValue(SensorType::AcceleratorPedal, 0); Sensor::setMockValue(SensorType::AcceleratorPedal, 0);
Sensor::setMockValue(SensorType::AcceleratorPedalPrimary, 0); Sensor::setMockValue(SensorType::AcceleratorPedalPrimary, 0);
// The presence of a second TPS indicates dual throttle Sensor::setMockValue(SensorType::Tps1, 25.0f, true);
Sensor::setMockValue(SensorType::Tps2, 25.0f); Sensor::setMockValue(SensorType::Tps2, 25.0f, true);
engineConfiguration->etbFunctions[0] = ETB_Throttle1; engineConfiguration->etbFunctions[0] = ETB_Throttle1;
engineConfiguration->etbFunctions[1] = ETB_Throttle2; engineConfiguration->etbFunctions[1] = ETB_Throttle2;
@ -172,6 +172,15 @@ TEST(etb, initializationNoFunction) {
dut.setOutput(0.5f); dut.setOutput(0.5f);
} }
TEST(etb, initializationNotRedundantTps) {
EtbController dut;
// Not redundant, should fail upon init
Sensor::setMockValue(SensorType::Tps1, 0.0f, false);
EXPECT_FATAL_ERROR(dut.init(ETB_Throttle1, nullptr, nullptr, nullptr));
}
TEST(etb, idlePlumbing) { TEST(etb, idlePlumbing) {
StrictMock<MockEtb> mocks[ETB_COUNT]; StrictMock<MockEtb> mocks[ETB_COUNT];
@ -208,6 +217,9 @@ TEST(etb, testSetpointOnlyPedal) {
// Uninitialized ETB must return unexpected (and not deference a null pointer) // Uninitialized ETB must return unexpected (and not deference a null pointer)
EXPECT_EQ(etb.getSetpoint(), unexpected); EXPECT_EQ(etb.getSetpoint(), unexpected);
// Must have TPS initialized for ETB setup
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
etb.init(ETB_Throttle1, nullptr, nullptr, &pedalMap); etb.init(ETB_Throttle1, nullptr, nullptr, &pedalMap);
// Check endpoints and midpoint // Check endpoints and midpoint
@ -249,6 +261,9 @@ TEST(etb, setpointIdle) {
engineConfiguration->useETBforIdleControl = true; engineConfiguration->useETBforIdleControl = true;
engineConfiguration->etbIdleThrottleRange = 0; engineConfiguration->etbIdleThrottleRange = 0;
// Must have TPS initialized for ETB setup
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
EtbController etb; EtbController etb;
INJECT_ENGINE_REFERENCE(&etb); INJECT_ENGINE_REFERENCE(&etb);
@ -344,8 +359,8 @@ TEST(etb, setpointWastegateController) {
TEST(etb, etbTpsSensor) { TEST(etb, etbTpsSensor) {
// Throw some distinct values on the TPS sensors so we can identify that we're getting the correct one // Throw some distinct values on the TPS sensors so we can identify that we're getting the correct one
Sensor::setMockValue(SensorType::Tps1, 25.0f); Sensor::setMockValue(SensorType::Tps1, 25.0f, true);
Sensor::setMockValue(SensorType::Tps2, 75.0f); Sensor::setMockValue(SensorType::Tps2, 75.0f, true);
Sensor::setMockValue(SensorType::WastegatePosition, 33.0f); Sensor::setMockValue(SensorType::WastegatePosition, 33.0f);
Sensor::setMockValue(SensorType::IdlePosition, 66.0f); Sensor::setMockValue(SensorType::IdlePosition, 66.0f);
@ -397,6 +412,9 @@ TEST(etb, setOutputValid) {
WITH_ENGINE_TEST_HELPER(TEST_ENGINE); WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
StrictMock<MockMotor> motor; StrictMock<MockMotor> motor;
// Must have TPS initialized for ETB setup
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
EtbController etb; EtbController etb;
INJECT_ENGINE_REFERENCE(&etb); INJECT_ENGINE_REFERENCE(&etb);
etb.init(ETB_Throttle1, &motor, nullptr, nullptr); etb.init(ETB_Throttle1, &motor, nullptr, nullptr);
@ -413,6 +431,9 @@ TEST(etb, setOutputValid2) {
WITH_ENGINE_TEST_HELPER(TEST_ENGINE); WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
StrictMock<MockMotor> motor; StrictMock<MockMotor> motor;
// Must have TPS initialized for ETB setup
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
EtbController etb; EtbController etb;
INJECT_ENGINE_REFERENCE(&etb); INJECT_ENGINE_REFERENCE(&etb);
etb.init(ETB_Throttle1, &motor, nullptr, nullptr); etb.init(ETB_Throttle1, &motor, nullptr, nullptr);
@ -429,6 +450,9 @@ TEST(etb, setOutputOutOfRangeHigh) {
WITH_ENGINE_TEST_HELPER(TEST_ENGINE); WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
StrictMock<MockMotor> motor; StrictMock<MockMotor> motor;
// Must have TPS initialized for ETB setup
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
EtbController etb; EtbController etb;
INJECT_ENGINE_REFERENCE(&etb); INJECT_ENGINE_REFERENCE(&etb);
etb.init(ETB_Throttle1, &motor, nullptr, nullptr); etb.init(ETB_Throttle1, &motor, nullptr, nullptr);
@ -445,6 +469,9 @@ TEST(etb, setOutputOutOfRangeLow) {
WITH_ENGINE_TEST_HELPER(TEST_ENGINE); WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
StrictMock<MockMotor> motor; StrictMock<MockMotor> motor;
// Must have TPS initialized for ETB setup
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
EtbController etb; EtbController etb;
INJECT_ENGINE_REFERENCE(&etb); INJECT_ENGINE_REFERENCE(&etb);
etb.init(ETB_Throttle1, &motor, nullptr, nullptr); etb.init(ETB_Throttle1, &motor, nullptr, nullptr);
@ -461,6 +488,9 @@ TEST(etb, setOutputPauseControl) {
WITH_ENGINE_TEST_HELPER(TEST_ENGINE); WITH_ENGINE_TEST_HELPER(TEST_ENGINE);
StrictMock<MockMotor> motor; StrictMock<MockMotor> motor;
// Must have TPS initialized for ETB setup
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
EtbController etb; EtbController etb;
INJECT_ENGINE_REFERENCE(&etb); INJECT_ENGINE_REFERENCE(&etb);
etb.init(ETB_Throttle1, &motor, nullptr, nullptr); etb.init(ETB_Throttle1, &motor, nullptr, nullptr);
@ -480,6 +510,9 @@ TEST(etb, closedLoopPid) {
pid.maxValue = 75; pid.maxValue = 75;
pid.minValue = -60; pid.minValue = -60;
// Must have TPS initialized for ETB setup
Sensor::setMockValue(SensorType::Tps1, 0.0f, true);
EtbController etb; EtbController etb;
etb.init(ETB_Throttle1, nullptr, &pid, nullptr); etb.init(ETB_Throttle1, nullptr, &pid, nullptr);