]> git.basschouten.com Git - openhab-addons.git/blob
8d73c758f43e95fb45ce4e91919b5f7371ff5ade
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.automation.pidcontroller.internal.handler;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.openhab.automation.pidcontroller.internal.LowpassFilter;
17
18 /**
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
21  *
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
25  */
26 @NonNullByDefault
27 class PIDController {
28     private double integralResult;
29     private double derivativeResult;
30     private double previousError;
31     private double output;
32
33     private double kp;
34     private double ki;
35     private double kd;
36     private double derivativeTimeConstantSec;
37
38     public PIDController(double kpAdjuster, double kiAdjuster, double kdAdjuster, double derivativeTimeConstantSec) {
39         this.kp = kpAdjuster;
40         this.ki = kiAdjuster;
41         this.kd = kdAdjuster;
42         this.derivativeTimeConstantSec = derivativeTimeConstantSec;
43     }
44
45     public PIDOutputDTO calculate(double input, double setpoint, long lastInvocationMs, int loopTimeMs) {
46         final double lastInvocationSec = lastInvocationMs / 1000d;
47         final double error = setpoint - input;
48
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;
54         }
55
56         // integral calculation
57         integralResult += error * lastInvocationMs / loopTimeMs;
58
59         // calculate parts
60         final double proportionalPart = kp * error;
61         final double integralPart = ki * integralResult;
62         final double derivativePart = kd * derivativeResult;
63         output = proportionalPart + integralPart + derivativePart;
64
65         return new PIDOutputDTO(output, proportionalPart, integralPart, derivativePart, error);
66     }
67
68     public void setIntegralResult(double integralResult) {
69         this.integralResult = integralResult;
70     }
71
72     public void setDerivativeResult(double derivativeResult) {
73         this.derivativeResult = derivativeResult;
74     }
75 }