xref: /openbmc/phosphor-pid-control/pid/stepwisecontroller.cpp (revision 23e22b90c32fc7b40489fae41b1ad6439152b07f)
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