vdr-plugin-softhddevice-drm-gles 1.6.2
pidcontroller.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
10#include <cmath>
11
12#include "logger.h"
13#include "pidcontroller.h"
14
15#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
16#include <arpa/inet.h>
17#include <cstdio>
18#include <cstring>
19#include <sys/socket.h>
20#include <unistd.h>
21#endif
22
36cPidController::cPidController(double kp, double ki, double kd, double maxOutput)
37 : proportionalGain(kp),
38 integralGain(ki),
39 derivativeGain(kd),
40 maxOutput(maxOutput)
41{
42 // Calculate max integral so the I-term alone can never exceed the max output
43 if (integralGain > 0)
45 else
47}
48
57{
58 if (dt <= 0.0)
59 return 0.0;
60
61 // Error > 0 means we are below target
63
65
66 if (!firstRun) { // the dt value is not yet valid on the first run
67 integralSum += error * dt;
68
69 // Anti-Windup: Clamp the integrator
72
75 }
76
77 double output = pTerm + iTerm + dTerm;
78
80 firstRun = false;
81
82 output = std::min(output, maxOutput);
83 output = std::max(output, -maxOutput);
84
85 if (std::abs(output) >= maxOutput) {
86 LOGWARNING("pidcontroller: max output value exceeded. Resetting.");
87 Reset();
88 }
89#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
91#endif
92
93 return output;
94}
95
100{
101 firstRun = true;
102 pTerm = 0;
103 iTerm = 0;
104 dTerm = 0;
105 integralSum = 0.0;
106 previousError = 0.0;
107}
108
109#ifdef PID_CONTROLLER_TUNING_AID_ADDRESS
121void cPidController::SendTuningAidData(double pTerm, double iTerm, double dTerm, double input, double output, double targetValue)
122{
123 static int sock = -1;
124 static struct sockaddr_in dest_addr;
125
126 // One-time setup check
127 if (sock < 0) {
129
130 memset(&dest_addr, 0, sizeof(dest_addr));
131 dest_addr.sin_family = AF_INET;
132 dest_addr.sin_port = htons(9870); // PlotJuggler port
133 inet_pton(AF_INET, PID_CONTROLLER_TUNING_AID_ADDRESS, &dest_addr.sin_addr); // replace with your PC's IP
134 }
135
136 // Actual Payload
137 char payload[512];
138 int len = snprintf(payload, sizeof(payload),
139 "{\"bufferFillLevelMs\":%g,\"targetBufferFillLevelMs\":%g,\"pTerm\":%g,\"iTerm\":%g,\"dTerm\":%g,\"outputPpm\":%g}",
141
142 // Send (Non-blocking usually, very fast)
143 sendto(sock, payload, len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
144}
145#endif
146
double integralGain
Integral Gain (Ki) - Drift correction.
double targetValue
The desired buffer fill level in frames.
double integralSum
Accumulator for the I-term.
double maxOutput
Hard limit for output correction.
double maxIntegral
Anti-windup limit for the integral term.
double iTerm
Integral term.
double dTerm
Derivative term.
double proportionalGain
Proportional Gain (Kp) - Reaction strength.
double pTerm
Proportional term.
bool firstRun
Flag for first run.
double previousError
Error from the previous step (for D-term)
double derivativeGain
Derivative Gain (Kd) - Dampening.
void Reset()
Reset the internal state (integral sum and error history).
cPidController(double, double, double, double)
Create a PID Controller.
double Update(double, double)
Calculate the new output value.
#define LOGWARNING
log to LOG_WARN
Definition logger.h:36
Logger Header File.
PID (proportional, integral, derivative) Controller Header File.