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 } 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 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 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