blob: ef4de66a784e28597cac3f0769c91d711e3d1ebb [file] [log] [blame]
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07001#include "pid/ec/pid.hpp"
Patrick Venture3349ef22018-06-12 14:09:29 -07002#include "pid/thermalcontroller.hpp"
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07003#include "test/zone_mock.hpp"
Patrick Venture3349ef22018-06-12 14:09:29 -07004
Patrick Venture3349ef22018-06-12 14:09:29 -07005#include <string>
6#include <vector>
7
Patrick Ventureda4a5dd2018-08-31 09:42:48 -07008#include <gmock/gmock.h>
9#include <gtest/gtest.h>
Patrick Venture3349ef22018-06-12 14:09:29 -070010
Patrick Venturea0764872020-08-08 07:48:43 -070011namespace pid_control
12{
13namespace
14{
15
James Feist572c43d2019-01-31 15:52:22 -080016using ::testing::_;
Patrick Venture3349ef22018-06-12 14:09:29 -070017using ::testing::Return;
18using ::testing::StrEq;
19
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070020TEST(ThermalControllerTest, BoringFactoryTest)
21{
Patrick Venture3349ef22018-06-12 14:09:29 -070022 // Verifies building a ThermalPIDController with the factory works as
23 // expected in the boring (uninteresting) case.
24
25 ZoneMock z;
26
27 std::vector<std::string> inputs = {"fleeting0"};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080028 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -070029 ec::pidinfo initial;
30
Patrick Venture563a3562018-10-30 09:31:26 -070031 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
James Feist734f9532018-11-15 12:13:18 -080032 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
Patrick Venture3349ef22018-06-12 14:09:29 -070033 // Success
34 EXPECT_FALSE(p == nullptr);
35}
36
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070037TEST(ThermalControllerTest, VerifyFactoryFailsWithZeroInputs)
38{
Patrick Venture3349ef22018-06-12 14:09:29 -070039 // A thermal controller needs at least one input.
40
41 ZoneMock z;
42
43 std::vector<std::string> inputs = {};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080044 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -070045 ec::pidinfo initial;
James Feist734f9532018-11-15 12:13:18 -080046 std::unique_ptr<PIDController> p;
47 EXPECT_THROW(
48 {
49 p = ThermalController::createThermalPid(
50 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
51 },
52 std::exception);
Patrick Venture3349ef22018-06-12 14:09:29 -070053 EXPECT_TRUE(p == nullptr);
54}
55
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070056TEST(ThermalControllerTest, InputProc_BehavesAsExpected)
57{
Patrick Venture563a3562018-10-30 09:31:26 -070058 // This test just verifies inputProc behaves as expected.
Patrick Venture3349ef22018-06-12 14:09:29 -070059
60 ZoneMock z;
61
62 std::vector<std::string> inputs = {"fleeting0"};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080063 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -070064 ec::pidinfo initial;
65
Patrick Venture563a3562018-10-30 09:31:26 -070066 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
James Feist734f9532018-11-15 12:13:18 -080067 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
Patrick Venture3349ef22018-06-12 14:09:29 -070068 EXPECT_FALSE(p == nullptr);
69
70 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0"))).WillOnce(Return(5.0));
71
Patrick Venture563a3562018-10-30 09:31:26 -070072 EXPECT_EQ(5.0, p->inputProc());
Patrick Venture3349ef22018-06-12 14:09:29 -070073}
74
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070075TEST(ThermalControllerTest, SetPtProc_BehavesAsExpected)
76{
Patrick Venture563a3562018-10-30 09:31:26 -070077 // This test just verifies inputProc behaves as expected.
Patrick Venture3349ef22018-06-12 14:09:29 -070078
79 ZoneMock z;
80
81 std::vector<std::string> inputs = {"fleeting0"};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080082 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -070083 ec::pidinfo initial;
84
Patrick Venture563a3562018-10-30 09:31:26 -070085 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
James Feist734f9532018-11-15 12:13:18 -080086 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
Patrick Venture3349ef22018-06-12 14:09:29 -070087 EXPECT_FALSE(p == nullptr);
88
Patrick Venture563a3562018-10-30 09:31:26 -070089 EXPECT_EQ(setpoint, p->setptProc());
Patrick Venture3349ef22018-06-12 14:09:29 -070090}
91
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070092TEST(ThermalControllerTest, OutputProc_BehavesAsExpected)
93{
James Feist734f9532018-11-15 12:13:18 -080094 // This test just verifies outputProc behaves as expected.
Patrick Venture3349ef22018-06-12 14:09:29 -070095
96 ZoneMock z;
97
98 std::vector<std::string> inputs = {"fleeting0"};
Patrick Venture5f59c0f2018-11-11 12:55:14 -080099 double setpoint = 10.0;
Patrick Venture3349ef22018-06-12 14:09:29 -0700100 ec::pidinfo initial;
101
Patrick Venture563a3562018-10-30 09:31:26 -0700102 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
James Feist734f9532018-11-15 12:13:18 -0800103 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
Patrick Venture3349ef22018-06-12 14:09:29 -0700104 EXPECT_FALSE(p == nullptr);
105
Patrick Venture5f59c0f2018-11-11 12:55:14 -0800106 double value = 90.0;
Patrick Venture9bbf3332019-07-16 10:50:37 -0700107 EXPECT_CALL(z, addSetPoint(value));
Patrick Venture3349ef22018-06-12 14:09:29 -0700108
Patrick Venture563a3562018-10-30 09:31:26 -0700109 p->outputProc(value);
Patrick Venture3349ef22018-06-12 14:09:29 -0700110}
James Feist734f9532018-11-15 12:13:18 -0800111
112TEST(ThermalControllerTest, InputProc_MultipleInputsAbsolute)
113{
114 // This test verifies inputProc behaves as expected with multiple absolute
115 // inputs.
116
117 ZoneMock z;
118
119 std::vector<std::string> inputs = {"fleeting0", "fleeting1"};
120 double setpoint = 10.0;
121 ec::pidinfo initial;
122
123 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
124 &z, "therm1", inputs, setpoint, initial, ThermalType::absolute);
125 EXPECT_FALSE(p == nullptr);
126
127 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0"))).WillOnce(Return(5.0));
128 EXPECT_CALL(z, getCachedValue(StrEq("fleeting1"))).WillOnce(Return(10.0));
129
130 EXPECT_EQ(10.0, p->inputProc());
131}
132
133TEST(ThermalControllerTest, InputProc_MultipleInputsMargin)
134{
135 // This test verifies inputProc behaves as expected with multiple margin
136 // inputs.
137
138 ZoneMock z;
139
140 std::vector<std::string> inputs = {"fleeting0", "fleeting1"};
141 double setpoint = 10.0;
142 ec::pidinfo initial;
143
144 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
145 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
146 EXPECT_FALSE(p == nullptr);
147
148 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0"))).WillOnce(Return(5.0));
149 EXPECT_CALL(z, getCachedValue(StrEq("fleeting1"))).WillOnce(Return(10.0));
150
151 EXPECT_EQ(5.0, p->inputProc());
James Feist572c43d2019-01-31 15:52:22 -0800152}
153
154TEST(ThermalControllerTest, NegHysteresis_BehavesAsExpected)
155{
156
157 // This test verifies Negative hysteresis behaves as expected by
158 // crossing the setpoint and noticing readings don't change until past the
159 // hysteresis value
160
161 ZoneMock z;
162
163 std::vector<std::string> inputs = {"fleeting0"};
164 double setpoint = 10.0;
165 ec::pidinfo initial;
166 initial.negativeHysteresis = 4.0;
167
168 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
169 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
170 EXPECT_FALSE(p == nullptr);
171
172 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0")))
173 .Times(3)
174 .WillOnce(Return(12.0))
175 .WillOnce(Return(9.0))
176 .WillOnce(Return(7.0));
177
Patrick Venture9bbf3332019-07-16 10:50:37 -0700178 EXPECT_CALL(z, addSetPoint(_)).Times(3);
James Feist572c43d2019-01-31 15:52:22 -0800179
180 std::vector<double> lastReadings = {12.0, 12.0, 7.0};
181 for (auto& reading : lastReadings)
182 {
183 p->process();
184 EXPECT_EQ(p->getLastInput(), reading);
185 }
186}
187
188TEST(ThermalControllerTest, PosHysteresis_BehavesAsExpected)
189{
190 // This test verifies Positive hysteresis behaves as expected by
191 // crossing the setpoint and noticing readings don't change until past the
192 // hysteresis value
193
194 ZoneMock z;
195
196 std::vector<std::string> inputs = {"fleeting0"};
197 double setpoint = 10.0;
198 ec::pidinfo initial;
199 initial.positiveHysteresis = 5.0;
200
201 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
202 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
203 EXPECT_FALSE(p == nullptr);
204
205 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0")))
206 .Times(3)
207 .WillOnce(Return(8.0))
208 .WillOnce(Return(13.0))
209 .WillOnce(Return(14.0));
210
Patrick Venture9bbf3332019-07-16 10:50:37 -0700211 EXPECT_CALL(z, addSetPoint(_)).Times(3);
James Feist572c43d2019-01-31 15:52:22 -0800212
213 std::vector<double> lastReadings = {8.0, 8.0, 14.0};
214 for (auto& reading : lastReadings)
215 {
216 p->process();
217 EXPECT_EQ(p->getLastInput(), reading);
218 }
Patrick Venturea0764872020-08-08 07:48:43 -0700219}
220
221} // namespace
222} // namespace pid_control