blob: 4e71a3bdca45f990e9e74a42e4056e7b4aef91cc [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
155TEST(ThermalControllerTest, NegHysteresis_BehavesAsExpected)
156{
157
158 // This test verifies Negative hysteresis behaves as expected by
159 // crossing the setpoint and noticing readings don't change until past the
160 // hysteresis value
161
162 ZoneMock z;
163
164 std::vector<std::string> inputs = {"fleeting0"};
165 double setpoint = 10.0;
166 ec::pidinfo initial;
167 initial.negativeHysteresis = 4.0;
168
169 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
170 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
171 EXPECT_FALSE(p == nullptr);
172
173 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0")))
174 .Times(3)
175 .WillOnce(Return(12.0))
176 .WillOnce(Return(9.0))
177 .WillOnce(Return(7.0));
178
Nirav Shahccc8bb62022-02-17 21:06:51 -0800179 EXPECT_CALL(z, addSetPoint(_, "therm1")).Times(3);
James Feist572c43d2019-01-31 15:52:22 -0800180
181 std::vector<double> lastReadings = {12.0, 12.0, 7.0};
182 for (auto& reading : lastReadings)
183 {
184 p->process();
185 EXPECT_EQ(p->getLastInput(), reading);
186 }
187}
188
189TEST(ThermalControllerTest, PosHysteresis_BehavesAsExpected)
190{
191 // This test verifies Positive hysteresis behaves as expected by
192 // crossing the setpoint and noticing readings don't change until past the
193 // hysteresis value
194
195 ZoneMock z;
196
197 std::vector<std::string> inputs = {"fleeting0"};
198 double setpoint = 10.0;
199 ec::pidinfo initial;
200 initial.positiveHysteresis = 5.0;
201
202 std::unique_ptr<PIDController> p = ThermalController::createThermalPid(
203 &z, "therm1", inputs, setpoint, initial, ThermalType::margin);
204 EXPECT_FALSE(p == nullptr);
205
206 EXPECT_CALL(z, getCachedValue(StrEq("fleeting0")))
207 .Times(3)
208 .WillOnce(Return(8.0))
209 .WillOnce(Return(13.0))
210 .WillOnce(Return(14.0));
211
Nirav Shahccc8bb62022-02-17 21:06:51 -0800212 EXPECT_CALL(z, addSetPoint(_, "therm1")).Times(3);
James Feist572c43d2019-01-31 15:52:22 -0800213
214 std::vector<double> lastReadings = {8.0, 8.0, 14.0};
215 for (auto& reading : lastReadings)
216 {
217 p->process();
218 EXPECT_EQ(p->getLastInput(), reading);
219 }
Patrick Venturea0764872020-08-08 07:48:43 -0700220}
221
222} // namespace
223} // namespace pid_control