diff options
author | Hank Liou <Hank.Liou@quantatw.com> | 2019-03-29 20:15:42 +0800 |
---|---|---|
committer | Patrick Venture <venture@google.com> | 2019-05-28 20:11:54 +0000 |
commit | 375f7098c232d38adcaab99b2f3ee561ded8c256 (patch) | |
tree | 231fdce4facbd958cdf4fa76c6bc633c6ad352c5 | |
parent | ded0ab5662212155e5d209343375e34ce9d34cdb (diff) | |
download | phosphor-pid-control-375f7098c232d38adcaab99b2f3ee561ded8c256.tar.gz phosphor-pid-control-375f7098c232d38adcaab99b2f3ee561ded8c256.zip |
Add stepwise parser
The json parser cannot read stepwise setting from config.
This change adds support to stepwise type of pid.
Change-Id: I650c5bd6a0040bf25630e33b3bd36abf388f0cd8
Signed-off-by: Hank Liou <Hank.Liou@quantatw.com>
-rw-r--r-- | pid/buildjson.cpp | 81 | ||||
-rw-r--r-- | test/pid_json_unittest.cpp | 85 |
2 files changed, 147 insertions, 19 deletions
diff --git a/pid/buildjson.cpp b/pid/buildjson.cpp index ad51d9b..5e90c47 100644 --- a/pid/buildjson.cpp +++ b/pid/buildjson.cpp @@ -37,36 +37,79 @@ void from_json(const json& j, conf::ControllerInfo& c) * accordingly. */ auto p = j.at("pid"); - p.at("samplePeriod").get_to(c.pidInfo.ts); - p.at("proportionalCoeff").get_to(c.pidInfo.proportionalCoeff); - p.at("integralCoeff").get_to(c.pidInfo.integralCoeff); - p.at("feedFwdOffsetCoeff").get_to(c.pidInfo.feedFwdOffset); - p.at("feedFwdGainCoeff").get_to(c.pidInfo.feedFwdGain); - p.at("integralLimit_min").get_to(c.pidInfo.integralLimit.min); - p.at("integralLimit_max").get_to(c.pidInfo.integralLimit.max); - p.at("outLim_min").get_to(c.pidInfo.outLim.min); - p.at("outLim_max").get_to(c.pidInfo.outLim.max); - p.at("slewNeg").get_to(c.pidInfo.slewNeg); - p.at("slewPos").get_to(c.pidInfo.slewPos); auto positiveHysteresis = p.find("positiveHysteresis"); - if (positiveHysteresis == p.end()) + auto negativeHysteresis = p.find("negativeHysteresis"); + auto positiveHysteresisValue = 0.0; + auto negativeHysteresisValue = 0.0; + if (positiveHysteresis != p.end()) { - c.pidInfo.positiveHysteresis = 0.0; + p.at("positiveHysteresis").get_to(positiveHysteresisValue); } - else + if (negativeHysteresis != p.end()) { - p.at("positiveHysteresis").get_to(c.pidInfo.positiveHysteresis); + p.at("negativeHysteresis").get_to(negativeHysteresisValue); } - auto negativeHysteresis = p.find("negativeHysteresis"); - if (negativeHysteresis == p.end()) + if (c.type != "stepwise") { - c.pidInfo.negativeHysteresis = 0.0; + p.at("samplePeriod").get_to(c.pidInfo.ts); + p.at("proportionalCoeff").get_to(c.pidInfo.proportionalCoeff); + p.at("integralCoeff").get_to(c.pidInfo.integralCoeff); + p.at("feedFwdOffsetCoeff").get_to(c.pidInfo.feedFwdOffset); + p.at("feedFwdGainCoeff").get_to(c.pidInfo.feedFwdGain); + p.at("integralLimit_min").get_to(c.pidInfo.integralLimit.min); + p.at("integralLimit_max").get_to(c.pidInfo.integralLimit.max); + p.at("outLim_min").get_to(c.pidInfo.outLim.min); + p.at("outLim_max").get_to(c.pidInfo.outLim.max); + p.at("slewNeg").get_to(c.pidInfo.slewNeg); + p.at("slewPos").get_to(c.pidInfo.slewPos); + + c.pidInfo.positiveHysteresis = positiveHysteresisValue; + c.pidInfo.negativeHysteresis = negativeHysteresisValue; } else { - p.at("negativeHysteresis").get_to(c.pidInfo.negativeHysteresis); + p.at("samplePeriod").get_to(c.stepwiseInfo.ts); + p.at("isCeiling").get_to(c.stepwiseInfo.isCeiling); + + for (size_t i = 0; i < ec::maxStepwisePoints; i++) + { + c.stepwiseInfo.reading[i] = + std::numeric_limits<double>::quiet_NaN(); + c.stepwiseInfo.output[i] = std::numeric_limits<double>::quiet_NaN(); + } + + auto reading = p.find("reading"); + if (reading != p.end()) + { + auto r = p.at("reading"); + for (size_t i = 0; i < ec::maxStepwisePoints; i++) + { + auto n = r.find(std::to_string(i)); + if (n != r.end()) + { + r.at(std::to_string(i)).get_to(c.stepwiseInfo.reading[i]); + } + } + } + + auto output = p.find("output"); + if (output != p.end()) + { + auto o = p.at("output"); + for (size_t i = 0; i < ec::maxStepwisePoints; i++) + { + auto n = o.find(std::to_string(i)); + if (n != o.end()) + { + o.at(std::to_string(i)).get_to(c.stepwiseInfo.output[i]); + } + } + } + + c.stepwiseInfo.positiveHysteresis = positiveHysteresisValue; + c.stepwiseInfo.negativeHysteresis = negativeHysteresisValue; } } } // namespace conf diff --git a/test/pid_json_unittest.cpp b/test/pid_json_unittest.cpp index 9d33789..2bd7d35 100644 --- a/test/pid_json_unittest.cpp +++ b/test/pid_json_unittest.cpp @@ -115,3 +115,88 @@ TEST(ZoneFromJson, oneZoneOnePidWithHysteresis) EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0); } + +TEST(ZoneFromJson, oneZoneOneStepwiseWithHysteresis) +{ + // Parse a valid configuration with one zone and one PID and the PID uses + // Hysteresis parameters. + + std::map<int64_t, conf::PIDConf> pidConfig; + std::map<int64_t, struct conf::ZoneConfig> zoneConfig; + + auto j2 = R"( + { + "zones" : [{ + "id": 1, + "minThermalOutput": 3000.0, + "failsafePercent": 75.0, + "pids": [{ + "name": "temp1", + "type": "stepwise", + "inputs": ["temp1"], + "setpoint": 30.0, + "pid": { + "samplePeriod": 0.1, + "positiveHysteresis": 1.0, + "negativeHysteresis": 1.0, + "isCeiling": false, + "reading": { + "0": 45, + "1": 46, + "2": 47, + "3": 48, + "4": 49, + "5": 50, + "6": 51, + "7": 52, + "8": 53, + "9": 54, + "10": 55, + "11": 56, + "12": 57, + "13": 58, + "14": 59, + "15": 60, + "16": 61, + "17": 62, + "18": 63, + "19": 64 + }, + "output": { + "0": 5000, + "1": 2400, + "2": 2600, + "3": 2800, + "4": 3000, + "5": 3200, + "6": 3400, + "7": 3600, + "8": 3800, + "9": 4000, + "10": 4200, + "11": 4400, + "12": 4600, + "13": 4800, + "14": 5000, + "15": 5200, + "16": 5400, + "17": 5600, + "18": 5800, + "19": 6000 + } + } + }] + }] + } + )"_json; + + std::tie(pidConfig, zoneConfig) = buildPIDsFromJson(j2); + EXPECT_EQ(pidConfig.size(), 1); + EXPECT_EQ(zoneConfig.size(), 1); + + EXPECT_EQ(pidConfig[1]["temp1"].type, "stepwise"); + EXPECT_DOUBLE_EQ(pidConfig[1]["temp1"].stepwiseInfo.positiveHysteresis, + 1.0); + + EXPECT_DOUBLE_EQ(zoneConfig[1].minThermalOutput, 3000.0); +}
\ No newline at end of file |