GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/test_hpfp.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 199 0 199
Functions: 100.0% 15 0 15
Branches: 54.4% 224 0 412
Decisions: 100.0% 36 - 36

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