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 3322c257abSJames Feist void StepwiseController::process(void) 3422c257abSJames Feist { 3522c257abSJames Feist // Get input value 365f59c0fdSPatrick Venture double input = inputProc(); 3722c257abSJames Feist 383dfaafdaSJames Feist ec::StepwiseInfo info = get_stepwise_info(); 3922c257abSJames Feist 405f59c0fdSPatrick Venture double output = lastOutput; 413dfaafdaSJames Feist 423dfaafdaSJames Feist // Calculate new output if hysteresis allows 433dfaafdaSJames Feist if (std::isnan(output)) 443dfaafdaSJames Feist { 453dfaafdaSJames Feist output = ec::stepwise(info, input); 463dfaafdaSJames Feist lastInput = input; 473dfaafdaSJames Feist } 483dfaafdaSJames Feist else if ((input - lastInput) > info.positiveHysteresis) 493dfaafdaSJames Feist { 503dfaafdaSJames Feist output = ec::stepwise(info, input); 513dfaafdaSJames Feist lastInput = input; 523dfaafdaSJames Feist } 533dfaafdaSJames Feist else if ((lastInput - input) > info.negativeHysteresis) 543dfaafdaSJames Feist { 553dfaafdaSJames Feist output = ec::stepwise(info, input); 563dfaafdaSJames Feist lastInput = input; 573dfaafdaSJames Feist } 583dfaafdaSJames Feist 593dfaafdaSJames Feist lastOutput = output; 6022c257abSJames Feist // Output new value 61563a356fSPatrick Venture outputProc(output); 6222c257abSJames Feist 6322c257abSJames Feist return; 6422c257abSJames Feist } 6522c257abSJames Feist 66563a356fSPatrick Venture std::unique_ptr<Controller> StepwiseController::createStepwiseController( 6722c257abSJames Feist ZoneInterface* owner, const std::string& id, 6822c257abSJames Feist const std::vector<std::string>& inputs, const ec::StepwiseInfo& initial) 6922c257abSJames Feist { 70734f9535SJames Feist // StepwiseController requires at least 1 input 71734f9535SJames Feist if (inputs.empty()) 7222c257abSJames Feist { 73734f9535SJames Feist throw ControllerBuildException("Stepwise controller missing inputs"); 7422c257abSJames Feist return nullptr; 7522c257abSJames Feist } 7622c257abSJames Feist 7722c257abSJames Feist auto thermal = std::make_unique<StepwiseController>(id, inputs, owner); 7822c257abSJames Feist 7922c257abSJames Feist ec::StepwiseInfo& info = thermal->get_stepwise_info(); 8022c257abSJames Feist 8122c257abSJames Feist info = 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 { 98*608304daSJames Feist if (get_stepwise_info().isCeiling) 99*608304daSJames Feist { 100*608304daSJames Feist _owner->addRPMCeiling(value); 101*608304daSJames Feist } 102*608304daSJames Feist else 103*608304daSJames Feist { 10422c257abSJames Feist _owner->addRPMSetPoint(value); 105*608304daSJames Feist } 10622c257abSJames Feist return; 10722c257abSJames Feist } 108