Line | Branch | Decision | Exec | Source |
---|---|---|---|---|
1 | #include "pch.h" | |||
2 | ||||
3 | #include "ac_control.h" | |||
4 | #include "deadband.h" | |||
5 | #include "max_limit_with_hysteresis.h" | |||
6 | ||||
7 | namespace { | |||
8 | // Deadbands to prevent rapid switching on/off of AC | |||
9 | Deadband<200> maxRpmDeadband; | |||
10 | Deadband<5> maxCltDeadband; | |||
11 | Deadband<5> maxTpsDeadband; | |||
12 | Deadband<AcController::PRESSURE_DEADBAND_WIDTH> minPressureDeadband; | |||
13 | MaxLimitWithHysteresis acPressureEnableHysteresis; | |||
14 | } | |||
15 | ||||
16 | 1085 | bool AcController::getAcState() { | ||
17 |
1/1✓ Branch 1 taken 1085 times.
|
1085 | auto rpm = Sensor::getOrZero(SensorType::Rpm); | |
18 | ||||
19 | 1085 | engineTooSlow = rpm < 500; | ||
20 | ||||
21 |
2/2✓ Branch 0 taken 921 times.
✓ Branch 1 taken 164 times.
|
2/2✓ Decision 'true' taken 921 times.
✓ Decision 'false' taken 164 times.
|
1085 | if (engineTooSlow) { |
22 | 921 | return false; | ||
23 | } | |||
24 | ||||
25 | 164 | auto maxRpm = engineConfiguration->maxAcRpm; | ||
26 |
3/4✓ Branch 1 taken 164 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 48 times.
✓ Branch 6 taken 116 times.
|
164 | engineTooFast = maxRpm != 0 && maxRpmDeadband.gt(rpm, maxRpm); | |
27 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 116 times.
|
2/2✓ Decision 'true' taken 48 times.
✓ Decision 'false' taken 116 times.
|
164 | if (engineTooFast) { |
28 | 48 | return false; | ||
29 | } | |||
30 | ||||
31 |
1/1✓ Branch 2 taken 116 times.
|
116 | auto clt = Sensor::get(SensorType::Clt); | |
32 | ||||
33 | 116 | noClt = !clt; | ||
34 | // No AC with failed CLT | |||
35 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 116 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 116 times.
|
116 | if (noClt) { |
36 | ✗ | return false; | ||
37 | } | |||
38 | ||||
39 | // Engine too hot, disable | |||
40 | 116 | auto maxClt = engineConfiguration->maxAcClt; | ||
41 |
2/4✓ Branch 0 taken 116 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 116 times.
|
116 | engineTooHot = (maxClt != 0) && maxCltDeadband.gt(clt.Value, maxClt); | |
42 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 116 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 116 times.
|
116 | if (engineTooHot) { |
43 | ✗ | return false; | ||
44 | } | |||
45 | ||||
46 | // TPS too high, disable | |||
47 | 116 | auto maxTps = engineConfiguration->maxAcTps; | ||
48 |
4/5✓ Branch 0 taken 116 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 116 times.
✓ Branch 6 taken 51 times.
✓ Branch 7 taken 65 times.
|
116 | tpsTooHigh = maxTps != 0 && maxTpsDeadband.gt(Sensor::getOrZero(SensorType::Tps1), maxTps); | |
49 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 65 times.
|
2/2✓ Decision 'true' taken 51 times.
✓ Decision 'false' taken 65 times.
|
116 | if (tpsTooHigh) { |
50 | 51 | return false; | ||
51 | } | |||
52 | ||||
53 |
1/1✓ Branch 1 taken 65 times.
|
65 | const auto acPressure= Sensor::get(SensorType::AcPressure); | |
54 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 38 times.
|
2/2✓ Decision 'true' taken 27 times.
✓ Decision 'false' taken 38 times.
|
65 | if (acPressure.Valid) { |
55 | 27 | const auto minAcPressure = static_cast<float>(engineConfiguration->minAcPressure); | ||
56 | 27 | acPressureTooLow = minPressureDeadband.lt(acPressure.Value, minAcPressure); | ||
57 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 21 times.
|
2/2✓ Decision 'true' taken 6 times.
✓ Decision 'false' taken 21 times.
|
27 | if (acPressureTooLow) { |
58 | 6 | return false; | ||
59 | } | |||
60 | ||||
61 | 21 | const auto maxAcPressure = static_cast<float>(engineConfiguration->maxAcPressure); | ||
62 | 63 | acPressureTooHigh = acPressureEnableHysteresis.checkIfLimitIsExceeded( | ||
63 |
1/1✓ Branch 1 taken 21 times.
|
21 | acPressure.Value, | |
64 | maxAcPressure, | |||
65 | 21 | engineConfiguration->acPressureEnableHyst | ||
66 | ); | |||
67 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15 times.
|
2/2✓ Decision 'true' taken 6 times.
✓ Decision 'false' taken 15 times.
|
21 | if (acPressureTooHigh) { |
68 | 6 | return false; | ||
69 | } | |||
70 | } | |||
71 | ||||
72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 53 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 53 times.
|
53 | if (isDisabledByLua) { |
73 | ✗ | return false; | ||
74 | } | |||
75 | ||||
76 | // All conditions allow AC, simply pass thru switch | |||
77 | 53 | return acButtonState; | ||
78 | } | |||
79 | ||||
80 | 1085 | void AcController::onSlowCallback() { | ||
81 | 1085 | bool isEnabled = getAcState(); | ||
82 | ||||
83 | 1085 | m_acEnabled = isEnabled; | ||
84 | ||||
85 |
2/2✓ Branch 0 taken 1070 times.
✓ Branch 1 taken 15 times.
|
2/2✓ Decision 'true' taken 1070 times.
✓ Decision 'false' taken 15 times.
|
1085 | if (!isEnabled) { |
86 | // reset the timer if AC is off | |||
87 | 1070 | m_timeSinceNoAc.reset(); | ||
88 | } | |||
89 | ||||
90 | 1085 | float acDelay = engineConfiguration->acDelay; | ||
91 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 1058 times.
|
2/2✓ Decision 'true' taken 27 times.
✓ Decision 'false' taken 1058 times.
|
1085 | if (acDelay == 0) { |
92 | // Without delay configured, enable immediately | |||
93 | 27 | acCompressorState = isEnabled; | ||
94 | } else { | |||
95 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
1058 | acCompressorState = isEnabled && m_timeSinceNoAc.hasElapsedSec(acDelay); | |
96 | } | |||
97 | ||||
98 | 1085 | enginePins.acRelay.setValue(acCompressorState); | ||
99 | 1085 | } | ||
100 | ||||
101 | 2197 | bool AcController::isAcEnabled() const { | ||
102 | 2197 | return m_acEnabled; | ||
103 | } | |||
104 |