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 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 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 return nullptr; 7922c257abSJames Feist } 8022c257abSJames Feist 8122c257abSJames Feist auto thermal = std::make_unique<StepwiseController>(id, inputs, owner); 82a5cf2086SPatrick Venture thermal->setStepwiseInfo(initial); 8322c257abSJames Feist 8422c257abSJames Feist return thermal; 8522c257abSJames Feist } 8622c257abSJames Feist 875f59c0fdSPatrick Venture double StepwiseController::inputProc(void) 8822c257abSJames Feist { 89734f9535SJames Feist double value = std::numeric_limits<double>::lowest(); 90734f9535SJames Feist for (const auto& in : _inputs) 91734f9535SJames Feist { 92734f9535SJames Feist value = std::max(value, _owner->getCachedValue(in)); 93734f9535SJames Feist } 94*c51ba919SBonnie Lo 95*c51ba919SBonnie Lo if (debugEnabled) 96*c51ba919SBonnie Lo { 97*c51ba919SBonnie Lo std::cerr << getID() 98*c51ba919SBonnie Lo << " choose the maximum temperature value: " << value << "\n"; 99*c51ba919SBonnie Lo } 100*c51ba919SBonnie Lo 1015f59c0fdSPatrick Venture return value; 10222c257abSJames Feist } 10322c257abSJames Feist 1045f59c0fdSPatrick Venture void StepwiseController::outputProc(double value) 10522c257abSJames Feist { 106eb428204SPatrick Venture if (getStepwiseInfo().isCeiling) 107608304daSJames Feist { 108608304daSJames Feist _owner->addRPMCeiling(value); 109608304daSJames Feist } 110608304daSJames Feist else 111608304daSJames Feist { 112ccc8bb62SNirav Shah _owner->addSetPoint(value, _id); 113*c51ba919SBonnie Lo if (debugEnabled) 114*c51ba919SBonnie Lo { 115*c51ba919SBonnie Lo std::cerr << getID() << " stepwise output pwm: " << value << "\n"; 116*c51ba919SBonnie Lo } 117608304daSJames Feist } 11822c257abSJames Feist return; 11922c257abSJames Feist } 120a076487aSPatrick Venture 121a076487aSPatrick Venture } // namespace pid_control 122