blob: ab45661b0ebbc5e23075170040f57ca324278882 [file] [log] [blame]
Josh Lehande745422020-11-07 02:14:09 -08001#include "pid/ec/logging.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07002#include "pid/ec/pid.hpp"
Patrick Venture3349ef22018-06-12 14:09:29 -07003#include "pid/thermalcontroller.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07004#include "test/zone_mock.hpp"
Patrick Venture3349ef22018-06-12 14:09:29 -07005
Patrick Venture3349ef22018-06-12 14:09:29 -07006#include <string>
7#include <vector>
8
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07009#include <gmock/gmock.h>
10#include <gtest/gtest.h>
Patrick Venture3349ef22018-06-12 14:09:29 -070011
Patrick Venturea0764872020-08-08 07:48:43 -070012namespace pid_control
13{
14namespace
15{
16
James Feist572c43d2019-01-31 15:52:22 -080017using ::testing::_;
Patrick Venture3349ef22018-06-12 14:09:29 -070018using ::testing::Return;
19using ::testing::StrEq;
20
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070021TEST(ThermalControllerTest, BoringFactoryTest)
22{
Patrick Venture3349ef22018-06-12 14:09:29 -070023 // Verifies building a ThermalPIDController with the factory works as
24 // expected in the boring (uninteresting) case.
25
26 ZoneMock z;
27
28 std::vector<std::string> inputs = {"fleeting0"};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080029 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -070030 ec::pidinfo initial;
31
Patrick Venture563a3562018-10-30 09:31:26 -070032 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
James Feist734f9532018-11-15 12:13:18 -080033 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
Patrick Venture3349ef22018-06-12 14:09:29 -070034 // Success
35 EXPECT_FALSE(p == nullptr);
36}
37
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070038TEST(ThermalControllerTest, VerifyFactoryFailsWithZeroInputs)
39{
Patrick Venture3349ef22018-06-12 14:09:29 -070040 // A thermal controller needs at least one input.
41
42 ZoneMock z;
43
44 std::vector<std::string> inputs = {};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080045 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -070046 ec::pidinfo initial;
James Feist734f9532018-11-15 12:13:18 -080047 std::unique_ptr<PIDController> p;
48 EXPECT_THROW(
49 {
50 p = ThermalController::createThermalPid(
51 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
52 },
53 std::exception);
Patrick Venture3349ef22018-06-12 14:09:29 -070054 EXPECT_TRUE(p == nullptr);
55}
56
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070057TEST(ThermalControllerTest, InputProc_BehavesAsExpected)
58{
Patrick Venture563a3562018-10-30 09:31:26 -070059 // This test just verifies inputProc behaves as expected.
Patrick Venture3349ef22018-06-12 14:09:29 -070060
61 ZoneMock z;
62
63 std::vector<std::string> inputs = {"fleeting0"};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080064 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -070065 ec::pidinfo initial;
66
Patrick Venture563a3562018-10-30 09:31:26 -070067 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
James Feist734f9532018-11-15 12:13:18 -080068 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
Patrick Venture3349ef22018-06-12 14:09:29 -070069 EXPECT_FALSE(p == nullptr);
70
71 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0"))).WillOnce(Return(5.0));
72
Patrick Venture563a3562018-10-30 09:31:26 -070073 EXPECT_EQ(5.0, p->inputProc());
Patrick Venture3349ef22018-06-12 14:09:29 -070074}
75
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070076TEST(ThermalControllerTest, SetPtProc_BehavesAsExpected)
77{
Patrick Venture563a3562018-10-30 09:31:26 -070078 // This test just verifies inputProc behaves as expected.
Patrick Venture3349ef22018-06-12 14:09:29 -070079
80 ZoneMock z;
81
82 std::vector<std::string> inputs = {"fleeting0"};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080083 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -070084 ec::pidinfo initial;
85
Patrick Venture563a3562018-10-30 09:31:26 -070086 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
James Feist734f9532018-11-15 12:13:18 -080087 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
Patrick Venture3349ef22018-06-12 14:09:29 -070088 EXPECT_FALSE(p == nullptr);
89
Patrick Venture563a3562018-10-30 09:31:26 -070090 EXPECT_EQ(setpoint, p->setptProc());
Patrick Venture3349ef22018-06-12 14:09:29 -070091}
92
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070093TEST(ThermalControllerTest, OutputProc_BehavesAsExpected)
94{
James Feist734f9532018-11-15 12:13:18 -080095 // This test just verifies outputProc behaves as expected.
Patrick Venture3349ef22018-06-12 14:09:29 -070096
97 ZoneMock z;
98
99 std::vector<std::string> inputs = {"fleeting0"};
Patrick Venture5f59c0f2018-11-11 12:55:14 -0800100 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -0700101 ec::pidinfo initial;
102
Patrick Venture563a3562018-10-30 09:31:26 -0700103 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
James Feist734f9532018-11-15 12:13:18 -0800104 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
Patrick Venture3349ef22018-06-12 14:09:29 -0700105 EXPECT_FALSE(p == nullptr);
106
Patrick Venture5f59c0f2018-11-11 12:55:14 -0800107 double value = 90.0;
Nirav Shahccc8bb62022-02-17 21:06:51 -0800108 EXPECT_CALL(z, addSetPoint(value, "therm1"));
Patrick Venture3349ef22018-06-12 14:09:29 -0700109
Patrick Venture563a3562018-10-30 09:31:26 -0700110 p->outputProc(value);
Patrick Venture3349ef22018-06-12 14:09:29 -0700111}
James Feist734f9532018-11-15 12:13:18 -0800112
113TEST(ThermalControllerTest, InputProc_MultipleInputsAbsolute)
114{
115 // This test verifies inputProc behaves as expected with multiple absolute
116 // inputs.
117
118 ZoneMock z;
119
120 std::vector<std::string> inputs = {"fleeting0", "fleeting1"};
121 double setpoint = 10.0;
122 ec::pidinfo initial;
123
124 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
125 &z, "therm1", inputs, setpoint, initial, ThermalType::absolute);
126 EXPECT_FALSE(p == nullptr);
127
128 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0"))).WillOnce(Return(5.0));
129 EXPECT_CALL(z, getCachedValue(StrEq("fleeting1"))).WillOnce(Return(10.0));
130
131 EXPECT_EQ(10.0, p->inputProc());
132}
133
134TEST(ThermalControllerTest, InputProc_MultipleInputsMargin)
135{
136 // This test verifies inputProc behaves as expected with multiple margin
137 // inputs.
138
139 ZoneMock z;
140
141 std::vector<std::string> inputs = {"fleeting0", "fleeting1"};
142 double setpoint = 10.0;
143 ec::pidinfo initial;
144
145 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
146 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
147 EXPECT_FALSE(p == nullptr);
148
149 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0"))).WillOnce(Return(5.0));
150 EXPECT_CALL(z, getCachedValue(StrEq("fleeting1"))).WillOnce(Return(10.0));
151
152 EXPECT_EQ(5.0, p->inputProc());
James Feist572c43d2019-01-31 15:52:22 -0800153}
154
Josh Lehan23e22b92022-11-12 22:37:58 -0800155TEST(ThermalControllerTest, InputProc_MultipleInputsSummation)
156{
157 // This test verifies inputProc behaves as expected with multiple summation
158 // inputs.
159
160 ZoneMock z;
161
162 std::vector<std::string> inputs = {"fleeting0", "fleeting1"};
163 double setpoint = 10.0;
164 ec::pidinfo initial;
165
166 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
167 &z, "therm1", inputs, setpoint, initial, ThermalType::summation);
168 EXPECT_FALSE(p == nullptr);
169
170 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0"))).WillOnce(Return(5.0));
171 EXPECT_CALL(z, getCachedValue(StrEq("fleeting1"))).WillOnce(Return(10.0));
172
173 EXPECT_EQ(15.0, p->inputProc());
174}
175
James Feist572c43d2019-01-31 15:52:22 -0800176TEST(ThermalControllerTest, NegHysteresis_BehavesAsExpected)
177{
178
179 // This test verifies Negative hysteresis behaves as expected by
180 // crossing the setpoint and noticing readings don't change until past the
181 // hysteresis value
182
183 ZoneMock z;
184
185 std::vector<std::string> inputs = {"fleeting0"};
186 double setpoint = 10.0;
187 ec::pidinfo initial;
188 initial.negativeHysteresis = 4.0;
189
190 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
191 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
192 EXPECT_FALSE(p == nullptr);
193
194 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0")))
195 .Times(3)
196 .WillOnce(Return(12.0))
197 .WillOnce(Return(9.0))
198 .WillOnce(Return(7.0));
199
Nirav Shahccc8bb62022-02-17 21:06:51 -0800200 EXPECT_CALL(z, addSetPoint(_, "therm1")).Times(3);
James Feist572c43d2019-01-31 15:52:22 -0800201
202 std::vector<double> lastReadings = {12.0, 12.0, 7.0};
203 for (auto& reading : lastReadings)
204 {
205 p->process();
206 EXPECT_EQ(p->getLastInput(), reading);
207 }
208}
209
210TEST(ThermalControllerTest, PosHysteresis_BehavesAsExpected)
211{
212 // This test verifies Positive hysteresis behaves as expected by
213 // crossing the setpoint and noticing readings don't change until past the
214 // hysteresis value
215
216 ZoneMock z;
217
218 std::vector<std::string> inputs = {"fleeting0"};
219 double setpoint = 10.0;
220 ec::pidinfo initial;
221 initial.positiveHysteresis = 5.0;
222
223 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
224 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
225 EXPECT_FALSE(p == nullptr);
226
227 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0")))
228 .Times(3)
229 .WillOnce(Return(8.0))
230 .WillOnce(Return(13.0))
231 .WillOnce(Return(14.0));
232
Nirav Shahccc8bb62022-02-17 21:06:51 -0800233 EXPECT_CALL(z, addSetPoint(_, "therm1")).Times(3);
James Feist572c43d2019-01-31 15:52:22 -0800234
235 std::vector<double> lastReadings = {8.0, 8.0, 14.0};
236 for (auto& reading : lastReadings)
237 {
238 p->process();
239 EXPECT_EQ(p->getLastInput(), reading);
240 }
Patrick Venturea0764872020-08-08 07:48:43 -0700241}
242
243} // namespace
244} // namespace pid_control