| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | /* | |||
| 2 | * @file test_pid_auto.cpp | |||
| 3 | * | |||
| 4 | * @date Sep 29, 2019 | |||
| 5 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
| 6 | */ | |||
| 7 | ||||
| 8 | // see also idle.timingPid test | |||
| 9 | ||||
| 10 | #include "pch.h" | |||
| 11 | ||||
| 12 | #include "efi_pid.h" | |||
| 13 | ||||
| 14 | 4 | TEST(util, pid) { | ||
| 15 | 1 | pid_s pidS; | ||
| 16 | 1 | pidS.pFactor = 50; | ||
| 17 | 1 | pidS.iFactor = 0.5; | ||
| 18 | 1 | pidS.dFactor = 0; | ||
| 19 | 1 | pidS.offset = 0; | ||
| 20 | 1 | pidS.minValue = 10; | ||
| 21 | 1 | pidS.maxValue = 90; | ||
| 22 | 1 | pidS.periodMs = 1; | ||
| 23 | ||||
| 24 |
1/1✓ Branch 2 taken 1 time.
|
1 | Pid pid(&pidS); | |
| 25 | ||||
| 26 |
4/10✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 time.
✗ Branch 31 not taken.
|
1 | ASSERT_FLOAT_EQ( 90, pid.getOutput(14, 12, 0.1)) << "getValue#90"; | |
| 27 | ||||
| 28 | ||||
| 29 |
4/10✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 time.
✗ Branch 31 not taken.
|
1 | ASSERT_FLOAT_EQ( 10, pid.getOutput(14, 16, 0.1)) << "getValue#10"; | |
| 30 |
4/9✓ 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.
✓ Branch 27 taken 1 time.
✗ Branch 28 not taken.
|
1 | ASSERT_FLOAT_EQ(10, pid.getOutput(14, 16, 1)); | |
| 31 | ||||
| 32 |
1/1✓ Branch 1 taken 1 time.
|
1 | pid.updateFactors(29, 0, 0); | |
| 33 |
4/9✓ 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.
✓ Branch 27 taken 1 time.
✗ Branch 28 not taken.
|
1 | ASSERT_FLOAT_EQ(10, pid.getOutput(14, 16, 1)); | |
| 34 | // ASSERT_FLOAT_EQ(68, pid.getIntegration()); | |||
| 35 | ||||
| 36 |
4/9✓ 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.
✓ Branch 27 taken 1 time.
✗ Branch 28 not taken.
|
1 | ASSERT_FLOAT_EQ(10, pid.getOutput(14, 16, 1)); | |
| 37 | // ASSERT_FLOAT_EQ(0, pid.getIntegration()); | |||
| 38 | ||||
| 39 |
4/9✓ 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.
✓ Branch 27 taken 1 time.
✗ Branch 28 not taken.
|
1 | ASSERT_FLOAT_EQ(10, pid.getOutput(14, 16, 1)); | |
| 40 | // ASSERT_FLOAT_EQ(68, pid.getIntegration()); | |||
| 41 | ||||
| 42 | ||||
| 43 | ||||
| 44 | 1 | pidS.pFactor = 1; | ||
| 45 | 1 | pidS.iFactor = 0; | ||
| 46 | 1 | pidS.dFactor = 0; | ||
| 47 | 1 | pidS.offset = 0; | ||
| 48 | 1 | pidS.minValue = 0; | ||
| 49 | 1 | pidS.maxValue = 100; | ||
| 50 | 1 | pidS.periodMs = 1; | ||
| 51 | ||||
| 52 |
1/1✓ Branch 1 taken 1 time.
|
1 | pid.reset(); | |
| 53 | ||||
| 54 |
4/10✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 time.
✗ Branch 31 not taken.
|
1 | ASSERT_FLOAT_EQ( 50, pid.getOutput(/*target*/50, /*input*/0)) << "target=50, input=0"; | |
| 55 |
3/9✓ 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.
✓ Branch 27 taken 1 time.
✗ Branch 28 not taken.
|
1 | ASSERT_FLOAT_EQ( 0, pid.iTerm) << "target=50, input=0 iTerm"; | |
| 56 | ||||
| 57 |
4/10✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 time.
✗ Branch 31 not taken.
|
1 | ASSERT_FLOAT_EQ( 0, pid.getOutput(/*target*/50, /*input*/70)) << "target=50, input=70"; | |
| 58 |
3/9✓ 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.
✓ Branch 27 taken 1 time.
✗ Branch 28 not taken.
|
1 | ASSERT_FLOAT_EQ( 0, pid.iTerm) << "target=50, input=70 iTerm"; | |
| 59 | ||||
| 60 |
4/10✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 time.
✗ Branch 31 not taken.
|
1 | ASSERT_FLOAT_EQ( 0, pid.getOutput(/*target*/50, /*input*/70)) << "target=50, input=70 #2"; | |
| 61 |
3/9✓ 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.
✓ Branch 27 taken 1 time.
✗ Branch 28 not taken.
|
1 | ASSERT_FLOAT_EQ( 0, pid.iTerm) << "target=50, input=70 iTerm #2"; | |
| 62 | ||||
| 63 |
4/10✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 1 time.
✗ Branch 31 not taken.
|
1 | ASSERT_FLOAT_EQ( 0, pid.getOutput(/*target*/50, /*input*/50)) << "target=50, input=50"; | |
| 64 |
3/9✓ 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.
✓ Branch 27 taken 1 time.
✗ Branch 28 not taken.
|
1 | ASSERT_FLOAT_EQ( 0, pid.iTerm) << "target=50, input=50 iTerm"; | |
| 65 | } | |||
| 66 | ||||
| 67 | 2 | static void commonPidTestParameters(pid_s * pidS) { | ||
| 68 | 2 | pidS->pFactor = 0; | ||
| 69 | 2 | pidS->iFactor = 50; | ||
| 70 | 2 | pidS->dFactor = 0; | ||
| 71 | 2 | pidS->offset = 0; | ||
| 72 | 2 | pidS->minValue = 10; | ||
| 73 | 2 | pidS->maxValue = 40; | ||
| 74 | 2 | pidS->periodMs = 1; | ||
| 75 | 2 | } | ||
| 76 | ||||
| 77 | 2 | static void commonPidTest(Pid *pid) { | ||
| 78 | 2 | pid->iTermMax = 45; | ||
| 79 | ||||
| 80 |
4/10✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
|
2 | ASSERT_FLOAT_EQ( 12.5, pid->getOutput(/*target*/50, /*input*/0)) << "target=50, input=0 #0"; | |
| 81 |
4/9✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 28 not taken.
|
2 | ASSERT_FLOAT_EQ( 12.5, pid->getIntegration()); | |
| 82 |
4/10✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
|
2 | ASSERT_FLOAT_EQ( 25 , pid->getOutput(/*target*/50, /*input*/0)) << "target=50, input=0 #1"; | |
| 83 | ||||
| 84 |
4/10✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
|
2 | ASSERT_FLOAT_EQ( 37.5, pid->getOutput(/*target*/50, /*input*/0)) << "target=50, input=0 #2"; | |
| 85 |
4/9✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 28 not taken.
|
2 | ASSERT_FLOAT_EQ( 37.5, pid->getIntegration()); | |
| 86 | ||||
| 87 |
4/10✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 12 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 23 not taken.
✓ Branch 30 taken 2 times.
✗ Branch 31 not taken.
|
2 | ASSERT_FLOAT_EQ( 40.0, pid->getOutput(/*target*/50, /*input*/0)) << "target=50, input=0 #3"; | |
| 88 |
4/9✓ Branch 2 taken 2 times.
✓ Branch 5 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 12 not taken.
✗ Branch 17 not taken.
✗ Branch 20 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 28 not taken.
|
2 | ASSERT_FLOAT_EQ( 45, pid->getIntegration()); | |
| 89 | } | |||
| 90 | ||||
| 91 | 4 | TEST(util, parallelPidLimits) { | ||
| 92 | 1 | pid_s pidS; | ||
| 93 | 1 | commonPidTestParameters(&pidS); | ||
| 94 | ||||
| 95 |
1/1✓ Branch 2 taken 1 time.
|
1 | Pid pid(&pidS); | |
| 96 |
1/1✓ Branch 1 taken 1 time.
|
1 | commonPidTest(&pid); | |
| 97 | 1 | } | ||
| 98 | ||||
| 99 | 4 | TEST(util, industrialPidLimits) { | ||
| 100 | 1 | pid_s pidS; | ||
| 101 | 1 | commonPidTestParameters(&pidS); | ||
| 102 | ||||
| 103 |
1/1✓ Branch 2 taken 1 time.
|
1 | PidIndustrial pid(&pidS); | |
| 104 |
1/1✓ Branch 1 taken 1 time.
|
1 | commonPidTest(&pid); | |
| 105 | 1 | } | ||
| 106 | ||||
| 107 | TEST(util, pidIndustrial) { | |||
| 108 | pid_s pidS; | |||
| 109 | pidS.pFactor = 1.0; | |||
| 110 | pidS.iFactor = 1.0; | |||
| 111 | pidS.dFactor = 1.0; | |||
| 112 | pidS.offset = 0; | |||
| 113 | pidS.minValue = 0; | |||
| 114 | pidS.maxValue = 100; | |||
| 115 | pidS.periodMs = 1; | |||
| 116 | ||||
| 117 | PidIndustrial pid; | |||
| 118 | pid.initPidClass(&pidS); | |||
| 119 | ||||
| 120 | // we want to compare with the "normal" PID controller | |||
| 121 | Pid pid0(&pidS); | |||
| 122 | ||||
| 123 | // no additional features | |||
| 124 | pid.derivativeFilterLoss = 0; | |||
| 125 | pid.antiwindupFreq = 0; | |||
| 126 | ||||
| 127 | float industValue = pid.getOutput(/*target*/1, /*input*/0); | |||
| 128 | // check if the first output is clamped because of large deviative | |||
| 129 | ASSERT_FLOAT_EQ(100.0, industValue); | |||
| 130 | ||||
| 131 | // check if all output of the 'zeroed' PidIndustrial (w/o new features) is the same as our "normal" Pid | |||
| 132 | for (int i = 0; i < 10; i++) { | |||
| 133 | float normalValue = pid0.getOutput(1, 0); | |||
| 134 | ASSERT_FLOAT_EQ(normalValue, industValue) << "[" << i << "]"; | |||
| 135 | industValue = pid.getOutput(1, 0); | |||
| 136 | } | |||
| 137 | ||||
| 138 | pid.reset(); | |||
| 139 | ||||
| 140 | // now test the "derivative filter loss" param (some small value) | |||
| 141 | pid.derivativeFilterLoss = 0.01; | |||
| 142 | ||||
| 143 | // now the first value is less (and not clipped!) due to the derivative filtering | |||
| 144 | ASSERT_FLOAT_EQ(67.671669f, pid.getOutput(1, 0)); | |||
| 145 | // here we still have some leftovers of the initial D-term | |||
| 146 | ASSERT_FLOAT_EQ(45.4544487f, pid.getOutput(1, 0)); | |||
| 147 | // but the value is quickly fading | |||
| 148 | ASSERT_FLOAT_EQ(30.6446342f, pid.getOutput(1, 0)); | |||
| 149 | ||||
| 150 | pid.reset(); | |||
| 151 | ||||
| 152 | // now test much stronger "derivative filter loss" | |||
| 153 | pid.derivativeFilterLoss = 0.1; | |||
| 154 | ||||
| 155 | // now the first value is much less due to the derivative filtering | |||
| 156 | ASSERT_NEAR(10.5288095f, pid.getOutput(1, 0), EPS4D); | |||
| 157 | // here we still have some leftovers of the initial D-term | |||
| 158 | ASSERT_NEAR(10.0802946f, pid.getOutput(1, 0), EPS4D); | |||
| 159 | // but the fading is slower than with 'weaker' derivative filter above | |||
| 160 | ASSERT_NEAR(9.65337563f, pid.getOutput(1, 0), EPS4D); | |||
| 161 | ||||
| 162 | pid.reset(); | |||
| 163 | pid.derivativeFilterLoss = 0; | |||
| 164 | ||||
| 165 | // now test "anti-windup" param | |||
| 166 | pid.antiwindupFreq = 0.1; | |||
| 167 | ||||
| 168 | // the first value is clipped, and that's when the anti-windup comes into effect | |||
| 169 | ASSERT_FLOAT_EQ(100.0f, pid.getOutput(1, 0)); | |||
| 170 | // it stores a small negative offset in the I-term to avoid it's saturation! | |||
| 171 | ASSERT_NEAR(-0.0455025025f, pid.getIntegration(), EPS4D); | |||
| 172 | // and that's why the second output is smaller then that of normal PID (=1.00999999) | |||
| 173 | ASSERT_NEAR(0.959497511f, pid.getOutput(1, 0), EPS4D); | |||
| 174 | ||||
| 175 | } | |||
| 176 |