Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | #include "pch.h" | |||
2 | #include "fuel_math.h" | |||
3 | #include "alphan_airmass.h" | |||
4 | #include "maf_airmass.h" | |||
5 | #include "speed_density_airmass.h" | |||
6 | #include "util/injection_crank_helper.h" | |||
7 | ||||
8 | using ::testing::StrictMock; | |||
9 | using ::testing::FloatNear; | |||
10 | using ::testing::InSequence; | |||
11 | using ::testing::_; | |||
12 | ||||
13 | 4 | TEST(FuelMath, getStandardAirCharge) { | ||
14 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
15 | ||||
16 | // Miata 1839cc 4cyl | |||
17 | 1 | engineConfiguration->displacement = 1.839f; | ||
18 | 1 | engineConfiguration->cylindersCount = 4; | ||
19 | ||||
20 |
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(0.5535934f, getStandardAirCharge()); | |
21 | ||||
22 | // LS 5.3 liter v8 | |||
23 | 1 | engineConfiguration->displacement = 5.327f; | ||
24 | 1 | engineConfiguration->cylindersCount = 8; | ||
25 | ||||
26 |
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(0.80179232f, getStandardAirCharge()); | |
27 | ||||
28 | // Chainsaw - single cylinder 32cc | |||
29 | 1 | engineConfiguration->displacement = 0.032f; | ||
30 | 1 | engineConfiguration->cylindersCount = 1; | ||
31 |
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(0.038531788f, getStandardAirCharge()); | |
32 | ||||
33 | // Leopard 1 47.666 liter v12 | |||
34 | 1 | engineConfiguration->displacement = 47.666f; | ||
35 | 1 | engineConfiguration->cylindersCount = 12; | ||
36 | ||||
37 |
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(4.782959f, getStandardAirCharge()); | |
38 | 2 | } | ||
39 | ||||
40 | 4 | TEST(AirmassModes, AlphaNNormal) { | ||
41 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
42 | // 4 cylinder 4 liter = easy math | |||
43 | 1 | engineConfiguration->displacement = 4.0f; | ||
44 | 1 | engineConfiguration->cylindersCount = 4; | ||
45 | ||||
46 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockVp3d> veTable; | |
47 | ||||
48 |
6/6✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 16 taken 1 time.
✓ Branch 20 taken 1 time.
|
3 | EXPECT_CALL(veTable, getValue(1200, FloatNear(0.71f, EPS4D))) | |
49 |
3/3✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
|
3 | .WillOnce(Return(35.0f)); | |
50 | ||||
51 |
1/1✓ Branch 2 taken 1 time.
|
1 | AlphaNAirmass dut(veTable); | |
52 | ||||
53 | // that's 0.71% not 71% | |||
54 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 0.71f); | |
55 | ||||
56 | // Mass of 1 liter of air * VE | |||
57 | 1 | mass_t expectedAirmass = 1.2047f * 0.35f; | ||
58 | ||||
59 |
1/1✓ Branch 1 taken 1 time.
|
1 | auto result = dut.getAirmass(1200, false); | |
60 |
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_NEAR(result.CylinderAirmass, expectedAirmass, EPS4D); | |
61 |
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_NEAR(result.EngineLoadPercent, 0.71f, EPS4D); | |
62 | 2 | } | ||
63 | ||||
64 | 4 | TEST(AirmassModes, AlphaNUseIat) { | ||
65 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
66 | // 4 cylinder 4 liter = easy math | |||
67 | 1 | engineConfiguration->displacement = 4.0f; | ||
68 | 1 | engineConfiguration->cylindersCount = 4; | ||
69 | ||||
70 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockVp3d> veTable; | |
71 | ||||
72 |
6/6✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 16 taken 1 time.
✓ Branch 20 taken 1 time.
|
3 | EXPECT_CALL(veTable, getValue(1200, FloatNear(0.71f, EPS4D))) | |
73 |
3/3✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
|
3 | .WillRepeatedly(Return(35.0f)); | |
74 | ||||
75 |
1/1✓ Branch 2 taken 1 time.
|
1 | AlphaNAirmass dut(veTable); | |
76 | ||||
77 | // that's 0.71% not 71% | |||
78 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 0.71f); | |
79 | ||||
80 | // Mass of 1 liter of air * VE | |||
81 | 1 | mass_t expectedAirmass = 1.2047f * 0.35f; | ||
82 | ||||
83 |
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(dut.getAirmass(1200, false).CylinderAirmass, expectedAirmass, EPS4D); | |
84 | ||||
85 | 1 | engineConfiguration->alphaNUseIat = true; | ||
86 | ||||
87 | // Cold we get more airmass | |||
88 | 1 | float expectedAirmassCold = expectedAirmass * (273.0f + 20) / (273.0f + 0); | ||
89 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Iat, 0); | |
90 |
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(dut.getAirmass(1200, false).CylinderAirmass, expectedAirmassCold, EPS4D); | |
91 | ||||
92 | // Hot we get less airmass | |||
93 | 1 | float expectedAirmassHot = expectedAirmass * (273.0f + 20) / (273.0f + 40); | ||
94 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Iat, 40); | |
95 |
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(dut.getAirmass(1200, false).CylinderAirmass, expectedAirmassHot, EPS4D); | |
96 | 2 | } | ||
97 | ||||
98 | 4 | TEST(AirmassModes, AlphaNFailedTps) { | ||
99 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
100 | ||||
101 | // Shouldn't get called | |||
102 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockVp3d> veTable; | |
103 | ||||
104 |
1/1✓ Branch 2 taken 1 time.
|
1 | AlphaNAirmass dut(veTable); | |
105 | ||||
106 | // explicitly reset the sensor | |||
107 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::resetMockValue(SensorType::Tps1); | |
108 | // Ensure that it's actually failed | |||
109 |
3/9✓ Branch 3 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✓ Branch 33 taken 1 time.
✗ Branch 34 not taken.
|
1 | ASSERT_FALSE(Sensor::get(SensorType::Tps1).Valid); | |
110 | ||||
111 |
1/1✓ Branch 2 taken 1 time.
|
1 | auto result = dut.getAirmass(1200, false); | |
112 |
2/6✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
|
1 | EXPECT_EQ(result.CylinderAirmass, 0); | |
113 | 1 | } | ||
114 | ||||
115 | 4 | TEST(AirmassModes, MafNormal) { | ||
116 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
117 | 1 | engineConfiguration->cylindersCount = 4; | ||
118 | 1 | engineConfiguration->displacement = 1.3; | ||
119 | 1 | engineConfiguration->fuelAlgorithm = engine_load_mode_e::LM_REAL_MAF; | ||
120 | 1 | engineConfiguration->injector.flow = 200; | ||
121 | ||||
122 |
1/1✓ Branch 2 taken 1 time.
|
1 | MockVp3d veTable; | |
123 | // Ensure that the correct cell is read from the VE table | |||
124 |
6/6✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 16 taken 1 time.
✓ Branch 20 taken 1 time.
|
3 | EXPECT_CALL(veTable, getValue(6000, FloatNear(70.9814f, EPS4D))) | |
125 |
3/3✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
|
3 | .WillOnce(Return(75.0f)); | |
126 | ||||
127 |
1/1✓ Branch 2 taken 1 time.
|
1 | MafAirmass dut(veTable); | |
128 | ||||
129 |
1/1✓ Branch 1 taken 1 time.
|
1 | auto airmass = dut.getAirmassImpl(200, 6000, false); | |
130 | ||||
131 | // Check results | |||
132 |
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_NEAR(0.277777f * 0.75f, airmass.CylinderAirmass, EPS4D); | |
133 |
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_NEAR(70.9814f, airmass.EngineLoadPercent, EPS4D); | |
134 | 2 | } | ||
135 | ||||
136 | 4 | TEST(AirmassModes, VeOverride) { | ||
137 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockVp3d> veTable; | |
138 | ||||
139 | { | |||
140 |
1/1✓ Branch 2 taken 1 time.
|
1 | InSequence is; | |
141 | ||||
142 | // Default | |||
143 |
8/8✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 29 taken 1 time.
|
1 | EXPECT_CALL(veTable, getValue(_, 10.0f)).WillOnce(Return(0)); | |
144 | // TPS | |||
145 |
8/8✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 29 taken 1 time.
|
1 | EXPECT_CALL(veTable, getValue(_, 30.0f)).WillOnce(Return(0)); | |
146 | 1 | } | ||
147 | ||||
148 | struct DummyAirmassModel : public AirmassVeModelBase { | |||
149 | DummyAirmassModel(const ValueProvider3D& veTable) : AirmassVeModelBase(veTable) {} | |||
150 | ||||
151 | AirmassResult getAirmass(float rpm, bool postState) override { | |||
152 | // Default load value 10, will be overriden | |||
153 | getVe(rpm, 10.0f, postState); | |||
154 | ||||
155 | return {}; | |||
156 | } | |||
157 | }; | |||
158 | ||||
159 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
160 |
1/1✓ Branch 2 taken 1 time.
|
1 | DummyAirmassModel dut(veTable); | |
161 | ||||
162 | // Use default mode - will call with 10 | |||
163 |
1/1✓ Branch 1 taken 1 time.
|
1 | dut.getAirmass(0, true); | |
164 |
2/6✓ Branch 3 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 18 not taken.
|
1 | EXPECT_FLOAT_EQ(engine->engineState.veTableYAxis, 10.0f); | |
165 | ||||
166 | // Override to TPS | |||
167 | 1 | engineConfiguration->veOverrideMode = VE_TPS; | ||
168 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 30.0f); | |
169 |
1/1✓ Branch 1 taken 1 time.
|
1 | dut.getAirmass(0, true); | |
170 |
2/6✓ Branch 3 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 18 not taken.
|
1 | EXPECT_FLOAT_EQ(engine->engineState.veTableYAxis, 30.0f); | |
171 | 2 | } | ||
172 | ||||
173 | 4 | TEST(AirmassModes, FallbackMap) { | ||
174 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockVp3d> veTable; | |
175 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockVp3d> mapFallback; | |
176 | ||||
177 | // Failed map -> use 75 | |||
178 | { | |||
179 |
1/1✓ Branch 2 taken 1 time.
|
1 | InSequence is; | |
180 | ||||
181 | // Working map -> return 33 (should be unused) | |||
182 |
8/8✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 29 taken 1 time.
|
1 | EXPECT_CALL(mapFallback, getValue(1234, 20)).WillOnce(Return(33)); | |
183 | ||||
184 | // Failed map -> use 75 | |||
185 |
8/8✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 29 taken 1 time.
|
1 | EXPECT_CALL(mapFallback, getValue(5678, 20)).WillOnce(Return(75)); | |
186 | 1 | } | ||
187 | ||||
188 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
189 | ||||
190 |
1/1✓ Branch 2 taken 1 time.
|
1 | SpeedDensityAirmass dut(veTable, mapFallback); | |
191 | ||||
192 | // TPS at 20% | |||
193 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 20); | |
194 | ||||
195 | // Working MAP sensor at 40 kPa | |||
196 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Map, 40); | |
197 |
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(dut.getMap(1234, false), 40); | |
198 | ||||
199 | // Failed MAP sensor, should use table | |||
200 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::resetMockValue(SensorType::Map); | |
201 |
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(dut.getMap(5678, false), 75); | |
202 | 2 | } | ||
203 | ||||
204 | void setInjectionMode(int value); | |||
205 | ||||
206 | #if FUEL_RPM_COUNT == 16 | |||
207 | 4 | TEST(FuelMath, testDifferentInjectionModes) { | ||
208 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
209 |
1/1✓ Branch 1 taken 1 time.
|
1 | setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð); | |
210 | ||||
211 |
5/5✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 17 taken 1 time.
|
3 | EXPECT_CALL(*eth.mockAirmass, getAirmass(_, _)) | |
212 |
3/3✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
|
3 | .WillRepeatedly(Return(AirmassResult{1.3440001f, 50.0f})); | |
213 | ||||
214 |
1/1✓ Branch 1 taken 1 time.
|
1 | setInjectionMode((int)IM_BATCH); | |
215 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
216 |
2/7✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ( 20, engine->engineState.injectionDuration) << "injection while batch"; | |
217 | ||||
218 |
1/1✓ Branch 1 taken 1 time.
|
1 | setInjectionMode((int)IM_SIMULTANEOUS); | |
219 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
220 |
2/7✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ( 10, engine->engineState.injectionDuration) << "injection while simultaneous"; | |
221 | ||||
222 |
1/1✓ Branch 1 taken 1 time.
|
1 | setInjectionMode((int)IM_SEQUENTIAL); | |
223 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
224 |
2/7✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ( 40, engine->engineState.injectionDuration) << "injection while IM_SEQUENTIAL"; | |
225 | ||||
226 |
1/1✓ Branch 1 taken 1 time.
|
1 | setInjectionMode((int)IM_SINGLE_POINT); | |
227 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
228 |
2/7✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
|
1 | EXPECT_FLOAT_EQ( 40, engine->engineState.injectionDuration) << "injection while IM_SINGLE_POINT"; | |
229 |
3/8✓ Branch 3 taken 1 time.
✓ Branch 8 taken 1 time.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 time.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✗ Branch 25 not taken.
✗ Branch 28 not taken.
|
1 | EXPECT_EQ( 0u, eth.recentWarnings()->getCount()) << "warningCounter#testDifferentInjectionModes"; | |
230 | 2 | } | ||
231 | #endif //FUEL_RPM_COUNT == 16 | |||
232 | ||||
233 | #if FUEL_RPM_COUNT == 16 | |||
234 | 4 | TEST(FuelMath, deadtime) { | ||
235 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
236 | ||||
237 |
1/1✓ Branch 1 taken 1 time.
|
1 | setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð); | |
238 | ||||
239 |
5/5✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 17 taken 1 time.
|
3 | EXPECT_CALL(*eth.mockAirmass, getAirmass(_, _)) | |
240 |
3/3✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
|
3 | .WillRepeatedly(Return(AirmassResult{1.3440001f, 50.0f})); | |
241 | ||||
242 | // First test with no deadtime | |||
243 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
244 |
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( 20, engine->engineState.injectionDuration); | |
245 | ||||
246 | // Now add some deadtime | |||
247 |
1/1✓ Branch 1 taken 1 time.
|
1 | setFlatInjectorLag(2.0f); | |
248 | ||||
249 | // Should have deadtime now! | |||
250 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
251 |
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( 20 + 2, engine->engineState.injectionDuration); | |
252 | 2 | } | ||
253 | #endif //FUEL_RPM_COUNT == 16 | |||
254 | ||||
255 | #ifndef SUPPRESS_FUEL_MATH_FUEL_TRIM_TEST | |||
256 | #if FUEL_RPM_COUNT == 16 | |||
257 | 4 | TEST(FuelMath, CylinderFuelTrim) { | ||
258 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
259 | ||||
260 |
5/5✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 13 taken 1 time.
✓ Branch 17 taken 1 time.
|
3 | EXPECT_CALL(*eth.mockAirmass, getAirmass(_, _)) | |
261 |
3/3✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
|
3 | .WillRepeatedly(Return(AirmassResult{1, 50.0f})); | |
262 | ||||
263 |
1/1✓ Branch 1 taken 1 time.
|
1 | setTable(config->fuelTrims[0].table, -4); | |
264 |
1/1✓ Branch 1 taken 1 time.
|
1 | setTable(config->fuelTrims[1].table, -2); | |
265 |
1/1✓ Branch 1 taken 1 time.
|
1 | setTable(config->fuelTrims[2].table, 2); | |
266 |
1/1✓ Branch 1 taken 1 time.
|
1 | setTable(config->fuelTrims[3].table, 4); | |
267 | ||||
268 | // run the fuel math | |||
269 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
270 | ||||
271 | // Check that each cylinder gets the expected amount of fuel | |||
272 | 1 | float unadjusted = 0.072142f; | ||
273 |
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_NEAR(engine->engineState.injectionMass[0], unadjusted * 0.96, EPS4D); | |
274 |
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_NEAR(engine->engineState.injectionMass[1], unadjusted * 0.98, EPS4D); | |
275 |
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_NEAR(engine->engineState.injectionMass[2], unadjusted * 1.02, EPS4D); | |
276 |
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_NEAR(engine->engineState.injectionMass[3], unadjusted * 1.04, EPS4D); | |
277 | 2 | } | ||
278 | #endif //FUEL_RPM_COUNT == 16 | |||
279 | #endif | |||
280 | ||||
281 | struct MockIdle : public MockIdleController { | |||
282 | bool isIdling = false; | |||
283 | ||||
284 | 24 | bool isIdlingOrTaper() const override { | ||
285 | 24 | return isIdling; | ||
286 | } | |||
287 | }; | |||
288 | ||||
289 | 4 | TEST(FuelMath, IdleVeTable) { | ||
290 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
291 | ||||
292 |
1/1✓ Branch 2 taken 1 time.
|
1 | MockAirmass dut; | |
293 | ||||
294 | // Install mock idle controller | |||
295 |
1/1✓ Branch 2 taken 1 time.
|
1 | MockIdle idler; | |
296 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->engineModules.get<IdleController>().set(&idler); | |
297 | ||||
298 | // Main VE table returns 50 | |||
299 |
8/8✓ Branch 3 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 1 time.
✓ Branch 14 taken 1 time.
✓ Branch 18 taken 1 time.
✓ Branch 23 taken 1 time.
✓ Branch 26 taken 1 time.
✓ Branch 29 taken 1 time.
|
1 | EXPECT_CALL(dut.veTable, getValue(_, _)).WillRepeatedly(Return(50)); | |
300 | ||||
301 | // Idle VE table returns 40 | |||
302 | 1 | setTable(config->idleVeTable, 40); | ||
303 | ||||
304 | // Enable separate idle VE table | |||
305 | 1 | engineConfiguration->useSeparateVeForIdle = true; | ||
306 | 1 | engineConfiguration->idlePidDeactivationTpsThreshold = 10; | ||
307 | ||||
308 | // Set TPS so this works | |||
309 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 0); | |
310 | ||||
311 | // Gets normal VE table | |||
312 | 1 | idler.isIdling = false; | ||
313 |
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(dut.getVe(1000, 50, false), 0.5f); | |
314 | ||||
315 | // Gets idle VE table | |||
316 | 1 | idler.isIdling = true; | ||
317 |
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(dut.getVe(1000, 50, false), 0.4f); | |
318 | ||||
319 | // Below half threshold, fully use idle VE table | |||
320 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 0); | |
321 |
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(dut.getVe(1000, 50, false), 0.4f); | |
322 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 2); | |
323 |
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(dut.getVe(1000, 50, false), 0.4f); | |
324 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 5); | |
325 |
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(dut.getVe(1000, 50, false), 0.4f); | |
326 | ||||
327 | // As TPS approaches idle threshold, phase-out the idle VE table | |||
328 | ||||
329 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 6); | |
330 |
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(dut.getVe(1000, 50, false), 0.42f); | |
331 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 8); | |
332 |
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(dut.getVe(1000, 50, false), 0.46f); | |
333 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 10); | |
334 |
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(dut.getVe(1000, 50, false), 0.5f); | |
335 | 2 | } | ||
336 | ||||
337 | 4 | TEST(FuelMath, getCycleFuelMassTest) { | ||
338 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
339 |
1/1✓ Branch 1 taken 1 time.
|
1 | setLinearCurve(config->crankingTpsCoef, /*from*/1, /*to*/8, 1); | |
340 |
1/1✓ Branch 1 taken 1 time.
|
1 | setTestFuelCrankingTable(4000 * 1.5f); | |
341 | ||||
342 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::DriverThrottleIntent, 35.0f); | |
343 | ||||
344 | // test running fuel as crank fuel case | |||
345 | 1 | engineConfiguration->useRunningMathForCranking = true; | ||
346 |
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(getCycleFuelMass(true, 0.05f), 0.171f, EPS3D); | |
347 | ||||
348 | 1 | engineConfiguration->useRunningMathForCranking = false; | ||
349 | ||||
350 | // simulate cranking | |||
351 |
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 (size_t i = 0; i < 5; i++) { |
352 |
1/1✓ Branch 1 taken 5 times.
|
5 | engine->rpmCalculator.onNewEngineCycle(); | |
353 | } | |||
354 | ||||
355 |
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(getCycleFuelMass(true, 0.05f), 20.571f, EPS3D); | |
356 |
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_NEAR(engine->engineState.crankingFuel.coolantTemperatureCoefficient, 1, EPS3D); | |
357 |
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_NEAR(engine->engineState.crankingFuel.tpsCoefficient, 3.428f, EPS3D); | |
358 | ||||
359 |
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 (size_t i = 0; i < 10; i++) { |
360 |
1/1✓ Branch 1 taken 10 times.
|
10 | engine->rpmCalculator.onNewEngineCycle(); | |
361 | } | |||
362 | ||||
363 |
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(getCycleFuelMass(true, 0.05f), 20.571f, EPS3D); | |
364 |
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_NEAR(engine->engineState.crankingFuel.coolantTemperatureCoefficient, 1, EPS3D); | |
365 |
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_NEAR(engine->engineState.crankingFuel.tpsCoefficient, 3.428f, EPS3D); | |
366 | ||||
367 | // simulate TPS error: | |||
368 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setInvalidMockValue(SensorType::DriverThrottleIntent); | |
369 |
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 (size_t i = 0; i < 10; i++) { |
370 |
1/1✓ Branch 1 taken 10 times.
|
10 | engine->rpmCalculator.onNewEngineCycle(); | |
371 | } | |||
372 | ||||
373 |
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(getCycleFuelMass(true, 0.05f), 6.0f, EPS3D); | |
374 |
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_NEAR(engine->engineState.crankingFuel.tpsCoefficient, 1, EPS3D); | |
375 | 2 | } | ||
376 | ||||
377 | 4 | TEST(FuelMath, postCrankingFactorAxis){ | ||
378 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
379 |
1/1✓ Branch 1 taken 1 time.
|
1 | setupSimpleTestEngineWithMafAndTT_ONE_trigger(ð); | |
380 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
381 |
1/1✓ Branch 1 taken 1 time.
|
1 | setTestFuelCrankingTable(4000 * 1.5f); | |
382 | ||||
383 | // simulate cranking | |||
384 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 30 times.
✓ Decision 'false' taken 1 time.
|
31 | for (size_t i = 0; i < 30; i++) { |
385 |
1/1✓ Branch 1 taken 30 times.
|
30 | engine->rpmCalculator.onNewEngineCycle(); | |
386 | } | |||
387 |
1/1✓ Branch 1 taken 1 time.
|
1 | setLinearCurve(config->postCrankingCLTBins, /*from*/-20, /*to*/80, 20); | |
388 |
1/1✓ Branch 1 taken 1 time.
|
1 | setLinearCurve(config->postCrankingDurationBins, /*from*/0, /*to*/150, 40); | |
389 | 1 | setTable(config->postCrankingFactor, 5); | ||
390 | ||||
391 | 1 | config->postCrankingFactor[0][0] = 1; | ||
392 | 1 | config->postCrankingFactor[0][1] = 1; | ||
393 | ||||
394 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Clt, -20); | |
395 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
396 | ||||
397 |
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_NEAR(engine->fuelComputer.running.postCrankingFuelCorrection, 1, EPS3D); | |
398 | ||||
399 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Clt, 70); | |
400 |
1/1✓ Branch 1 taken 1 time.
|
1 | engine->periodicFastCallback(); | |
401 |
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_NEAR(engine->fuelComputer.running.postCrankingFuelCorrection, 5, EPS3D); | |
402 | 2 | } | ||
403 | ||||
404 | ||||
405 | 4 | TEST(AirmassModes, PredictiveMapCalculation) { | ||
406 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockVp3d> veTable; | |
407 |
1/1✓ Branch 2 taken 1 time.
|
1 | StrictMock<MockVp3d> mapFallback; | |
408 | ||||
409 | // Configure the mock MAP estimation table to return specific values | |||
410 |
5/5✓ Branch 2 taken 1 time.
✓ Branch 6 taken 1 time.
✓ Branch 9 taken 1 time.
✓ Branch 12 taken 1 time.
✓ Branch 16 taken 1 time.
|
3 | EXPECT_CALL(mapFallback, getValue(1500, 30.0f)) | |
411 |
3/3✓ Branch 5 taken 1 time.
✓ Branch 8 taken 1 time.
✓ Branch 11 taken 1 time.
|
3 | .WillRepeatedly(Return(85.0f)); // Predicted MAP is 85 kPa | |
412 | ||||
413 |
1/1✓ Branch 2 taken 1 time.
|
1 | EngineTestHelper eth(engine_type_e::TEST_ENGINE); | |
414 | ||||
415 | // Configure engine for predictive MAP mode | |||
416 | 1 | engineConfiguration->accelEnrichmentMode = AE_MODE_PREDICTIVE_MAP; | ||
417 | ||||
418 | // FIXME! setLinearCurve(config->predictiveMapBlendDurationValues, /*value*/0.5, /*precision*/0.1); | |||
419 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 time.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 1 time.
|
5 | for (auto index = 0;index < efi::size(config->predictiveMapBlendDurationValues);index++) { |
420 | 4 | config->predictiveMapBlendDurationValues[index] = 0.5f; | ||
421 | } | |||
422 | ||||
423 | // Create our speed density airmass model | |||
424 |
1/1✓ Branch 2 taken 1 time.
|
1 | SpeedDensityAirmass dut(veTable, mapFallback); | |
425 | ||||
426 | // Setup TPS sensor | |||
427 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Tps1, 30.0f); | |
428 | ||||
429 | // Setup MAP sensor | |||
430 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Map, 65.0f); | |
431 | ||||
432 |
1/1✓ Branch 1 taken 1 time.
|
1 | auto& tpsAccel = *engine->module<TpsAccelEnrichment>(); | |
433 | // Without an acceleration event, we should get the actual MAP sensor value | |||
434 |
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(dut.getMap(1500, false), 65.0f); | |
435 | ||||
436 | // Now trigger acceleration event | |||
437 | 1 | tpsAccel.m_accelEventJustOccurred = true; | ||
438 | ||||
439 | // Now the predictive MAP should be used, which is 85 kPa from the map estimation table | |||
440 |
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(dut.getMap(1500, true), 85.0f); | |
441 | ||||
442 | // Subsequent calls should still give predicted until blend starts | |||
443 |
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(dut.getMap(1500, false), 85.0f); | |
444 | ||||
445 | // Test at 25% blend progress (75% predicted, 25% actual) | |||
446 | // Simulate passing 25% of blend time (125ms) | |||
447 |
1/1✓ Branch 1 taken 1 time.
|
1 | eth.moveTimeForwardMs(125); // 25% of 500ms | |
448 | // Expected: 85 - (85-65) * 0.25 = 85 - 5 = 80 | |||
449 |
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(dut.getMap(1500, false), 80.0f, EPS4D); | |
450 | ||||
451 | // At 50% blend progress | |||
452 |
1/1✓ Branch 1 taken 1 time.
|
1 | eth.moveTimeForwardMs(125); // Now at 250ms | |
453 | // Expected: 85 - (85-65) * 0.5 = 85 - 10 = 75 | |||
454 |
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(dut.getMap(1500, false), 75.0f, EPS4D); | |
455 | ||||
456 | // At 75% blend progress | |||
457 |
1/1✓ Branch 1 taken 1 time.
|
1 | eth.moveTimeForwardMs(125); // Now at 375ms | |
458 | // Expected: 85 - (85-65) * 0.75 = 85 - 15 = 70 | |||
459 |
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(dut.getMap(1500, false), 70.0f, EPS4D); | |
460 | ||||
461 | // Test after blend is complete - should return to sensor value | |||
462 | // Move time past blend duration (more than 500ms total) | |||
463 |
1/1✓ Branch 1 taken 1 time.
|
1 | eth.moveTimeForwardMs(125); // Now at 500ms | |
464 | // Should be back to the actual MAP value | |||
465 |
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(dut.getMap(1500, false), 65.0f); | |
466 | ||||
467 | // Test MAP prediction cancellation | |||
468 | 1 | tpsAccel.m_accelEventJustOccurred = true; | ||
469 |
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(dut.getMap(1500, false), 85.0f); | |
470 | ||||
471 | // Now increase the actual MAP to exceed the predicted value | |||
472 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::setMockValue(SensorType::Map, 90.0f); | |
473 | ||||
474 | // Prediction should be canceled, and we should get the actual MAP | |||
475 |
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(dut.getMap(1500, false), 90.0f); | |
476 | ||||
477 | // 5. Test with failed MAP sensor | |||
478 |
1/1✓ Branch 1 taken 1 time.
|
1 | Sensor::resetMockValue(SensorType::Map); | |
479 | ||||
480 | // Should use the fallback MAP from the table | |||
481 |
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(dut.getMap(1500, false), 85.0f); | |
482 | 2 | } | ||
483 |