| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | #include "pch.h" | |||
| 2 | ||||
| 3 | #include "high_pressure_fuel_pump.h" | |||
| 4 | #include "fuel_computer.h" | |||
| 5 | ||||
| 6 | using ::testing::_; | |||
| 7 | using ::testing::StrictMock; | |||
| 8 | ||||
| 9 | 4 | TEST(HPFP, Lobe) { | ||
| 10 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
| 11 | ||||
| 12 | 1 | engineConfiguration->hpfpCam = HPFP_CAM_NONE; | ||
| 13 | 1 | engineConfiguration->hpfpPeakPos = 123; | ||
| 14 | 1 | engineConfiguration->hpfpCamLobes = 3; | ||
| 15 | ||||
| 16 |
1/1✓ Branch 1 taken 1 time.
|
1 | validateConfigOnStartUpOrBurn(); | |
| 17 | ||||
| 18 | 1 | engine->triggerCentral.vvtPosition[0][0] = 40; // Bank 0 | ||
| 19 | 1 | engine->triggerCentral.vvtPosition[0][1] = 80; | ||
| 20 | 1 | engine->triggerCentral.vvtPosition[1][0] =120; // Bank 1 | ||
| 21 | 1 | engine->triggerCentral.vvtPosition[1][1] =160; | ||
| 22 | ||||
| 23 | 1 | HpfpLobe lobe; | ||
| 24 | ||||
| 25 | // Run through all five CAM modes | |||
| 26 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 1 time.
|
6 | for (int cam = 0; cam < 5; cam++) { |
| 27 | static hpfp_cam_e map[5] = { HPFP_CAM_NONE, HPFP_CAM_IN1, HPFP_CAM_EX1, | |||
| 28 | HPFP_CAM_IN2, HPFP_CAM_EX2}; | |||
| 29 | 5 | engineConfiguration->hpfpCam = map[cam]; | ||
| 30 | ||||
| 31 | // Run through several cycles of the engine to make sure we keep wrapping around | |||
| 32 |
2/2✓ Branch 0 taken 20 times.
✓ Branch 1 taken 5 times.
|
2/2✓ Decision 'true' taken 20 times.
✓ Decision 'false' taken 5 times.
|
25 | for (int i = 0; i < 4; i++) { |
| 33 |
3/7✓ Branch 4 taken 20 times.
✓ Branch 7 taken 20 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
20 | EXPECT_EQ(lobe.findNextLobe(), 240 + 123 + cam * 20); | |
| 34 |
3/7✓ Branch 4 taken 20 times.
✓ Branch 7 taken 20 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
20 | EXPECT_EQ(lobe.findNextLobe(), 480 + 123 + cam * 20); | |
| 35 |
3/7✓ Branch 4 taken 20 times.
✓ Branch 7 taken 20 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
20 | EXPECT_EQ(lobe.findNextLobe(), 0 + 123 + cam * 20); | |
| 36 | } | |||
| 37 | } | |||
| 38 | ||||
| 39 | // Can we change the number of lobes? | |||
| 40 | 1 | engineConfiguration->hpfpCam = HPFP_CAM_NONE; | ||
| 41 | 1 | engineConfiguration->hpfpCamLobes = 4; | ||
| 42 |
3/7✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
1 | EXPECT_EQ(lobe.findNextLobe(), 180 + 123); | |
| 43 |
3/7✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
1 | EXPECT_EQ(lobe.findNextLobe(), 360 + 123); | |
| 44 |
3/7✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
1 | EXPECT_EQ(lobe.findNextLobe(), 540 + 123); | |
| 45 |
3/7✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
1 | EXPECT_EQ(lobe.findNextLobe(), 0 + 123); | |
| 46 | ||||
| 47 | // Can we change the peak position? | |||
| 48 | 1 | engineConfiguration->hpfpPeakPos = 95; | ||
| 49 |
3/7✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
1 | EXPECT_EQ(lobe.findNextLobe(), 180 + 95); | |
| 50 |
3/7✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
1 | EXPECT_EQ(lobe.findNextLobe(), 360 + 95); | |
| 51 |
3/7✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
1 | EXPECT_EQ(lobe.findNextLobe(), 540 + 95); | |
| 52 |
3/7✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 16 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
|
1 | EXPECT_EQ(lobe.findNextLobe(), 0 + 95); | |
| 53 | 2 | } | ||
| 54 | ||||
| 55 | 4 | TEST(HPFP, InjectionReplacementFuel) { | ||
| 56 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
| 57 | ||||
| 58 | 1 | engineConfiguration->cylindersCount = 4; | ||
| 59 | 1 | engineConfiguration->hpfpCamLobes = 4; | ||
| 60 | 1 | engine->engineState.injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; | ||
| 61 | 1 | engineConfiguration->hpfpPumpVolume = 0.2; // cc/lobe | ||
| 62 | ||||
| 63 | 1 | HpfpQuantity math; | ||
| 64 | ||||
| 65 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 25); | |
| 66 | ||||
| 67 | // What if we change the # of lobes? | |||
| 68 | 1 | engineConfiguration->hpfpCamLobes = 3; | ||
| 69 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 25 * 1.333333333f); | |
| 70 | ||||
| 71 | // More fuel! | |||
| 72 | 1 | engine->engineState.injectionMass[0] = 0.1 /* cc/cyl */ * fuelDensity; | ||
| 73 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 50 * 1.333333333f); | |
| 74 | ||||
| 75 | // More cylinders! | |||
| 76 | 1 | engineConfiguration->cylindersCount = 6; | ||
| 77 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 50 * 2.); // Ooops we maxed out | |
| 78 | ||||
| 79 | // Compensation testing | |||
| 80 | 1 | engineConfiguration->cylindersCount = | ||
| 81 | 1 | engineConfiguration->hpfpCamLobes; // Make math easier | ||
| 82 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int i = 0; i < HPFP_COMPENSATION_SIZE; i++) { |
| 83 | // one bin every 1000 RPM | |||
| 84 | 10 | config->hpfpCompensationRpmBins[i] = std::min(i * 1000, 8000); | ||
| 85 | } | |||
| 86 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int i = 0; i < HPFP_COMPENSATION_SIZE; i++) { |
| 87 | // one bin every 0.05 cc/lobe | |||
| 88 | 10 | config->hpfpCompensationLoadBins[i] = std::min(i * 0.05, 60.); | ||
| 89 | } | |||
| 90 | ||||
| 91 | 1 | config->hpfpCompensation[2][1] = -10; | ||
| 92 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 40); // -10, in cell | |
| 93 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1500), 45); // -5, half way | |
| 94 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(2000), 50); // -0, in next cell | |
| 95 | ||||
| 96 | 1 | config->hpfpCompensation[2][1] = 20; | ||
| 97 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 70); // +20, in cell | |
| 98 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1500), 60); // +10, half way | |
| 99 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(2000), 50); // +0, in next cell | |
| 100 | ||||
| 101 | // 25% more fuel (1.25*50=62.5 base), but half way between comp of 20 and 0 (so comp of 10) | |||
| 102 | 1 | engine->engineState.injectionMass[0] = 0.125 /* cc/cyl */ * fuelDensity; | ||
| 103 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 72.5); // +10 comp | |
| 104 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1500), 67.5); // +5, half way | |
| 105 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(2000), 62.5); // +0 base | |
| 106 | 2 | } | ||
| 107 | ||||
| 108 | 4 | TEST(HPFP, PI) { | ||
| 109 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
| 110 | ||||
| 111 | 1 | engineConfiguration->hpfpTargetDecay = 0; | ||
| 112 | 1 | engineConfiguration->hpfpPidP = 0; | ||
| 113 | 1 | engineConfiguration->hpfpPidI = 0; | ||
| 114 | 1 | engineConfiguration->hpfpPeakPos = 0; | ||
| 115 | ||||
| 116 | 1 | engineConfiguration->cylindersCount = 4; | ||
| 117 | 1 | engineConfiguration->hpfpCamLobes = 4; | ||
| 118 | 1 | engine->engineState.injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; | ||
| 119 | 1 | engineConfiguration->hpfpPumpVolume = 0.2; // cc/lobe | ||
| 120 | ||||
| 121 | 1 | HpfpQuantity math; | ||
| 122 | 1 | HpfpController model; | ||
| 123 | ||||
| 124 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int i = 0; i < HPFP_TARGET_SIZE; i++) { |
| 125 | // one bin every 1000 RPM | |||
| 126 | 10 | config->hpfpTargetRpmBins[i] = std::min(i * 1000, 8000); | ||
| 127 | } | |||
| 128 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int i = 0; i < HPFP_TARGET_SIZE; i++) { |
| 129 | // one bin every 20kPa | |||
| 130 | 10 | config->hpfpTargetLoadBins[i] = std::min(i * 20, 200); | ||
| 131 | } | |||
| 132 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int r = 0; r < HPFP_TARGET_SIZE; r++) { |
| 133 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 10 times.
|
2/2✓ Decision 'true' taken 100 times.
✓ Decision 'false' taken 10 times.
|
110 | for (int c = 0; c < HPFP_TARGET_SIZE; c++) { |
| 134 | 100 | config->hpfpTarget[r][c] = 1000 * r + 10 * c; | ||
| 135 | } | |||
| 136 | } | |||
| 137 | ||||
| 138 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Map, 40); | |
| 139 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::FuelPressureHigh, 1000); | |
| 140 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, 120, &model), -20); // Test integral clamp | |
| 141 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.hpfp_i_control_percent, -20); // and again | |
| 142 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.m_pressureTarget_kPa, 2010); | |
| 143 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, -40, &model), 40); // Test integral clamp | |
| 144 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.hpfp_i_control_percent, 40); // and again | |
| 145 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.m_pressureTarget_kPa, 2010); | |
| 146 | ||||
| 147 | // Test pressure decay | |||
| 148 |
1/1✓ Branch 1 taken 1 time.
|
1 | math.calcPI(4000, 0, &model); | |
| 149 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.m_pressureTarget_kPa, 2040); | |
| 150 |
1/1✓ Branch 1 taken 1 time.
|
1 | math.calcPI(1000, 0, &model); | |
| 151 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.m_pressureTarget_kPa, 2040); | |
| 152 | 1 | engineConfiguration->hpfpTargetDecay = 1000; | ||
| 153 |
1/1✓ Branch 1 taken 1 time.
|
1 | math.calcPI(1000, 0, &model); | |
| 154 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.m_pressureTarget_kPa, 2035); // 5ms of decay | |
| 155 | ||||
| 156 | // Proportional gain | |||
| 157 | 1 | model.resetQuantity(); // Reset for ease of testing | ||
| 158 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, 0, &model), 0); // Validate reset | |
| 159 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.m_pressureTarget_kPa, 2010); | |
| 160 | 1 | engineConfiguration->hpfpPidP = 0.01; | ||
| 161 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, 0, &model), 10.10); | |
| 162 | 1 | engineConfiguration->hpfpPidP = 0.02; | ||
| 163 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, 0, &model), 20.20); | |
| 164 | ||||
| 165 | // Integral gain | |||
| 166 | 1 | engineConfiguration->hpfpPidI = 0.001; | ||
| 167 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, 0, &model), 20.368334); | |
| 168 |
2/6✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
|
1 | EXPECT_FLOAT_EQ(model.hpfp_i_control_percent, 0.168333333); | |
| 169 | 2 | } | ||
| 170 | ||||
| 171 | 4 | TEST(HPFP, Angle) { | ||
| 172 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
| 173 | ||||
| 174 | 1 | engineConfiguration->hpfpTargetDecay = 0; | ||
| 175 | 1 | engineConfiguration->hpfpPidP = 0; | ||
| 176 | 1 | engineConfiguration->hpfpPidI = 0; | ||
| 177 | 1 | engineConfiguration->hpfpPeakPos = 0; | ||
| 178 | ||||
| 179 | 1 | engineConfiguration->cylindersCount = 4; | ||
| 180 | 1 | engineConfiguration->hpfpCamLobes = 4; | ||
| 181 | 1 | engine->engineState.injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; | ||
| 182 | 1 | engineConfiguration->hpfpPumpVolume = 0.2; // cc/lobe | ||
| 183 | ||||
| 184 | 1 | HpfpQuantity math; | ||
| 185 | ||||
| 186 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int i = 0; i < HPFP_TARGET_SIZE; i++) { |
| 187 | // one bin every 1000 RPM | |||
| 188 | 10 | config->hpfpTargetRpmBins[i] = std::min(i * 1000, 8000); | ||
| 189 | } | |||
| 190 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int i = 0; i < HPFP_TARGET_SIZE; i++) { |
| 191 | // one bin every 20kPa | |||
| 192 | 10 | config->hpfpTargetLoadBins[i] = std::min(i * 20, 200); | ||
| 193 | } | |||
| 194 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int r = 0; r < HPFP_TARGET_SIZE; r++) { |
| 195 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 10 times.
|
2/2✓ Decision 'true' taken 100 times.
✓ Decision 'false' taken 10 times.
|
110 | for (int c = 0; c < HPFP_TARGET_SIZE; c++) { |
| 196 | 100 | config->hpfpTarget[r][c] = 1000 * r + 10 * c; | ||
| 197 | } | |||
| 198 | } | |||
| 199 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 16 times.
✓ Decision 'false' taken 1 time.
|
17 | for (int i = 0; i < HPFP_LOBE_PROFILE_SIZE; i++) { |
| 200 | 16 | config->hpfpLobeProfileQuantityBins[i] = 100. * i / (HPFP_LOBE_PROFILE_SIZE - 1); | ||
| 201 | 16 | config->hpfpLobeProfileAngle[i] = 150. * i / (HPFP_LOBE_PROFILE_SIZE - 1); | ||
| 202 | } | |||
| 203 | ||||
| 204 | 1 | HpfpController model; | ||
| 205 | ||||
| 206 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 25); // Double check baseline | |
| 207 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, 10, &model), 0); // Validate no PI | |
| 208 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_NEAR(math.pumpAngleFuel(1000, &model), 37.5, 0.4); // Given the profile, should be 50% higher | |
| 209 | ||||
| 210 | 1 | engine->engineState.injectionMass[0] = 0.08 /* cc/cyl */ * fuelDensity; | ||
| 211 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcFuelPercent(1000), 40); // Double check baseline | |
| 212 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, 10, &model), 0); // Validate no PI | |
| 213 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_NEAR(math.pumpAngleFuel(1000, &model), 60, 0.4); // Given the profile, should be 50% higher | |
| 214 | ||||
| 215 | 1 | engineConfiguration->hpfpPidP = 0.01; | ||
| 216 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Map, 40); | |
| 217 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::FuelPressureHigh, 1000); | |
| 218 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ(math.calcPI(1000, 10, &model), 10.1); | |
| 219 |
3/7✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_NEAR(math.pumpAngleFuel(1000, &model), 50.1 * 1.5, 0.4); // Given the profile, should be 50% higher | |
| 220 | 2 | } | ||
| 221 | ||||
| 222 | 4 | TEST(HPFP, Schedule) { | ||
| 223 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
| 224 | ||||
| 225 | 1 | engineConfiguration->cylindersCount = 4; | ||
| 226 | 1 | engineConfiguration->hpfpCamLobes = 4; | ||
| 227 | 1 | engineConfiguration->hpfpPumpVolume = 0.2; // cc/lobe | ||
| 228 | ||||
| 229 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int i = 0; i < HPFP_TARGET_SIZE; i++) { |
| 230 | // one bin every 1000 RPM | |||
| 231 | 10 | config->hpfpTargetRpmBins[i] = std::min(i * 1000, 8000); | ||
| 232 | } | |||
| 233 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int i = 0; i < HPFP_TARGET_SIZE; i++) { |
| 234 | // one bin every 20kPa | |||
| 235 | 10 | config->hpfpTargetLoadBins[i] = std::min(i * 20, 200); | ||
| 236 | } | |||
| 237 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | for (int r = 0; r < HPFP_TARGET_SIZE; r++) { |
| 238 |
2/2✓ Branch 0 taken 100 times.
✓ Branch 1 taken 10 times.
|
2/2✓ Decision 'true' taken 100 times.
✓ Decision 'false' taken 10 times.
|
110 | for (int c = 0; c < HPFP_TARGET_SIZE; c++) { |
| 239 | 100 | config->hpfpTarget[r][c] = 1000 * r + 10 * c; | ||
| 240 | } | |||
| 241 | } | |||
| 242 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 16 times.
✓ Decision 'false' taken 1 time.
|
17 | for (int i = 0; i < HPFP_LOBE_PROFILE_SIZE; i++) { |
| 243 | 16 | config->hpfpLobeProfileQuantityBins[i] = 100. * i / (HPFP_LOBE_PROFILE_SIZE - 1); | ||
| 244 | 16 | config->hpfpLobeProfileAngle[i] = 150. * i / (HPFP_LOBE_PROFILE_SIZE - 1); | ||
| 245 | } | |||
| 246 | ||||
| 247 |
1/1✓ Branch 1 taken 1 time.
|
1 | auto & hpfp = *engine->module<HpfpController>(); | |
| 248 | ||||
| 249 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockExecutor> mockExec; | |
| 250 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->scheduler.setMockExecutor(&mockExec); | |
| 251 | 1 | engineConfiguration->hpfpActivationAngle = 30; | ||
| 252 | ||||
| 253 | 1 | constexpr angle_t angle0 = 90; | ||
| 254 | 1 | constexpr angle_t angle1 = 270 - 37.6923065; | ||
| 255 | 1 | constexpr angle_t angle2 = angle1 + 30; | ||
| 256 | ||||
| 257 | 1 | constexpr float tick_per_deg = USF2NT(1000000.)*60/360/1000; | ||
| 258 | ||||
| 259 | 1 | constexpr efitick_t nt0 = tick_per_deg * angle0; | ||
| 260 | 1 | constexpr efitick_t nt1 = tick_per_deg * angle1; | ||
| 261 | 1 | constexpr efitick_t nt2 = tick_per_deg * angle2; | ||
| 262 | ||||
| 263 | { | |||
| 264 |
1/1✓ Branch 2 taken 1 time.
|
1 | testing::InSequence is; | |
| 265 | ||||
| 266 | // First call to setRpmValue will cause a dummy call to fast periodic timer. | |||
| 267 | // Injection Mass will be 0 so expect a no-op. | |||
| 268 |
8/8✓ Branch 5 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 21 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 28 taken 1 time.
✓ Branch 32 taken 1 time.
|
1 | EXPECT_CALL(mockExec, schedule(testing::NotNull(), &hpfp.m_event.eventScheduling, nt0, action_s::make<HpfpController::pinTurnOff>(&hpfp))); | |
| 269 | ||||
| 270 | // Second call will be the start of a real pump event. | |||
| 271 |
8/8✓ Branch 5 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 21 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 28 taken 1 time.
✓ Branch 32 taken 1 time.
|
1 | EXPECT_CALL(mockExec, schedule(testing::NotNull(), &hpfp.m_event.eventScheduling, nt1, action_s::make<HpfpController::pinTurnOn>(&hpfp))); | |
| 272 | ||||
| 273 | // Third call will be off event | |||
| 274 |
8/8✓ Branch 5 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 21 taken 1 time.
✓ Branch 24 taken 1 time.
✓ Branch 28 taken 1 time.
✓ Branch 32 taken 1 time.
|
1 | EXPECT_CALL(mockExec, schedule(testing::NotNull(), &hpfp.m_event.eventScheduling, nt2, action_s::make<HpfpController::pinTurnOff>(&hpfp))); | |
| 275 | 1 | } | ||
| 276 |
5/5✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 17 taken 1 time.
|
1 | EXPECT_CALL(mockExec, cancel(_)).Times(2); | |
| 277 | ||||
| 278 | // For HPFP to work, events need to be scheduled after the next tooth. This makes sure the | |||
| 279 | // peak pos occurs after the next tooth. | |||
| 280 | 1 | engineConfiguration->hpfpPeakPos = 90; | ||
| 281 | // This will call the fast callback routine | |||
| 282 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->rpmCalculator.setRpmValue(1000); | |
| 283 | 1 | engine->engineState.injectionMass[0] = 0.05 /* cc/cyl */ * fuelDensity; | ||
| 284 | 1 | engineConfiguration->hpfpValvePin = Gpio::A2; // arbitrary | ||
| 285 | ||||
| 286 |
1/1✓ Branch 1 taken 1 time.
|
1 | hpfp.onFastCallback(); | |
| 287 | ||||
| 288 | 1 | auto const pinTurnOffAction{ action_s::make<HpfpController::pinTurnOff>((HpfpController*){}) }; | ||
| 289 | // First event was scheduled by setRpmValue with 0 injection mass. So, it's off. | |||
| 290 |
1/1✓ Branch 1 taken 1 time.
|
1 | eth.assertTriggerEvent("h0", 0, &hpfp.m_event, pinTurnOffAction, 270); | |
| 291 | ||||
| 292 | // Make the previous event happen, schedule the next. | |||
| 293 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 5 taken 1 time.
|
1 | engine->module<TriggerScheduler>()->scheduleEventsUntilNextTriggerTooth( | |
| 294 | 1000, tick_per_deg * 0, 180, 360); | |||
| 295 | // Mock executor doesn't run events, so we run it manually | |||
| 296 |
1/1✓ Branch 1 taken 1 time.
|
1 | HpfpController::pinTurnOff(&hpfp); | |
| 297 | ||||
| 298 | 1 | auto const pinTurnOnAction{ action_s::make<HpfpController::pinTurnOn>((HpfpController*){}) }; | ||
| 299 | // Now we should have a regular on/off event. | |||
| 300 |
1/1✓ Branch 1 taken 1 time.
|
1 | eth.assertTriggerEvent("h1", 0, &hpfp.m_event, pinTurnOnAction, 450 - 37.6923065f); | |
| 301 | ||||
| 302 | // Make it happen | |||
| 303 |
2/2✓ Branch 1 taken 1 time.
✓ Branch 5 taken 1 time.
|
1 | engine->module<TriggerScheduler>()->scheduleEventsUntilNextTriggerTooth( | |
| 304 | 1000, tick_per_deg * 180, 360, 540); | |||
| 305 | ||||
| 306 | // Since we have a mock scheduler, lets insert the correct timestamp in the scheduling | |||
| 307 | // struct. | |||
| 308 | 1 | hpfp.m_event.eventScheduling.setMomentNt(nt1); | ||
| 309 | ||||
| 310 |
1/1✓ Branch 1 taken 1 time.
|
1 | HpfpController::pinTurnOn(&hpfp); | |
| 311 | ||||
| 312 | // The off event goes directly to scheduleByAngle and is tested by the last EXPECT_CALL | |||
| 313 | // above. | |||
| 314 | 2 | } | ||
| 315 |