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" 2122c257abSJames Feist #include "util.hpp" 2222c257abSJames Feist #include "zone.hpp" 2322c257abSJames Feist 2422c257abSJames Feist #include <algorithm> 2522c257abSJames Feist #include <chrono> 263dfaafdaSJames Feist #include <cmath> 2722c257abSJames Feist #include <iostream> 2822c257abSJames Feist #include <map> 2922c257abSJames Feist #include <memory> 3022c257abSJames Feist #include <thread> 3122c257abSJames Feist #include <vector> 3222c257abSJames Feist 33a076487aSPatrick Venture namespace pid_control 34a076487aSPatrick Venture { 35a076487aSPatrick Venture 3622c257abSJames Feist void StepwiseController::process(void) 3722c257abSJames Feist { 3822c257abSJames Feist // Get input value 395f59c0fdSPatrick Venture double input = inputProc(); 4022c257abSJames Feist 41eb428204SPatrick Venture ec::StepwiseInfo info = getStepwiseInfo(); 4222c257abSJames Feist 435f59c0fdSPatrick Venture double output = lastOutput; 443dfaafdaSJames Feist 453dfaafdaSJames Feist // Calculate new output if hysteresis allows 463dfaafdaSJames Feist if (std::isnan(output)) 473dfaafdaSJames Feist { 483dfaafdaSJames Feist output = ec::stepwise(info, input); 493dfaafdaSJames Feist lastInput = input; 503dfaafdaSJames Feist } 513dfaafdaSJames Feist else if ((input - lastInput) > info.positiveHysteresis) 523dfaafdaSJames Feist { 533dfaafdaSJames Feist output = ec::stepwise(info, input); 543dfaafdaSJames Feist lastInput = input; 553dfaafdaSJames Feist } 563dfaafdaSJames Feist else if ((lastInput - input) > info.negativeHysteresis) 573dfaafdaSJames Feist { 583dfaafdaSJames Feist output = ec::stepwise(info, input); 593dfaafdaSJames Feist lastInput = input; 603dfaafdaSJames Feist } 613dfaafdaSJames Feist 623dfaafdaSJames Feist lastOutput = output; 6322c257abSJames Feist // Output new value 64563a356fSPatrick Venture outputProc(output); 6522c257abSJames Feist 6622c257abSJames Feist return; 6722c257abSJames Feist } 6822c257abSJames Feist 69563a356fSPatrick Venture std::unique_ptr<Controller> StepwiseController::createStepwiseController( 7022c257abSJames Feist ZoneInterface* owner, const std::string& id, 7122c257abSJames Feist const std::vector<std::string>& inputs, const ec::StepwiseInfo& initial) 7222c257abSJames Feist { 73734f9535SJames Feist // StepwiseController requires at least 1 input 74734f9535SJames Feist if (inputs.empty()) 7522c257abSJames Feist { 76734f9535SJames Feist throw ControllerBuildException("Stepwise controller missing inputs"); 7722c257abSJames Feist return nullptr; 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 } 935f59c0fdSPatrick Venture return value; 9422c257abSJames Feist } 9522c257abSJames Feist 965f59c0fdSPatrick Venture void StepwiseController::outputProc(double value) 9722c257abSJames Feist { 98eb428204SPatrick Venture if (getStepwiseInfo().isCeiling) 99608304daSJames Feist { 100608304daSJames Feist _owner->addRPMCeiling(value); 101608304daSJames Feist } 102608304daSJames Feist else 103608304daSJames Feist { 104*ccc8bb62SNirav Shah _owner->addSetPoint(value, _id); 105608304daSJames Feist } 10622c257abSJames Feist return; 10722c257abSJames Feist } 108a076487aSPatrick Venture 109a076487aSPatrick Venture } // namespace pid_control 110