GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/launch/test_ignition_angle_advance.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 100.0% 91 0 91
Functions: 100.0% 33 0 33
Branches: 82.7% 43 0 52
Decisions: 100.0% 4 - 4

Line Branch Decision Exec Source
1 //
2 // Created by kifir on 5/27/24.
3 //
4 // Tests for functionality decscribed in https://github.com/rusefi/rusefi/issues/5611
5 //
6
7 #include "pch.h"
8
9 #include "launch_test_base.h"
10
11 namespace {
12 constexpr float TEST_IGNITION_650 = 15.3f;
13 constexpr float TEST_IGNITION_800 = 15.4f;
14 constexpr float TEST_IGNITION_1100 = 15.5f;
15 constexpr float TEST_IGNITION_1400 = 15.6f;
16 constexpr float TEST_IGNITION_1700 = 15.7f;
17 constexpr float TEST_IGNITION_2000 = 15.8f;
18 constexpr float TEST_IGNITION_2300 = 15.9f;
19 constexpr float TEST_IGNITION_2600 = 16.0f;
20 constexpr float TEST_IGNITION_2900 = 16.1f;
21 constexpr float TEST_IGNITION_3200 = 16.2f;
22 constexpr float TEST_IGNITION_3500 = 16.3f;
23 constexpr float TEST_IGNITION_3800 = 16.4f;
24 constexpr float TEST_IGNITION_4100 = 16.5f;
25 constexpr float TEST_IGNITION_4400 = 16.6f;
26 constexpr float TEST_IGNITION_4700 = 16.7f;
27 constexpr float TEST_IGNITION_7000 = 16.8f;
28
29 constexpr int TEST_LAUNCH_RPM = 3800;
30 constexpr int TEST_LAUNCH_RPM_WINDOW = 1800;
31 constexpr int TEST_SMOOTH_RETARD_END_RPM = 900;
32 constexpr int TEST_SMOOTH_RETARD_RPM_WINDOW_START = TEST_LAUNCH_RPM - TEST_LAUNCH_RPM_WINDOW;
33 constexpr int TEST_SMOOTH_RETARD_RPM_WINDOW_END = TEST_LAUNCH_RPM - TEST_SMOOTH_RETARD_END_RPM;
34 constexpr int TEST_SMOOTH_RETARD_RPM_WINDOW = TEST_SMOOTH_RETARD_RPM_WINDOW_END - TEST_SMOOTH_RETARD_RPM_WINDOW_START;
35
36 constexpr float TEST_LAUNCH_TIMING_RETARD = 17.0f;
37
38 class IgnitionAngleAdvanceTestConfig : public LaunchTestConfig {
39 public:
40 IgnitionAngleAdvanceTestConfig(
41 const std::optional<bool> launchControlEnabled,
42 const std::optional<bool> ignitionRetardEnable,
43 const std::optional<bool> smoothRetardMode,
44 const bool satisfySwitchSpeedThresholdAndTpsConditions
45 );
46 };
47
48 10 IgnitionAngleAdvanceTestConfig::IgnitionAngleAdvanceTestConfig(
49 const std::optional<bool> launchControlEnabled,
50 const std::optional<bool> ignitionRetardEnable,
51 const std::optional<bool> smoothRetardMode,
52 const bool satisfySwitchSpeedThresholdAndTpsConditions
53 10 ) {
54
1/1
✓ Branch 2 taken 10 times.
10 setLaunchControlEnabled(launchControlEnabled);
55
56
1/1
✓ Branch 4 taken 10 times.
10 setLaunchRpm({TEST_LAUNCH_RPM });
57
1/1
✓ Branch 4 taken 10 times.
10 setLaunchRpmWindow({TEST_LAUNCH_RPM_WINDOW });
58
1/1
✓ Branch 4 taken 10 times.
10 setLaunchCorrectionsEndRpm({TEST_SMOOTH_RETARD_END_RPM });
59
60
1/1
✓ Branch 2 taken 10 times.
10 setIgnitionRetardEnable({ ignitionRetardEnable });
61
1/1
✓ Branch 4 taken 10 times.
10 setIgnitionRetard({ TEST_LAUNCH_TIMING_RETARD });
62
1/1
✓ Branch 2 taken 10 times.
10 setSmoothRetardMode({ smoothRetardMode });
63
64
1/1
✓ Branch 5 taken 10 times.
10 setEnableIgnitionCut(true);
65
66 10 setSatisfyActivationSwitchSpeedAndTpsConditions(satisfySwitchSpeedThresholdAndTpsConditions);
67 10 }
68
69 struct IgnitionAngleAdvanceTestData {
70 const std::string context;
71 const int rpm;
72 const float expectedIgnitionAdvance;
73 const float epsilon = EPS5D;
74 };
75
76 #if (IGN_RPM_COUNT == 16) // the following test uses hardcoded test ignition table with 16 columns
77 class IgnitionAngleAdvanceTest : public LaunchTestBase {
78 protected:
79 void doTest(
80 const IgnitionAngleAdvanceTestConfig& config,
81 const std::vector<IgnitionAngleAdvanceTestData> &testData
82 );
83
84 static const std::vector<IgnitionAngleAdvanceTestData> TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE;
85 private:
86 void configureTestIgnitionTable();
87 };
88
89 10 void IgnitionAngleAdvanceTest::doTest(
90 const IgnitionAngleAdvanceTestConfig& config,
91 const std::vector<IgnitionAngleAdvanceTestData> &testData
92 ) {
93 10 configureTestIgnitionTable();
94 10 setUpTestConfig(config);
95
96
2/2
✓ Branch 7 taken 160 times.
✓ Branch 8 taken 10 times.
2/2
✓ Decision 'true' taken 160 times.
✓ Decision 'false' taken 10 times.
170 for (const IgnitionAngleAdvanceTestData &testDataItem: testData) {
97
1/1
✓ Branch 3 taken 160 times.
160 updateRpm(testDataItem.rpm);
98
2/6
✓ Branch 3 taken 160 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 160 times.
✗ Branch 10 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
160 EXPECT_NEAR(
99 testDataItem.expectedIgnitionAdvance,
100 engine->ignitionState.baseIgnitionAdvance,
101 testDataItem.epsilon
102
0/1
✗ Branch 1 not taken.
160 ) << testDataItem.context;
103 }
104 10 }
105
106 const std::vector<IgnitionAngleAdvanceTestData> IgnitionAngleAdvanceTest::TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE = {
107 { "TEST_IGNITION_650", 650, TEST_IGNITION_650 },
108 { "TEST_IGNITION_800", 800, TEST_IGNITION_800 },
109 { "TEST_IGNITION_1100", 1100, TEST_IGNITION_1100 },
110 { "TEST_IGNITION_1400", 1400, TEST_IGNITION_1400 },
111 { "TEST_IGNITION_1700", 1700, TEST_IGNITION_1700 },
112 /* We've entered smooth retard RPM window: */
113 { "TEST_IGNITION_2000", 2000, TEST_IGNITION_2000 },
114 { "TEST_IGNITION_2300", 2300, TEST_IGNITION_2300 },
115 { "TEST_IGNITION_2600", 2600, TEST_IGNITION_2600 },
116 { "TEST_IGNITION_2900", 2900, TEST_IGNITION_2900 },
117 /* See https://github.com/rusefi/rusefi/issues/5611#issuecomment-2137028838
118 * We've left smooth retard RPM window:
119 */
120 { "TEST_IGNITION_3200", 3200, TEST_IGNITION_3200 },
121 { "TEST_IGNITION_3500", 3500, TEST_IGNITION_3500 },
122 /* We've reached TEST_LAUNCH_RPM: */
123 { "TEST_IGNITION_3800", 3800, TEST_IGNITION_3800 },
124 { "TEST_IGNITION_4100", 4100, TEST_IGNITION_4100 },
125 { "TEST_IGNITION_4400", 4400, TEST_IGNITION_4400 },
126 { "TEST_IGNITION_4700", 4700, TEST_IGNITION_4700 },
127 { "TEST_IGNITION_7000", 7000, TEST_IGNITION_7000 }
128 };
129
130 10 void IgnitionAngleAdvanceTest::configureTestIgnitionTable() {
131 10 IgnitionTable testIgnitionTable;
132
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 10 times.
2/2
✓ Decision 'true' taken 160 times.
✓ Decision 'false' taken 10 times.
170 for (int loadIdx = 0; loadIdx < IGN_LOAD_COUNT; loadIdx++) {
133 160 testIgnitionTable[loadIdx][0] = TEST_IGNITION_650;
134 160 testIgnitionTable[loadIdx][1] = TEST_IGNITION_800;
135 160 testIgnitionTable[loadIdx][2] = TEST_IGNITION_1100;
136 160 testIgnitionTable[loadIdx][3] = TEST_IGNITION_1400;
137 160 testIgnitionTable[loadIdx][4] = TEST_IGNITION_1700;
138 160 testIgnitionTable[loadIdx][5] = TEST_IGNITION_2000;
139 160 testIgnitionTable[loadIdx][6] = TEST_IGNITION_2300;
140 160 testIgnitionTable[loadIdx][7] = TEST_IGNITION_2600;
141 160 testIgnitionTable[loadIdx][8] = TEST_IGNITION_2900;
142 160 testIgnitionTable[loadIdx][9] = TEST_IGNITION_3200;
143 160 testIgnitionTable[loadIdx][10] = TEST_IGNITION_3500;
144 160 testIgnitionTable[loadIdx][11] = TEST_IGNITION_3800;
145 160 testIgnitionTable[loadIdx][12] = TEST_IGNITION_4100;
146 160 testIgnitionTable[loadIdx][13] = TEST_IGNITION_4400;
147 160 testIgnitionTable[loadIdx][14] = TEST_IGNITION_4700;
148 160 testIgnitionTable[loadIdx][15] = TEST_IGNITION_7000;
149 static_assert(IGN_RPM_COUNT == 16);
150 };
151
2/2
✓ Branch 1 taken 10 times.
✓ Branch 4 taken 10 times.
10 getTestPersistentConfiguration().setIgnitionTable(testIgnitionTable);
152 10 }
153
154 4 TEST_F(IgnitionAngleAdvanceTest, withDisabledLaunchControlAndWithoutLaunchRetardWithSatisfiedLaunchConditions) {
155
2/2
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
1 doTest(
156 /* config = */ {
157 /* launchControlEnabled = */ {},
158 /* ignitionRetardEnable = */ {},
159 /* smoothRetardMode = */ {},
160 /* satisfySwitchSpeedThresholdAndTpsConditions = */ true
161 },
162 /* testData = */ TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE
163 );
164 1 }
165
166 4 TEST_F(
167 IgnitionAngleAdvanceTest,
168 withEnabledLaunchControlAndLaunchRetardWithoutSmoothWithSatisfiedLaunchConditions
169 ) {
170
5/7
✓ Branch 3 taken 1 time.
✓ Branch 16 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 30 taken 16 times.
✓ Branch 31 taken 1 time.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
20 doTest(
171 /* config = */ {
172 /* launchControlEnabled = */ { true },
173 /* ignitionRetardEnable = */ { true },
174 /* smoothRetardMode = */ { false },
175 /* satisfySwitchSpeedThresholdAndTpsConditions = */ true
176 },
177 /* testData = */ {
178 { "TEST_IGNITION_650", 650, TEST_IGNITION_650 },
179 { "TEST_IGNITION_800", 800, TEST_IGNITION_800 },
180 { "TEST_IGNITION_1100", 1100, TEST_IGNITION_1100 },
181 { "TEST_IGNITION_1400", 1400, TEST_IGNITION_1400 },
182 { "TEST_IGNITION_1700", 1700, TEST_IGNITION_1700 },
183 /* We've entered smooth retard RPM window: */
184 { "TEST_IGNITION_2000", 2000, TEST_LAUNCH_TIMING_RETARD },
185 { "TEST_IGNITION_2300", 2300, TEST_LAUNCH_TIMING_RETARD },
186 { "TEST_IGNITION_2600", 2600, TEST_LAUNCH_TIMING_RETARD },
187 { "TEST_IGNITION_2900", 2900, TEST_LAUNCH_TIMING_RETARD },
188 /* See https://github.com/rusefi/rusefi/issues/5611#issuecomment-2137028838
189 * We've left smooth retard RPM window:
190 */
191 { "TEST_IGNITION_3200", 3200, TEST_LAUNCH_TIMING_RETARD },
192 { "TEST_IGNITION_3500", 3500, TEST_LAUNCH_TIMING_RETARD },
193 /* We've reached TEST_LAUNCH_RPM: */
194 { "TEST_IGNITION_3800", 3800, TEST_LAUNCH_TIMING_RETARD },
195 { "TEST_IGNITION_4100", 4100, TEST_LAUNCH_TIMING_RETARD },
196 { "TEST_IGNITION_4400", 4400, TEST_LAUNCH_TIMING_RETARD },
197 { "TEST_IGNITION_4700", 4700, TEST_LAUNCH_TIMING_RETARD },
198 { "TEST_IGNITION_7000", 7000, TEST_LAUNCH_TIMING_RETARD },
199 }
200 );
201 4 }
202
203 4 TEST_F(
204 IgnitionAngleAdvanceTest,
205 withEnabledLaunchControlAndLaunchRetardAndLaunchSmoothRetardWithSatisfiedLaunchConditions
206 ) {
207
5/7
✓ Branch 3 taken 1 time.
✓ Branch 16 taken 1 time.
✓ Branch 19 taken 1 time.
✓ Branch 30 taken 16 times.
✓ Branch 31 taken 1 time.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
20 doTest(
208 /* config = */ {
209 /* launchControlEnabled = */ { true },
210 /* ignitionRetardEnable = */ { true },
211 /* smoothRetardMode = */ { true },
212 /* satisfySwitchSpeedThresholdAndTpsConditions = */ true
213 },
214 /* testData = */ {
215 { "TEST_IGNITION_650", 650, TEST_IGNITION_650 },
216 { "TEST_IGNITION_800", 800, TEST_IGNITION_800 },
217 { "TEST_IGNITION_1100", 1100, TEST_IGNITION_1100 },
218 { "TEST_IGNITION_1400", 1400, TEST_IGNITION_1400 },
219 { "TEST_IGNITION_1700", 1700, TEST_IGNITION_1700 },
220 /* We've entered smooth retard RPM window: */
221 { "TEST_IGNITION_2000", 2000, TEST_IGNITION_2000 },
222 {
223 "TEST_IGNITION_2300",
224 2300,
225 TEST_IGNITION_2300
226 + (2300.0f - TEST_SMOOTH_RETARD_RPM_WINDOW_START) *
227 (TEST_LAUNCH_TIMING_RETARD - TEST_IGNITION_2300) / TEST_SMOOTH_RETARD_RPM_WINDOW,
228 EPS2D //TODO: check if this precision loss is expected
229 },
230 {
231 "TEST_IGNITION_2600",
232 2600,
233 TEST_IGNITION_2600
234 + (2600.0f - TEST_SMOOTH_RETARD_RPM_WINDOW_START) *
235 (TEST_LAUNCH_TIMING_RETARD - TEST_IGNITION_2600) / TEST_SMOOTH_RETARD_RPM_WINDOW,
236 EPS2D //TODO: check if this precision loss is expected
237 },
238 { "TEST_IGNITION_2900", 2900, TEST_LAUNCH_TIMING_RETARD },
239 /* See https://github.com/rusefi/rusefi/issues/5611#issuecomment-2137028838
240 * We've left smooth retard RPM window:
241 */
242 { "TEST_IGNITION_3200", 3200, TEST_LAUNCH_TIMING_RETARD },
243 { "TEST_IGNITION_3500", 3500, TEST_LAUNCH_TIMING_RETARD },
244 /* We've reached TEST_LAUNCH_RPM: */
245 { "TEST_IGNITION_3800", 3800, TEST_LAUNCH_TIMING_RETARD },
246 { "TEST_IGNITION_4100", 4100, TEST_LAUNCH_TIMING_RETARD },
247 { "TEST_IGNITION_4400", 4400, TEST_LAUNCH_TIMING_RETARD },
248 { "TEST_IGNITION_4700", 4700, TEST_LAUNCH_TIMING_RETARD },
249 { "TEST_IGNITION_7000", 7000, TEST_LAUNCH_TIMING_RETARD }
250 }
251 );
252 4 }
253
254 /* Tests for https://github.com/rusefi/rusefi/issues/6571: */
255
256 4 TEST_F(
257 IgnitionAngleAdvanceTest,
258 withDisabledLaunchControlAndLaunchRetardWithoutSmoothWithSatisfiedLaunchConditions
259 ) {
260
2/2
✓ Branch 11 taken 1 time.
✓ Branch 14 taken 1 time.
1 doTest(
261 /* config = */ {
262 /* launchControlEnabled = */ { false },
263 /* ignitionRetardEnable = */ { true },
264 /* smoothRetardMode = */ { false },
265 /* satisfySwitchSpeedThresholdAndTpsConditions = */ true
266 },
267 /* testData = */ TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE
268 );
269 1 }
270
271 4 TEST_F(IgnitionAngleAdvanceTest, withDisabledLaunchControlAndLaunchRetardAndSmoothWithSatisfiedLaunchConditions) {
272
2/2
✓ Branch 11 taken 1 time.
✓ Branch 14 taken 1 time.
1 doTest(
273 /* config = */ {
274 /* launchControlEnabled = */ { false },
275 /* ignitionRetardEnable = */ { true },
276 /* smoothRetardMode = */ { true },
277 /* satisfySwitchSpeedThresholdAndTpsConditions = */ true
278 },
279 /* testData = */ TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE
280 );
281 1 }
282
283 /* Tests with unsatisfied launch conditions: */
284
285 4 TEST_F(
286 IgnitionAngleAdvanceTest,
287 withDisabledLaunchControlAndWithoutLaunchRetardWithDisabledSmoothRetardWithoutSatisfiedLaunchConditions
288 ) {
289
2/2
✓ Branch 11 taken 1 time.
✓ Branch 14 taken 1 time.
1 doTest(
290 /* config = */ {
291 /* launchControlEnabled = */ { false },
292 /* ignitionRetardEnable = */ { false },
293 /* smoothRetardMode = */ { false },
294 /* satisfySwitchSpeedThresholdAndTpsConditions = */ false
295 },
296 /* testData = */ TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE
297 );
298 1 }
299
300 4 TEST_F(
301 IgnitionAngleAdvanceTest,
302 withEnabledLaunchControlAndLaunchRetardWithoutSmoothAndSatisfiedLaunchConditions
303 ) {
304
2/2
✓ Branch 11 taken 1 time.
✓ Branch 14 taken 1 time.
1 doTest(
305 /* config = */ {
306 /* launchControlEnabled = */ { true },
307 /* ignitionRetardEnable = */ { true },
308 /* smoothRetardMode = */ { false },
309 /* satisfySwitchSpeedThresholdAndTpsConditions = */ false
310 },
311 /* testData = */ TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE
312 );
313 1 }
314
315 4 TEST_F(
316 IgnitionAngleAdvanceTest,
317 withEnabledLaunchControlAndLaunchRetardAndLaunchSmoothRetardWithoutSatisfiedLaunchConditions
318 ) {
319
2/2
✓ Branch 11 taken 1 time.
✓ Branch 14 taken 1 time.
1 doTest(
320 /* config = */ {
321 /* launchControlEnabled = */ { true },
322 /* ignitionRetardEnable = */ { true },
323 /* smoothRetardMode = */ { true },
324 /* satisfySwitchSpeedThresholdAndTpsConditions = */ false
325 },
326 /* testData = */ TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE
327 );
328 1 }
329
330 4 TEST_F(
331 IgnitionAngleAdvanceTest,
332 withDisabledLaunchControlAndLaunchRetardWithoutSmoothAndWithoutSatisfiedLaunchConditions
333 ) {
334
2/2
✓ Branch 11 taken 1 time.
✓ Branch 14 taken 1 time.
1 doTest(
335 /* config = */ {
336 /* launchControlEnabled = */ { false },
337 /* ignitionRetardEnable = */ { true },
338 /* smoothRetardMode = */ { false },
339 /* satisfySwitchSpeedThresholdAndTpsConditions = */ false
340 },
341 /* testData = */ TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE
342 );
343 1 }
344
345 4 TEST_F(
346 IgnitionAngleAdvanceTest,
347 withDisabledLaunchControlAndLaunchRetardAndSmoothAndWithoutSatisfiedLaunchConditions
348 ) {
349
2/2
✓ Branch 11 taken 1 time.
✓ Branch 14 taken 1 time.
1 doTest(
350 /* config = */ {
351 /* launchControlEnabled = */ { false },
352 /* ignitionRetardEnable = */ { true },
353 /* smoothRetardMode = */ { true },
354 /* satisfySwitchSpeedThresholdAndTpsConditions = */ false
355 },
356 /* testData = */ TEST_DATA_WITHOUT_LAUNCH_ANGLE_ADVANCE
357 );
358 1 }
359 #endif //(IGN_RPM_COUNT == 16)
360 }
361