122c257abSJames Feist /*
222c257abSJames Feist // Copyright (c) 2018 Intel Corporation
322c257abSJames Feist //
422c257abSJames Feist // Licensed under the Apache License, Version 2.0 (the "License");
522c257abSJames Feist // you may not use this file except in compliance with the License.
622c257abSJames Feist // You may obtain a copy of the License at
722c257abSJames Feist //
822c257abSJames Feist // http://www.apache.org/licenses/LICENSE-2.0
922c257abSJames Feist //
1022c257abSJames Feist // Unless required by applicable law or agreed to in writing, software
1122c257abSJames Feist // distributed under the License is distributed on an "AS IS" BASIS,
1222c257abSJames Feist // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1322c257abSJames Feist // See the License for the specific language governing permissions and
1422c257abSJames Feist // limitations under the License.
1522c257abSJames Feist */
1622c257abSJames Feist
1722c257abSJames Feist #include "stepwisecontroller.hpp"
1822c257abSJames Feist
1922c257abSJames Feist #include "ec/stepwise.hpp"
20734f9535SJames Feist #include "errors/exception.hpp"
21*c51ba919SBonnie Lo #include "tuning.hpp"
2222c257abSJames Feist #include "util.hpp"
2322c257abSJames Feist #include "zone.hpp"
2422c257abSJames Feist
2522c257abSJames Feist #include <algorithm>
2622c257abSJames Feist #include <chrono>
273dfaafdaSJames Feist #include <cmath>
2822c257abSJames Feist #include <iostream>
2922c257abSJames Feist #include <map>
3022c257abSJames Feist #include <memory>
3122c257abSJames Feist #include <thread>
3222c257abSJames Feist #include <vector>
3322c257abSJames Feist
34a076487aSPatrick Venture namespace pid_control
35a076487aSPatrick Venture {
36a076487aSPatrick Venture
process(void)3722c257abSJames Feist void StepwiseController::process(void)
3822c257abSJames Feist {
3922c257abSJames Feist // Get input value
405f59c0fdSPatrick Venture double input = inputProc();
4122c257abSJames Feist
42eb428204SPatrick Venture ec::StepwiseInfo info = getStepwiseInfo();
4322c257abSJames Feist
445f59c0fdSPatrick Venture double output = lastOutput;
453dfaafdaSJames Feist
463dfaafdaSJames Feist // Calculate new output if hysteresis allows
473dfaafdaSJames Feist if (std::isnan(output))
483dfaafdaSJames Feist {
493dfaafdaSJames Feist output = ec::stepwise(info, input);
503dfaafdaSJames Feist lastInput = input;
513dfaafdaSJames Feist }
523dfaafdaSJames Feist else if ((input - lastInput) > info.positiveHysteresis)
533dfaafdaSJames Feist {
543dfaafdaSJames Feist output = ec::stepwise(info, input);
553dfaafdaSJames Feist lastInput = input;
563dfaafdaSJames Feist }
573dfaafdaSJames Feist else if ((lastInput - input) > info.negativeHysteresis)
583dfaafdaSJames Feist {
593dfaafdaSJames Feist output = ec::stepwise(info, input);
603dfaafdaSJames Feist lastInput = input;
613dfaafdaSJames Feist }
623dfaafdaSJames Feist
633dfaafdaSJames Feist lastOutput = output;
6422c257abSJames Feist // Output new value
65563a356fSPatrick Venture outputProc(output);
6622c257abSJames Feist
6722c257abSJames Feist return;
6822c257abSJames Feist }
6922c257abSJames Feist
createStepwiseController(ZoneInterface * owner,const std::string & id,const std::vector<std::string> & inputs,const ec::StepwiseInfo & initial)70563a356fSPatrick Venture std::unique_ptr<Controller> StepwiseController::createStepwiseController(
7122c257abSJames Feist ZoneInterface* owner, const std::string& id,
7222c257abSJames Feist const std::vector<std::string>& inputs, const ec::StepwiseInfo& initial)
7322c257abSJames Feist {
74734f9535SJames Feist // StepwiseController requires at least 1 input
75734f9535SJames Feist if (inputs.empty())
7622c257abSJames Feist {
77734f9535SJames Feist throw ControllerBuildException("Stepwise controller missing inputs");
7822c257abSJames Feist }
7922c257abSJames Feist
8022c257abSJames Feist auto thermal = std::make_unique<StepwiseController>(id, inputs, owner);
81a5cf2086SPatrick Venture thermal->setStepwiseInfo(initial);
8222c257abSJames Feist
8322c257abSJames Feist return thermal;
8422c257abSJames Feist }
8522c257abSJames Feist
inputProc(void)865f59c0fdSPatrick Venture double StepwiseController::inputProc(void)
8722c257abSJames Feist {
88734f9535SJames Feist double value = std::numeric_limits<double>::lowest();
89734f9535SJames Feist for (const auto& in : _inputs)
90734f9535SJames Feist {
91734f9535SJames Feist value = std::max(value, _owner->getCachedValue(in));
92734f9535SJames Feist }
93*c51ba919SBonnie Lo
94*c51ba919SBonnie Lo if (debugEnabled)
95*c51ba919SBonnie Lo {
96*c51ba919SBonnie Lo std::cerr << getID()
97*c51ba919SBonnie Lo << " choose the maximum temperature value: " << value << "\n";
98*c51ba919SBonnie Lo }
99*c51ba919SBonnie Lo
1005f59c0fdSPatrick Venture return value;
10122c257abSJames Feist }
10222c257abSJames Feist
outputProc(double value)1035f59c0fdSPatrick Venture void StepwiseController::outputProc(double value)
10422c257abSJames Feist {
105eb428204SPatrick Venture if (getStepwiseInfo().isCeiling)
106608304daSJames Feist {
107608304daSJames Feist _owner->addRPMCeiling(value);
108608304daSJames Feist }
109608304daSJames Feist else
110608304daSJames Feist {
111ccc8bb62SNirav Shah _owner->addSetPoint(value, _id);
112*c51ba919SBonnie Lo if (debugEnabled)
113*c51ba919SBonnie Lo {
114*c51ba919SBonnie Lo std::cerr << getID() << " stepwise output pwm: " << value << "\n";
115*c51ba919SBonnie Lo }
116608304daSJames Feist }
11722c257abSJames Feist return;
11822c257abSJames Feist }
119a076487aSPatrick Venture
120a076487aSPatrick Venture } // namespace pid_control
121