GCC Code Coverage Report


Directory: ./
File: firmware/controllers/algo/airmass/maf_airmass.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 38.5% 10 0 26
Functions: 33.3% 1 0 3
Branches: 5.9% 1 0 17
Decisions: 10.0% 1 - 10

Line Branch Decision Exec Source
1 #include "pch.h"
2
3 #include "maf_airmass.h"
4 #include "maf.h"
5 #include "fuel_math.h"
6
7 float MafAirmass::getMaf() const {
8 auto maf = Sensor::get(SensorType::Maf);
9
10 if (Sensor::hasSensor(SensorType::Maf2)) {
11 auto maf2 = Sensor::get(SensorType::Maf2);
12
13 if (maf && maf2) {
14 // Both MAFs work, return the sum
15 return maf.Value + maf2.Value;
16 } else if (maf) {
17 // MAF 1 works, but not MAF 2, so double the value from #1
18 return 2 * maf.Value;
19 } else if (maf2) {
20 // MAF 2 works, but not MAF 1, so double the value from #2
21 return 2 * maf2.Value;
22 } else {
23 // Both MAFs are broken, give up.
24 return 0;
25 }
26 } else {
27 return maf.value_or(0);
28 }
29 }
30
31 AirmassResult MafAirmass::getAirmass(float rpm, bool postState) {
32 float maf = getMaf();
33
34 return getAirmassImpl(maf, rpm, postState);
35 }
36
37 /**
38 * Function block now works to create a standardised load from the cylinder filling as well as tune fuel via VE table.
39 * @return total duration of fuel injection per engine cycle, in milliseconds
40 */
41 1 AirmassResult MafAirmass::getAirmassImpl(float massAirFlow, float rpm, bool postState) const {
42 // If the engine is stopped, MAF is meaningless
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1/2
✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 time.
1 if (rpm == 0) {
44 return {};
45 }
46
47 // kg/hr -> g/s
48 1 float gramPerSecond = massAirFlow * 1000 / 3600;
49
50 // 1/min -> 1/s
51 1 float revsPerSecond = rpm / 60.0f;
52 1 mass_t airPerRevolution = gramPerSecond / revsPerSecond;
53
54 // Now we have to divide among cylinders - on a 4 stroke, half of the cylinders happen every revolution
55 // This math is floating point to work properly on engines with odd cylinder count
56 1 float halfCylCount = engineConfiguration->cylindersCount / 2.0f;
57
58 1 mass_t cylinderAirmass = airPerRevolution / halfCylCount;
59
60 //Create % load for fuel table using relative naturally aspirated cylinder filling
61 1 float airChargeLoad = 100 * cylinderAirmass / getStandardAirCharge();
62
63 //Correct air mass by VE table
64 1 mass_t correctedAirmass = cylinderAirmass * getVe(rpm, airChargeLoad, postState);
65
66 return {
67 correctedAirmass,
68 airChargeLoad, // AFR/VE/ignition table Y axis
69 1 };
70 }
71