2 * Copyright (c) 2010-2022 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.automation.pidcontroller.internal.handler;
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.automation.pidcontroller.internal.LowpassFilter;
19 * The {@link PIDController} provides the necessary methods for retrieving part(s) of the PID calculations
20 * and it provides the method for the overall PID calculations. It also resets the PID controller
22 * @author George Erhan - Initial contribution
23 * @author Hilbrand Bouwkamp - Adapted for new rule engine
24 * @author Fabian Wolter - Add T1 to D part, add debugging ability for PID values
28 private double integralResult;
29 private double derivativeResult;
30 private double previousError;
31 private double output;
36 private double derivativeTimeConstantSec;
38 public PIDController(double kpAdjuster, double kiAdjuster, double kdAdjuster, double derivativeTimeConstantSec) {
42 this.derivativeTimeConstantSec = derivativeTimeConstantSec;
45 public PIDOutputDTO calculate(double input, double setpoint, long lastInvocationMs, int loopTimeMs) {
46 final double lastInvocationSec = lastInvocationMs / 1000d;
47 final double error = setpoint - input;
49 // derivative T1 calculation
50 final double timeQuotient = lastInvocationSec / derivativeTimeConstantSec;
51 if (derivativeTimeConstantSec != 0) {
52 derivativeResult = LowpassFilter.calculate(derivativeResult, error - previousError, timeQuotient);
53 previousError = error;
56 // integral calculation
57 integralResult += error * lastInvocationMs / loopTimeMs;
60 final double proportionalPart = kp * error;
61 final double integralPart = ki * integralResult;
62 final double derivativePart = kd * derivativeResult;
63 output = proportionalPart + integralPart + derivativePart;
65 return new PIDOutputDTO(output, proportionalPart, integralPart, derivativePart, error);
68 public void setIntegralResult(double integralResult) {
69 this.integralResult = integralResult;
72 public void setDerivativeResult(double derivativeResult) {
73 this.derivativeResult = derivativeResult;